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