]>
git.proxmox.com Git - ovs.git/blob - tests/test-ovsdb.py
1 # Copyright (c) 2009, 2010, 2011, 2012, 2016 Nicira, Inc.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 from __future__
import print_function
30 from ovs
.db
import data
31 from ovs
.db
import error
32 from ovs
.fatal_signal
import signal_alarm
38 if type(json
) == list and len(json
) == 1:
44 def do_default_atoms():
45 for type_
in ovs
.db
.types
.ATOMIC_TYPES
:
46 if type_
== ovs
.db
.types
.VoidType
:
49 sys
.stdout
.write("%s: " % type_
.to_string())
51 atom
= data
.Atom
.default(type_
)
52 if atom
!= data
.Atom
.default(type_
):
53 sys
.stdout
.write("wrong\n")
56 sys
.stdout
.write("OK\n")
59 def do_default_data():
62 for key
in ovs
.db
.types
.ATOMIC_TYPES
:
63 if key
== ovs
.db
.types
.VoidType
:
65 for value
in ovs
.db
.types
.ATOMIC_TYPES
:
66 if value
== ovs
.db
.types
.VoidType
:
69 valueBase
= ovs
.db
.types
.BaseType(value
)
70 type_
= ovs
.db
.types
.Type(ovs
.db
.types
.BaseType(key
),
72 assert type_
.is_valid()
74 sys
.stdout
.write("key %s, value %s, n_min %d: "
75 % (key
.to_string(), value
.to_string(), n_min
))
77 datum
= data
.Datum
.default(type_
)
78 if datum
!= data
.Datum
.default(type_
):
79 sys
.stdout
.write("wrong\n")
82 sys
.stdout
.write("OK\n")
87 def do_parse_atomic_type(type_string
):
88 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
89 atomic_type
= ovs
.db
.types
.AtomicType
.from_json(type_json
)
90 print(ovs
.json
.to_string(atomic_type
.to_json(), sort_keys
=True))
93 def do_parse_base_type(type_string
):
94 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
95 base_type
= ovs
.db
.types
.BaseType
.from_json(type_json
)
96 print(ovs
.json
.to_string(base_type
.to_json(), sort_keys
=True))
99 def do_parse_type(type_string
):
100 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
101 type_
= ovs
.db
.types
.Type
.from_json(type_json
)
102 print(ovs
.json
.to_string(type_
.to_json(), sort_keys
=True))
105 def do_parse_atoms(type_string
, *atom_strings
):
106 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
107 base
= ovs
.db
.types
.BaseType
.from_json(type_json
)
108 for atom_string
in atom_strings
:
109 atom_json
= unbox_json(ovs
.json
.from_string(atom_string
))
111 atom
= data
.Atom
.from_json(base
, atom_json
)
112 print(ovs
.json
.to_string(atom
.to_json()))
113 except error
.Error
as e
:
117 def do_parse_data(type_string
, *data_strings
):
118 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
119 type_
= ovs
.db
.types
.Type
.from_json(type_json
)
120 for datum_string
in data_strings
:
121 datum_json
= unbox_json(ovs
.json
.from_string(datum_string
))
122 datum
= data
.Datum
.from_json(type_
, datum_json
)
123 print(ovs
.json
.to_string(datum
.to_json()))
126 def do_sort_atoms(type_string
, atom_strings
):
127 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
128 base
= ovs
.db
.types
.BaseType
.from_json(type_json
)
129 atoms
= [data
.Atom
.from_json(base
, atom_json
)
130 for atom_json
in unbox_json(ovs
.json
.from_string(atom_strings
))]
131 print(ovs
.json
.to_string([data
.Atom
.to_json(atom
)
132 for atom
in sorted(atoms
)]))
135 def do_parse_column(name
, column_string
):
136 column_json
= unbox_json(ovs
.json
.from_string(column_string
))
137 column
= ovs
.db
.schema
.ColumnSchema
.from_json(column_json
, name
)
138 print(ovs
.json
.to_string(column
.to_json(), sort_keys
=True))
141 def do_parse_table(name
, table_string
, default_is_root_string
='false'):
142 default_is_root
= default_is_root_string
== 'true'
143 table_json
= unbox_json(ovs
.json
.from_string(table_string
))
144 table
= ovs
.db
.schema
.TableSchema
.from_json(table_json
, name
)
145 print(ovs
.json
.to_string(table
.to_json(default_is_root
), sort_keys
=True))
148 def do_parse_schema(schema_string
):
149 schema_json
= unbox_json(ovs
.json
.from_string(schema_string
))
150 schema
= ovs
.db
.schema
.DbSchema
.from_json(schema_json
)
151 print(ovs
.json
.to_string(schema
.to_json(), sort_keys
=True))
154 def get_simple_printable_row_string(row
, columns
):
156 for column
in columns
:
157 if hasattr(row
, column
) and not (type(getattr(row
, column
))
158 is ovs
.db
.data
.Atom
):
159 value
= getattr(row
, column
)
160 if isinstance(value
, dict):
161 value
= sorted(value
.items())
162 s
+= "%s=%s " % (column
, value
)
164 s
= re
.sub('""|,|u?\'', "", s
)
165 s
= re
.sub('UUID\(([^)]+)\)', r
'\1', s
)
166 s
= re
.sub('False', 'false', s
)
167 s
= re
.sub('True', 'true', s
)
168 s
= re
.sub(r
'(ba)=([^[][^ ]*) ', r
'\1=[\2] ', s
)
172 def get_simple_table_printable_row(row
):
173 simple_columns
= ["i", "r", "b", "s", "u", "ia",
174 "ra", "ba", "sa", "ua", "uuid"]
175 return get_simple_printable_row_string(row
, simple_columns
)
178 def get_simple2_table_printable_row(row
):
179 simple2_columns
= ["name", "smap", "imap"]
180 return get_simple_printable_row_string(row
, simple2_columns
)
183 def get_simple3_table_printable_row(row
):
184 simple3_columns
= ["name", "uset"]
185 return get_simple_printable_row_string(row
, simple3_columns
)
188 def print_idl(idl
, step
):
190 if "simple" in idl
.tables
:
191 simple
= idl
.tables
["simple"].rows
192 for row
in six
.itervalues(simple
):
194 s
+= get_simple_table_printable_row(row
)
198 if "simple2" in idl
.tables
:
199 simple2
= idl
.tables
["simple2"].rows
200 for row
in six
.itervalues(simple2
):
202 s
+= get_simple2_table_printable_row(row
)
206 if "simple3" in idl
.tables
:
207 simple3
= idl
.tables
["simple3"].rows
208 for row
in six
.itervalues(simple3
):
210 s
+= get_simple3_table_printable_row(row
)
214 if "link1" in idl
.tables
:
215 l1
= idl
.tables
["link1"].rows
216 for row
in six
.itervalues(l1
):
217 s
= ["%03d: i=%s k=" % (step
, row
.i
)]
218 if hasattr(row
, "k") and row
.k
:
219 s
.append(str(row
.k
.i
))
220 if hasattr(row
, "ka"):
222 s
.append(' '.join(sorted(str(ka
.i
) for ka
in row
.ka
)))
224 if hasattr(row
, "l2") and row
.l2
:
225 s
.append(str(row
.l2
[0].i
))
226 if hasattr(row
, "uuid"):
227 s
.append(" uuid=%s" % row
.uuid
)
231 if "link2" in idl
.tables
:
232 l2
= idl
.tables
["link2"].rows
233 for row
in six
.itervalues(l2
):
235 s
.append(" i=%s l1=" % row
.i
)
236 if hasattr(row
, "l1") and row
.l1
:
237 s
.append(str(row
.l1
[0].i
))
238 if hasattr(row
, "uuid"):
239 s
.append(" uuid=%s" % row
.uuid
)
244 print("%03d: empty" % step
)
248 def substitute_uuids(json
, symtab
):
249 if isinstance(json
, six
.string_types
):
250 symbol
= symtab
.get(json
)
253 elif type(json
) == list:
254 return [substitute_uuids(element
, symtab
) for element
in json
]
255 elif type(json
) == dict:
257 for key
, value
in six
.iteritems(json
):
258 d
[key
] = substitute_uuids(value
, symtab
)
263 def parse_uuids(json
, symtab
):
264 if (isinstance(json
, six
.string_types
)
265 and ovs
.ovsuuid
.is_valid_string(json
)):
266 name
= "#%d#" % len(symtab
)
267 sys
.stderr
.write("%s = %s\n" % (name
, json
))
269 elif type(json
) == list:
271 parse_uuids(element
, symtab
)
272 elif type(json
) == dict:
273 for value
in six
.itervalues(json
):
274 parse_uuids(value
, symtab
)
277 def idltest_find_simple(idl
, i
):
278 for row
in six
.itervalues(idl
.tables
["simple"].rows
):
284 def idltest_find_simple2(idl
, i
):
285 for row
in six
.itervalues(idl
.tables
["simple2"].rows
):
291 def idltest_find_simple3(idl
, i
):
292 for row
in six
.itervalues(idl
.tables
["simple3"].rows
):
298 def idl_set(idl
, commands
, step
):
299 txn
= ovs
.db
.idl
.Transaction(idl
)
303 for command
in commands
.split(','):
304 words
= command
.split()
308 if name
== "notifytest":
311 old_notify
= idl
.notify
313 def notify(event
, row
, updates
=None):
315 upcol
= list(updates
._data
.keys())[0]
318 events
.append("%s|%s|%s" % (event
, row
.i
, upcol
))
319 idl
.notify
= old_notify
325 sys
.stderr
.write('"set" command requires 3 arguments\n')
328 s
= idltest_find_simple(idl
, int(args
[0]))
330 sys
.stderr
.write('"set" command asks for nonexistent i=%d\n'
338 s
.s
= args
[2].decode('utf-8')
340 s
.s
= args
[2].encode('utf-8', 'surrogateescape') \
341 .decode('utf-8', 'replace')
343 s
.u
= uuid
.UUID(args
[2])
347 sys
.stderr
.write('"set" comamnd asks for unknown column %s\n'
350 elif name
== "insert":
352 sys
.stderr
.write('"set" command requires 1 argument\n')
355 s
= txn
.insert(idl
.tables
["simple"])
357 elif name
== "delete":
359 sys
.stderr
.write('"delete" command requires 1 argument\n')
362 s
= idltest_find_simple(idl
, int(args
[0]))
364 sys
.stderr
.write('"delete" command asks for nonexistent i=%d\n'
368 elif name
== "verify":
370 sys
.stderr
.write('"verify" command requires 2 arguments\n')
373 s
= idltest_find_simple(idl
, int(args
[0]))
375 sys
.stderr
.write('"verify" command asks for nonexistent i=%d\n'
379 if args
[1] in ("i", "b", "s", "u", "r"):
382 sys
.stderr
.write('"verify" command asks for unknown column '
385 elif name
== "fetch":
387 sys
.stderr
.write('"fetch" command requires 2 argument\n')
390 row
= idltest_find_simple(idl
, int(args
[0]))
392 sys
.stderr
.write('"fetch" command asks for nonexistent i=%d\n'
398 fetch_cmds
.append([row
, column
])
399 elif name
== "increment":
401 sys
.stderr
.write('"increment" command requires 1 argument\n')
404 s
= idltest_find_simple(idl
, int(args
[0]))
406 sys
.stderr
.write('"set" command asks for nonexistent i=%d\n'
412 elif name
== "abort":
415 elif name
== "destroy":
416 print("%03d: destroy" % step
)
420 elif name
== "linktest":
421 l1_0
= txn
.insert(idl
.tables
["link1"])
425 l1_1
= txn
.insert(idl
.tables
["link1"])
428 l1_1
.ka
= [l1_0
, l1_1
]
429 elif name
== 'getattrtest':
430 l1
= txn
.insert(idl
.tables
["link1"])
431 i
= getattr(l1
, 'i', 1)
434 i
= getattr(l1
, 'i', 1)
437 elif name
== 'partialmapinsertelement':
438 row
= idltest_find_simple2(idl
, 'myString1')
439 len_smap
= len(getattr(row
, 'smap'))
440 row
.setkey('smap', 'key1', 'myList1')
441 len_imap
= len(getattr(row
, 'imap'))
442 row
.setkey('imap', 3, 'myids2')
443 row
.__setattr
__('name', 'String2')
444 assert len(getattr(row
, 'smap')) == len_smap
445 assert len(getattr(row
, 'imap')) == len_imap
+ 1
446 elif name
== 'partialmapinsertmultipleelements':
447 row
= idltest_find_simple2(idl
, 'String2')
448 len_smap
= len(getattr(row
, 'smap'))
449 row
.setkey('smap', 'key2', 'myList2')
450 row
.setkey('smap', 'key3', 'myList3')
451 row
.setkey('smap', 'key4', 'myList4')
452 assert len(getattr(row
, 'smap')) == len_smap
+ 2
453 elif name
== 'partialmapdelelements':
454 row
= idltest_find_simple2(idl
, 'String2')
455 len_smap
= len(getattr(row
, 'smap'))
456 row
.delkey('smap', 'key1', 'myList1')
457 row
.delkey('smap', 'key2', 'wrongvalue')
458 row
.delkey('smap', 'key3')
459 row
.delkey('smap', 'key4')
460 assert len(getattr(row
, 'smap')) == len_smap
- 3
461 elif name
== 'partialmapmutatenew':
462 new_row2
= txn
.insert(idl
.tables
["simple2"])
463 setattr(new_row2
, 'name', 'String2New')
464 new_row2
.setkey('smap', 'key1', 'newList1')
465 assert len(getattr(new_row2
, 'smap')) == 1
466 new_row2
.setkey('smap', 'key2', 'newList2')
467 assert len(getattr(new_row2
, 'smap')) == 2
468 elif name
== 'partialrenamesetadd':
469 row
= idltest_find_simple3(idl
, 'mySet1')
470 old_size
= len(getattr(row
, 'uset', []))
472 uuid
.UUID("001e43d2-dd3f-4616-ab6a-83a490bb0991"))
473 row
.__setattr
__('name', 'String2')
474 assert len(getattr(row
, 'uset', [])) == old_size
+ 1
475 elif name
== 'partialduplicateadd':
476 row
= idltest_find_simple3(idl
, 'String2')
477 old_size
= len(getattr(row
, 'uset', []))
479 uuid
.UUID("0026b3ba-571b-4729-8227-d860a5210ab8"))
481 uuid
.UUID("0026b3ba-571b-4729-8227-d860a5210ab8"))
482 assert len(getattr(row
, 'uset', [])) == old_size
+ 1
483 elif name
== 'partialsetdel':
484 row
= idltest_find_simple3(idl
, 'String2')
485 old_size
= len(getattr(row
, 'uset', []))
487 uuid
.UUID("001e43d2-dd3f-4616-ab6a-83a490bb0991"))
488 assert len(getattr(row
, 'uset', [])) == old_size
- 1
489 elif name
== 'partialsetref':
490 new_row
= txn
.insert(idl
.tables
["simple4"])
491 new_row
.__setattr
__('name', 'test')
492 row
= idltest_find_simple3(idl
, 'String2')
493 old_size
= len(getattr(row
, 'uref', []))
494 row
.addvalue('uref', new_row
.uuid
)
495 assert len(getattr(row
, 'uref', [])) == old_size
+ 1
496 elif name
== 'partialsetoverrideops':
497 row
= idltest_find_simple3(idl
, 'String2')
499 uuid
.UUID("579e978d-776c-4f19-a225-268e5890e670"))
501 uuid
.UUID("0026b3ba-571b-4729-8227-d860a5210ab8"))
502 row
.__setattr
__('uset',
503 [uuid
.UUID("0026b3ba-571b-4729-8227-d860a5210ab8")])
504 assert len(getattr(row
, 'uset', [])) == 1
505 elif name
== 'partialsetadddelete':
506 row
= idltest_find_simple3(idl
, 'String2')
508 uuid
.UUID('b6272353-af9c-40b7-90fe-32a43e6518a1'))
510 uuid
.UUID('1d6a71a2-dffb-426e-b2fa-b727091f9901'))
512 uuid
.UUID('0026b3ba-571b-4729-8227-d860a5210ab8'))
513 assert len(getattr(row
, 'uset', [])) == 2
514 elif name
== 'partialsetmutatenew':
515 new_row41
= txn
.insert(idl
.tables
["simple4"])
516 new_row41
.__setattr__('name', 'new_row41')
517 new_row3
= txn
.insert(idl
.tables
["simple3"])
518 setattr(new_row3
, 'name', 'String3')
519 new_row3
.addvalue('uset', new_row41
.uuid
)
520 assert len(getattr(new_row3
, 'uset', [])) == 1
522 sys
.stderr
.write("unknown command %s\n" % name
)
525 status
= txn
.commit_block()
526 sys
.stdout
.write("%03d: commit, status=%s"
527 % (step
, ovs
.db
.idl
.Transaction
.status_to_string(status
)))
528 if increment
and status
== ovs
.db
.idl
.Transaction
.SUCCESS
:
529 sys
.stdout
.write(", increment=%d" % txn
.get_increment_new_value())
531 # Event notifications from operations in a single transaction are
532 # not in a gauranteed order due to update messages being dicts
533 sys
.stdout
.write(", events=" + ", ".join(sorted(events
)))
534 sys
.stdout
.write("\n")
538 def update_condition(idl
, commands
):
539 commands
= commands
[len("condition "):].split(";")
540 for command
in commands
:
541 command
= command
.split(" ")
542 if(len(command
) != 2):
543 sys
.stderr
.write("Error parsing condition %s\n" % command
)
547 cond
= ovs
.json
.from_string(command
[1])
549 idl
.cond_change(table
, cond
)
552 def do_idl(schema_file
, remote
, *commands
):
553 schema_helper
= ovs
.db
.idl
.SchemaHelper(schema_file
)
556 if remote
.startswith("ssl:"):
557 ovs
.stream
.Stream
.ssl_set_private_key_file(commands
[0])
558 ovs
.stream
.Stream
.ssl_set_certificate_file(commands
[1])
559 ovs
.stream
.Stream
.ssl_set_ca_cert_file(commands
[2])
560 commands
= commands
[3:]
562 if commands
and commands
[0] == "track-notify":
563 commands
= commands
[1:]
566 if commands
and commands
[0].startswith("?"):
568 for x
in commands
[0][1:].split("?"):
570 table
, columns
= x
.split(":")
571 columns
= columns
.split(",")
572 for index
, column
in enumerate(columns
):
573 if column
[-1] == '!':
574 columns
[index
] = columns
[index
][:-1]
575 readonly
.append(columns
[index
])
576 schema_helper
.register_columns(table
, columns
, readonly
)
577 commands
= commands
[1:]
579 schema_helper
.register_all()
580 idl
= ovs
.db
.idl
.Idl(remote
, schema_helper
)
583 error
, stream
= ovs
.stream
.Stream
.open_block(
584 ovs
.stream
.Stream
.open(remote
))
586 sys
.stderr
.write("failed to connect to \"%s\"" % remote
)
588 rpc
= ovs
.jsonrpc
.Connection(stream
)
596 def mock_notify(event
, row
, updates
=None):
597 output
= "%03d: " % step
598 output
+= "event:" + str(event
) + ", row={"
599 output
+= get_simple_table_printable_row(row
) + "}, updates="
603 output
+= "{" + get_simple_table_printable_row(updates
) + "}"
606 sys
.stdout
.write(output
)
609 if track_notify
and "simple" in idl
.tables
:
610 idl
.notify
= mock_notify
612 commands
= list(commands
)
613 if len(commands
) >= 1 and "condition" in commands
[0]:
614 update_condition(idl
, commands
.pop(0))
615 sys
.stdout
.write("%03d: change conditions\n" % step
)
619 for command
in commands
:
620 if command
.startswith("+"):
621 # The previous transaction didn't change anything.
622 command
= command
[1:]
625 while idl
.change_seqno
== seqno
and not idl
.run():
628 poller
= ovs
.poller
.Poller()
636 seqno
= idl
.change_seqno
638 if command
== "reconnect":
639 print("%03d: reconnect" % step
)
642 idl
.force_reconnect()
643 elif "condition" in command
:
644 update_condition(idl
, command
)
645 sys
.stdout
.write("%03d: change conditions\n" % step
)
648 elif not command
.startswith("["):
649 idl_set(idl
, command
, step
)
652 json
= ovs
.json
.from_string(command
)
653 if isinstance(json
, six
.string_types
):
654 sys
.stderr
.write("\"%s\": %s\n" % (command
, json
))
656 json
= substitute_uuids(json
, symtab
)
657 request
= ovs
.jsonrpc
.Message
.create_request("transact", json
)
658 error
, reply
= rpc
.transact_block(request
)
660 sys
.stderr
.write("jsonrpc transaction failed: %s"
661 % os
.strerror(error
))
663 elif reply
.error
is not None:
664 sys
.stderr
.write("jsonrpc transaction failed: %s"
668 sys
.stdout
.write("%03d: " % step
)
671 if reply
.result
is not None:
672 parse_uuids(reply
.result
, symtab
)
674 sys
.stdout
.write("%s\n" % ovs
.json
.to_string(reply
.to_json()))
679 while idl
.change_seqno
== seqno
and not idl
.run():
680 poller
= ovs
.poller
.Poller()
686 print("%03d: done" % step
)
689 def do_idl_passive(schema_file
, remote
, *commands
):
692 schema_helper
= ovs
.db
.idl
.SchemaHelper(schema_file
)
693 schema_helper
.register_all()
694 idl
= ovs
.db
.idl
.Idl(remote
, schema_helper
)
696 while idl
._session
.rpc
is None:
699 rpc
= idl
._session
.rpc
704 for command
in commands
:
705 json
= ovs
.json
.from_string(command
)
706 if isinstance(json
, six
.string_types
):
707 sys
.stderr
.write("\"%s\": %s\n" % (command
, json
))
709 json
= substitute_uuids(json
, symtab
)
710 request
= ovs
.jsonrpc
.Message
.create_request("transact", json
)
711 error
, reply
= rpc
.transact_block(request
)
713 sys
.stderr
.write("jsonrpc transaction failed: %s"
714 % os
.strerror(error
))
716 elif reply
.error
is not None:
717 sys
.stderr
.write("jsonrpc transaction failed: %s"
721 sys
.stdout
.write("%03d: " % step
)
724 if reply
.result
is not None:
725 parse_uuids(reply
.result
, symtab
)
727 sys
.stdout
.write("%s\n" % ovs
.json
.to_string(reply
.to_json()))
731 print("%03d: done" % step
)
736 %(program_name)s: test utility for Open vSwitch database Python bindings
737 usage: %(program_name)s [OPTIONS] COMMAND ARG...
739 The following commands are supported:
741 test ovsdb_atom_default()
743 test ovsdb_datum_default()
744 parse-atomic-type TYPE
745 parse TYPE as OVSDB atomic type, and re-serialize
747 parse TYPE as OVSDB base type, and re-serialize
749 parse JSON as OVSDB type, and re-serialize
750 parse-atoms TYPE ATOM...
751 parse JSON ATOMs as atoms of TYPE, and re-serialize
752 parse-atom-strings TYPE ATOM...
753 parse string ATOMs as atoms of given TYPE, and re-serialize
754 sort-atoms TYPE ATOM...
755 print JSON ATOMs in sorted order
756 parse-data TYPE DATUM...
757 parse JSON DATUMs as data of given TYPE, and re-serialize
758 parse-column NAME OBJECT
759 parse column NAME with info OBJECT, and re-serialize
760 parse-table NAME OBJECT [DEFAULT-IS-ROOT]
761 parse table NAME with info OBJECT
763 parse JSON as an OVSDB schema, and re-serialize
764 idl SCHEMA SERVER [?T1:C1,C2...[?T2:C1,C2,...]...] [TRANSACTION...]
765 connect to SERVER (which has the specified SCHEMA) and dump the
766 contents of the database as seen initially by the IDL implementation
767 and after executing each TRANSACTION. (Each TRANSACTION must modify
768 the database or this command will hang.)
769 By default, all columns of all tables are monitored. The "?" option
770 can be used to monitor specific Table:Column(s). The table and their
771 columns are listed as a string of the form starting with "?":
772 ?<table-name>:<column-name>,<column-name>,...
774 ?simple:b - Monitor column "b" in table "simple"
775 Entries for multiple tables are seperated by "?":
776 ?<table-name>:<column-name>,...?<table-name>:<column-name>,...
778 ?simple:b?link1:i,k - Monitor column "b" in table "simple",
779 and column "i", "k" in table "link1"
780 Readonly columns: Suffixing a "!" after a column indicates that the
781 column is to be registered "readonly".
783 ?simple:i,b! - Register interest in column "i" (monitoring) and
784 column "b" (readonly).
787 The following options are also available:
788 -t, --timeout=SECS give up after SECS seconds
789 -h, --help display this help message\
790 """ % {'program_name': ovs
.util
.PROGRAM_NAME
})
796 options
, args
= getopt
.gnu_getopt(argv
[1:], 't:h',
799 except getopt
.GetoptError
as geo
:
800 sys
.stderr
.write("%s: %s\n" % (ovs
.util
.PROGRAM_NAME
, geo
.msg
))
803 for key
, value
in options
:
804 if key
in ['-h', '--help']:
806 elif key
in ['-t', '--timeout']:
812 raise error
.Error("value %s on -t or --timeout is not at "
814 signal_alarm(timeout
)
819 sys
.stderr
.write("%s: missing command argument "
820 "(use --help for help)\n" % ovs
.util
.PROGRAM_NAME
)
823 commands
= {"default-atoms": (do_default_atoms
, 0),
824 "default-data": (do_default_data
, 0),
825 "parse-atomic-type": (do_parse_atomic_type
, 1),
826 "parse-base-type": (do_parse_base_type
, 1),
827 "parse-type": (do_parse_type
, 1),
828 "parse-atoms": (do_parse_atoms
, (2,)),
829 "parse-data": (do_parse_data
, (2,)),
830 "sort-atoms": (do_sort_atoms
, 2),
831 "parse-column": (do_parse_column
, 2),
832 "parse-table": (do_parse_table
, (2, 3)),
833 "parse-schema": (do_parse_schema
, 1),
834 "idl": (do_idl
, (2,)),
835 "idl_passive": (do_idl_passive
, (2,))}
837 command_name
= args
[0]
839 if command_name
not in commands
:
840 sys
.stderr
.write("%s: unknown command \"%s\" "
841 "(use --help for help)\n" % (ovs
.util
.PROGRAM_NAME
,
845 func
, n_args
= commands
[command_name
]
846 if type(n_args
) == tuple:
847 if len(args
) < n_args
[0]:
848 sys
.stderr
.write("%s: \"%s\" requires at least %d arguments but "
850 % (ovs
.util
.PROGRAM_NAME
, command_name
,
853 elif type(n_args
) == int:
854 if len(args
) != n_args
:
855 sys
.stderr
.write("%s: \"%s\" requires %d arguments but %d "
857 % (ovs
.util
.PROGRAM_NAME
, command_name
,
866 if __name__
== '__main__':
869 except error
.Error
as e
:
870 sys
.stderr
.write("%s\n" % e
)