tests: Add support for automatically running Ryu tests against OVS.
[sliver-openvswitch.git] / ovsdb / ovsdb-dot.in
1 #! @PYTHON@
2
3 from datetime import date
4 import ovs.db.error
5 import ovs.db.schema
6 import getopt
7 import os
8 import re
9 import sys
10
11 argv0 = sys.argv[0]
12
13 def printEdge(tableName, type, baseType, label):
14     if baseType.ref_table_name:
15         if type.n_min == 0:
16             if type.n_max == 1:
17                 arity = "?"
18             elif type.n_max == sys.maxint:
19                 arity = "*"
20             else:
21                 arity = "{,%d}" % type.n_max
22         elif type.n_min == 1:
23             if type.n_max == 1:
24                 arity = ""
25             elif type.n_max == sys.maxint:
26                 arity = "+"
27             else:
28                 arity = "{1,%d}" % type.n_max
29
30         options = {}
31         options['label'] = '"%s%s"' % (label, arity)
32         if baseType.ref_type == 'weak':
33             options['constraint'] = 'false'
34             options['style'] = 'dotted'
35         print "\t%s -> %s [%s];" % (
36             tableName,
37             baseType.ref_table_name,
38             ', '.join(['%s=%s' % (k,v) for k,v in options.items()]))
39
40 def schemaToDot(schemaFile, arrows):
41     schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schemaFile))
42
43     print "digraph %s {" % schema.name
44     print '\trankdir=LR;'
45     print '\tsize="6.5,4";'
46     print '\tmargin="0";'
47     print "\tnode [shape=box];"
48     if not arrows:
49         print "\tedge [dir=none, arrowhead=none, arrowtail=none];"
50     for tableName, table in schema.tables.iteritems():
51         options = {}
52         if table.is_root:
53             options['style'] = 'bold'
54         print "\t%s [%s];" % (
55             tableName,
56             ', '.join(['%s=%s' % (k,v) for k,v in options.items()]))
57         for columnName, column in table.columns.iteritems():
58             if column.type.value:
59                 printEdge(tableName, column.type, column.type.key, "%s key" % columnName)
60                 printEdge(tableName, column.type, column.type.value, "%s value" % columnName)
61             else:
62                 printEdge(tableName, column.type, column.type.key, columnName)
63     print "}";
64
65 def usage():
66     print """\
67 %(argv0)s: compiles ovsdb schemas to graphviz format
68 Prints a .dot file that "dot" can render to an entity-relationship diagram
69 usage: %(argv0)s [OPTIONS] SCHEMA
70 where SCHEMA is an OVSDB schema in JSON format
71
72 The following options are also available:
73   --no-arrows                 omit arrows from diagram
74   -h, --help                  display this help message
75   -V, --version               display version information\
76 """ % {'argv0': argv0}
77     sys.exit(0)
78
79 if __name__ == "__main__":
80     try:
81         try:
82             options, args = getopt.gnu_getopt(sys.argv[1:], 'hV',
83                                               ['no-arrows',
84                                                'help', 'version',])
85         except getopt.GetoptError, geo:
86             sys.stderr.write("%s: %s\n" % (argv0, geo.msg))
87             sys.exit(1)
88
89         arrows = True
90         for key, value in options:
91             if key == '--no-arrows':
92                 arrows = False
93             elif key in ['-h', '--help']:
94                 usage()
95             elif key in ['-V', '--version']:
96                 print "ovsdb-dot (Open vSwitch) @VERSION@"
97             else:
98                 sys.exit(0)
99
100         if len(args) != 1:
101             sys.stderr.write("%s: exactly 1 non-option argument required "
102                              "(use --help for help)\n" % argv0)
103             sys.exit(1)
104
105         schemaToDot(args[0], arrows)
106
107     except ovs.db.error.Error, e:
108         sys.stderr.write("%s: %s\n" % (argv0, e.msg))
109         sys.exit(1)
110
111 # Local variables:
112 # mode: python
113 # End: