]>
git.proxmox.com Git - mirror_ovs.git/blob - tests/test-ovsdb.py
1 # Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
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
33 if type(json
) == list and len(json
) == 1:
39 def do_default_atoms():
40 for type_
in types
.ATOMIC_TYPES
:
41 if type_
== types
.VoidType
:
44 sys
.stdout
.write("%s: " % type_
.to_string())
46 atom
= data
.Atom
.default(type_
)
47 if atom
!= data
.Atom
.default(type_
):
48 sys
.stdout
.write("wrong\n")
51 sys
.stdout
.write("OK\n")
54 def do_default_data():
57 for key
in types
.ATOMIC_TYPES
:
58 if key
== types
.VoidType
:
60 for value
in types
.ATOMIC_TYPES
:
61 if value
== types
.VoidType
:
64 valueBase
= types
.BaseType(value
)
65 type_
= types
.Type(types
.BaseType(key
), valueBase
, n_min
, 1)
66 assert type_
.is_valid()
68 sys
.stdout
.write("key %s, value %s, n_min %d: "
69 % (key
.to_string(), value
.to_string(), n_min
))
71 datum
= data
.Datum
.default(type_
)
72 if datum
!= data
.Datum
.default(type_
):
73 sys
.stdout
.write("wrong\n")
76 sys
.stdout
.write("OK\n")
81 def do_parse_atomic_type(type_string
):
82 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
83 atomic_type
= types
.AtomicType
.from_json(type_json
)
84 print ovs
.json
.to_string(atomic_type
.to_json(), sort_keys
=True)
87 def do_parse_base_type(type_string
):
88 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
89 base_type
= types
.BaseType
.from_json(type_json
)
90 print ovs
.json
.to_string(base_type
.to_json(), sort_keys
=True)
93 def do_parse_type(type_string
):
94 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
95 type_
= types
.Type
.from_json(type_json
)
96 print ovs
.json
.to_string(type_
.to_json(), sort_keys
=True)
99 def do_parse_atoms(type_string
, *atom_strings
):
100 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
101 base
= types
.BaseType
.from_json(type_json
)
102 for atom_string
in atom_strings
:
103 atom_json
= unbox_json(ovs
.json
.from_string(atom_string
))
105 atom
= data
.Atom
.from_json(base
, atom_json
)
106 print ovs
.json
.to_string(atom
.to_json())
107 except error
.Error
, e
:
108 print e
.args
[0].encode("utf8")
111 def do_parse_data(type_string
, *data_strings
):
112 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
113 type_
= types
.Type
.from_json(type_json
)
114 for datum_string
in data_strings
:
115 datum_json
= unbox_json(ovs
.json
.from_string(datum_string
))
116 datum
= data
.Datum
.from_json(type_
, datum_json
)
117 print ovs
.json
.to_string(datum
.to_json())
120 def do_sort_atoms(type_string
, atom_strings
):
121 type_json
= unbox_json(ovs
.json
.from_string(type_string
))
122 base
= types
.BaseType
.from_json(type_json
)
123 atoms
= [data
.Atom
.from_json(base
, atom_json
)
124 for atom_json
in unbox_json(ovs
.json
.from_string(atom_strings
))]
125 print ovs
.json
.to_string([data
.Atom
.to_json(atom
)
126 for atom
in sorted(atoms
)])
129 def do_parse_column(name
, column_string
):
130 column_json
= unbox_json(ovs
.json
.from_string(column_string
))
131 column
= ovs
.db
.schema
.ColumnSchema
.from_json(column_json
, name
)
132 print ovs
.json
.to_string(column
.to_json(), sort_keys
=True)
135 def do_parse_table(name
, table_string
, default_is_root_string
='false'):
136 default_is_root
= default_is_root_string
== 'true'
137 table_json
= unbox_json(ovs
.json
.from_string(table_string
))
138 table
= ovs
.db
.schema
.TableSchema
.from_json(table_json
, name
)
139 print ovs
.json
.to_string(table
.to_json(default_is_root
), sort_keys
=True)
142 def do_parse_schema(schema_string
):
143 schema_json
= unbox_json(ovs
.json
.from_string(schema_string
))
144 schema
= ovs
.db
.schema
.DbSchema
.from_json(schema_json
)
145 print ovs
.json
.to_string(schema
.to_json(), sort_keys
=True)
148 def print_idl(idl
, step
):
150 if "simple" in idl
.tables
:
151 simple_columns
= ["i", "r", "b", "s", "u", "ia",
152 "ra", "ba", "sa", "ua", "uuid"]
153 simple
= idl
.tables
["simple"].rows
154 for row
in simple
.itervalues():
156 for column
in simple_columns
:
157 if hasattr(row
, column
) and not (type(getattr(row
, column
))
158 is ovs
.db
.data
.Atom
):
159 s
+= " %s=%s" % (column
, getattr(row
, column
))
160 s
= re
.sub('""|,|u?\'', "", s
)
161 s
= re
.sub('UUID\(([^)]+)\)', r
'\1', s
)
162 s
= re
.sub('False', 'false', s
)
163 s
= re
.sub('True', 'true', s
)
164 s
= re
.sub(r
'(ba)=([^[][^ ]*) ', r
'\1=[\2] ', s
)
168 if "link1" in idl
.tables
:
169 l1
= idl
.tables
["link1"].rows
170 for row
in l1
.itervalues():
171 s
= ["%03d: i=%s k=" % (step
, row
.i
)]
172 if hasattr(row
, "k") and row
.k
:
173 s
.append(str(row
.k
.i
))
174 if hasattr(row
, "ka"):
176 s
.append(' '.join(sorted(str(ka
.i
) for ka
in row
.ka
)))
178 if hasattr(row
, "l2") and row
.l2
:
179 s
.append(str(row
.l2
[0].i
))
180 if hasattr(row
, "uuid"):
181 s
.append(" uuid=%s" % row
.uuid
)
185 if "link2" in idl
.tables
:
186 l2
= idl
.tables
["link2"].rows
187 for row
in l2
.itervalues():
189 s
.append(" i=%s l1=" % row
.i
)
190 if hasattr(row
, "l1") and row
.l1
:
191 s
.append(str(row
.l1
[0].i
))
192 if hasattr(row
, "uuid"):
193 s
.append(" uuid=%s" % row
.uuid
)
198 print("%03d: empty" % step
)
202 def substitute_uuids(json
, symtab
):
203 if type(json
) in [str, unicode]:
204 symbol
= symtab
.get(json
)
207 elif type(json
) == list:
208 return [substitute_uuids(element
, symtab
) for element
in json
]
209 elif type(json
) == dict:
211 for key
, value
in json
.iteritems():
212 d
[key
] = substitute_uuids(value
, symtab
)
217 def parse_uuids(json
, symtab
):
218 if type(json
) in [str, unicode] and ovs
.ovsuuid
.is_valid_string(json
):
219 name
= "#%d#" % len(symtab
)
220 sys
.stderr
.write("%s = %s\n" % (name
, json
))
222 elif type(json
) == list:
224 parse_uuids(element
, symtab
)
225 elif type(json
) == dict:
226 for value
in json
.itervalues():
227 parse_uuids(value
, symtab
)
230 def idltest_find_simple(idl
, i
):
231 for row
in idl
.tables
["simple"].rows
.itervalues():
237 def idl_set(idl
, commands
, step
):
238 txn
= ovs
.db
.idl
.Transaction(idl
)
242 for command
in commands
.split(','):
243 words
= command
.split()
247 if name
== "notifytest":
250 old_notify
= idl
.notify
252 def notify(event
, row
, updates
=None):
254 upcol
= updates
._data
.keys()[0]
257 events
.append("%s|%s|%s" % (event
, row
.i
, upcol
))
258 idl
.notify
= old_notify
264 sys
.stderr
.write('"set" command requires 3 arguments\n')
267 s
= idltest_find_simple(idl
, int(args
[0]))
269 sys
.stderr
.write('"set" command asks for nonexistent i=%d\n'
278 s
.u
= uuid
.UUID(args
[2])
282 sys
.stderr
.write('"set" comamnd asks for unknown column %s\n'
285 elif name
== "insert":
287 sys
.stderr
.write('"set" command requires 1 argument\n')
290 s
= txn
.insert(idl
.tables
["simple"])
292 elif name
== "delete":
294 sys
.stderr
.write('"delete" command requires 1 argument\n')
297 s
= idltest_find_simple(idl
, int(args
[0]))
299 sys
.stderr
.write('"delete" command asks for nonexistent i=%d\n'
303 elif name
== "verify":
305 sys
.stderr
.write('"verify" command requires 2 arguments\n')
308 s
= idltest_find_simple(idl
, int(args
[0]))
310 sys
.stderr
.write('"verify" command asks for nonexistent i=%d\n'
314 if args
[1] in ("i", "b", "s", "u", "r"):
317 sys
.stderr
.write('"verify" command asks for unknown column '
320 elif name
== "fetch":
322 sys
.stderr
.write('"fetch" command requires 2 argument\n')
325 row
= idltest_find_simple(idl
, int(args
[0]))
327 sys
.stderr
.write('"fetch" command asks for nonexistent i=%d\n'
333 fetch_cmds
.append([row
, column
])
334 elif name
== "increment":
336 sys
.stderr
.write('"increment" command requires 1 argument\n')
339 s
= idltest_find_simple(idl
, int(args
[0]))
341 sys
.stderr
.write('"set" command asks for nonexistent i=%d\n'
347 elif name
== "abort":
350 elif name
== "destroy":
351 print "%03d: destroy" % step
355 elif name
== "linktest":
356 l1_0
= txn
.insert(idl
.tables
["link1"])
360 l1_1
= txn
.insert(idl
.tables
["link1"])
363 l1_1
.ka
= [l1_0
, l1_1
]
364 elif name
== 'getattrtest':
365 l1
= txn
.insert(idl
.tables
["link1"])
366 i
= getattr(l1
, 'i', 1)
369 i
= getattr(l1
, 'i', 1)
373 sys
.stderr
.write("unknown command %s\n" % name
)
376 status
= txn
.commit_block()
377 sys
.stdout
.write("%03d: commit, status=%s"
378 % (step
, ovs
.db
.idl
.Transaction
.status_to_string(status
)))
379 if increment
and status
== ovs
.db
.idl
.Transaction
.SUCCESS
:
380 sys
.stdout
.write(", increment=%d" % txn
.get_increment_new_value())
382 # Event notifications from operations in a single transaction are
383 # not in a gauranteed order due to update messages being dicts
384 sys
.stdout
.write(", events=" + ", ".join(sorted(events
)))
385 sys
.stdout
.write("\n")
389 def do_idl(schema_file
, remote
, *commands
):
390 schema_helper
= ovs
.db
.idl
.SchemaHelper(schema_file
)
391 if commands
and commands
[0].startswith("?"):
394 for x
in commands
[0][1:].split("?"):
396 table
, columns
= x
.split(":")
397 columns
= columns
.split(",")
398 for index
, column
in enumerate(columns
):
399 if column
[-1] == '!':
400 columns
[index
] = columns
[index
][:-1]
401 readonly
.append(columns
[index
])
402 schema_helper
.register_columns(table
, columns
, readonly
)
403 commands
= commands
[1:]
405 schema_helper
.register_all()
406 idl
= ovs
.db
.idl
.Idl(remote
, schema_helper
)
409 error
, stream
= ovs
.stream
.Stream
.open_block(
410 ovs
.stream
.Stream
.open(remote
))
412 sys
.stderr
.write("failed to connect to \"%s\"" % remote
)
414 rpc
= ovs
.jsonrpc
.Connection(stream
)
421 for command
in commands
:
422 if command
.startswith("+"):
423 # The previous transaction didn't change anything.
424 command
= command
[1:]
427 while idl
.change_seqno
== seqno
and not idl
.run():
430 poller
= ovs
.poller
.Poller()
438 seqno
= idl
.change_seqno
440 if command
== "reconnect":
441 print("%03d: reconnect" % step
)
444 idl
.force_reconnect()
445 elif not command
.startswith("["):
446 idl_set(idl
, command
, step
)
449 json
= ovs
.json
.from_string(command
)
450 if type(json
) in [str, unicode]:
451 sys
.stderr
.write("\"%s\": %s\n" % (command
, json
))
453 json
= substitute_uuids(json
, symtab
)
454 request
= ovs
.jsonrpc
.Message
.create_request("transact", json
)
455 error
, reply
= rpc
.transact_block(request
)
457 sys
.stderr
.write("jsonrpc transaction failed: %s"
458 % os
.strerror(error
))
460 elif reply
.error
is not None:
461 sys
.stderr
.write("jsonrpc transaction failed: %s"
465 sys
.stdout
.write("%03d: " % step
)
468 if reply
.result
is not None:
469 parse_uuids(reply
.result
, symtab
)
471 sys
.stdout
.write("%s\n" % ovs
.json
.to_string(reply
.to_json()))
476 while idl
.change_seqno
== seqno
and not idl
.run():
477 poller
= ovs
.poller
.Poller()
483 print("%03d: done" % step
)
488 %(program_name)s: test utility for Open vSwitch database Python bindings
489 usage: %(program_name)s [OPTIONS] COMMAND ARG...
491 The following commands are supported:
493 test ovsdb_atom_default()
495 test ovsdb_datum_default()
496 parse-atomic-type TYPE
497 parse TYPE as OVSDB atomic type, and re-serialize
499 parse TYPE as OVSDB base type, and re-serialize
501 parse JSON as OVSDB type, and re-serialize
502 parse-atoms TYPE ATOM...
503 parse JSON ATOMs as atoms of TYPE, and re-serialize
504 parse-atom-strings TYPE ATOM...
505 parse string ATOMs as atoms of given TYPE, and re-serialize
506 sort-atoms TYPE ATOM...
507 print JSON ATOMs in sorted order
508 parse-data TYPE DATUM...
509 parse JSON DATUMs as data of given TYPE, and re-serialize
510 parse-column NAME OBJECT
511 parse column NAME with info OBJECT, and re-serialize
512 parse-table NAME OBJECT [DEFAULT-IS-ROOT]
513 parse table NAME with info OBJECT
515 parse JSON as an OVSDB schema, and re-serialize
516 idl SCHEMA SERVER [?T1:C1,C2...[?T2:C1,C2,...]...] [TRANSACTION...]
517 connect to SERVER (which has the specified SCHEMA) and dump the
518 contents of the database as seen initially by the IDL implementation
519 and after executing each TRANSACTION. (Each TRANSACTION must modify
520 the database or this command will hang.)
521 By default, all columns of all tables are monitored. The "?" option
522 can be used to monitor specific Table:Column(s). The table and their
523 columns are listed as a string of the form starting with "?":
524 ?<table-name>:<column-name>,<column-name>,...
526 ?simple:b - Monitor column "b" in table "simple"
527 Entries for multiple tables are seperated by "?":
528 ?<table-name>:<column-name>,...?<table-name>:<column-name>,...
530 ?simple:b?link1:i,k - Monitor column "b" in table "simple",
531 and column "i", "k" in table "link1"
532 Readonly columns: Suffixing a "!" after a column indicates that the
533 column is to be registered "readonly".
535 ?simple:i,b! - Register interest in column "i" (monitoring) and
536 column "b" (readonly).
539 The following options are also available:
540 -t, --timeout=SECS give up after SECS seconds
541 -h, --help display this help message\
542 """ % {'program_name': ovs
.util
.PROGRAM_NAME
}
548 options
, args
= getopt
.gnu_getopt(argv
[1:], 't:h',
551 except getopt
.GetoptError
, geo
:
552 sys
.stderr
.write("%s: %s\n" % (ovs
.util
.PROGRAM_NAME
, geo
.msg
))
555 for key
, value
in options
:
556 if key
in ['-h', '--help']:
558 elif key
in ['-t', '--timeout']:
564 raise error
.Error("value %s on -t or --timeout is not at "
566 signal
.alarm(timeout
)
571 sys
.stderr
.write("%s: missing command argument "
572 "(use --help for help)\n" % ovs
.util
.PROGRAM_NAME
)
575 commands
= {"default-atoms": (do_default_atoms
, 0),
576 "default-data": (do_default_data
, 0),
577 "parse-atomic-type": (do_parse_atomic_type
, 1),
578 "parse-base-type": (do_parse_base_type
, 1),
579 "parse-type": (do_parse_type
, 1),
580 "parse-atoms": (do_parse_atoms
, (2,)),
581 "parse-data": (do_parse_data
, (2,)),
582 "sort-atoms": (do_sort_atoms
, 2),
583 "parse-column": (do_parse_column
, 2),
584 "parse-table": (do_parse_table
, (2, 3)),
585 "parse-schema": (do_parse_schema
, 1),
586 "idl": (do_idl
, (2,))}
588 command_name
= args
[0]
590 if not command_name
in commands
:
591 sys
.stderr
.write("%s: unknown command \"%s\" "
592 "(use --help for help)\n" % (ovs
.util
.PROGRAM_NAME
,
596 func
, n_args
= commands
[command_name
]
597 if type(n_args
) == tuple:
598 if len(args
) < n_args
[0]:
599 sys
.stderr
.write("%s: \"%s\" requires at least %d arguments but "
601 % (ovs
.util
.PROGRAM_NAME
, command_name
,
604 elif type(n_args
) == int:
605 if len(args
) != n_args
:
606 sys
.stderr
.write("%s: \"%s\" requires %d arguments but %d "
608 % (ovs
.util
.PROGRAM_NAME
, command_name
,
617 if __name__
== '__main__':
620 except error
.Error
, e
:
621 sys
.stderr
.write("%s\n" % e
)