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:
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)
231 for command in commands.split(','):
232 words = command.split()
238 sys.stderr.write('"set" command requires 3 arguments\n')
241 s = idltest_find_simple(idl, int(args[0]))
243 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
252 s.u = uuid.UUID(args[2])
256 sys.stderr.write('"set" comamnd asks for unknown column %s\n'
259 elif name == "insert":
261 sys.stderr.write('"set" command requires 1 argument\n')
264 s = txn.insert(idl.tables["simple"])
266 elif name == "delete":
268 sys.stderr.write('"delete" command requires 1 argument\n')
271 s = idltest_find_simple(idl, int(args[0]))
273 sys.stderr.write('"delete" command asks for nonexistent i=%d\n'
277 elif name == "verify":
279 sys.stderr.write('"verify" command requires 2 arguments\n')
282 s = idltest_find_simple(idl, int(args[0]))
284 sys.stderr.write('"verify" command asks for nonexistent i=%d\n'
288 if args[1] in ("i", "b", "s", "u", "r"):
291 sys.stderr.write('"verify" command asks for unknown column '
294 elif name == "increment":
296 sys.stderr.write('"increment" command requires 1 argument\n')
299 s = idltest_find_simple(idl, int(args[0]))
301 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
307 elif name == "abort":
310 elif name == "destroy":
311 print "%03d: destroy" % step
315 elif name == "linktest":
316 l1_0 = txn.insert(idl.tables["link1"])
320 l1_1 = txn.insert(idl.tables["link1"])
323 l1_1.ka = [l1_0, l1_1]
324 elif name == 'getattrtest':
325 l1 = txn.insert(idl.tables["link1"])
326 i = getattr(l1, 'i', 1)
329 i = getattr(l1, 'i', 1)
333 sys.stderr.write("unknown command %s\n" % name)
336 status = txn.commit_block()
337 sys.stdout.write("%03d: commit, status=%s"
338 % (step, ovs.db.idl.Transaction.status_to_string(status)))
339 if increment and status == ovs.db.idl.Transaction.SUCCESS:
340 sys.stdout.write(", increment=%d" % txn.get_increment_new_value())
341 sys.stdout.write("\n")
345 def do_idl(schema_file, remote, *commands):
346 schema_helper = ovs.db.idl.SchemaHelper(schema_file)
347 schema_helper.register_all()
348 idl = ovs.db.idl.Idl(remote, schema_helper)
351 error, stream = ovs.stream.Stream.open_block(
352 ovs.stream.Stream.open(remote))
354 sys.stderr.write("failed to connect to \"%s\"" % remote)
356 rpc = ovs.jsonrpc.Connection(stream)
363 for command in commands:
364 if command.startswith("+"):
365 # The previous transaction didn't change anything.
366 command = command[1:]
369 while idl.change_seqno == seqno and not idl.run():
372 poller = ovs.poller.Poller()
380 seqno = idl.change_seqno
382 if command == "reconnect":
383 print("%03d: reconnect" % step)
386 idl.force_reconnect()
387 elif not command.startswith("["):
388 idl_set(idl, command, step)
391 json = ovs.json.from_string(command)
392 if type(json) in [str, unicode]:
393 sys.stderr.write("\"%s\": %s\n" % (command, json))
395 json = substitute_uuids(json, symtab)
396 request = ovs.jsonrpc.Message.create_request("transact", json)
397 error, reply = rpc.transact_block(request)
399 sys.stderr.write("jsonrpc transaction failed: %s"
400 % os.strerror(error))
402 elif reply.error is not None:
403 sys.stderr.write("jsonrpc transaction failed: %s"
407 sys.stdout.write("%03d: " % step)
410 if reply.result is not None:
411 parse_uuids(reply.result, symtab)
413 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
418 while idl.change_seqno == seqno and not idl.run():
419 poller = ovs.poller.Poller()
425 print("%03d: done" % step)
430 %(program_name)s: test utility for Open vSwitch database Python bindings
431 usage: %(program_name)s [OPTIONS] COMMAND ARG...
433 The following commands are supported:
435 test ovsdb_atom_default()
437 test ovsdb_datum_default()
438 parse-atomic-type TYPE
439 parse TYPE as OVSDB atomic type, and re-serialize
441 parse TYPE as OVSDB base type, and re-serialize
443 parse JSON as OVSDB type, and re-serialize
444 parse-atoms TYPE ATOM...
445 parse JSON ATOMs as atoms of TYPE, and re-serialize
446 parse-atom-strings TYPE ATOM...
447 parse string ATOMs as atoms of given TYPE, and re-serialize
448 sort-atoms TYPE ATOM...
449 print JSON ATOMs in sorted order
450 parse-data TYPE DATUM...
451 parse JSON DATUMs as data of given TYPE, and re-serialize
452 parse-column NAME OBJECT
453 parse column NAME with info OBJECT, and re-serialize
454 parse-table NAME OBJECT [DEFAULT-IS-ROOT]
455 parse table NAME with info OBJECT
457 parse JSON as an OVSDB schema, and re-serialize
458 idl SCHEMA SERVER [TRANSACTION...]
459 connect to SERVER (which has the specified SCHEMA) and dump the
460 contents of the database as seen initially by the IDL implementation
461 and after executing each TRANSACTION. (Each TRANSACTION must modify
462 the database or this command will hang.)
464 The following options are also available:
465 -t, --timeout=SECS give up after SECS seconds
466 -h, --help display this help message\
467 """ % {'program_name': ovs.util.PROGRAM_NAME}
473 options, args = getopt.gnu_getopt(argv[1:], 't:h',
476 except getopt.GetoptError, geo:
477 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
480 for key, value in options:
481 if key in ['-h', '--help']:
483 elif key in ['-t', '--timeout']:
489 raise error.Error("value %s on -t or --timeout is not at "
491 signal.alarm(timeout)
496 sys.stderr.write("%s: missing command argument "
497 "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
500 commands = {"default-atoms": (do_default_atoms, 0),
501 "default-data": (do_default_data, 0),
502 "parse-atomic-type": (do_parse_atomic_type, 1),
503 "parse-base-type": (do_parse_base_type, 1),
504 "parse-type": (do_parse_type, 1),
505 "parse-atoms": (do_parse_atoms, (2,)),
506 "parse-data": (do_parse_data, (2,)),
507 "sort-atoms": (do_sort_atoms, 2),
508 "parse-column": (do_parse_column, 2),
509 "parse-table": (do_parse_table, (2, 3)),
510 "parse-schema": (do_parse_schema, 1),
511 "idl": (do_idl, (2,))}
513 command_name = args[0]
515 if not command_name in commands:
516 sys.stderr.write("%s: unknown command \"%s\" "
517 "(use --help for help)\n" % (ovs.util.PROGRAM_NAME,
521 func, n_args = commands[command_name]
522 if type(n_args) == tuple:
523 if len(args) < n_args[0]:
524 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
526 % (ovs.util.PROGRAM_NAME, command_name,
529 elif type(n_args) == int:
530 if len(args) != n_args:
531 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
533 % (ovs.util.PROGRAM_NAME, command_name,
542 if __name__ == '__main__':
545 except error.Error, e:
546 sys.stderr.write("%s\n" % e)