AT_BANNER([OVSDB -- execution])
-m4_define([ORDINAL_SCHEMA],
- [[{"name": "ordinals",
+m4_divert_push([PREPARE_TESTS])
+[
+
+ordinal_schema () {
+ cat <<'EOF'
+ {"name": "ordinals",
"tables": {
"ordinals": {
"columns": {
"number": {"type": "integer"},
- "name": {"type": "string"}}}},
+ "name": {"type": "string"}},
+ "indexes": [["number"]]}},
"version": "5.1.3",
- "cksum": "12345678 9"}]])
+ "cksum": "12345678 9"}
+EOF
+}
-m4_define([CONSTRAINT_SCHEMA],
- [[{"name": "constraints",
+constraint_schema () {
+ cat << 'EOF'
+ {"name": "constraints",
"tables": {
"a": {
"columns": {
"b2a": {"type": {"key": {"type": "uuid", "refTable": "a"},
"min": 0, "max": "unlimited"}},
"b2b": {"type": {"key": {"type": "uuid", "refTable": "b"},
- "min": 0, "max": "unlimited"}}}},
+ "min": 0, "max": "unlimited"}},
+ "x": {"type": {"key": "integer", "min": 1, "max": 2}}}},
"constrained": {
"columns": {
"positive": {"type": {"key": {"type": "integer",
"minInteger": 1}}}},
- "maxRows": 1}}}]])
+ "maxRows": 1}}}
+EOF
+}
-m4_define([WEAK_SCHEMA],
- [[{"name": "weak",
+weak_schema () {
+ cat <<'EOF'
+ {"name": "weak",
"tables": {
"a": {
"columns": {
"b2a": {"type": {"key": {"type": "uuid",
"refTable": "a",
"refType": "weak"},
- "min": 0, "max": "unlimited"}}}}}}]])
+ "min": 0, "max": "unlimited"}}}}}}
+EOF
+}
-m4_define([GC_SCHEMA],
- [[{"name": "gc",
+gc_schema () {
+ cat <<'EOF'
+ {"name": "gc",
"tables": {
"root": {
"columns": {
"refTable": "a",
"refType": "weak"},
"min": 0, "max": "unlimited"}}},
- "isRoot": false}}}]])
+ "isRoot": false}}}
+EOF
+}
+]
+m4_divert_pop([PREPARE_TESTS])
# OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
#
# same marker.
#
# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
-m4_define([OVSDB_CHECK_EXECUTION],
+m4_define([OVSDB_CHECK_EXECUTION],
[AT_SETUP([$1])
AT_KEYWORDS([ovsdb execute execution positive $5])
- AT_CHECK([test-ovsdb execute '$2' m4_foreach([txn], [$3], [ 'txn'])],
+ AT_CHECK([test-ovsdb execute "`$2`" m4_foreach([txn], [$3], [ 'txn'])],
[0], [stdout], [])
AT_CHECK([perl $srcdir/uuidfilt.pl stdout], [0], [$4])
AT_CLEANUP])
OVSDB_CHECK_EXECUTION([uuid-name must be <id>],
- [CONSTRAINT_SCHEMA],
+ [constraint_schema],
[[[["constraints",
{"op": "insert",
"table": "a",
]])
OVSDB_CHECK_EXECUTION([named-uuid must be <id>],
- [CONSTRAINT_SCHEMA],
+ [constraint_schema],
[[[["constraints",
{"op": "insert",
"table": "a",
]])
OVSDB_CHECK_EXECUTION([duplicate uuid-name not allowed],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
dnl At one point the "commit" code ignored new rows with all-default values,
dnl so this checks for that problem.
OVSDB_CHECK_EXECUTION([insert default row, query table],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert row, query table],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, query by value],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, query by named-uuid],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, update rows by value],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, mutate rows],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, delete by named-uuid],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, delete rows by value],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, delete by (non-matching) value],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert rows, delete all],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert row, query table, commit],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert row, query table, commit durably],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([equality wait with correct rows],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([equality wait with extra row],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([equality wait with missing row],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([inequality wait with correct rows],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([inequality wait with extra row],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([inequality wait with missing row],
- [ORDINAL_SCHEMA],
+ [ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
]])
OVSDB_CHECK_EXECUTION([insert and update constraints],
- [CONSTRAINT_SCHEMA],
+ [constraint_schema],
[[[["constraints",
{"op": "insert",
"table": "constrained",
[{"uuid":["uuid","<1>"]},{"details":"transaction causes \"constrained\" table to contain 2 rows, greater than the schema-defined limit of 1 row(s)","error":"constraint violation"}]
]])
+OVSDB_CHECK_EXECUTION([index uniqueness checking],
+ [ordinal_schema],
+dnl Insert initial row.
+ [[[["ordinals",
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 1, "name": "one"}}]]],
+dnl Try to insert row with identical value (fails).
+ [[["ordinals",
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 1, "name": "another one"}}]]],
+dnl Remove initial row and insert new row with identical value in a single
+dnl transaction (succeeds).
+ [[["ordinals",
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 1, "name": "another one"}},
+ {"op": "delete",
+ "table": "ordinals",
+ "where": [["name", "==", "one"]]}]]],
+dnl Remove row and insert two new rows with identical value in a single
+dnl transaction (fails).
+ [[["ordinals",
+ {"op": "delete",
+ "table": "ordinals",
+ "where": []},
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 1, "name": "one"}},
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 1, "name": "still another one"}}]]],
+dnl Add new row with different value (succeeds).
+ [[["ordinals",
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 2, "name": "two"}}]]],
+dnl Change rows so values collide (fails).
+ [[["ordinals",
+ {"op": "update",
+ "table": "ordinals",
+ "where": [],
+ "row": {"number": 3}}]]],
+dnl Swap rows' values (succeeds).
+ [[["ordinals",
+ {"op": "update",
+ "table": "ordinals",
+ "where": [["number", "==", 1]],
+ "row": {"number": 2, "name": "old two"}},
+ {"op": "update",
+ "table": "ordinals",
+ "where": [["name", "==", "two"]],
+ "row": {"number": 1, "name": "old one"}}]]],
+dnl Change all rows' values to values not used before and insert values that
+dnl collide (only) with their previous values (succeeds).
+ [[["ordinals",
+ {"op": "mutate",
+ "table": "ordinals",
+ "where": [],
+ "mutations": [["number", "*=", 10]]},
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 1, "name": "new one"}},
+ {"op": "insert",
+ "table": "ordinals",
+ "row": {"number": 2, "name": "new two"}},
+ {"op": "select",
+ "table": "ordinals",
+ "where": [],
+ "columns": ["number", "name"],
+ "sort": ["number"]}]]]],
+ [[[{"uuid":["uuid","<0>"]}]
+[{"uuid":["uuid","<1>"]},{"details":"Transaction causes multiple rows in \"ordinals\" table to have identical values (1) for index on column \"number\". First row, with UUID <0>, existed in the database before this transaction and was not modified by the transaction. Second row, with UUID <1>, was inserted by this transaction.","error":"constraint violation"}]
+[{"uuid":["uuid","<2>"]},{"count":1}]
+[{"count":1},{"uuid":["uuid","<3>"]},{"uuid":["uuid","<4>"]},{"details":"Transaction causes multiple rows in \"ordinals\" table to have identical values (1) for index on column \"number\". First row, with UUID <4>, was inserted by this transaction. Second row, with UUID <3>, was inserted by this transaction.","error":"constraint violation"}]
+[{"uuid":["uuid","<5>"]}]
+[{"count":2},{"details":"Transaction causes multiple rows in \"ordinals\" table to have identical values (3) for index on column \"number\". First row, with UUID <5>, had the following index values before the transaction: 2. Second row, with UUID <2>, had the following index values before the transaction: 1.","error":"constraint violation"}]
+[{"count":1},{"count":1}]
+[{"count":2},{"uuid":["uuid","<6>"]},{"uuid":["uuid","<7>"]},{"rows":[{"name":"new one","number":1},{"name":"new two","number":2},{"name":"old one","number":10},{"name":"old two","number":20}]}]
+]])
+
OVSDB_CHECK_EXECUTION([referential integrity -- simple],
- [CONSTRAINT_SCHEMA],
+ [constraint_schema],
[[[["constraints",
{"op": "insert",
"table": "b",
{"op": "delete",
"table": "b",
"where": []}]]],
+dnl Check that "mutate" honors number-of-elements constraints on sets and maps.
+ [[["constraints",
+ {"op": "mutate",
+ "table": "b",
+ "where": [],
+ "mutations": [["x", "delete", 0]]}]]],
[[["constraints",
{"op": "delete",
"table": "a",
"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"}]
+[{"details":"Attempted to store 0 elements in set of 1 to 2 integers.","error":"constraint violation"}]
[{"count":1}]
[{"count":1},{"details":"cannot delete b row <0> because of 2 remaining reference(s)","error":"referential integrity violation"}]
[{"count":1}]
]])
OVSDB_CHECK_EXECUTION([referential integrity -- mutual references],
- [CONSTRAINT_SCHEMA],
+ [constraint_schema],
[[[["constraints",
{"op": "insert",
"table": "a",
]])
OVSDB_CHECK_EXECUTION([weak references],
- [WEAK_SCHEMA],
+ [weak_schema],
[[[["weak",
{"op": "insert",
"table": "a",
]])
OVSDB_CHECK_EXECUTION([garbage collection],
- [GC_SCHEMA],
+ [gc_schema],
[dnl Check that inserting a row without any references is a no-op.
[[["gc",
{"op": "insert",