1 # Copyright (c) 2009, 2010, 2011, 2012 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.
22 from ovs.db import error
25 from ovs.db import data
26 from ovs.db import types
33 if type(json) == list and len(json) == 1:
39 def do_default_atoms():
40 for type_ in types.ATOMIC_TYPES:
41 if type_ == types.VoidType:
44 sys.stdout.write("%s: " % type_.to_string())
46 atom = data.Atom.default(type_)
47 if atom != data.Atom.default(type_):
48 sys.stdout.write("wrong\n")
51 sys.stdout.write("OK\n")
54 def do_default_data():
57 for key in types.ATOMIC_TYPES:
58 if key == types.VoidType:
60 for value in types.ATOMIC_TYPES:
61 if value == types.VoidType:
64 valueBase = types.BaseType(value)
65 type_ = types.Type(types.BaseType(key), valueBase, n_min, 1)
66 assert type_.is_valid()
68 sys.stdout.write("key %s, value %s, n_min %d: "
69 % (key.to_string(), value.to_string(), n_min))
71 datum = data.Datum.default(type_)
72 if datum != data.Datum.default(type_):
73 sys.stdout.write("wrong\n")
76 sys.stdout.write("OK\n")
81 def do_parse_atomic_type(type_string):
82 type_json = unbox_json(ovs.json.from_string(type_string))
83 atomic_type = types.AtomicType.from_json(type_json)
84 print ovs.json.to_string(atomic_type.to_json(), sort_keys=True)
87 def do_parse_base_type(type_string):
88 type_json = unbox_json(ovs.json.from_string(type_string))
89 base_type = types.BaseType.from_json(type_json)
90 print ovs.json.to_string(base_type.to_json(), sort_keys=True)
93 def do_parse_type(type_string):
94 type_json = unbox_json(ovs.json.from_string(type_string))
95 type_ = types.Type.from_json(type_json)
96 print ovs.json.to_string(type_.to_json(), sort_keys=True)
99 def do_parse_atoms(type_string, *atom_strings):
100 type_json = unbox_json(ovs.json.from_string(type_string))
101 base = types.BaseType.from_json(type_json)
102 for atom_string in atom_strings:
103 atom_json = unbox_json(ovs.json.from_string(atom_string))
105 atom = data.Atom.from_json(base, atom_json)
106 print ovs.json.to_string(atom.to_json())
107 except error.Error, e:
108 print e.args[0].encode("utf8")
111 def do_parse_data(type_string, *data_strings):
112 type_json = unbox_json(ovs.json.from_string(type_string))
113 type_ = types.Type.from_json(type_json)
114 for datum_string in data_strings:
115 datum_json = unbox_json(ovs.json.from_string(datum_string))
116 datum = data.Datum.from_json(type_, datum_json)
117 print ovs.json.to_string(datum.to_json())
120 def do_sort_atoms(type_string, atom_strings):
121 type_json = unbox_json(ovs.json.from_string(type_string))
122 base = types.BaseType.from_json(type_json)
123 atoms = [data.Atom.from_json(base, atom_json)
124 for atom_json in unbox_json(ovs.json.from_string(atom_strings))]
125 print ovs.json.to_string([data.Atom.to_json(atom)
126 for atom in sorted(atoms)])
129 def do_parse_column(name, column_string):
130 column_json = unbox_json(ovs.json.from_string(column_string))
131 column = ovs.db.schema.ColumnSchema.from_json(column_json, name)
132 print ovs.json.to_string(column.to_json(), sort_keys=True)
135 def do_parse_table(name, table_string, default_is_root_string='false'):
136 default_is_root = default_is_root_string == 'true'
137 table_json = unbox_json(ovs.json.from_string(table_string))
138 table = ovs.db.schema.TableSchema.from_json(table_json, name)
139 print ovs.json.to_string(table.to_json(default_is_root), sort_keys=True)
142 def do_parse_schema(schema_string):
143 schema_json = unbox_json(ovs.json.from_string(schema_string))
144 schema = ovs.db.schema.DbSchema.from_json(schema_json)
145 print ovs.json.to_string(schema.to_json(), sort_keys=True)
148 def print_idl(idl, step):
149 simple = idl.tables["simple"].rows
150 l1 = idl.tables["link1"].rows
151 l2 = idl.tables["link2"].rows
154 for row in simple.itervalues():
155 s = ("%03d: i=%s r=%s b=%s s=%s u=%s "
156 "ia=%s ra=%s ba=%s sa=%s ua=%s uuid=%s"
157 % (step, row.i, row.r, row.b, row.s, row.u,
158 row.ia, row.ra, row.ba, row.sa, row.ua, row.uuid))
159 s = re.sub('""|,|u?\'', "", s)
160 s = re.sub('UUID\(([^)]+)\)', r'\1', s)
161 s = re.sub('False', 'false', s)
162 s = re.sub('True', 'true', s)
163 s = re.sub(r'(ba)=([^[][^ ]*) ', r'\1=[\2] ', s)
167 for row in l1.itervalues():
168 s = ["%03d: i=%s k=" % (step, row.i)]
170 s.append(str(row.k.i))
172 s.append(' '.join(sorted(str(ka.i) for ka in row.ka)))
175 s.append(str(row.l2[0].i))
176 s.append(" uuid=%s" % row.uuid)
180 for row in l2.itervalues():
181 s = ["%03d: i=%s l1=" % (step, row.i)]
183 s.append(str(row.l1[0].i))
184 s.append(" uuid=%s" % row.uuid)
189 print("%03d: empty" % step)
193 def substitute_uuids(json, symtab):
194 if type(json) in [str, unicode]:
195 symbol = symtab.get(json)
198 elif type(json) == list:
199 return [substitute_uuids(element, symtab) for element in json]
200 elif type(json) == dict:
202 for key, value in json.iteritems():
203 d[key] = substitute_uuids(value, symtab)
208 def parse_uuids(json, symtab):
209 if type(json) in [str, unicode] and ovs.ovsuuid.is_valid_string(json):
210 name = "#%d#" % len(symtab)
211 sys.stderr.write("%s = %s\n" % (name, json))
213 elif type(json) == list:
215 parse_uuids(element, symtab)
216 elif type(json) == dict:
217 for value in json.itervalues():
218 parse_uuids(value, symtab)
221 def idltest_find_simple(idl, i):
222 for row in idl.tables["simple"].rows.itervalues():
228 def idl_set(idl, commands, step):
229 txn = ovs.db.idl.Transaction(idl)
232 for command in commands.split(','):
233 words = command.split()
237 if name == "notifytest":
240 old_notify = idl.notify
242 def notify(event, row, updates=None):
243 upcol = updates._data.keys()[0] if updates else None
244 events.append("%s|%s|%s" % (event, row.i, upcol))
245 idl.notify = old_notify
251 sys.stderr.write('"set" command requires 3 arguments\n')
254 s = idltest_find_simple(idl, int(args[0]))
256 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
265 s.u = uuid.UUID(args[2])
269 sys.stderr.write('"set" comamnd asks for unknown column %s\n'
272 elif name == "insert":
274 sys.stderr.write('"set" command requires 1 argument\n')
277 s = txn.insert(idl.tables["simple"])
279 elif name == "delete":
281 sys.stderr.write('"delete" command requires 1 argument\n')
284 s = idltest_find_simple(idl, int(args[0]))
286 sys.stderr.write('"delete" command asks for nonexistent i=%d\n'
290 elif name == "verify":
292 sys.stderr.write('"verify" command requires 2 arguments\n')
295 s = idltest_find_simple(idl, int(args[0]))
297 sys.stderr.write('"verify" command asks for nonexistent i=%d\n'
301 if args[1] in ("i", "b", "s", "u", "r"):
304 sys.stderr.write('"verify" command asks for unknown column '
307 elif name == "increment":
309 sys.stderr.write('"increment" command requires 1 argument\n')
312 s = idltest_find_simple(idl, int(args[0]))
314 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
320 elif name == "abort":
323 elif name == "destroy":
324 print "%03d: destroy" % step
328 elif name == "linktest":
329 l1_0 = txn.insert(idl.tables["link1"])
333 l1_1 = txn.insert(idl.tables["link1"])
336 l1_1.ka = [l1_0, l1_1]
337 elif name == 'getattrtest':
338 l1 = txn.insert(idl.tables["link1"])
339 i = getattr(l1, 'i', 1)
342 i = getattr(l1, 'i', 1)
346 sys.stderr.write("unknown command %s\n" % name)
349 status = txn.commit_block()
350 sys.stdout.write("%03d: commit, status=%s"
351 % (step, ovs.db.idl.Transaction.status_to_string(status)))
352 if increment and status == ovs.db.idl.Transaction.SUCCESS:
353 sys.stdout.write(", increment=%d" % txn.get_increment_new_value())
355 # Event notifications from operations in a single transaction are
356 # not in a gauranteed order due to update messages being dicts
357 sys.stdout.write(", events=" + ", ".join(sorted(events)))
358 sys.stdout.write("\n")
362 def do_idl(schema_file, remote, *commands):
363 schema_helper = ovs.db.idl.SchemaHelper(schema_file)
364 schema_helper.register_all()
365 idl = ovs.db.idl.Idl(remote, schema_helper)
368 error, stream = ovs.stream.Stream.open_block(
369 ovs.stream.Stream.open(remote))
371 sys.stderr.write("failed to connect to \"%s\"" % remote)
373 rpc = ovs.jsonrpc.Connection(stream)
380 for command in commands:
381 if command.startswith("+"):
382 # The previous transaction didn't change anything.
383 command = command[1:]
386 while idl.change_seqno == seqno and not idl.run():
389 poller = ovs.poller.Poller()
397 seqno = idl.change_seqno
399 if command == "reconnect":
400 print("%03d: reconnect" % step)
403 idl.force_reconnect()
404 elif not command.startswith("["):
405 idl_set(idl, command, step)
408 json = ovs.json.from_string(command)
409 if type(json) in [str, unicode]:
410 sys.stderr.write("\"%s\": %s\n" % (command, json))
412 json = substitute_uuids(json, symtab)
413 request = ovs.jsonrpc.Message.create_request("transact", json)
414 error, reply = rpc.transact_block(request)
416 sys.stderr.write("jsonrpc transaction failed: %s"
417 % os.strerror(error))
419 elif reply.error is not None:
420 sys.stderr.write("jsonrpc transaction failed: %s"
424 sys.stdout.write("%03d: " % step)
427 if reply.result is not None:
428 parse_uuids(reply.result, symtab)
430 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
435 while idl.change_seqno == seqno and not idl.run():
436 poller = ovs.poller.Poller()
442 print("%03d: done" % step)
447 %(program_name)s: test utility for Open vSwitch database Python bindings
448 usage: %(program_name)s [OPTIONS] COMMAND ARG...
450 The following commands are supported:
452 test ovsdb_atom_default()
454 test ovsdb_datum_default()
455 parse-atomic-type TYPE
456 parse TYPE as OVSDB atomic type, and re-serialize
458 parse TYPE as OVSDB base type, and re-serialize
460 parse JSON as OVSDB type, and re-serialize
461 parse-atoms TYPE ATOM...
462 parse JSON ATOMs as atoms of TYPE, and re-serialize
463 parse-atom-strings TYPE ATOM...
464 parse string ATOMs as atoms of given TYPE, and re-serialize
465 sort-atoms TYPE ATOM...
466 print JSON ATOMs in sorted order
467 parse-data TYPE DATUM...
468 parse JSON DATUMs as data of given TYPE, and re-serialize
469 parse-column NAME OBJECT
470 parse column NAME with info OBJECT, and re-serialize
471 parse-table NAME OBJECT [DEFAULT-IS-ROOT]
472 parse table NAME with info OBJECT
474 parse JSON as an OVSDB schema, and re-serialize
475 idl SCHEMA SERVER [TRANSACTION...]
476 connect to SERVER (which has the specified SCHEMA) and dump the
477 contents of the database as seen initially by the IDL implementation
478 and after executing each TRANSACTION. (Each TRANSACTION must modify
479 the database or this command will hang.)
481 The following options are also available:
482 -t, --timeout=SECS give up after SECS seconds
483 -h, --help display this help message\
484 """ % {'program_name': ovs.util.PROGRAM_NAME}
490 options, args = getopt.gnu_getopt(argv[1:], 't:h',
493 except getopt.GetoptError, geo:
494 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
497 for key, value in options:
498 if key in ['-h', '--help']:
500 elif key in ['-t', '--timeout']:
506 raise error.Error("value %s on -t or --timeout is not at "
508 signal.alarm(timeout)
513 sys.stderr.write("%s: missing command argument "
514 "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
517 commands = {"default-atoms": (do_default_atoms, 0),
518 "default-data": (do_default_data, 0),
519 "parse-atomic-type": (do_parse_atomic_type, 1),
520 "parse-base-type": (do_parse_base_type, 1),
521 "parse-type": (do_parse_type, 1),
522 "parse-atoms": (do_parse_atoms, (2,)),
523 "parse-data": (do_parse_data, (2,)),
524 "sort-atoms": (do_sort_atoms, 2),
525 "parse-column": (do_parse_column, 2),
526 "parse-table": (do_parse_table, (2, 3)),
527 "parse-schema": (do_parse_schema, 1),
528 "idl": (do_idl, (2,))}
530 command_name = args[0]
532 if not command_name in commands:
533 sys.stderr.write("%s: unknown command \"%s\" "
534 "(use --help for help)\n" % (ovs.util.PROGRAM_NAME,
538 func, n_args = commands[command_name]
539 if type(n_args) == tuple:
540 if len(args) < n_args[0]:
541 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
543 % (ovs.util.PROGRAM_NAME, command_name,
546 elif type(n_args) == int:
547 if len(args) != n_args:
548 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
550 % (ovs.util.PROGRAM_NAME, command_name,
559 if __name__ == '__main__':
562 except error.Error, e:
563 sys.stderr.write("%s\n" % e)