summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-02-08 14:09:41 -0800
committerBen Pfaff <blp@nicira.com>2010-02-08 14:16:19 -0800
commit0d0f05b909b6428d44eb147bd4edd73782d2a137 (patch)
treec64d595c7df2281b6a69d00dc2a4f73d37986a40 /tests
parentbd76d25d8b3b7d11c5a326e91d784ad2cdeecd45 (diff)
downloadopenvswitch-0d0f05b909b6428d44eb147bd4edd73782d2a137.tar.gz
ovsdb: Add support for referential integrity in the database itself.
Diffstat (limited to 'tests')
-rw-r--r--tests/automake.mk1
-rw-r--r--tests/idltest.ann4
-rw-r--r--tests/idltest.ovsschema134
-rw-r--r--tests/ovs-vsctl.at18
-rw-r--r--tests/ovsdb-execution.at112
-rw-r--r--tests/ovsdb-idl.at88
-rw-r--r--tests/ovsdb-schema.at47
-rw-r--r--tests/ovsdb-types.at7
-rw-r--r--tests/ovsdb.at1
-rw-r--r--tests/test-ovsdb.c34
10 files changed, 358 insertions, 88 deletions
diff --git a/tests/automake.mk b/tests/automake.mk
index 8fa6c1580..fe493fd36 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -26,6 +26,7 @@ TESTSUITE_AT = \
tests/ovsdb-column.at \
tests/ovsdb-table.at \
tests/ovsdb-row.at \
+ tests/ovsdb-schema.at \
tests/ovsdb-condition.at \
tests/ovsdb-mutation.at \
tests/ovsdb-query.at \
diff --git a/tests/idltest.ann b/tests/idltest.ann
index 2ffd1af68..66e863737 100644
--- a/tests/idltest.ann
+++ b/tests/idltest.ann
@@ -7,7 +7,3 @@
s["idlPrefix"] = "idltest_"
s["idlHeader"] = "\"tests/idltest.h\""
-s["tables"]["link1"]["columns"]["k"]["type"]["keyRefTable"] = "link1"
-s["tables"]["link1"]["columns"]["ka"]["type"]["keyRefTable"] = "link1"
-s["tables"]["link1"]["columns"]["l2"]["type"]["keyRefTable"] = "link2"
-s["tables"]["link2"]["columns"]["l1"]["type"]["keyRefTable"] = "link1"
diff --git a/tests/idltest.ovsschema b/tests/idltest.ovsschema
index 239a34335..545242bea 100644
--- a/tests/idltest.ovsschema
+++ b/tests/idltest.ovsschema
@@ -1,25 +1,109 @@
-{"name": "idltest",
- "tables": {
- "simple": {
- "columns": {
- "i": {"type": "integer"},
- "r": {"type": "real"},
- "b": {"type": "boolean"},
- "s": {"type": "string"},
- "u": {"type": "uuid"},
- "ia": {"type": {"key": "integer", "min": 0, "max": "unlimited"}},
- "ra": {"type": {"key": "real", "min": 0, "max": "unlimited"}},
- "ba": {"type": {"key": "boolean", "min": 0, "max": "unlimited"}},
- "sa": {"type": {"key": "string", "min": 0, "max": "unlimited"}},
- "ua": {"type": {"key": "uuid", "min": 0, "max": "unlimited"}}}},
- "link1": {
- "columns": {
- "i": {"type": "integer"},
- "k": {"type": {"key": "uuid"}},
- "ka": {"type": {"key": "uuid",
- "min": 0, "max": "unlimited"}},
- "l2": {"type": {"key": "uuid", "min": 0, "max": 1}}}},
- "link2": {
- "columns": {
- "i": {"type": "integer"},
- "l1": {"type": {"key": "uuid", "min": 0, "max": 1}}}}}}
+{
+ "name": "idltest",
+ "tables": {
+ "link1": {
+ "columns": {
+ "i": {
+ "type": "integer"
+ },
+ "k": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "link1"
+ }
+ }
+ },
+ "ka": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "link1"
+ },
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "l2": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "link2"
+ },
+ "min": 0
+ }
+ }
+ }
+ },
+ "link2": {
+ "columns": {
+ "i": {
+ "type": "integer"
+ },
+ "l1": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "link1"
+ },
+ "min": 0
+ }
+ }
+ }
+ },
+ "simple": {
+ "columns": {
+ "b": {
+ "type": "boolean"
+ },
+ "ba": {
+ "type": {
+ "key": "boolean",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "i": {
+ "type": "integer"
+ },
+ "ia": {
+ "type": {
+ "key": "integer",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "r": {
+ "type": "real"
+ },
+ "ra": {
+ "type": {
+ "key": "real",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "s": {
+ "type": "string"
+ },
+ "sa": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "u": {
+ "type": "uuid"
+ },
+ "ua": {
+ "type": {
+ "key": "uuid",
+ "max": "unlimited",
+ "min": 0
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at
index 06bff53b5..103b17ae0 100644
--- a/tests/ovs-vsctl.at
+++ b/tests/ovs-vsctl.at
@@ -451,7 +451,7 @@ AT_BANNER([ovs-vsctl unit tests -- database commands])
AT_SETUP([database commands -- positive checks])
AT_KEYWORDS([ovs-vsctl])
OVS_VSCTL_SETUP
-AT_CHECK([RUN_OVS_VSCTL([--force create b name=br0])],
+AT_CHECK([RUN_OVS_VSCTL([create b name=br0])],
[0], [stdout], [], [OVS_VSCTL_CLEANUP])
cp stdout out1
AT_CHECK([RUN_OVS_VSCTL([list b])],
@@ -496,7 +496,7 @@ AT_CHECK([RUN_OVS_VSCTL([remove br br0 other_config 'datapath_id="0123456789ab"'
AT_CHECK([RUN_OVS_VSCTL([clear br br0 external-ids -- get br br0 external_ids])],
[0], [{}
], [], [OVS_VSCTL_CLEANUP])
-AT_CHECK([RUN_OVS_VSCTL([--force destroy b br0])],
+AT_CHECK([RUN_OVS_VSCTL([destroy b br0])],
[0], [stdout], [], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([list b])],
[0], [], [], [OVS_VSCTL_CLEANUP])
@@ -506,13 +506,13 @@ AT_CLEANUP
AT_SETUP([database commands -- negative checks])
AT_KEYWORDS([ovs-vsctl])
OVS_VSCTL_SETUP
-AT_CHECK([RUN_OVS_VSCTL([--force create b name=br0])],
+AT_CHECK([RUN_OVS_VSCTL([create b name=br0])],
[0], [ignore], [], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([add-br br1])],
[0], [ignore], [], [OVS_VSCTL_CLEANUP])
AT_CHECK([RUN_OVS_VSCTL([set-controller br1 tcp:127.0.0.1])],
[0], [ignore], [], [OVS_VSCTL_CLEANUP])
-AT_CHECK([RUN_OVS_VSCTL([--force create n targets='"1.2.3.4:567"'])],
+AT_CHECK([RUN_OVS_VSCTL([create n targets='"1.2.3.4:567"'])],
[0], [stdout], [], [OVS_VSCTL_CLEANUP])
cp stdout netflow-uuid
AT_CHECK([RUN_OVS_VSCTL([list n `cat netflow-uuid`])],
@@ -577,13 +577,7 @@ AT_CHECK([RUN_OVS_VSCTL([remove n `cat netflow-uuid` targets '"1.2.3.4:567"'])],
AT_CHECK([RUN_OVS_VSCTL([clear n `cat netflow-uuid` targets])],
[1], [], [ovs-vsctl: "clear" operation cannot be applied to column targets of table NetFlow, which is not allowed to be empty
], [OVS_VSCTL_CLEANUP])
-AT_CHECK([RUN_OVS_VSCTL([create b name=br2])],
- [1], [], [ovs-vsctl: "create" requires --force
-], [OVS_VSCTL_CLEANUP])
-AT_CHECK([RUN_OVS_VSCTL([destroy b br0])],
- [1], [], [ovs-vsctl: "destroy" requires --force
-], [OVS_VSCTL_CLEANUP])
-AT_CHECK([RUN_OVS_VSCTL([--force destroy b br2])],
+AT_CHECK([RUN_OVS_VSCTL([destroy b br2])],
[1], [], [ovs-vsctl: no row "br2" in table Bridge
], [OVS_VSCTL_CLEANUP])
OVS_VSCTL_CLEANUP
@@ -595,7 +589,7 @@ dnl The bug is documented in ovs-vsctl.8.
AT_SETUP([created row UUID is wrong in same execution])
AT_KEYWORDS([ovs-vsctl])
OVS_VSCTL_SETUP
-AT_CHECK([RUN_OVS_VSCTL([--force create Bridge name=br0 -- list b])],
+AT_CHECK([RUN_OVS_VSCTL([create Bridge name=br0 -- list b])],
[0], [stdout], [], [OVS_VSCTL_CLEANUP])
AT_CHECK([perl $srcdir/uuidfilt.pl stdout], [0],
[[<0>
diff --git a/tests/ovsdb-execution.at b/tests/ovsdb-execution.at
index bb9d6cf43..334e20848 100644
--- a/tests/ovsdb-execution.at
+++ b/tests/ovsdb-execution.at
@@ -11,6 +11,20 @@ m4_define([ORDINAL_SCHEMA],
m4_define([CONSTRAINT_SCHEMA],
[[{"name": "constraints",
"tables": {
+ "a": {
+ "columns": {
+ "a": {"type": "integer"},
+ "a2a": {"type": {"key": {"type": "uuid", "refTable": "a"},
+ "min": 0, "max": "unlimited"}},
+ "a2b": {"type": {"key": {"type": "uuid", "refTable": "b"},
+ "min": 0, "max": "unlimited"}}}},
+ "b": {
+ "columns": {
+ "b": {"type": "integer"},
+ "b2a": {"type": {"key": {"type": "uuid", "refTable": "a"},
+ "min": 0, "max": "unlimited"}},
+ "b2b": {"type": {"key": {"type": "uuid", "refTable": "b"},
+ "min": 0, "max": "unlimited"}}}},
"constrained": {
"columns": {
"positive": {"type": {"key": {"type": "integer",
@@ -376,6 +390,104 @@ OVSDB_CHECK_EXECUTION([insert and update constraints],
[[[{"details":"0 is less than minimum allowed value 1","error":"constraint violation"}]
[{"details":"-1 is less than minimum allowed value 1","error":"constraint violation"}]
[{"details":"-2 is less than minimum allowed value 1","error":"constraint violation"}]
+]])
+
+OVSDB_CHECK_EXECUTION([referential integrity -- simple],
+ [CONSTRAINT_SCHEMA],
+ [[[[{"op": "insert",
+ "table": "b",
+ "row": {"b": 1},
+ "uuid-name": "brow"},
+ {"op": "insert",
+ "table": "a",
+ "row": {"a": 0,
+ "a2b": ["set", [["named-uuid", "brow"]]]}},
+ {"op": "insert",
+ "table": "a",
+ "row": {"a": 1,
+ "a2b": ["set", [["named-uuid", "brow"]]]}},
+ {"op": "insert",
+ "table": "a",
+ "row": {"a": 2,
+ "a2b": ["set", [["named-uuid", "brow"]]]}}]]],
+ [[[{"op": "delete",
+ "table": "b",
+ "where": []}]]],
+ [[[{"op": "delete",
+ "table": "a",
+ "where": [["a", "==", 0]]}]]],
+ [[[{"op": "delete",
+ "table": "b",
+ "where": []}]]],
+ [[[{"op": "delete",
+ "table": "a",
+ "where": [["a", "==", 1]]}]]],
+ [[[{"op": "delete",
+ "table": "b",
+ "where": []}]]],
+ [[[{"op": "delete",
+ "table": "a",
+ "where": [["a", "==", 2]]}]]],
+ [[[{"op": "delete",
+ "table": "b",
+ "where": []}]]]],
+ [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]
+[{"count":1},{"details":"cannot delete b row <0> because of 3 remaining reference(s)","error":"referential integrity violation"}]
+[{"count":1}]
+[{"count":1},{"details":"cannot delete b row <0> because of 2 remaining reference(s)","error":"referential integrity violation"}]
+[{"count":1}]
+[{"count":1},{"details":"cannot delete b row <0> because of 1 remaining reference(s)","error":"referential integrity violation"}]
+[{"count":1}]
+[{"count":1}]
+]])
+
+OVSDB_CHECK_EXECUTION([referential integrity -- mutual references],
+ [CONSTRAINT_SCHEMA],
+ [[[[{"op": "declare",
+ "uuid-name": "row1"},
+ {"op": "declare",
+ "uuid-name": "row2"},
+ {"op": "insert",
+ "table": "a",
+ "row": {"a": 0,
+ "a2b": ["set", [["named-uuid", "row2"]]],
+ "a2a": ["set", [["named-uuid", "row1"]]]},
+ "uuid-name": "row1"},
+ {"op": "insert",
+ "table": "b",
+ "row": {"b": 1,
+ "b2b": ["set", [["named-uuid", "row2"]]],
+ "b2a": ["set", [["named-uuid", "row1"]]]},
+ "uuid-name": "row2"}]]],
+ [[[{"op": "insert",
+ "table": "a",
+ "row": {"a2b": ["set", [["uuid", "b516b960-5b19-4fc2-bb82-fe1cbd6d0241"]]]}}]]],
+ [[[{"op": "delete",
+ "table": "a",
+ "where": [["a", "==", 0]]}]]],
+ [[[{"op": "delete",
+ "table": "b",
+ "where": [["b", "==", 1]]}]]],
+ dnl Try the deletions again to make sure that the refcounts got rolled back.
+ [[[{"op": "delete",
+ "table": "a",
+ "where": [["a", "==", 0]]}]]],
+ [[[{"op": "delete",
+ "table": "b",
+ "where": [["b", "==", 1]]}]]],
+ [[[{"op": "delete",
+ "table": "a",
+ "where": [["a", "==", 0]]},
+ {"op": "delete",
+ "table": "b",
+ "where": [["b", "==", 1]]}]]]],
+ [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]
+[{"uuid":["uuid","<2>"]},{"details":"reference to nonexistent row <3>","error":"referential integrity violation"}]
+[{"count":1},{"details":"cannot delete a row <0> because of 1 remaining reference(s)","error":"referential integrity violation"}]
+[{"count":1},{"details":"cannot delete b row <1> because of 1 remaining reference(s)","error":"referential integrity violation"}]
+[{"count":1},{"details":"cannot delete a row <0> because of 1 remaining reference(s)","error":"referential integrity violation"}]
+[{"count":1},{"details":"cannot delete b row <1> because of 1 remaining reference(s)","error":"referential integrity violation"}]
+[{"count":1},{"count":1}]
]])])
EXECUTION_EXAMPLES
diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at
index 0be2a11e1..552f627f8 100644
--- a/tests/ovsdb-idl.at
+++ b/tests/ovsdb-idl.at
@@ -227,55 +227,58 @@ OVSDB_CHECK_IDL([self-linking idl, inconsistent ops],
[['[{"op": "insert",
"table": "link1",
"row": {"i": 0, "k": ["uuid", "cf197cc5-c8c9-42f5-82d5-c71a9f2cb96b"]}}]' \
- '[{"op": "update",
+ '+[{"op": "insert",
"table": "link1",
- "where": [],
- "row": {"k": ["uuid", "#0#"]}}]' \
+ "uuid-name": "one",
+ "row": {"i": 1, "k": ["named-uuid", "one"]}},
+ {"op": "insert",
+ "table": "link1",
+ "row": {"i": 2, "k": ["named-uuid", "one"]}}]' \
'[{"op": "update",
"table": "link1",
"where": [],
"row": {"k": ["uuid", "c2fca39a-e69a-42a4-9c56-5eca85839ce9"]}}]' \
- '[{"op": "insert",
+ '+[{"op": "delete",
"table": "link1",
- "row": {"i": 1, "k": ["uuid", "52d752a3-b062-4668-9446-d2e0d4a14703"]}}]' \
- '[{"op": "update",
+ "where": [["_uuid", "==", ["uuid", "#1#"]]]}]' \
+ '+[{"op": "delete",
"table": "link1",
- "where": [],
- "row": {"k": ["uuid", "#1#"]}}]' \
+ "where": [["_uuid", "==", ["uuid", "#2#"]]]}]' \
+ '[{"op": "delete",
+ "table": "link1",
+ "where": []}]' \
]],
[[000: empty
-001: {"error":null,"result":[{"uuid":["uuid","<0>"]}]}
-002: i=0 k= ka=[] l2= uuid=<0>
-003: {"error":null,"result":[{"count":1}]}
-004: i=0 k=0 ka=[] l2= uuid=<0>
-005: {"error":null,"result":[{"count":1}]}
-006: i=0 k= ka=[] l2= uuid=<0>
-007: {"error":null,"result":[{"uuid":["uuid","<1>"]}]}
-008: i=0 k= ka=[] l2= uuid=<0>
-008: i=1 k= ka=[] l2= uuid=<1>
-009: {"error":null,"result":[{"count":2}]}
-010: i=0 k=1 ka=[] l2= uuid=<0>
-010: i=1 k=1 ka=[] l2= uuid=<1>
-011: done
+001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"details":"reference to nonexistent row <1>","error":"referential integrity violation"}]}
+002: {"error":null,"result":[{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]}
+003: i=1 k=1 ka=[] l2= uuid=<2>
+003: i=2 k=1 ka=[] l2= uuid=<3>
+004: {"error":null,"result":[{"count":2},{"details":"reference to nonexistent row <4>","error":"referential integrity violation"}]}
+005: {"error":null,"result":[{"count":1},{"details":"cannot delete link1 row <2> because of 1 remaining reference(s)","error":"referential integrity violation"}]}
+006: {"error":null,"result":[{"count":1}]}
+007: i=1 k=1 ka=[] l2= uuid=<2>
+008: {"error":null,"result":[{"count":1}]}
+009: empty
+010: done
]])
OVSDB_CHECK_IDL([self-linking idl, sets],
[],
[['[{"op": "insert",
"table": "link1",
- "row": {"i": 0, "ka": ["set", [["named-uuid", "i0"]]]},
+ "row": {"i": 0, "k": ["named-uuid", "i0"], "ka": ["set", [["named-uuid", "i0"]]]},
"uuid-name": "i0"},
{"op": "insert",
"table": "link1",
- "row": {"i": 1, "ka": ["set", [["named-uuid", "i1"]]]},
+ "row": {"i": 1, "k": ["named-uuid", "i0"], "ka": ["set", [["named-uuid", "i1"]]]},
"uuid-name": "i1"},
{"op": "insert",
"table": "link1",
- "row": {"i": 2, "ka": ["set", [["named-uuid", "i2"]]]},
+ "row": {"i": 2, "k": ["named-uuid", "i0"], "ka": ["set", [["named-uuid", "i2"]]]},
"uuid-name": "i2"},
{"op": "insert",
"table": "link1",
- "row": {"i": 3, "ka": ["set", [["named-uuid", "i3"]]]},
+ "row": {"i": 3, "k": ["named-uuid", "i0"], "ka": ["set", [["named-uuid", "i3"]]]},
"uuid-name": "i3"}]' \
'[{"op": "update",
"table": "link1",
@@ -284,24 +287,25 @@ OVSDB_CHECK_IDL([self-linking idl, sets],
'[{"op": "update",
"table": "link1",
"where": [],
- "row": {"ka": ["set", [["uuid", "#0#"], ["uuid", "88702e78-845b-4a6e-ad08-cf68922ae84a"], ["uuid", "#2#"], ["uuid", "1ac2b12e-b767-4805-a55d-43976e40c465"]]]}}]']],
+ "row": {"ka": ["set", [["uuid", "#0#"], ["uuid", "88702e78-845b-4a6e-ad08-cf68922ae84a"], ["uuid", "#2#"], ["uuid", "1ac2b12e-b767-4805-a55d-43976e40c465"]]]}}]' \
+ '+[{"op": "delete",
+ "table": "link1",
+ "where": []}]']],
[[000: empty
001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]}
-002: i=0 k= ka=[0] l2= uuid=<0>
-002: i=1 k= ka=[1] l2= uuid=<1>
-002: i=2 k= ka=[2] l2= uuid=<2>
-002: i=3 k= ka=[3] l2= uuid=<3>
+002: i=0 k=0 ka=[0] l2= uuid=<0>
+002: i=1 k=0 ka=[1] l2= uuid=<1>
+002: i=2 k=0 ka=[2] l2= uuid=<2>
+002: i=3 k=0 ka=[3] l2= uuid=<3>
003: {"error":null,"result":[{"count":4}]}
-004: i=0 k= ka=[0 1 2 3] l2= uuid=<0>
-004: i=1 k= ka=[0 1 2 3] l2= uuid=<1>
-004: i=2 k= ka=[0 1 2 3] l2= uuid=<2>
-004: i=3 k= ka=[0 1 2 3] l2= uuid=<3>
-005: {"error":null,"result":[{"count":4}]}
-006: i=0 k= ka=[0 2] l2= uuid=<0>
-006: i=1 k= ka=[0 2] l2= uuid=<1>
-006: i=2 k= ka=[0 2] l2= uuid=<2>
-006: i=3 k= ka=[0 2] l2= uuid=<3>
-007: done
+004: i=0 k=0 ka=[0 1 2 3] l2= uuid=<0>
+004: i=1 k=0 ka=[0 1 2 3] l2= uuid=<1>
+004: i=2 k=0 ka=[0 1 2 3] l2= uuid=<2>
+004: i=3 k=0 ka=[0 1 2 3] l2= uuid=<3>
+005: {"error":null,"result":[{"count":4},{"details":"reference to nonexistent row <4>","error":"referential integrity violation"}]}
+006: {"error":null,"result":[{"count":4}]}
+007: empty
+008: done
]])
OVSDB_CHECK_IDL([external-linking idl, consistent ops],
@@ -312,11 +316,11 @@ OVSDB_CHECK_IDL([external-linking idl, consistent ops],
"uuid-name": "row0"},
{"op": "insert",
"table": "link1",
- "row": {"i": 1, "l2": ["set", [["named-uuid", "row0"]]]},
+ "row": {"i": 1, "k": ["named-uuid", "row1"], "l2": ["set", [["named-uuid", "row0"]]]},
"uuid-name": "row1"}]']],
[[000: empty
001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]}
002: i=0 l1= uuid=<0>
-002: i=1 k= ka=[] l2=0 uuid=<1>
+002: i=1 k=1 ka=[] l2=0 uuid=<1>
003: done
]])
diff --git a/tests/ovsdb-schema.at b/tests/ovsdb-schema.at
new file mode 100644
index 000000000..6cd2fa20f
--- /dev/null
+++ b/tests/ovsdb-schema.at
@@ -0,0 +1,47 @@
+AT_BANNER([OVSDB -- schemas])
+
+OVSDB_CHECK_POSITIVE([schema with valid refTables],
+ [[parse-schema \
+ '{"name": "mydb",
+ "tables": {
+ "a": {
+ "columns": {
+ "map": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "b"},
+ "value": {
+ "type": "uuid",
+ "refTable": "a"}}}}},
+ "b": {
+ "columns": {
+ "aRef": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "a"}}}}}}}']],
+ [[{"name":"mydb","tables":{"a":{"columns":{"map":{"type":{"key":{"refTable":"b","type":"uuid"},"value":{"refTable":"a","type":"uuid"}}}}},"b":{"columns":{"aRef":{"type":{"key":{"refTable":"a","type":"uuid"}}}}}}}]])
+
+OVSDB_CHECK_NEGATIVE([schema with invalid refTables],
+ [[parse-schema \
+ '{"name": "mydb",
+ "tables": {
+ "a": {
+ "columns": {
+ "map": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "c"},
+ "value": {
+ "type": "uuid",
+ "refTable": "a"}}}}},
+ "b": {
+ "columns": {
+ "aRef": {
+ "type": {
+ "key": {
+ "type": "uuid",
+ "refTable": "a"}}}}}}}']],
+ [[test-ovsdb: syntax error: column map key refers to undefined table c]])
diff --git a/tests/ovsdb-types.at b/tests/ovsdb-types.at
index b7fddc7e2..4647e69de 100644
--- a/tests/ovsdb-types.at
+++ b/tests/ovsdb-types.at
@@ -70,6 +70,13 @@ OVSDB_CHECK_NEGATIVE([maxLength must not be negative],
[[parse-base-type '{"type": "string", "maxLength": -1}']],
[maxLength out of valid range 0 to 4294967295])
+OVSDB_CHECK_POSITIVE([uuid refTable],
+ [[parse-base-type '{"type": "uuid", "refTable": "myTable"}' ]],
+ [{"refTable":"myTable","type":"uuid"}])
+OVSDB_CHECK_NEGATIVE([uuid refTable must be valid id],
+ [[parse-base-type '{"type": "uuid", "refTable": "a-b-c"}' ]],
+ [Type mismatch for member 'refTable'])
+
OVSDB_CHECK_NEGATIVE([void is not a valid base-type],
[[parse-base-type '["void"]' ]], ["void" is not an atomic-type])
OVSDB_CHECK_NEGATIVE(["type" member must be present],
diff --git a/tests/ovsdb.at b/tests/ovsdb.at
index d10bedd3d..275c90d6d 100644
--- a/tests/ovsdb.at
+++ b/tests/ovsdb.at
@@ -41,6 +41,7 @@ m4_include([tests/ovsdb-data.at])
m4_include([tests/ovsdb-column.at])
m4_include([tests/ovsdb-table.at])
m4_include([tests/ovsdb-row.at])
+m4_include([tests/ovsdb-schema.at])
m4_include([tests/ovsdb-condition.at])
m4_include([tests/ovsdb-mutation.at])
m4_include([tests/ovsdb-query.at])
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
index 4b38ecb5a..3025ce390 100644
--- a/tests/test-ovsdb.c
+++ b/tests/test-ovsdb.c
@@ -159,6 +159,8 @@ usage(void)
" query-distinct TABLE [ROW,...] [CONDITION,...] COLUMNS\n"
" add each ROW to TABLE, then query and print the rows that\n"
" satisfy each CONDITION and have distinct COLUMNS.\n"
+ " parse-schema JSON\n"
+ " parse JSON as an OVSDB schema, and re-serialize\n"
" transact COMMAND\n"
" execute each specified transactional COMMAND:\n"
" commit\n"
@@ -1139,6 +1141,19 @@ do_query_distinct(int argc UNUSED, char *argv[])
}
static void
+do_parse_schema(int argc UNUSED, char *argv[])
+{
+ struct ovsdb_schema *schema;
+ struct json *json;
+
+ json = parse_json(argv[1]);
+ check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
+ json_destroy(json);
+ print_and_free_json(ovsdb_schema_to_json(schema));
+ ovsdb_schema_destroy(schema);
+}
+
+static void
do_execute(int argc UNUSED, char *argv[])
{
struct ovsdb_schema *schema;
@@ -1773,20 +1788,28 @@ do_idl(int argc, char *argv[])
rpc = NULL;
}
+ setvbuf(stdout, NULL, _IOLBF, 0);
+
symtab = ovsdb_symbol_table_create();
for (i = 2; i < argc; i++) {
+ char *arg = argv[i];
struct jsonrpc_msg *request, *reply;
int error;
- seqno = print_updated_idl(idl, rpc, step++, seqno);
+ if (*arg == '+') {
+ /* The previous transaction didn't change anything. */
+ arg++;
+ } else {
+ seqno = print_updated_idl(idl, rpc, step++, seqno);
+ }
- if (!strcmp(argv[i], "reconnect")) {
+ if (!strcmp(arg, "reconnect")) {
printf("%03d: reconnect\n", step++);
ovsdb_idl_force_reconnect(idl);
- } else if (argv[i][0] != '[') {
- idl_set(idl, argv[i], step++);
+ } else if (arg[0] != '[') {
+ idl_set(idl, arg, step++);
} else {
- struct json *json = parse_json(argv[i]);
+ struct json *json = parse_json(arg);
substitute_uuids(json, symtab);
request = jsonrpc_create_request("transact", json, NULL);
error = jsonrpc_transact_block(rpc, request, &reply);
@@ -1833,6 +1856,7 @@ static struct command all_commands[] = {
{ "query", 3, 3, do_query },
{ "query-distinct", 4, 4, do_query_distinct },
{ "transact", 1, INT_MAX, do_transact },
+ { "parse-schema", 1, 1, do_parse_schema },
{ "execute", 2, INT_MAX, do_execute },
{ "trigger", 2, INT_MAX, do_trigger },
{ "idl", 1, INT_MAX, do_idl },