1 # Copyright (c) 2009, 2010 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):
125 table_json = unbox_json(ovs.json.from_string(table_string))
126 table = ovs.db.schema.TableSchema.from_json(table_json, name)
127 print ovs.json.to_string(table.to_json(), sort_keys=True)
129 def do_parse_rows(table_string, *rows):
130 table_json = unbox_json(ovs.json.from_string(table_string))
131 table = ovs.db.schema.TableSchema.from_json(table_json, name)
133 def do_parse_schema(schema_string):
134 schema_json = unbox_json(ovs.json.from_string(schema_string))
135 schema = ovs.db.schema.DbSchema.from_json(schema_json)
136 print ovs.json.to_string(schema.to_json(), sort_keys=True)
138 def print_idl(idl, step):
140 for uuid, row in idl.data["simple"].iteritems():
141 s = ("%03d: i=%s r=%s b=%s s=%s u=%s "
142 "ia=%s ra=%s ba=%s sa=%s ua=%s uuid=%s"
143 % (step, row.i, row.r, row.b, row.s, row.u,
144 row.ia, row.ra, row.ba, row.sa, row.ua, uuid))
145 print(re.sub('""|,', "", s))
148 print("%03d: empty" % step)
150 def substitute_uuids(json, symtab):
151 if type(json) in [str, unicode]:
152 symbol = symtab.get(json)
155 elif type(json) == list:
156 return [substitute_uuids(element, symtab) for element in json]
157 elif type(json) == dict:
159 for key, value in json.iteritems():
160 d[key] = substitute_uuids(value, symtab)
164 def parse_uuids(json, symtab):
165 if type(json) in [str, unicode] and ovs.ovsuuid.UUID.is_valid_string(json):
166 name = "#%d#" % len(symtab)
167 sys.stderr.write("%s = %s\n" % (name, json))
169 elif type(json) == list:
171 parse_uuids(element, symtab)
172 elif type(json) == dict:
173 for value in json.itervalues():
174 parse_uuids(value, symtab)
176 def do_idl(remote, *commands):
177 idl = ovs.db.idl.Idl(remote, "idltest")
180 error, stream = ovs.stream.Stream.open_block(
181 ovs.stream.Stream.open(remote))
183 sys.stderr.write("failed to connect to \"%s\"" % remote)
185 rpc = ovs.jsonrpc.Connection(stream)
192 for command in commands:
193 if command.startswith("+"):
194 # The previous transaction didn't change anything.
195 command = command[1:]
198 while idl.get_seqno() == seqno and not idl.run():
201 poller = ovs.poller.Poller()
209 seqno = idl.get_seqno()
211 if command == "reconnect":
212 print("%03d: reconnect" % step)
214 idl.force_reconnect()
215 elif not command.startswith("["):
216 idl_set(idl, command, step)
219 json = ovs.json.from_string(command)
220 if type(json) in [str, unicode]:
221 sys.stderr.write("\"%s\": %s\n" % (command, json))
223 json = substitute_uuids(json, symtab)
224 request = ovs.jsonrpc.Message.create_request("transact", json)
225 error, reply = rpc.transact_block(request)
227 sys.stderr.write("jsonrpc transaction failed: %s"
228 % os.strerror(error))
230 sys.stdout.write("%03d: " % step)
233 if reply.result is not None:
234 parse_uuids(reply.result, symtab)
236 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
240 while idl.get_seqno() == seqno and not idl.run():
241 poller = ovs.poller.Poller()
247 print("%03d: done" % step)
251 %(program_name)s: test utility for Open vSwitch database Python bindings
252 usage: %(program_name)s [OPTIONS] COMMAND ARG...
254 The following commands are supported:
256 test ovsdb_atom_default()
258 test ovsdb_datum_default()
259 parse-atomic-type TYPE
260 parse TYPE as OVSDB atomic type, and re-serialize
262 parse TYPE as OVSDB base type, and re-serialize
264 parse JSON as OVSDB type, and re-serialize
265 parse-atoms TYPE ATOM...
266 parse JSON ATOMs as atoms of TYPE, and re-serialize
267 parse-atom-strings TYPE ATOM...
268 parse string ATOMs as atoms of given TYPE, and re-serialize
269 sort-atoms TYPE ATOM...
270 print JSON ATOMs in sorted order
271 parse-data TYPE DATUM...
272 parse JSON DATUMs as data of given TYPE, and re-serialize
273 parse-column NAME OBJECT
274 parse column NAME with info OBJECT, and re-serialize
275 parse-table NAME OBJECT
276 parse table NAME with info OBJECT
278 parse JSON as an OVSDB schema, and re-serialize
279 idl SERVER [TRANSACTION...]
280 connect to SERVER and dump the contents of the database
281 as seen initially by the IDL implementation and after
282 executing each TRANSACTION. (Each TRANSACTION must modify
283 the database or this command will hang.)
285 The following options are also available:
286 -t, --timeout=SECS give up after SECS seconds
287 -h, --help display this help message\
288 """ % {'program_name': ovs.util.PROGRAM_NAME}
292 # Make stdout and stderr UTF-8, even if they are redirected to a file.
293 sys.stdout = codecs.getwriter("utf-8")(sys.stdout)
294 sys.stderr = codecs.getwriter("utf-8")(sys.stderr)
297 options, args = getopt.gnu_getopt(argv[1:], 't:h',
300 except getopt.GetoptError, geo:
301 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
304 for key, value in options:
305 if key in ['-h', '--help']:
307 elif key in ['-t', '--timeout']:
313 raise error.Error("value %s on -t or --timeout is not at "
315 signal.alarm(timeout)
319 optKeys = [key for key, value in options]
322 sys.stderr.write("%s: missing command argument "
323 "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
326 commands = {"default-atoms": (do_default_atoms, 0),
327 "default-data": (do_default_data, 0),
328 "parse-atomic-type": (do_parse_atomic_type, 1),
329 "parse-base-type": (do_parse_base_type, 1),
330 "parse-type": (do_parse_type, 1),
331 "parse-atoms": (do_parse_atoms, (2,)),
332 "parse-data": (do_parse_data, (2,)),
333 "sort-atoms": (do_sort_atoms, 2),
334 "parse-column": (do_parse_column, 2),
335 "parse-table": (do_parse_table, 2),
336 "parse-schema": (do_parse_schema, 1),
337 "idl": (do_idl, (1,))}
339 command_name = args[0]
341 if not command_name in commands:
342 sys.stderr.write("%s: unknown command \"%s\" "
343 "(use --help for help)\n" % (ovs.util.PROGRAM_NAME,
347 func, n_args = commands[command_name]
348 if type(n_args) == tuple:
349 if len(args) < n_args[0]:
350 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
352 % (ovs.util.PROGRAM_NAME, command_name,
355 elif type(n_args) == int:
356 if len(args) != n_args:
357 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
359 % (ovs.util.PROGRAM_NAME, command_name,
367 if __name__ == '__main__':
370 except error.Error, e:
371 sys.stderr.write("%s\n" % e)