]> git.proxmox.com Git - mirror_ovs.git/blame - tests/test-ovsdb.py
utilities: Fix and unify parsing of timeout option.
[mirror_ovs.git] / tests / test-ovsdb.py
CommitLineData
0164e367 1# Copyright (c) 2009, 2010, 2011, 2012, 2016 Nicira, Inc.
99155935
BP
2#
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:
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
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.
14
8ea171ab
RB
15from __future__ import print_function
16
99155935 17import getopt
99155935 18import os
6c7050b5 19import re
99155935 20import sys
8cdf0349 21import uuid
99155935 22
99155935
BP
23import ovs.db.idl
24import ovs.db.schema
3c057118 25import ovs.db.types
99155935
BP
26import ovs.ovsuuid
27import ovs.poller
d90ed7d6 28import ovs.stream
99155935 29import ovs.util
6c7050b5 30from ovs.db import data
31from ovs.db import error
36d51634 32from ovs.fatal_signal import signal_alarm
6c7050b5 33
cb96c1b2 34import six
99155935 35
26bb0f31 36
99155935
BP
37def unbox_json(json):
38 if type(json) == list and len(json) == 1:
39 return json[0]
40 else:
41 return json
42
26bb0f31 43
99155935 44def do_default_atoms():
3c057118
RB
45 for type_ in ovs.db.types.ATOMIC_TYPES:
46 if type_ == ovs.db.types.VoidType:
99155935
BP
47 continue
48
8cdf0349 49 sys.stdout.write("%s: " % type_.to_string())
99155935 50
8cdf0349
BP
51 atom = data.Atom.default(type_)
52 if atom != data.Atom.default(type_):
99155935
BP
53 sys.stdout.write("wrong\n")
54 sys.exit(1)
55
56 sys.stdout.write("OK\n")
57
26bb0f31 58
99155935
BP
59def do_default_data():
60 any_errors = False
61 for n_min in 0, 1:
3c057118
RB
62 for key in ovs.db.types.ATOMIC_TYPES:
63 if key == ovs.db.types.VoidType:
99155935 64 continue
3c057118
RB
65 for value in ovs.db.types.ATOMIC_TYPES:
66 if value == ovs.db.types.VoidType:
99155935
BP
67 valueBase = None
68 else:
3c057118
RB
69 valueBase = ovs.db.types.BaseType(value)
70 type_ = ovs.db.types.Type(ovs.db.types.BaseType(key),
71 valueBase, n_min, 1)
8cdf0349 72 assert type_.is_valid()
99155935
BP
73
74 sys.stdout.write("key %s, value %s, n_min %d: "
75 % (key.to_string(), value.to_string(), n_min))
76
8cdf0349
BP
77 datum = data.Datum.default(type_)
78 if datum != data.Datum.default(type_):
99155935
BP
79 sys.stdout.write("wrong\n")
80 any_errors = True
81 else:
82 sys.stdout.write("OK\n")
83 if any_errors:
84 sys.exit(1)
85
26bb0f31 86
99155935
BP
87def do_parse_atomic_type(type_string):
88 type_json = unbox_json(ovs.json.from_string(type_string))
3c057118 89 atomic_type = ovs.db.types.AtomicType.from_json(type_json)
8ea171ab 90 print(ovs.json.to_string(atomic_type.to_json(), sort_keys=True))
99155935 91
26bb0f31 92
99155935
BP
93def do_parse_base_type(type_string):
94 type_json = unbox_json(ovs.json.from_string(type_string))
3c057118 95 base_type = ovs.db.types.BaseType.from_json(type_json)
8ea171ab 96 print(ovs.json.to_string(base_type.to_json(), sort_keys=True))
99155935 97
26bb0f31 98
99155935
BP
99def do_parse_type(type_string):
100 type_json = unbox_json(ovs.json.from_string(type_string))
3c057118 101 type_ = ovs.db.types.Type.from_json(type_json)
8ea171ab 102 print(ovs.json.to_string(type_.to_json(), sort_keys=True))
99155935 103
26bb0f31 104
99155935
BP
105def do_parse_atoms(type_string, *atom_strings):
106 type_json = unbox_json(ovs.json.from_string(type_string))
3c057118 107 base = ovs.db.types.BaseType.from_json(type_json)
99155935
BP
108 for atom_string in atom_strings:
109 atom_json = unbox_json(ovs.json.from_string(atom_string))
110 try:
111 atom = data.Atom.from_json(base, atom_json)
8ea171ab 112 print(ovs.json.to_string(atom.to_json()))
f3068bff 113 except error.Error as e:
64eb96a9 114 print(e.args[0])
99155935 115
26bb0f31 116
99155935
BP
117def do_parse_data(type_string, *data_strings):
118 type_json = unbox_json(ovs.json.from_string(type_string))
3c057118 119 type_ = ovs.db.types.Type.from_json(type_json)
99155935
BP
120 for datum_string in data_strings:
121 datum_json = unbox_json(ovs.json.from_string(datum_string))
8cdf0349 122 datum = data.Datum.from_json(type_, datum_json)
8ea171ab 123 print(ovs.json.to_string(datum.to_json()))
99155935 124
26bb0f31 125
99155935
BP
126def do_sort_atoms(type_string, atom_strings):
127 type_json = unbox_json(ovs.json.from_string(type_string))
3c057118 128 base = ovs.db.types.BaseType.from_json(type_json)
99155935
BP
129 atoms = [data.Atom.from_json(base, atom_json)
130 for atom_json in unbox_json(ovs.json.from_string(atom_strings))]
8ea171ab
RB
131 print(ovs.json.to_string([data.Atom.to_json(atom)
132 for atom in sorted(atoms)]))
99155935 133
26bb0f31 134
99155935
BP
135def do_parse_column(name, column_string):
136 column_json = unbox_json(ovs.json.from_string(column_string))
137 column = ovs.db.schema.ColumnSchema.from_json(column_json, name)
8ea171ab 138 print(ovs.json.to_string(column.to_json(), sort_keys=True))
99155935 139
26bb0f31 140
c5f341ab
BP
141def do_parse_table(name, table_string, default_is_root_string='false'):
142 default_is_root = default_is_root_string == 'true'
99155935
BP
143 table_json = unbox_json(ovs.json.from_string(table_string))
144 table = ovs.db.schema.TableSchema.from_json(table_json, name)
8ea171ab 145 print(ovs.json.to_string(table.to_json(default_is_root), sort_keys=True))
99155935 146
26bb0f31 147
99155935
BP
148def do_parse_schema(schema_string):
149 schema_json = unbox_json(ovs.json.from_string(schema_string))
150 schema = ovs.db.schema.DbSchema.from_json(schema_json)
8ea171ab 151 print(ovs.json.to_string(schema.to_json(), sort_keys=True))
99155935 152
26bb0f31 153
330b9c9c 154def get_simple_printable_row_string(row, columns):
a7261bf7 155 s = ""
330b9c9c 156 for column in columns:
a7261bf7
NS
157 if hasattr(row, column) and not (type(getattr(row, column))
158 is ovs.db.data.Atom):
330b9c9c
AB
159 value = getattr(row, column)
160 if isinstance(value, dict):
161 value = sorted(value.items())
162 s += "%s=%s " % (column, value)
a7261bf7
NS
163 s = s.strip()
164 s = re.sub('""|,|u?\'', "", s)
165 s = re.sub('UUID\(([^)]+)\)', r'\1', s)
166 s = re.sub('False', 'false', s)
167 s = re.sub('True', 'true', s)
168 s = re.sub(r'(ba)=([^[][^ ]*) ', r'\1=[\2] ', s)
169 return s
170
171
330b9c9c
AB
172def get_simple_table_printable_row(row):
173 simple_columns = ["i", "r", "b", "s", "u", "ia",
174 "ra", "ba", "sa", "ua", "uuid"]
175 return get_simple_printable_row_string(row, simple_columns)
176
177
a59912a0
RM
178def get_simple2_table_printable_row(row):
179 simple2_columns = ["name", "smap", "imap"]
330b9c9c 180 return get_simple_printable_row_string(row, simple2_columns)
a59912a0
RM
181
182
183def get_simple3_table_printable_row(row):
184 simple3_columns = ["name", "uset"]
330b9c9c 185 return get_simple_printable_row_string(row, simple3_columns)
a59912a0
RM
186
187
99155935
BP
188def print_idl(idl, step):
189 n = 0
80c12152 190 if "simple" in idl.tables:
80c12152 191 simple = idl.tables["simple"].rows
cb96c1b2 192 for row in six.itervalues(simple):
a7261bf7
NS
193 s = "%03d: " % step
194 s += get_simple_table_printable_row(row)
80c12152
SA
195 print(s)
196 n += 1
197
a59912a0
RM
198 if "simple2" in idl.tables:
199 simple2 = idl.tables["simple2"].rows
200 for row in six.itervalues(simple2):
201 s = "%03d: " % step
202 s += get_simple2_table_printable_row(row)
203 print(s)
204 n += 1
205
206 if "simple3" in idl.tables:
207 simple3 = idl.tables["simple3"].rows
208 for row in six.itervalues(simple3):
209 s = "%03d: " % step
210 s += get_simple3_table_printable_row(row)
211 print(s)
212 n += 1
213
80c12152
SA
214 if "link1" in idl.tables:
215 l1 = idl.tables["link1"].rows
cb96c1b2 216 for row in six.itervalues(l1):
80c12152
SA
217 s = ["%03d: i=%s k=" % (step, row.i)]
218 if hasattr(row, "k") and row.k:
219 s.append(str(row.k.i))
220 if hasattr(row, "ka"):
221 s.append(" ka=[")
222 s.append(' '.join(sorted(str(ka.i) for ka in row.ka)))
223 s.append("] l2=")
224 if hasattr(row, "l2") and row.l2:
225 s.append(str(row.l2[0].i))
226 if hasattr(row, "uuid"):
227 s.append(" uuid=%s" % row.uuid)
228 print(''.join(s))
229 n += 1
230
231 if "link2" in idl.tables:
232 l2 = idl.tables["link2"].rows
cb96c1b2 233 for row in six.itervalues(l2):
80c12152
SA
234 s = ["%03d:" % step]
235 s.append(" i=%s l1=" % row.i)
236 if hasattr(row, "l1") and row.l1:
237 s.append(str(row.l1[0].i))
238 if hasattr(row, "uuid"):
239 s.append(" uuid=%s" % row.uuid)
240 print(''.join(s))
241 n += 1
8cdf0349 242
079ace1f
MM
243 if "singleton" in idl.tables:
244 sng = idl.tables["singleton"].rows
245 for row in six.itervalues(sng):
246 s = ["%03d:" % step]
247 s.append(" name=%s" % row.name)
248 if hasattr(row, "uuid"):
249 s.append(" uuid=%s" % row.uuid)
250 print(''.join(s))
251 n += 1
252
99155935
BP
253 if not n:
254 print("%03d: empty" % step)
8cdf0349 255 sys.stdout.flush()
99155935 256
26bb0f31 257
99155935 258def substitute_uuids(json, symtab):
25f599fb 259 if isinstance(json, six.string_types):
99155935
BP
260 symbol = symtab.get(json)
261 if symbol:
262 return str(symbol)
263 elif type(json) == list:
264 return [substitute_uuids(element, symtab) for element in json]
265 elif type(json) == dict:
266 d = {}
cb96c1b2 267 for key, value in six.iteritems(json):
99155935
BP
268 d[key] = substitute_uuids(value, symtab)
269 return d
270 return json
271
26bb0f31 272
99155935 273def parse_uuids(json, symtab):
25f599fb
RB
274 if (isinstance(json, six.string_types)
275 and ovs.ovsuuid.is_valid_string(json)):
99155935
BP
276 name = "#%d#" % len(symtab)
277 sys.stderr.write("%s = %s\n" % (name, json))
278 symtab[name] = json
279 elif type(json) == list:
280 for element in json:
281 parse_uuids(element, symtab)
282 elif type(json) == dict:
cb96c1b2 283 for value in six.itervalues(json):
99155935
BP
284 parse_uuids(value, symtab)
285
26bb0f31 286
8cdf0349 287def idltest_find_simple(idl, i):
cb96c1b2 288 for row in six.itervalues(idl.tables["simple"].rows):
8cdf0349
BP
289 if row.i == i:
290 return row
291 return None
292
26bb0f31 293
a59912a0
RM
294def idltest_find_simple2(idl, i):
295 for row in six.itervalues(idl.tables["simple2"].rows):
296 if row.name == i:
297 return row
298 return None
299
300
301def idltest_find_simple3(idl, i):
13973bc4 302 return next(idl.index_equal("simple3", "simple3_by_name", i), None)
a59912a0
RM
303
304
8cdf0349
BP
305def idl_set(idl, commands, step):
306 txn = ovs.db.idl.Transaction(idl)
307 increment = False
80c12152 308 fetch_cmds = []
d7d417fc 309 events = []
8cdf0349
BP
310 for command in commands.split(','):
311 words = command.split()
312 name = words[0]
313 args = words[1:]
314
d7d417fc
TW
315 if name == "notifytest":
316 name = args[0]
317 args = args[1:]
318 old_notify = idl.notify
319
320 def notify(event, row, updates=None):
1aa2bf92 321 if updates:
cb96c1b2 322 upcol = list(updates._data.keys())[0]
1aa2bf92
AW
323 else:
324 upcol = None
d7d417fc
TW
325 events.append("%s|%s|%s" % (event, row.i, upcol))
326 idl.notify = old_notify
327
328 idl.notify = notify
329
8cdf0349
BP
330 if name == "set":
331 if len(args) != 3:
332 sys.stderr.write('"set" command requires 3 arguments\n')
333 sys.exit(1)
334
335 s = idltest_find_simple(idl, int(args[0]))
336 if not s:
337 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
338 % int(args[0]))
339 sys.exit(1)
340
341 if args[1] == "b":
342 s.b = args[2] == "1"
343 elif args[1] == "s":
e7164d96
LR
344 if six.PY2:
345 s.s = args[2].decode('utf-8')
346 else:
42253e5e
AB
347 s.s = args[2].encode(sys.getfilesystemencoding(),
348 'surrogateescape') \
e7164d96 349 .decode('utf-8', 'replace')
8cdf0349
BP
350 elif args[1] == "u":
351 s.u = uuid.UUID(args[2])
352 elif args[1] == "r":
353 s.r = float(args[2])
354 else:
355 sys.stderr.write('"set" comamnd asks for unknown column %s\n'
356 % args[2])
357 sys.stderr.exit(1)
358 elif name == "insert":
359 if len(args) != 1:
360 sys.stderr.write('"set" command requires 1 argument\n')
361 sys.exit(1)
362
363 s = txn.insert(idl.tables["simple"])
364 s.i = int(args[0])
365 elif name == "delete":
366 if len(args) != 1:
367 sys.stderr.write('"delete" command requires 1 argument\n')
368 sys.exit(1)
369
370 s = idltest_find_simple(idl, int(args[0]))
371 if not s:
372 sys.stderr.write('"delete" command asks for nonexistent i=%d\n'
373 % int(args[0]))
374 sys.exit(1)
375 s.delete()
376 elif name == "verify":
377 if len(args) != 2:
378 sys.stderr.write('"verify" command requires 2 arguments\n')
379 sys.exit(1)
380
381 s = idltest_find_simple(idl, int(args[0]))
382 if not s:
383 sys.stderr.write('"verify" command asks for nonexistent i=%d\n'
384 % int(args[0]))
385 sys.exit(1)
386
387 if args[1] in ("i", "b", "s", "u", "r"):
388 s.verify(args[1])
389 else:
390 sys.stderr.write('"verify" command asks for unknown column '
391 '"%s"\n' % args[1])
392 sys.exit(1)
80c12152
SA
393 elif name == "fetch":
394 if len(args) != 2:
395 sys.stderr.write('"fetch" command requires 2 argument\n')
396 sys.exit(1)
397
398 row = idltest_find_simple(idl, int(args[0]))
399 if not row:
400 sys.stderr.write('"fetch" command asks for nonexistent i=%d\n'
401 % int(args[0]))
402 sys.exit(1)
403
404 column = args[1]
405 row.fetch(column)
406 fetch_cmds.append([row, column])
8cdf0349 407 elif name == "increment":
94fbe1aa
BP
408 if len(args) != 1:
409 sys.stderr.write('"increment" command requires 1 argument\n')
410 sys.exit(1)
411
412 s = idltest_find_simple(idl, int(args[0]))
413 if not s:
414 sys.stderr.write('"set" command asks for nonexistent i=%d\n'
415 % int(args[0]))
8cdf0349
BP
416 sys.exit(1)
417
94fbe1aa 418 s.increment("i")
8cdf0349
BP
419 increment = True
420 elif name == "abort":
421 txn.abort()
422 break
423 elif name == "destroy":
8ea171ab 424 print("%03d: destroy" % step)
8cdf0349
BP
425 sys.stdout.flush()
426 txn.abort()
427 return
225b582a
IY
428 elif name == "linktest":
429 l1_0 = txn.insert(idl.tables["link1"])
430 l1_0.i = 1
431 l1_0.k = [l1_0]
432 l1_0.ka = [l1_0]
433 l1_1 = txn.insert(idl.tables["link1"])
434 l1_1.i = 2
435 l1_1.k = [l1_0]
436 l1_1.ka = [l1_0, l1_1]
3b4c362f
IY
437 elif name == 'getattrtest':
438 l1 = txn.insert(idl.tables["link1"])
439 i = getattr(l1, 'i', 1)
440 assert i == 1
441 l1.i = 2
442 i = getattr(l1, 'i', 1)
443 assert i == 2
444 l1.k = [l1]
a59912a0
RM
445 elif name == 'partialmapinsertelement':
446 row = idltest_find_simple2(idl, 'myString1')
2d54d801 447 len_smap = len(getattr(row, 'smap'))
a59912a0 448 row.setkey('smap', 'key1', 'myList1')
2d54d801 449 len_imap = len(getattr(row, 'imap'))
a59912a0
RM
450 row.setkey('imap', 3, 'myids2')
451 row.__setattr__('name', 'String2')
2d54d801
AB
452 assert len(getattr(row, 'smap')) == len_smap
453 assert len(getattr(row, 'imap')) == len_imap + 1
330b9c9c
AB
454 elif name == 'partialmapinsertmultipleelements':
455 row = idltest_find_simple2(idl, 'String2')
2d54d801 456 len_smap = len(getattr(row, 'smap'))
330b9c9c
AB
457 row.setkey('smap', 'key2', 'myList2')
458 row.setkey('smap', 'key3', 'myList3')
2d54d801
AB
459 row.setkey('smap', 'key4', 'myList4')
460 assert len(getattr(row, 'smap')) == len_smap + 2
330b9c9c 461 elif name == 'partialmapdelelements':
a59912a0 462 row = idltest_find_simple2(idl, 'String2')
2d54d801 463 len_smap = len(getattr(row, 'smap'))
884d9bad 464 row.delkey('smap', 'key1', 'myList1')
330b9c9c
AB
465 row.delkey('smap', 'key2', 'wrongvalue')
466 row.delkey('smap', 'key3')
2d54d801
AB
467 row.delkey('smap', 'key4')
468 assert len(getattr(row, 'smap')) == len_smap - 3
469 elif name == 'partialmapmutatenew':
470 new_row2 = txn.insert(idl.tables["simple2"])
471 setattr(new_row2, 'name', 'String2New')
472 new_row2.setkey('smap', 'key1', 'newList1')
473 assert len(getattr(new_row2, 'smap')) == 1
474 new_row2.setkey('smap', 'key2', 'newList2')
475 assert len(getattr(new_row2, 'smap')) == 2
a59912a0
RM
476 elif name == 'partialrenamesetadd':
477 row = idltest_find_simple3(idl, 'mySet1')
2d54d801 478 old_size = len(getattr(row, 'uset', []))
a59912a0
RM
479 row.addvalue('uset',
480 uuid.UUID("001e43d2-dd3f-4616-ab6a-83a490bb0991"))
481 row.__setattr__('name', 'String2')
2d54d801 482 assert len(getattr(row, 'uset', [])) == old_size + 1
330b9c9c 483 elif name == 'partialduplicateadd':
a59912a0 484 row = idltest_find_simple3(idl, 'String2')
2d54d801 485 old_size = len(getattr(row, 'uset', []))
a59912a0
RM
486 row.addvalue('uset',
487 uuid.UUID("0026b3ba-571b-4729-8227-d860a5210ab8"))
330b9c9c
AB
488 row.addvalue('uset',
489 uuid.UUID("0026b3ba-571b-4729-8227-d860a5210ab8"))
2d54d801 490 assert len(getattr(row, 'uset', [])) == old_size + 1
a59912a0
RM
491 elif name == 'partialsetdel':
492 row = idltest_find_simple3(idl, 'String2')
2d54d801 493 old_size = len(getattr(row, 'uset', []))
a59912a0
RM
494 row.delvalue('uset',
495 uuid.UUID("001e43d2-dd3f-4616-ab6a-83a490bb0991"))
2d54d801 496 assert len(getattr(row, 'uset', [])) == old_size - 1
a59912a0
RM
497 elif name == 'partialsetref':
498 new_row = txn.insert(idl.tables["simple4"])
499 new_row.__setattr__('name', 'test')
500 row = idltest_find_simple3(idl, 'String2')
2d54d801 501 old_size = len(getattr(row, 'uref', []))
a59912a0 502 row.addvalue('uref', new_row.uuid)
2d54d801 503 assert len(getattr(row, 'uref', [])) == old_size + 1
330b9c9c
AB
504 elif name == 'partialsetoverrideops':
505 row = idltest_find_simple3(idl, 'String2')
506 row.addvalue('uset',
507 uuid.UUID("579e978d-776c-4f19-a225-268e5890e670"))
508 row.delvalue('uset',
509 uuid.UUID("0026b3ba-571b-4729-8227-d860a5210ab8"))
510 row.__setattr__('uset',
511 [uuid.UUID("0026b3ba-571b-4729-8227-d860a5210ab8")])
2d54d801
AB
512 assert len(getattr(row, 'uset', [])) == 1
513 elif name == 'partialsetadddelete':
514 row = idltest_find_simple3(idl, 'String2')
515 row.addvalue('uset',
516 uuid.UUID('b6272353-af9c-40b7-90fe-32a43e6518a1'))
517 row.addvalue('uset',
518 uuid.UUID('1d6a71a2-dffb-426e-b2fa-b727091f9901'))
519 row.delvalue('uset',
520 uuid.UUID('0026b3ba-571b-4729-8227-d860a5210ab8'))
521 assert len(getattr(row, 'uset', [])) == 2
b3220c67
AB
522 elif name == 'partialsetmutatenew':
523 new_row41 = txn.insert(idl.tables["simple4"])
524 new_row41.__setattr__('name', 'new_row41')
525 new_row3 = txn.insert(idl.tables["simple3"])
526 setattr(new_row3, 'name', 'String3')
527 new_row3.addvalue('uset', new_row41.uuid)
2d54d801 528 assert len(getattr(new_row3, 'uset', [])) == 1
8cdf0349
BP
529 else:
530 sys.stderr.write("unknown command %s\n" % name)
531 sys.exit(1)
532
533 status = txn.commit_block()
534 sys.stdout.write("%03d: commit, status=%s"
535 % (step, ovs.db.idl.Transaction.status_to_string(status)))
536 if increment and status == ovs.db.idl.Transaction.SUCCESS:
537 sys.stdout.write(", increment=%d" % txn.get_increment_new_value())
d7d417fc
TW
538 if events:
539 # Event notifications from operations in a single transaction are
540 # not in a gauranteed order due to update messages being dicts
541 sys.stdout.write(", events=" + ", ".join(sorted(events)))
8cdf0349
BP
542 sys.stdout.write("\n")
543 sys.stdout.flush()
544
26bb0f31 545
16ebb90e 546def update_condition(idl, commands):
0164e367 547 commands = commands[len("condition "):].split(";")
16ebb90e 548 for command in commands:
16ebb90e
LS
549 command = command.split(" ")
550 if(len(command) != 2):
0164e367 551 sys.stderr.write("Error parsing condition %s\n" % command)
16ebb90e
LS
552 sys.exit(1)
553
554 table = command[0]
555 cond = ovs.json.from_string(command[1])
556
0164e367 557 idl.cond_change(table, cond)
16ebb90e
LS
558
559
8cdf0349 560def do_idl(schema_file, remote, *commands):
bf42f674 561 schema_helper = ovs.db.idl.SchemaHelper(schema_file)
a7261bf7
NS
562 track_notify = False
563
d90ed7d6 564 if remote.startswith("ssl:"):
6612648d
JS
565 if len(commands) < 3:
566 sys.stderr.write("SSL connection requires private key, "
567 "certificate for private key, and peer CA "
568 "certificate as arguments\n")
569 sys.exit(1)
d90ed7d6
NS
570 ovs.stream.Stream.ssl_set_private_key_file(commands[0])
571 ovs.stream.Stream.ssl_set_certificate_file(commands[1])
572 ovs.stream.Stream.ssl_set_ca_cert_file(commands[2])
573 commands = commands[3:]
574
a7261bf7
NS
575 if commands and commands[0] == "track-notify":
576 commands = commands[1:]
577 track_notify = True
578
01dc1516 579 if commands and commands[0].startswith("?"):
80c12152 580 readonly = {}
01dc1516 581 for x in commands[0][1:].split("?"):
80c12152 582 readonly = []
01dc1516 583 table, columns = x.split(":")
80c12152
SA
584 columns = columns.split(",")
585 for index, column in enumerate(columns):
586 if column[-1] == '!':
587 columns[index] = columns[index][:-1]
588 readonly.append(columns[index])
589 schema_helper.register_columns(table, columns, readonly)
01dc1516
SA
590 commands = commands[1:]
591 else:
592 schema_helper.register_all()
bf42f674 593 idl = ovs.db.idl.Idl(remote, schema_helper)
13973bc4
TW
594 if "simple3" in idl.tables:
595 idl.index_create("simple3", "simple3_by_name")
99155935
BP
596
597 if commands:
31e434fc
NS
598 remotes = remote.split(',')
599 stream = None
600 for r in remotes:
601 error, stream = ovs.stream.Stream.open_block(
602 ovs.stream.Stream.open(r))
603 if not error and stream:
604 break
605 stream = None
606
607 if not stream:
99155935
BP
608 sys.stderr.write("failed to connect to \"%s\"" % remote)
609 sys.exit(1)
610 rpc = ovs.jsonrpc.Connection(stream)
611 else:
612 rpc = None
613
614 symtab = {}
615 seqno = 0
616 step = 0
16ebb90e 617
a7261bf7
NS
618 def mock_notify(event, row, updates=None):
619 output = "%03d: " % step
620 output += "event:" + str(event) + ", row={"
621 output += get_simple_table_printable_row(row) + "}, updates="
622 if updates is None:
623 output += "None"
624 else:
625 output += "{" + get_simple_table_printable_row(updates) + "}"
626
627 output += '\n'
628 sys.stdout.write(output)
629 sys.stdout.flush()
630
631 if track_notify and "simple" in idl.tables:
632 idl.notify = mock_notify
633
16ebb90e
LS
634 commands = list(commands)
635 if len(commands) >= 1 and "condition" in commands[0]:
636 update_condition(idl, commands.pop(0))
637 sys.stdout.write("%03d: change conditions\n" % step)
638 sys.stdout.flush()
639 step += 1
640
99155935
BP
641 for command in commands:
642 if command.startswith("+"):
643 # The previous transaction didn't change anything.
644 command = command[1:]
645 else:
646 # Wait for update.
8cdf0349 647 while idl.change_seqno == seqno and not idl.run():
99155935
BP
648 rpc.run()
649
650 poller = ovs.poller.Poller()
651 idl.wait(poller)
652 rpc.wait(poller)
653 poller.block()
26bb0f31 654
99155935
BP
655 print_idl(idl, step)
656 step += 1
657
8cdf0349 658 seqno = idl.change_seqno
99155935
BP
659
660 if command == "reconnect":
661 print("%03d: reconnect" % step)
8cdf0349 662 sys.stdout.flush()
99155935
BP
663 step += 1
664 idl.force_reconnect()
16ebb90e
LS
665 elif "condition" in command:
666 update_condition(idl, command)
667 sys.stdout.write("%03d: change conditions\n" % step)
668 sys.stdout.flush()
669 step += 1
99155935
BP
670 elif not command.startswith("["):
671 idl_set(idl, command, step)
672 step += 1
673 else:
674 json = ovs.json.from_string(command)
25f599fb 675 if isinstance(json, six.string_types):
99155935
BP
676 sys.stderr.write("\"%s\": %s\n" % (command, json))
677 sys.exit(1)
678 json = substitute_uuids(json, symtab)
679 request = ovs.jsonrpc.Message.create_request("transact", json)
680 error, reply = rpc.transact_block(request)
681 if error:
682 sys.stderr.write("jsonrpc transaction failed: %s"
683 % os.strerror(error))
684 sys.exit(1)
66eb76d0
EJ
685 elif reply.error is not None:
686 sys.stderr.write("jsonrpc transaction failed: %s"
687 % reply.error)
688 sys.exit(1)
689
99155935
BP
690 sys.stdout.write("%03d: " % step)
691 sys.stdout.flush()
692 step += 1
693 if reply.result is not None:
694 parse_uuids(reply.result, symtab)
695 reply.id = None
696 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
8cdf0349 697 sys.stdout.flush()
99155935
BP
698
699 if rpc:
700 rpc.close()
8cdf0349 701 while idl.change_seqno == seqno and not idl.run():
99155935
BP
702 poller = ovs.poller.Poller()
703 idl.wait(poller)
704 poller.block()
705 print_idl(idl, step)
706 step += 1
707 idl.close()
708 print("%03d: done" % step)
709
26bb0f31 710
af358237
OBY
711def do_idl_passive(schema_file, remote, *commands):
712 symtab = {}
713 step = 0
714 schema_helper = ovs.db.idl.SchemaHelper(schema_file)
715 schema_helper.register_all()
716 idl = ovs.db.idl.Idl(remote, schema_helper)
717
718 while idl._session.rpc is None:
719 idl.run()
720
721 rpc = idl._session.rpc
722
723 print_idl(idl, step)
724 step += 1
725
726 for command in commands:
727 json = ovs.json.from_string(command)
728 if isinstance(json, six.string_types):
729 sys.stderr.write("\"%s\": %s\n" % (command, json))
730 sys.exit(1)
731 json = substitute_uuids(json, symtab)
732 request = ovs.jsonrpc.Message.create_request("transact", json)
733 error, reply = rpc.transact_block(request)
734 if error:
735 sys.stderr.write("jsonrpc transaction failed: %s"
736 % os.strerror(error))
737 sys.exit(1)
738 elif reply.error is not None:
739 sys.stderr.write("jsonrpc transaction failed: %s"
740 % reply.error)
741 sys.exit(1)
742
743 sys.stdout.write("%03d: " % step)
744 sys.stdout.flush()
745 step += 1
746 if reply.result is not None:
747 parse_uuids(reply.result, symtab)
748 reply.id = None
749 sys.stdout.write("%s\n" % ovs.json.to_string(reply.to_json()))
750 sys.stdout.flush()
751
752 idl.close()
753 print("%03d: done" % step)
754
755
99155935 756def usage():
8ea171ab 757 print("""\
99155935
BP
758%(program_name)s: test utility for Open vSwitch database Python bindings
759usage: %(program_name)s [OPTIONS] COMMAND ARG...
760
761The following commands are supported:
762default-atoms
763 test ovsdb_atom_default()
764default-data
765 test ovsdb_datum_default()
766parse-atomic-type TYPE
767 parse TYPE as OVSDB atomic type, and re-serialize
768parse-base-type TYPE
769 parse TYPE as OVSDB base type, and re-serialize
770parse-type JSON
771 parse JSON as OVSDB type, and re-serialize
772parse-atoms TYPE ATOM...
773 parse JSON ATOMs as atoms of TYPE, and re-serialize
774parse-atom-strings TYPE ATOM...
775 parse string ATOMs as atoms of given TYPE, and re-serialize
776sort-atoms TYPE ATOM...
777 print JSON ATOMs in sorted order
778parse-data TYPE DATUM...
779 parse JSON DATUMs as data of given TYPE, and re-serialize
780parse-column NAME OBJECT
781 parse column NAME with info OBJECT, and re-serialize
c5f341ab 782parse-table NAME OBJECT [DEFAULT-IS-ROOT]
99155935
BP
783 parse table NAME with info OBJECT
784parse-schema JSON
785 parse JSON as an OVSDB schema, and re-serialize
01dc1516 786idl SCHEMA SERVER [?T1:C1,C2...[?T2:C1,C2,...]...] [TRANSACTION...]
8cdf0349
BP
787 connect to SERVER (which has the specified SCHEMA) and dump the
788 contents of the database as seen initially by the IDL implementation
789 and after executing each TRANSACTION. (Each TRANSACTION must modify
99155935 790 the database or this command will hang.)
01dc1516
SA
791 By default, all columns of all tables are monitored. The "?" option
792 can be used to monitor specific Table:Column(s). The table and their
793 columns are listed as a string of the form starting with "?":
794 ?<table-name>:<column-name>,<column-name>,...
795 e.g.:
796 ?simple:b - Monitor column "b" in table "simple"
797 Entries for multiple tables are seperated by "?":
798 ?<table-name>:<column-name>,...?<table-name>:<column-name>,...
799 e.g.:
800 ?simple:b?link1:i,k - Monitor column "b" in table "simple",
801 and column "i", "k" in table "link1"
80c12152
SA
802 Readonly columns: Suffixing a "!" after a column indicates that the
803 column is to be registered "readonly".
804 e.g.:
805 ?simple:i,b! - Register interest in column "i" (monitoring) and
806 column "b" (readonly).
807
99155935
BP
808
809The following options are also available:
810 -t, --timeout=SECS give up after SECS seconds
811 -h, --help display this help message\
8ea171ab 812""" % {'program_name': ovs.util.PROGRAM_NAME})
99155935
BP
813 sys.exit(0)
814
26bb0f31 815
99155935 816def main(argv):
99155935
BP
817 try:
818 options, args = getopt.gnu_getopt(argv[1:], 't:h',
819 ['timeout',
820 'help'])
f3068bff 821 except getopt.GetoptError as geo:
99155935
BP
822 sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
823 sys.exit(1)
824
825 for key, value in options:
826 if key in ['-h', '--help']:
827 usage()
828 elif key in ['-t', '--timeout']:
829 try:
830 timeout = int(value)
831 if timeout < 1:
832 raise TypeError
833 except TypeError:
834 raise error.Error("value %s on -t or --timeout is not at "
835 "least 1" % value)
36d51634 836 signal_alarm(timeout)
99155935
BP
837 else:
838 sys.exit(0)
839
99155935
BP
840 if not args:
841 sys.stderr.write("%s: missing command argument "
842 "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
843 sys.exit(1)
844
845 commands = {"default-atoms": (do_default_atoms, 0),
846 "default-data": (do_default_data, 0),
847 "parse-atomic-type": (do_parse_atomic_type, 1),
848 "parse-base-type": (do_parse_base_type, 1),
849 "parse-type": (do_parse_type, 1),
850 "parse-atoms": (do_parse_atoms, (2,)),
851 "parse-data": (do_parse_data, (2,)),
852 "sort-atoms": (do_sort_atoms, 2),
853 "parse-column": (do_parse_column, 2),
c5f341ab 854 "parse-table": (do_parse_table, (2, 3)),
99155935 855 "parse-schema": (do_parse_schema, 1),
af358237
OBY
856 "idl": (do_idl, (2,)),
857 "idl_passive": (do_idl_passive, (2,))}
99155935
BP
858
859 command_name = args[0]
860 args = args[1:]
603e325f 861 if command_name not in commands:
99155935
BP
862 sys.stderr.write("%s: unknown command \"%s\" "
863 "(use --help for help)\n" % (ovs.util.PROGRAM_NAME,
864 command_name))
865 sys.exit(1)
866
867 func, n_args = commands[command_name]
868 if type(n_args) == tuple:
869 if len(args) < n_args[0]:
870 sys.stderr.write("%s: \"%s\" requires at least %d arguments but "
871 "only %d provided\n"
872 % (ovs.util.PROGRAM_NAME, command_name,
117637b7 873 n_args[0], len(args)))
99155935
BP
874 sys.exit(1)
875 elif type(n_args) == int:
876 if len(args) != n_args:
877 sys.stderr.write("%s: \"%s\" requires %d arguments but %d "
878 "provided\n"
879 % (ovs.util.PROGRAM_NAME, command_name,
880 n_args, len(args)))
881 sys.exit(1)
882 else:
883 assert False
884
885 func(*args)
886
26bb0f31 887
99155935
BP
888if __name__ == '__main__':
889 try:
890 main(sys.argv)
f3068bff 891 except error.Error as e:
99155935
BP
892 sys.stderr.write("%s\n" % e)
893 sys.exit(1)