1 # Copyright (c) 2009, 2010, 2011 Nicira Networks
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:
38 def do_default_atoms():
39 for type_ in types.ATOMIC_TYPES:
40 if type_ == types.VoidType:
43 sys.stdout.write("%s: " % type_.to_string())
45 atom = data.Atom.default(type_)
46 if atom != data.Atom.default(type_):
47 sys.stdout.write("wrong\n")
50 sys.stdout.write("OK\n")
52 def do_default_data():
55 for key in types.ATOMIC_TYPES:
56 if key == types.VoidType:
58 for value in types.ATOMIC_TYPES:
59 if value == types.VoidType:
62 valueBase = types.BaseType(value)
63 type_ = types.Type(types.BaseType(key), valueBase, n_min, 1)
64 assert type_.is_valid()
66 sys.stdout.write("key %s, value %s, n_min %d: "
67 % (key.to_string(), value.to_string(), n_min))
69 datum = data.Datum.default(type_)
70 if datum != data.Datum.default(type_):
71 sys.stdout.write("wrong\n")
74 sys.stdout.write("OK\n")
78 def do_parse_atomic_type(type_string):
79 type_json = unbox_json(ovs.json.from_string(type_string))
80 atomic_type = types.AtomicType.from_json(type_json)
81 print ovs.json.to_string(atomic_type.to_json(), sort_keys=True)
83 def do_parse_base_type(type_string):
84 type_json = unbox_json(ovs.json.from_string(type_string))
85 base_type = types.BaseType.from_json(type_json)
86 print ovs.json.to_string(base_type.to_json(), sort_keys=True)
88 def do_parse_type(type_string):
89 type_json = unbox_json(ovs.json.from_string(type_string))
90 type_ = types.Type.from_json(type_json)
91 print ovs.json.to_string(type_.to_json(), sort_keys=True)
93 def do_parse_atoms(type_string, *atom_strings):
94 type_json = unbox_json(ovs.json.from_string(type_string))
95 base = types.BaseType.from_json(type_json)
96 for atom_string in atom_strings:
97 atom_json = unbox_json(ovs.json.from_string(atom_string))
99 atom = data.Atom.from_json(base, atom_json)
100 print ovs.json.to_string(atom.to_json())
101 except error.Error, e:
104 def do_parse_data(type_string, *data_strings):
105 type_json = unbox_json(ovs.json.from_string(type_string))
106 type_ = types.Type.from_json(type_json)
107 for datum_string in data_strings:
108 datum_json = unbox_json(ovs.json.from_string(datum_string))
109 datum = data.Datum.from_json(type_, datum_json)
110 print ovs.json.to_string(datum.to_json())
112 def do_sort_atoms(type_string, atom_strings):
113 type_json = unbox_json(ovs.json.from_string(type_string))
114 base = types.BaseType.from_json(type_json)
115 atoms = [data.Atom.from_json(base, atom_json)
116 for atom_json in unbox_json(ovs.json.from_string(atom_strings))]
117 print ovs.json.to_string([data.Atom.to_json(atom)
118 for atom in sorted(atoms)])
120 def do_parse_column(name, column_string):
121 column_json = unbox_json(ovs.json.from_string(column_string))
122 column = ovs.db.schema.ColumnSchema.from_json(column_json, name)
123 print ovs.json.to_string(column.to_json(), sort_keys=True)
125 def do_parse_table(name, table_string, default_is_root_string='false'):
126 default_is_root = default_is_root_string == 'true'
127 table_json = unbox_json(ovs.json.from_string(table_string))
128 table = ovs.db.schema.TableSchema.from_json(table_json, name)
129 print ovs.json.to_string(table.to_json(default_is_root), sort_keys=True)
131 def do_parse_schema(schema_string):
132 schema_json = unbox_json(ovs.json.from_string(schema_string))
133 schema = ovs.db.schema.DbSchema.from_json(schema_json)
134 print ovs.json.to_string(schema.to_json(), sort_keys=True)
136 def print_idl(idl, step):
137 simple = idl.tables["simple"].rows
138 l1 = idl.tables["link1"].rows
139 l2 = idl.tables["link2"].rows
142 for row in simple.itervalues():
143 s = ("%03d: i=%s r=%s b=%s s=%s u=%s "
144 "ia=%s ra=%s ba=%s sa=%s ua=%s uuid=%s"
145 % (step, row.i, row.r, row.b, row.s, row.u,
146 row.ia, row.ra, row.ba, row.sa, row.ua, row.uuid))
147 s = re.sub('""|,|u?\'', "", s)
148 s = re.sub('UUID\(([^)]+)\)', r'\1', s)
149 s = re.sub('False', 'false', s)
150 s = re.sub('True', 'true', s)
151 s = re.sub(r'(ba)=([^[][^ ]*) ', r'\1=[\2] ', s)
155 for row in l1.itervalues():
156 s = ["%03d: i=%s k=" % (step, row.i)]
158 s.append(str(row.k.i))
160 s.append(' '.join(sorted(str(ka.i) for ka in row.ka)))
163 s.append(str(row.l2[0].i))
164 s.append(" uuid=%s" % row.uuid)
168 for row in l2.itervalues():
169 s = ["%03d: i=%s l1=" % (step, row.i)]
171 s.append(str(row.l1.i))
172 s.append(" uuid=%s" % row.uuid)
177 print("%03d: empty" % step)
180 def substitute_uuids(json, symtab):
181 if type(json) in [str, unicode]:
182 symbol = symtab.get(json)
185 elif type(json) == list:
186 return [substitute_uuids(element, symtab) for element in json]
187 elif type(json) == dict:
189 for key, value in json.iteritems():
190 d[key] = substitute_uuids(value, symtab)
194 def parse_uuids(json, symtab):
195 if type(json) in [str, unicode] and ovs.ovsuuid.is_valid_string(json):
196 name = "#%d#" % len(symtab)
197 sys.stderr.write("%s = %s\n" % (name, json))
199 elif type(json) == list:
201 parse_uuids(element, symtab)
202 elif type(json) == dict:
203 for value in json.itervalues():
204 parse_uuids(value, symtab)
206 def idltest_find_simple(idl, i):
207 for row in idl.tables["simple"].rows.itervalues():
212 def idl_set(idl, commands, step):
213 txn = ovs.db.idl.Transaction(idl)
215 for command in commands.split(','):
216 words = command.split()
222 sys.stderr.write('"set" command requires 3 arguments\n')
225 s = idltest_find_simple(idl, int(args[0]))
227 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
236 s.u = uuid.UUID(args[2])
240 sys.stderr.write('"set" comamnd asks for unknown column %s\n'
243 elif name == "insert":
245 sys.stderr.write('"set" command requires 1 argument\n')
248 s = txn.insert(idl.tables["simple"])
250 elif name == "delete":
252 sys.stderr.write('"delete" command requires 1 argument\n')
255 s = idltest_find_simple(idl, int(args[0]))
257 sys.stderr.write('"delete" command asks for nonexistent i=%d\n'
261 elif name == "verify":
263 sys.stderr.write('"verify" command requires 2 arguments\n')
266 s = idltest_find_simple(idl, int(args[0]))
268 sys.stderr.write('"verify" command asks for nonexistent i=%d\n'
272 if args[1] in ("i", "b", "s", "u", "r"):
275 sys.stderr.write('"verify" command asks for unknown column '
278 elif name == "increment":
280 sys.stderr.write('"increment" command requires 2 arguments\n')
283 txn.increment(args[0], args[1], [])
285 elif name == "abort":
288 elif name == "destroy":
289 print "%03d: destroy" % step
294 sys.stderr.write("unknown command %s\n" % name)
297 status = txn.commit_block()
298 sys.stdout.write("%03d: commit, status=%s"
299 % (step, ovs.db.idl.Transaction.status_to_string(status)))
300 if increment and status == ovs.db.idl.Transaction.SUCCESS:
301 sys.stdout.write(", increment=%d" % txn.get_increment_new_value())
302 sys.stdout.write("\n")
305 def do_idl(schema_file, remote, *commands):
306 schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schema_file))
307 idl = ovs.db.idl.Idl(remote, schema)
310 error, stream = ovs.stream.Stream.open_block(
311 ovs.stream.Stream.open(remote))
313 sys.stderr.write("failed to connect to \"%s\"" % remote)
315 rpc = ovs.jsonrpc.Connection(stream)
322 for command in commands:
323 if command.startswith("+"):
324 # The previous transaction didn't change anything.
325 command = command[1:]
328 while idl.change_seqno == seqno and not idl.run():
331 poller = ovs.poller.Poller()
339 seqno = idl.change_seqno
341 if command == "reconnect":
342 print("%03d: reconnect" % step)
345 idl.force_reconnect()
346 elif not command.startswith("["):
347 idl_set(idl, command, step)
350 json = ovs.json.from_string(command)
351 if type(json) in [str, unicode]:
352 sys.stderr.write("\"%s\": %s\n" % (command, json))
354 json = substitute_uuids(json, symtab)
355 request = ovs.jsonrpc.Message.create_request("transact", json)
356 error, reply = rpc.transact_block(request)
358 sys.stderr.write("jsonrpc transaction failed: %s"
359 % os.strerror(error))
361 sys.stdout.write("%03d: " % step)
364 if reply.result is not None:
365 parse_uuids(reply.result, symtab)
367 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
372 while idl.change_seqno == seqno and not idl.run():
373 poller = ovs.poller.Poller()
379 print("%03d: done" % step)
383 %(program_name)s: test utility for Open vSwitch database Python bindings
384 usage: %(program_name)s [OPTIONS] COMMAND ARG...
386 The following commands are supported:
388 test ovsdb_atom_default()
390 test ovsdb_datum_default()
391 parse-atomic-type TYPE
392 parse TYPE as OVSDB atomic type, and re-serialize
394 parse TYPE as OVSDB base type, and re-serialize
396 parse JSON as OVSDB type, and re-serialize
397 parse-atoms TYPE ATOM...
398 parse JSON ATOMs as atoms of TYPE, and re-serialize
399 parse-atom-strings TYPE ATOM...
400 parse string ATOMs as atoms of given TYPE, and re-serialize
401 sort-atoms TYPE ATOM...
402 print JSON ATOMs in sorted order
403 parse-data TYPE DATUM...
404 parse JSON DATUMs as data of given TYPE, and re-serialize
405 parse-column NAME OBJECT
406 parse column NAME with info OBJECT, and re-serialize
407 parse-table NAME OBJECT [DEFAULT-IS-ROOT]
408 parse table NAME with info OBJECT
410 parse JSON as an OVSDB schema, and re-serialize
411 idl SCHEMA SERVER [TRANSACTION...]
412 connect to SERVER (which has the specified SCHEMA) and dump the
413 contents of the database as seen initially by the IDL implementation
414 and after executing each TRANSACTION. (Each TRANSACTION must modify
415 the database or this command will hang.)
417 The following options are also available:
418 -t, --timeout=SECS give up after SECS seconds
419 -h, --help display this help message\
420 """ % {'program_name': ovs.util.PROGRAM_NAME}
425 options, args = getopt.gnu_getopt(argv[1:], 't:h',
428 except getopt.GetoptError, geo:
429 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
432 for key, value in options:
433 if key in ['-h', '--help']:
435 elif key in ['-t', '--timeout']:
441 raise error.Error("value %s on -t or --timeout is not at "
443 signal.alarm(timeout)
448 sys.stderr.write("%s: missing command argument "
449 "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
452 commands = {"default-atoms": (do_default_atoms, 0),
453 "default-data": (do_default_data, 0),
454 "parse-atomic-type": (do_parse_atomic_type, 1),
455 "parse-base-type": (do_parse_base_type, 1),
456 "parse-type": (do_parse_type, 1),
457 "parse-atoms": (do_parse_atoms, (2,)),
458 "parse-data": (do_parse_data, (2,)),
459 "sort-atoms": (do_sort_atoms, 2),
460 "parse-column": (do_parse_column, 2),
461 "parse-table": (do_parse_table, (2, 3)),
462 "parse-schema": (do_parse_schema, 1),
463 "idl": (do_idl, (2,))}
465 command_name = args[0]
467 if not command_name in commands:
468 sys.stderr.write("%s: unknown command \"%s\" "
469 "(use --help for help)\n" % (ovs.util.PROGRAM_NAME,
473 func, n_args = commands[command_name]
474 if type(n_args) == tuple:
475 if len(args) < n_args[0]:
476 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
478 % (ovs.util.PROGRAM_NAME, command_name,
481 elif type(n_args) == int:
482 if len(args) != n_args:
483 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
485 % (ovs.util.PROGRAM_NAME, command_name,
493 if __name__ == '__main__':
496 except error.Error, e:
497 sys.stderr.write("%s\n" % e)