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
32 if type(json) == list and len(json) == 1:
37 def do_default_atoms():
38 for type_ in types.ATOMIC_TYPES:
39 if type_ == types.VoidType:
42 sys.stdout.write("%s: " % type_.to_string())
44 atom = data.Atom.default(type_)
45 if atom != data.Atom.default(type_):
46 sys.stdout.write("wrong\n")
49 sys.stdout.write("OK\n")
51 def do_default_data():
54 for key in types.ATOMIC_TYPES:
55 if key == types.VoidType:
57 for value in types.ATOMIC_TYPES:
58 if value == types.VoidType:
61 valueBase = types.BaseType(value)
62 type_ = types.Type(types.BaseType(key), valueBase, n_min, 1)
63 assert type_.is_valid()
65 sys.stdout.write("key %s, value %s, n_min %d: "
66 % (key.to_string(), value.to_string(), n_min))
68 datum = data.Datum.default(type_)
69 if datum != data.Datum.default(type_):
70 sys.stdout.write("wrong\n")
73 sys.stdout.write("OK\n")
77 def do_parse_atomic_type(type_string):
78 type_json = unbox_json(ovs.json.from_string(type_string))
79 atomic_type = types.AtomicType.from_json(type_json)
80 print ovs.json.to_string(atomic_type.to_json(), sort_keys=True)
82 def do_parse_base_type(type_string):
83 type_json = unbox_json(ovs.json.from_string(type_string))
84 base_type = types.BaseType.from_json(type_json)
85 print ovs.json.to_string(base_type.to_json(), sort_keys=True)
87 def do_parse_type(type_string):
88 type_json = unbox_json(ovs.json.from_string(type_string))
89 type_ = types.Type.from_json(type_json)
90 print ovs.json.to_string(type_.to_json(), sort_keys=True)
92 def do_parse_atoms(type_string, *atom_strings):
93 type_json = unbox_json(ovs.json.from_string(type_string))
94 base = types.BaseType.from_json(type_json)
95 for atom_string in atom_strings:
96 atom_json = unbox_json(ovs.json.from_string(atom_string))
98 atom = data.Atom.from_json(base, atom_json)
99 print ovs.json.to_string(atom.to_json())
100 except error.Error, e:
103 def do_parse_data(type_string, *data_strings):
104 type_json = unbox_json(ovs.json.from_string(type_string))
105 type_ = types.Type.from_json(type_json)
106 for datum_string in data_strings:
107 datum_json = unbox_json(ovs.json.from_string(datum_string))
108 datum = data.Datum.from_json(type_, datum_json)
109 print ovs.json.to_string(datum.to_json())
111 def do_sort_atoms(type_string, atom_strings):
112 type_json = unbox_json(ovs.json.from_string(type_string))
113 base = types.BaseType.from_json(type_json)
114 atoms = [data.Atom.from_json(base, atom_json)
115 for atom_json in unbox_json(ovs.json.from_string(atom_strings))]
116 print ovs.json.to_string([data.Atom.to_json(atom)
117 for atom in sorted(atoms)])
119 def do_parse_column(name, column_string):
120 column_json = unbox_json(ovs.json.from_string(column_string))
121 column = ovs.db.schema.ColumnSchema.from_json(column_json, name)
122 print ovs.json.to_string(column.to_json(), sort_keys=True)
124 def do_parse_table(name, table_string, default_is_root_string='false'):
125 default_is_root = default_is_root_string == 'true'
126 table_json = unbox_json(ovs.json.from_string(table_string))
127 table = ovs.db.schema.TableSchema.from_json(table_json, name)
128 print ovs.json.to_string(table.to_json(default_is_root), sort_keys=True)
130 def do_parse_schema(schema_string):
131 schema_json = unbox_json(ovs.json.from_string(schema_string))
132 schema = ovs.db.schema.DbSchema.from_json(schema_json)
133 print ovs.json.to_string(schema.to_json(), sort_keys=True)
135 def print_idl(idl, step):
136 simple = idl.tables["simple"].rows
137 l1 = idl.tables["link1"].rows
138 l2 = idl.tables["link2"].rows
141 for row in simple.itervalues():
142 s = ("%03d: i=%s r=%s b=%s s=%s u=%s "
143 "ia=%s ra=%s ba=%s sa=%s ua=%s uuid=%s"
144 % (step, row.i, row.r, row.b, row.s, row.u,
145 row.ia, row.ra, row.ba, row.sa, row.ua, row.uuid))
146 s = re.sub('""|,|u?\'', "", s)
147 s = re.sub('UUID\(([^)]+)\)', r'\1', s)
148 s = re.sub('False', 'false', s)
149 s = re.sub('True', 'true', s)
150 s = re.sub(r'(ba)=([^[][^ ]*) ', r'\1=[\2] ', s)
154 for row in l1.itervalues():
155 s = ["%03d: i=%s k=" % (step, row.i)]
157 s.append(str(row.k.i))
159 s.append(' '.join(sorted(str(ka.i) for ka in row.ka)))
162 s.append(str(row.l2[0].i))
163 s.append(" uuid=%s" % row.uuid)
167 for row in l2.itervalues():
168 s = ["%03d: i=%s l1=" % (step, row.i)]
170 s.append(str(row.l1.i))
171 s.append(" uuid=%s" % row.uuid)
176 print("%03d: empty" % step)
179 def substitute_uuids(json, symtab):
180 if type(json) in [str, unicode]:
181 symbol = symtab.get(json)
184 elif type(json) == list:
185 return [substitute_uuids(element, symtab) for element in json]
186 elif type(json) == dict:
188 for key, value in json.iteritems():
189 d[key] = substitute_uuids(value, symtab)
193 def parse_uuids(json, symtab):
194 if type(json) in [str, unicode] and ovs.ovsuuid.is_valid_string(json):
195 name = "#%d#" % len(symtab)
196 sys.stderr.write("%s = %s\n" % (name, json))
198 elif type(json) == list:
200 parse_uuids(element, symtab)
201 elif type(json) == dict:
202 for value in json.itervalues():
203 parse_uuids(value, symtab)
205 def idltest_find_simple(idl, i):
206 for row in idl.tables["simple"].rows.itervalues():
211 def idl_set(idl, commands, step):
212 txn = ovs.db.idl.Transaction(idl)
214 for command in commands.split(','):
215 words = command.split()
221 sys.stderr.write('"set" command requires 3 arguments\n')
224 s = idltest_find_simple(idl, int(args[0]))
226 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
235 s.u = uuid.UUID(args[2])
239 sys.stderr.write('"set" comamnd asks for unknown column %s\n'
242 elif name == "insert":
244 sys.stderr.write('"set" command requires 1 argument\n')
247 s = txn.insert(idl.tables["simple"])
249 elif name == "delete":
251 sys.stderr.write('"delete" command requires 1 argument\n')
254 s = idltest_find_simple(idl, int(args[0]))
256 sys.stderr.write('"delete" command asks for nonexistent i=%d\n'
260 elif name == "verify":
262 sys.stderr.write('"verify" command requires 2 arguments\n')
265 s = idltest_find_simple(idl, int(args[0]))
267 sys.stderr.write('"verify" command asks for nonexistent i=%d\n'
271 if args[1] in ("i", "b", "s", "u", "r"):
274 sys.stderr.write('"verify" command asks for unknown column '
277 elif name == "increment":
279 sys.stderr.write('"increment" command requires 2 arguments\n')
282 txn.increment(args[0], args[1], [])
284 elif name == "abort":
287 elif name == "destroy":
288 print "%03d: destroy" % step
293 sys.stderr.write("unknown command %s\n" % name)
296 status = txn.commit_block()
297 sys.stdout.write("%03d: commit, status=%s"
298 % (step, ovs.db.idl.Transaction.status_to_string(status)))
299 if increment and status == ovs.db.idl.Transaction.SUCCESS:
300 sys.stdout.write(", increment=%d" % txn.get_increment_new_value())
301 sys.stdout.write("\n")
304 def do_idl(schema_file, remote, *commands):
305 schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schema_file))
306 idl = ovs.db.idl.Idl(remote, schema)
309 error, stream = ovs.stream.Stream.open_block(
310 ovs.stream.Stream.open(remote))
312 sys.stderr.write("failed to connect to \"%s\"" % remote)
314 rpc = ovs.jsonrpc.Connection(stream)
321 for command in commands:
322 if command.startswith("+"):
323 # The previous transaction didn't change anything.
324 command = command[1:]
327 while idl.change_seqno == seqno and not idl.run():
330 poller = ovs.poller.Poller()
338 seqno = idl.change_seqno
340 if command == "reconnect":
341 print("%03d: reconnect" % step)
344 idl.force_reconnect()
345 elif not command.startswith("["):
346 idl_set(idl, command, step)
349 json = ovs.json.from_string(command)
350 if type(json) in [str, unicode]:
351 sys.stderr.write("\"%s\": %s\n" % (command, json))
353 json = substitute_uuids(json, symtab)
354 request = ovs.jsonrpc.Message.create_request("transact", json)
355 error, reply = rpc.transact_block(request)
357 sys.stderr.write("jsonrpc transaction failed: %s"
358 % os.strerror(error))
360 sys.stdout.write("%03d: " % step)
363 if reply.result is not None:
364 parse_uuids(reply.result, symtab)
366 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
371 while idl.change_seqno == seqno and not idl.run():
372 poller = ovs.poller.Poller()
378 print("%03d: done" % step)
382 %(program_name)s: test utility for Open vSwitch database Python bindings
383 usage: %(program_name)s [OPTIONS] COMMAND ARG...
385 The following commands are supported:
387 test ovsdb_atom_default()
389 test ovsdb_datum_default()
390 parse-atomic-type TYPE
391 parse TYPE as OVSDB atomic type, and re-serialize
393 parse TYPE as OVSDB base type, and re-serialize
395 parse JSON as OVSDB type, and re-serialize
396 parse-atoms TYPE ATOM...
397 parse JSON ATOMs as atoms of TYPE, and re-serialize
398 parse-atom-strings TYPE ATOM...
399 parse string ATOMs as atoms of given TYPE, and re-serialize
400 sort-atoms TYPE ATOM...
401 print JSON ATOMs in sorted order
402 parse-data TYPE DATUM...
403 parse JSON DATUMs as data of given TYPE, and re-serialize
404 parse-column NAME OBJECT
405 parse column NAME with info OBJECT, and re-serialize
406 parse-table NAME OBJECT [DEFAULT-IS-ROOT]
407 parse table NAME with info OBJECT
409 parse JSON as an OVSDB schema, and re-serialize
410 idl SCHEMA SERVER [TRANSACTION...]
411 connect to SERVER (which has the specified SCHEMA) and dump the
412 contents of the database as seen initially by the IDL implementation
413 and after executing each TRANSACTION. (Each TRANSACTION must modify
414 the database or this command will hang.)
416 The following options are also available:
417 -t, --timeout=SECS give up after SECS seconds
418 -h, --help display this help message\
419 """ % {'program_name': ovs.util.PROGRAM_NAME}
424 options, args = getopt.gnu_getopt(argv[1:], 't:h',
427 except getopt.GetoptError, geo:
428 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
431 for key, value in options:
432 if key in ['-h', '--help']:
434 elif key in ['-t', '--timeout']:
440 raise error.Error("value %s on -t or --timeout is not at "
442 signal.alarm(timeout)
447 sys.stderr.write("%s: missing command argument "
448 "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
451 commands = {"default-atoms": (do_default_atoms, 0),
452 "default-data": (do_default_data, 0),
453 "parse-atomic-type": (do_parse_atomic_type, 1),
454 "parse-base-type": (do_parse_base_type, 1),
455 "parse-type": (do_parse_type, 1),
456 "parse-atoms": (do_parse_atoms, (2,)),
457 "parse-data": (do_parse_data, (2,)),
458 "sort-atoms": (do_sort_atoms, 2),
459 "parse-column": (do_parse_column, 2),
460 "parse-table": (do_parse_table, (2, 3)),
461 "parse-schema": (do_parse_schema, 1),
462 "idl": (do_idl, (2,))}
464 command_name = args[0]
466 if not command_name in commands:
467 sys.stderr.write("%s: unknown command \"%s\" "
468 "(use --help for help)\n" % (ovs.util.PROGRAM_NAME,
472 func, n_args = commands[command_name]
473 if type(n_args) == tuple:
474 if len(args) < n_args[0]:
475 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
477 % (ovs.util.PROGRAM_NAME, command_name,
480 elif type(n_args) == int:
481 if len(args) != n_args:
482 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
484 % (ovs.util.PROGRAM_NAME, command_name,
492 if __name__ == '__main__':
495 except error.Error, e:
496 sys.stderr.write("%s\n" % e)