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_rows(table_string, *rows):
131 table_json = unbox_json(ovs.json.from_string(table_string))
132 table = ovs.db.schema.TableSchema.from_json(table_json, name)
134 def do_parse_schema(schema_string):
135 schema_json = unbox_json(ovs.json.from_string(schema_string))
136 schema = ovs.db.schema.DbSchema.from_json(schema_json)
137 print ovs.json.to_string(schema.to_json(), sort_keys=True)
139 def print_idl(idl, step):
141 for uuid, row in idl.data["simple"].iteritems():
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, uuid))
146 print(re.sub('""|,', "", s))
149 print("%03d: empty" % step)
151 def substitute_uuids(json, symtab):
152 if type(json) in [str, unicode]:
153 symbol = symtab.get(json)
156 elif type(json) == list:
157 return [substitute_uuids(element, symtab) for element in json]
158 elif type(json) == dict:
160 for key, value in json.iteritems():
161 d[key] = substitute_uuids(value, symtab)
165 def parse_uuids(json, symtab):
166 if type(json) in [str, unicode] and ovs.ovsuuid.UUID.is_valid_string(json):
167 name = "#%d#" % len(symtab)
168 sys.stderr.write("%s = %s\n" % (name, json))
170 elif type(json) == list:
172 parse_uuids(element, symtab)
173 elif type(json) == dict:
174 for value in json.itervalues():
175 parse_uuids(value, symtab)
177 def do_idl(remote, *commands):
178 idl = ovs.db.idl.Idl(remote, "idltest")
181 error, stream = ovs.stream.Stream.open_block(
182 ovs.stream.Stream.open(remote))
184 sys.stderr.write("failed to connect to \"%s\"" % remote)
186 rpc = ovs.jsonrpc.Connection(stream)
193 for command in commands:
194 if command.startswith("+"):
195 # The previous transaction didn't change anything.
196 command = command[1:]
199 while idl.get_seqno() == seqno and not idl.run():
202 poller = ovs.poller.Poller()
210 seqno = idl.get_seqno()
212 if command == "reconnect":
213 print("%03d: reconnect" % step)
215 idl.force_reconnect()
216 elif not command.startswith("["):
217 idl_set(idl, command, step)
220 json = ovs.json.from_string(command)
221 if type(json) in [str, unicode]:
222 sys.stderr.write("\"%s\": %s\n" % (command, json))
224 json = substitute_uuids(json, symtab)
225 request = ovs.jsonrpc.Message.create_request("transact", json)
226 error, reply = rpc.transact_block(request)
228 sys.stderr.write("jsonrpc transaction failed: %s"
229 % os.strerror(error))
231 sys.stdout.write("%03d: " % step)
234 if reply.result is not None:
235 parse_uuids(reply.result, symtab)
237 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
241 while idl.get_seqno() == seqno and not idl.run():
242 poller = ovs.poller.Poller()
248 print("%03d: done" % step)
252 %(program_name)s: test utility for Open vSwitch database Python bindings
253 usage: %(program_name)s [OPTIONS] COMMAND ARG...
255 The following commands are supported:
257 test ovsdb_atom_default()
259 test ovsdb_datum_default()
260 parse-atomic-type TYPE
261 parse TYPE as OVSDB atomic type, and re-serialize
263 parse TYPE as OVSDB base type, and re-serialize
265 parse JSON as OVSDB type, and re-serialize
266 parse-atoms TYPE ATOM...
267 parse JSON ATOMs as atoms of TYPE, and re-serialize
268 parse-atom-strings TYPE ATOM...
269 parse string ATOMs as atoms of given TYPE, and re-serialize
270 sort-atoms TYPE ATOM...
271 print JSON ATOMs in sorted order
272 parse-data TYPE DATUM...
273 parse JSON DATUMs as data of given TYPE, and re-serialize
274 parse-column NAME OBJECT
275 parse column NAME with info OBJECT, and re-serialize
276 parse-table NAME OBJECT [DEFAULT-IS-ROOT]
277 parse table NAME with info OBJECT
279 parse JSON as an OVSDB schema, and re-serialize
280 idl SERVER [TRANSACTION...]
281 connect to SERVER and dump the contents of the database
282 as seen initially by the IDL implementation and after
283 executing each TRANSACTION. (Each TRANSACTION must modify
284 the database or this command will hang.)
286 The following options are also available:
287 -t, --timeout=SECS give up after SECS seconds
288 -h, --help display this help message\
289 """ % {'program_name': ovs.util.PROGRAM_NAME}
293 # Make stdout and stderr UTF-8, even if they are redirected to a file.
294 sys.stdout = codecs.getwriter("utf-8")(sys.stdout)
295 sys.stderr = codecs.getwriter("utf-8")(sys.stderr)
298 options, args = getopt.gnu_getopt(argv[1:], 't:h',
301 except getopt.GetoptError, geo:
302 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
305 for key, value in options:
306 if key in ['-h', '--help']:
308 elif key in ['-t', '--timeout']:
314 raise error.Error("value %s on -t or --timeout is not at "
316 signal.alarm(timeout)
320 optKeys = [key for key, value in options]
323 sys.stderr.write("%s: missing command argument "
324 "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
327 commands = {"default-atoms": (do_default_atoms, 0),
328 "default-data": (do_default_data, 0),
329 "parse-atomic-type": (do_parse_atomic_type, 1),
330 "parse-base-type": (do_parse_base_type, 1),
331 "parse-type": (do_parse_type, 1),
332 "parse-atoms": (do_parse_atoms, (2,)),
333 "parse-data": (do_parse_data, (2,)),
334 "sort-atoms": (do_sort_atoms, 2),
335 "parse-column": (do_parse_column, 2),
336 "parse-table": (do_parse_table, (2, 3)),
337 "parse-schema": (do_parse_schema, 1),
338 "idl": (do_idl, (1,))}
340 command_name = args[0]
342 if not command_name in commands:
343 sys.stderr.write("%s: unknown command \"%s\" "
344 "(use --help for help)\n" % (ovs.util.PROGRAM_NAME,
348 func, n_args = commands[command_name]
349 if type(n_args) == tuple:
350 if len(args) < n_args[0]:
351 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
353 % (ovs.util.PROGRAM_NAME, command_name,
356 elif type(n_args) == int:
357 if len(args) != n_args:
358 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
360 % (ovs.util.PROGRAM_NAME, command_name,
368 if __name__ == '__main__':
371 except error.Error, e:
372 sys.stderr.write("%s\n" % e)