d014804a60efe6c84ec91de49a441391fdcec6e0
[sliver-openvswitch.git] / tests / ovsdb-execution.at
1 AT_BANNER([OVSDB -- execution])
2
3 m4_divert_push([PREPARE_TESTS])
4 [
5
6 ordinal_schema () {
7     cat <<'EOF'
8     {"name": "ordinals",
9      "tables": {
10        "ordinals": {
11          "columns": {
12            "number": {"type": "integer"},
13            "name": {"type": "string"}},
14          "indexes": [["number"]]}},
15      "version": "5.1.3",
16      "cksum": "12345678 9"}
17 EOF
18 }
19
20 constraint_schema () {
21     cat << 'EOF'
22     {"name": "constraints",
23      "tables": {
24        "a": {
25          "columns": {
26            "a": {"type": "integer"},
27            "a2a": {"type": {"key": {"type": "uuid", "refTable": "a"},
28                             "min": 0, "max": "unlimited"}},
29            "a2b": {"type": {"key": {"type": "uuid", "refTable": "b"},
30                             "min": 0, "max": "unlimited"}}}},
31        "b": {
32          "columns": {
33            "b": {"type": "integer"},
34            "b2a": {"type": {"key": {"type": "uuid", "refTable": "a"},
35                             "min": 0, "max": "unlimited"}},
36            "b2b": {"type": {"key": {"type": "uuid", "refTable": "b"},
37                             "min": 0, "max": "unlimited"}},
38            "x": {"type": {"key": "integer", "min": 1, "max": 2}}}},
39        "constrained": {
40          "columns": {
41            "positive": {"type": {"key": {"type": "integer",
42                                          "minInteger": 1}}}},
43          "maxRows": 1}}}
44 EOF
45 }
46
47 weak_schema () {
48     cat <<'EOF'
49     {"name": "weak",
50      "tables": {
51        "a": {
52          "columns": {
53            "a": {"type": "integer"},
54            "a2a": {"type": {"key": {"type": "uuid",
55                                     "refTable": "a",
56                                     "refType": "weak"},
57                             "min": 0, "max": "unlimited"}},
58            "a2a1": {"type": {"key": {"type": "uuid",
59                                      "refTable": "a",
60                                      "refType": "weak"}}},
61            "a2b": {"type": {"key": {"type": "uuid",
62                                     "refTable": "b",
63                                     "refType": "weak"}}}}},
64        "b": {
65          "columns": {
66            "b": {"type": "integer"},
67            "b2a": {"type": {"key": {"type": "uuid",
68                                     "refTable": "a",
69                                     "refType": "weak"},
70                             "min": 0, "max": "unlimited"}}}}}}
71 EOF
72 }
73
74 gc_schema () {
75     cat <<'EOF'
76     {"name": "gc",
77      "tables": {
78        "root": {
79          "columns": {
80            "a": {"type": {"key": {"type": "uuid",
81                                   "refTable": "a"},
82                             "min": 0, "max": "unlimited"}}},
83          "isRoot": true},
84        "a": {
85          "columns": {
86            "a": {"type": "integer"},
87            "a2a": {"type": {"key": {"type": "uuid",
88                                     "refTable": "a"},
89                             "min": 0, "max": "unlimited"}},
90            "a2b": {"type": {"key": {"type": "uuid",
91                                     "refTable": "b"},
92                             "min": 0, "max": "unlimited"}},
93            "wa2a": {"type": {"key": {"type": "uuid",
94                                      "refTable": "a",
95                                      "refType": "weak"},
96                              "min": 0, "max": "unlimited"}},
97            "wa2b": {"type": {"key": {"type": "uuid",
98                                     "refTable": "b",
99                                     "refType": "weak"},
100                              "min": 0, "max": "unlimited"}}}},
101        "b": {
102          "columns": {
103            "b": {"type": "integer"},
104            "b2a": {"type": {"key": {"type": "uuid",
105                                     "refTable": "a"},
106                             "min": 0, "max": "unlimited"}},
107            "wb2a": {"type": {"key": {"type": "uuid",
108                                      "refTable": "a",
109                                      "refType": "weak"},
110                              "min": 0, "max": "unlimited"}}},
111          "isRoot": false}}}
112 EOF
113 }
114
115 immutable_schema () {
116     cat <<'EOF'
117 {"name": "immutable",
118  "tables": {
119     "a": {
120         "columns": {"i": {"type": "integer", "mutable": false}}}}}
121 EOF
122 }
123 ]
124 m4_divert_pop([PREPARE_TESTS])
125
126 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
127 #
128 # Runs "test-ovsdb execute" with the given SCHEMA and each of the
129 # TRANSACTIONS (which should be a quoted list of quoted strings).
130 #
131 # Checks that the overall output is OUTPUT, but UUIDs in the output
132 # are replaced by markers of the form <N> where N is a number.  The
133 # first unique UUID is replaced by <0>, the next by <1>, and so on.
134 # If a given UUID appears more than once it is always replaced by the
135 # same marker.
136 #
137 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
138 m4_define([OVSDB_CHECK_EXECUTION],
139   [AT_SETUP([$1])
140    AT_KEYWORDS([ovsdb execute execution positive $5])
141    OVS_RUNDIR=`pwd`; export OVS_RUNDIR
142    AT_CHECK([test-ovsdb execute "`$2`" m4_foreach([txn], [$3], [ 'txn'])],
143      [0], [stdout], [])
144    AT_CHECK([${PERL} $srcdir/uuidfilt.pl stdout], [0], [$4])
145    AT_CLEANUP])
146
147 OVSDB_CHECK_EXECUTION([uuid-name must be <id>],
148   [constraint_schema],
149   [[[["constraints",
150       {"op": "insert",
151        "table": "a",
152        "row": {},
153        "uuid-name": "0"}]]]],
154   [[[{"details":"Parsing ovsdb operation 1 of 1 failed: Type mismatch for member 'uuid-name'.","error":"syntax error","syntax":"{\"op\":\"insert\",\"row\":{},\"table\":\"a\",\"uuid-name\":\"0\"}"}]
155 ]])
156
157 OVSDB_CHECK_EXECUTION([named-uuid must be <id>],
158   [constraint_schema],
159   [[[["constraints",
160       {"op": "insert",
161        "table": "a",
162        "row": {"a2a": ["named-uuid", "0"]}}]]]],
163   [[[{"details":"named-uuid string is not a valid <id>","error":"syntax error","syntax":"[\"named-uuid\",\"0\"]"}]
164 ]])
165
166 OVSDB_CHECK_EXECUTION([duplicate uuid-name not allowed],
167   [ordinal_schema],
168   [[[["ordinals",
169       {"op": "insert",
170        "table": "ordinals",
171        "row": {},
172        "uuid-name": "x"},
173       {"op": "insert",
174        "table": "ordinals",
175        "row": {},
176        "uuid-name": "x"}]]]],
177   [[[{"uuid":["uuid","<0>"]},{"details":"This \"uuid-name\" appeared on an earlier \"insert\" operation.","error":"duplicate uuid-name","syntax":"\"x\""}]
178 ]])
179
180 m4_define([EXECUTION_EXAMPLES], [
181 dnl At one point the "commit" code ignored new rows with all-default values,
182 dnl so this checks for that problem.
183 OVSDB_CHECK_EXECUTION([insert default row, query table],
184   [ordinal_schema],
185   [[[["ordinals",
186       {"op": "insert",
187        "table": "ordinals",
188        "row": {}}]]],
189    [[["ordinals",
190       {"op": "select",
191        "table": "ordinals",
192        "where": []}]]]],
193   [[[{"uuid":["uuid","<0>"]}]
194 [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<1>"],"name":"","number":0}]}]
195 ]])
196
197 OVSDB_CHECK_EXECUTION([insert row, query table],
198   [ordinal_schema],
199   [[[["ordinals",
200       {"op": "insert",
201        "table": "ordinals",
202        "row": {"number": 0, "name": "zero"}}]]],
203    [[["ordinals",
204       {"op": "select",
205        "table": "ordinals",
206        "where": []}]]]],
207   [[[{"uuid":["uuid","<0>"]}]
208 [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<1>"],"name":"zero","number":0}]}]
209 ]])
210
211 OVSDB_CHECK_EXECUTION([insert rows, query by value],
212   [ordinal_schema],
213   [[[["ordinals",
214       {"op": "insert",
215        "table": "ordinals",
216        "row": {"number": 0, "name": "zero"}}]]],
217    [[["ordinals",
218       {"op": "insert",
219        "table": "ordinals",
220        "row": {"number": 1, "name": "one"}}]]],
221    [[["ordinals",
222       {"op": "select",
223        "table": "ordinals",
224        "where": [["name", "==", "zero"]]}]]],
225    [[["ordinals",
226       {"op": "select",
227        "table": "ordinals",
228        "where": [["name", "==", "one"]]}]]]],
229   [[[{"uuid":["uuid","<0>"]}]
230 [{"uuid":["uuid","<1>"]}]
231 [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"zero","number":0}]}]
232 [{"rows":[{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
233 ]])
234
235 OVSDB_CHECK_EXECUTION([insert rows, query by named-uuid],
236   [ordinal_schema],
237   [[[["ordinals",
238       {"op": "insert",
239        "table": "ordinals",
240        "row": {"number": 0, "name": "zero"},
241        "uuid-name": "first"},
242       {"op": "insert",
243        "table": "ordinals",
244        "row": {"number": 1, "name": "one"},
245        "uuid-name": "second"},
246       {"op": "select",
247        "table": "ordinals",
248        "where": [["_uuid", "==", ["named-uuid", "first"]]]},
249       {"op": "select",
250        "table": "ordinals",
251        "where": [["_uuid", "==", ["named-uuid", "second"]]]}]]]],
252   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"zero","number":0}]},{"rows":[{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
253 ]])
254
255 OVSDB_CHECK_EXECUTION([insert rows, update rows by value],
256   [ordinal_schema],
257   [[[["ordinals",
258       {"op": "insert",
259        "table": "ordinals",
260        "row": {"number": 0, "name": "zero"},
261        "uuid-name": "first"}]]],
262    [[["ordinals",
263       {"op": "insert",
264        "table": "ordinals",
265        "row": {"number": 1, "name": "one"},
266        "uuid-name": "first"}]]],
267    [[["ordinals",
268       {"op": "update",
269        "table": "ordinals",
270        "where": [["name", "==", "zero"]],
271        "row": {"name": "nought"}}]]],
272    [[["ordinals",
273       {"op": "select",
274        "table": "ordinals",
275        "where": [],
276        "sort": ["number"]}]]]],
277   [[[{"uuid":["uuid","<0>"]}]
278 [{"uuid":["uuid","<1>"]}]
279 [{"count":1}]
280 [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"nought","number":0},{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
281 ]])
282
283 OVSDB_CHECK_EXECUTION([insert rows, mutate rows],
284   [ordinal_schema],
285   [[[["ordinals",
286       {"op": "insert",
287        "table": "ordinals",
288        "row": {"number": 0, "name": "zero"},
289        "uuid-name": "first"}]]],
290    [[["ordinals",
291       {"op": "insert",
292        "table": "ordinals",
293        "row": {"number": 1, "name": "one"},
294        "uuid-name": "first"}]]],
295    [[["ordinals",
296       {"op": "mutate",
297        "table": "ordinals",
298        "where": [["name", "==", "zero"]],
299        "mutations": [["number", "+=", 2]]}]]],
300    [[["ordinals",
301       {"op": "select",
302        "table": "ordinals",
303        "where": [],
304        "sort": ["number"]}]]]],
305   [[[{"uuid":["uuid","<0>"]}]
306 [{"uuid":["uuid","<1>"]}]
307 [{"count":1}]
308 [{"rows":[{"_uuid":["uuid","<1>"],"_version":["uuid","<2>"],"name":"one","number":1},{"_uuid":["uuid","<0>"],"_version":["uuid","<3>"],"name":"zero","number":2}]}]
309 ]])
310
311 OVSDB_CHECK_EXECUTION([insert rows, delete by named-uuid],
312   [ordinal_schema],
313   [[[["ordinals",
314       {"op": "insert",
315        "table": "ordinals",
316        "row": {"number": 0, "name": "zero"},
317        "uuid-name": "first"},
318       {"op": "insert",
319        "table": "ordinals",
320        "row": {"number": 1, "name": "one"},
321        "uuid-name": "second"},
322       {"op": "delete",
323        "table": "ordinals",
324        "where": [["_uuid", "==", ["named-uuid", "first"]]]},
325       {"op": "select",
326        "table": "ordinals",
327        "where": [],
328        "columns": ["name","number"]}]]]],
329   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"count":1},{"rows":[{"name":"one","number":1}]}]
330 ]])
331
332 OVSDB_CHECK_EXECUTION([insert rows, delete rows by value],
333   [ordinal_schema],
334   [[[["ordinals",
335       {"op": "insert",
336        "table": "ordinals",
337        "row": {"number": 0, "name": "zero"},
338        "uuid-name": "first"}]]],
339    [[["ordinals",
340       {"op": "insert",
341        "table": "ordinals",
342        "row": {"number": 1, "name": "one"},
343        "uuid-name": "first"}]]],
344    [[["ordinals",
345       {"op": "delete",
346        "table": "ordinals",
347        "where": [["name", "==", "zero"]]}]]],
348    [[["ordinals",
349       {"op": "select",
350        "table": "ordinals",
351        "where": []}]]]],
352   [[[{"uuid":["uuid","<0>"]}]
353 [{"uuid":["uuid","<1>"]}]
354 [{"count":1}]
355 [{"rows":[{"_uuid":["uuid","<1>"],"_version":["uuid","<2>"],"name":"one","number":1}]}]
356 ]])
357
358 OVSDB_CHECK_EXECUTION([insert rows, delete by (non-matching) value],
359   [ordinal_schema],
360   [[[["ordinals",
361       {"op": "insert",
362        "table": "ordinals",
363        "row": {"number": 0, "name": "zero"},
364        "uuid-name": "first"}]]],
365    [[["ordinals",
366       {"op": "insert",
367        "table": "ordinals",
368        "row": {"number": 1, "name": "one"},
369        "uuid-name": "first"}]]],
370    [[["ordinals",
371       {"op": "delete",
372        "table": "ordinals",
373        "where": [["name", "==", "nought"]]}]]],
374    [[["ordinals",
375       {"op": "select",
376        "table": "ordinals",
377        "where": [],
378        "sort": ["number"]}]]]],
379   [[[{"uuid":["uuid","<0>"]}]
380 [{"uuid":["uuid","<1>"]}]
381 [{"count":0}]
382 [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"zero","number":0},{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
383 ]])
384
385 OVSDB_CHECK_EXECUTION([insert rows, delete all],
386   [ordinal_schema],
387   [[[["ordinals",
388       {"op": "insert",
389        "table": "ordinals",
390        "row": {"number": 0, "name": "zero"},
391        "uuid-name": "first"},
392       {"op": "insert",
393        "table": "ordinals",
394        "row": {"number": 1, "name": "one"},
395        "uuid-name": "second"},
396       {"op": "delete",
397        "table": "ordinals",
398        "where": []},
399       {"op": "select",
400        "table": "ordinals",
401        "where": [],
402        "columns": ["name","number"]}]]]],
403   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"count":2},{"rows":[]}]
404 ]])
405
406 OVSDB_CHECK_EXECUTION([insert row, query table, commit],
407   [ordinal_schema],
408   [[[["ordinals",
409       {"op": "insert",
410        "table": "ordinals",
411        "row": {"number": 0, "name": "zero"}},
412       {"op": "select",
413        "table": "ordinals",
414        "where": []},
415       {"op": "commit",
416        "durable": false}]]]],
417   [[[{"uuid":["uuid","<0>"]},{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<1>"],"name":"zero","number":0}]},{}]
418 ]])
419
420 OVSDB_CHECK_EXECUTION([insert row, query table, commit durably],
421   [ordinal_schema],
422   [[[["ordinals",
423       {"op": "insert",
424        "table": "ordinals",
425        "row": {"number": 0, "name": "zero"}},
426       {"op": "select",
427        "table": "ordinals",
428        "where": []},
429       {"op": "commit",
430        "durable": true}]]]],
431   [[[{"uuid":["uuid","<0>"]},{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<1>"],"name":"zero","number":0}]},{}]
432 ]])
433
434 OVSDB_CHECK_EXECUTION([equality wait with correct rows],
435   [ordinal_schema],
436   [[[["ordinals",
437       {"op": "insert",
438        "table": "ordinals",
439        "row": {"number": 0, "name": "zero"}},
440       {"op": "insert",
441        "table": "ordinals",
442        "row": {"number": 1, "name": "one"}},
443       {"op": "wait",
444        "timeout": 0,
445        "table": "ordinals",
446        "where": [],
447        "columns": ["name", "number"],
448        "until": "==",
449        "rows": [{"name": "zero", "number": 0},
450                 {"name": "one", "number": 1}]}]]]],
451   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{}]
452 ]])
453
454 OVSDB_CHECK_EXECUTION([equality wait with extra row],
455   [ordinal_schema],
456   [[[["ordinals",
457       {"op": "insert",
458        "table": "ordinals",
459        "row": {"number": 0, "name": "zero"}},
460       {"op": "insert",
461        "table": "ordinals",
462        "row": {"number": 1, "name": "one"}},
463       {"op": "wait",
464        "timeout": 0,
465        "table": "ordinals",
466        "where": [],
467        "columns": ["name", "number"],
468        "until": "==",
469        "rows": [{"name": "zero", "number": 0},
470                 {"name": "one", "number": 1},
471                 {"name": "two", "number": 2}]}]]]],
472   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"details":"\"wait\" timed out","error":"timed out"}]
473 ]])
474
475 OVSDB_CHECK_EXECUTION([equality wait with missing row],
476   [ordinal_schema],
477   [[[["ordinals",
478       {"op": "insert",
479        "table": "ordinals",
480        "row": {"number": 0, "name": "zero"}},
481       {"op": "insert",
482        "table": "ordinals",
483        "row": {"number": 1, "name": "one"}},
484       {"op": "wait",
485        "timeout": 0,
486        "table": "ordinals",
487        "where": [],
488        "columns": ["name", "number"],
489        "until": "==",
490        "rows": [{"name": "one", "number": 1}]}]]]],
491   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"details":"\"wait\" timed out","error":"timed out"}]
492 ]])
493
494 OVSDB_CHECK_EXECUTION([inequality wait with correct rows],
495   [ordinal_schema],
496   [[[["ordinals",
497       {"op": "insert",
498        "table": "ordinals",
499        "row": {"number": 0, "name": "zero"}},
500       {"op": "insert",
501        "table": "ordinals",
502        "row": {"number": 1, "name": "one"}},
503       {"op": "wait",
504        "timeout": 0,
505        "table": "ordinals",
506        "where": [],
507        "columns": ["name", "number"],
508        "until": "!=",
509        "rows": [{"name": "zero", "number": 0},
510                 {"name": "one", "number": 1}]}]]]],
511   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"details":"\"wait\" timed out","error":"timed out"}]
512 ]])
513
514 OVSDB_CHECK_EXECUTION([inequality wait with extra row],
515   [ordinal_schema],
516   [[[["ordinals",
517       {"op": "insert",
518        "table": "ordinals",
519        "row": {"number": 0, "name": "zero"}},
520       {"op": "insert",
521        "table": "ordinals",
522        "row": {"number": 1, "name": "one"}},
523       {"op": "wait",
524        "timeout": 0,
525        "table": "ordinals",
526        "where": [],
527        "columns": ["name", "number"],
528        "until": "!=",
529        "rows": [{"name": "zero", "number": 0},
530                 {"name": "one", "number": 1},
531                 {"name": "two", "number": 2}]}]]]],
532   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{}]
533 ]])
534
535 OVSDB_CHECK_EXECUTION([inequality wait with missing row],
536   [ordinal_schema],
537   [[[["ordinals",
538       {"op": "insert",
539        "table": "ordinals",
540        "row": {"number": 0, "name": "zero"}},
541       {"op": "insert",
542        "table": "ordinals",
543        "row": {"number": 1, "name": "one"}},
544       {"op": "wait",
545        "timeout": 0,
546        "table": "ordinals",
547        "where": [],
548        "columns": ["name", "number"],
549        "until": "!=",
550        "rows": [{"name": "one", "number": 1}]}]]]],
551   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{}]
552 ]])
553
554 OVSDB_CHECK_EXECUTION([insert and update constraints],
555   [constraint_schema],
556   [[[["constraints",
557       {"op": "insert",
558        "table": "constrained",
559        "row": {}}]]],
560    [[["constraints",
561       {"op": "insert",
562        "table": "constrained",
563        "row": {"positive": -1}}]]],
564    [[["constraints",
565       {"op": "update",
566        "table": "constrained",
567        "where": [],
568        "row": {"positive": -2}}]]],
569    [[["constraints",
570       {"op": "insert",
571        "table": "constrained",
572        "row": {"positive": 1}}]]],
573    [[["constraints",
574       {"op": "insert",
575        "table": "constrained",
576        "row": {"positive": 2}}]]]],
577   [[[{"details":"0 is less than minimum allowed value 1","error":"constraint violation"}]
578 [{"details":"-1 is less than minimum allowed value 1","error":"constraint violation"}]
579 [{"details":"-2 is less than minimum allowed value 1","error":"constraint violation"}]
580 [{"uuid":["uuid","<0>"]}]
581 [{"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"}]
582 ]])
583
584 OVSDB_CHECK_EXECUTION([index uniqueness checking],
585   [ordinal_schema],
586 dnl Insert initial row.
587   [[[["ordinals",
588       {"op": "insert",
589        "table": "ordinals",
590        "row": {"number": 1, "name": "one"}}]]],
591 dnl Try to insert row with identical value (fails).
592    [[["ordinals",
593       {"op": "insert",
594        "table": "ordinals",
595        "row": {"number": 1, "name": "another one"}}]]],
596 dnl Remove initial row and insert new row with identical value in a single
597 dnl transaction (succeeds).
598    [[["ordinals",
599       {"op": "insert",
600        "table": "ordinals",
601        "row": {"number": 1, "name": "another one"}},
602       {"op": "delete",
603        "table": "ordinals",
604        "where": [["name", "==", "one"]]}]]],
605 dnl Remove row and insert two new rows with identical value in a single
606 dnl transaction (fails).
607    [[["ordinals",
608       {"op": "delete",
609        "table": "ordinals",
610        "where": []},
611       {"op": "insert",
612        "table": "ordinals",
613        "row": {"number": 1, "name": "one"}},
614       {"op": "insert",
615        "table": "ordinals",
616        "row": {"number": 1, "name": "still another one"}}]]],
617 dnl Add new row with different value (succeeds).
618    [[["ordinals",
619       {"op": "insert",
620        "table": "ordinals",
621        "row": {"number": 2, "name": "two"}}]]],
622 dnl Change rows so values collide (fails).
623    [[["ordinals",
624       {"op": "update",
625        "table": "ordinals",
626        "where": [],
627        "row": {"number": 3}}]]],
628 dnl Swap rows' values (succeeds).
629    [[["ordinals",
630       {"op": "update",
631        "table": "ordinals",
632        "where": [["number", "==", 1]],
633        "row": {"number": 2, "name": "old two"}},
634       {"op": "update",
635        "table": "ordinals",
636        "where": [["name", "==", "two"]],
637        "row": {"number": 1, "name": "old one"}}]]],
638 dnl Change all rows' values to values not used before and insert values that
639 dnl collide (only) with their previous values (succeeds).
640    [[["ordinals",
641       {"op": "mutate",
642        "table": "ordinals",
643        "where": [],
644        "mutations": [["number", "*=", 10]]},
645       {"op": "insert",
646        "table": "ordinals",
647        "row": {"number": 1, "name": "new one"}},
648       {"op": "insert",
649        "table": "ordinals",
650        "row": {"number": 2, "name": "new two"}},
651       {"op": "select",
652        "table": "ordinals",
653        "where": [],
654        "columns": ["number", "name"],
655        "sort": ["number"]}]]]],
656   [[[{"uuid":["uuid","<0>"]}]
657 [{"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"}]
658 [{"uuid":["uuid","<2>"]},{"count":1}]
659 [{"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"}]
660 [{"uuid":["uuid","<5>"]}]
661 [{"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"}]
662 [{"count":1},{"count":1}]
663 [{"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}]}]
664 ]])
665
666 OVSDB_CHECK_EXECUTION([referential integrity -- simple],
667   [constraint_schema],
668   [[[["constraints",
669       {"op": "insert",
670        "table": "b",
671        "row": {"b": 1},
672        "uuid-name": "brow"},
673       {"op": "insert",
674        "table": "a",
675        "row": {"a": 0,
676                "a2b": ["set", [["named-uuid", "brow"]]]}},
677       {"op": "insert",
678        "table": "a",
679        "row": {"a": 1,
680                "a2b": ["set", [["named-uuid", "brow"]]]}},
681       {"op": "insert",
682        "table": "a",
683        "row": {"a": 2,
684                "a2b": ["set", [["named-uuid", "brow"]]]}}]]],
685    [[["constraints",
686       {"op": "delete",
687        "table": "b",
688        "where": []}]]],
689 dnl Check that "mutate" honors number-of-elements constraints on sets and maps.
690    [[["constraints",
691       {"op": "mutate",
692        "table": "b",
693        "where": [],
694        "mutations": [["x", "delete", 0]]}]]],
695    [[["constraints",
696       {"op": "delete",
697        "table": "a",
698        "where": [["a", "==", 0]]}]]],
699    [[["constraints",
700       {"op": "delete",
701        "table": "b",
702        "where": []}]]],
703    [[["constraints",
704       {"op": "delete",
705        "table": "a",
706        "where": [["a", "==", 1]]}]]],
707    [[["constraints",
708       {"op": "delete",
709        "table": "b",
710        "where": []}]]],
711    [[["constraints",
712       {"op": "delete",
713        "table": "a",
714        "where": [["a", "==", 2]]}]]],
715    [[["constraints",
716       {"op": "delete",
717        "table": "b",
718        "where": []}]]]],
719   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]
720 [{"count":1},{"details":"cannot delete b row <0> because of 3 remaining reference(s)","error":"referential integrity violation"}]
721 [{"details":"Attempted to store 0 elements in set of 1 to 2 integers.","error":"constraint violation"}]
722 [{"count":1}]
723 [{"count":1},{"details":"cannot delete b row <0> because of 2 remaining reference(s)","error":"referential integrity violation"}]
724 [{"count":1}]
725 [{"count":1},{"details":"cannot delete b row <0> because of 1 remaining reference(s)","error":"referential integrity violation"}]
726 [{"count":1}]
727 [{"count":1}]
728 ]])
729
730 OVSDB_CHECK_EXECUTION([referential integrity -- mutual references],
731   [constraint_schema],
732   [[[["constraints",
733       {"op": "insert",
734        "table": "a",
735        "row": {"a": 0,
736                "a2b": ["set", [["named-uuid", "row2"]]],
737                "a2a": ["set", [["named-uuid", "row1"]]]},
738        "uuid-name": "row1"},
739       {"op": "insert",
740        "table": "b",
741        "row": {"b": 1,
742                "b2b": ["set", [["named-uuid", "row2"]]],
743                "b2a": ["set", [["named-uuid", "row1"]]]},
744        "uuid-name": "row2"}]]],
745    [[["constraints",
746       {"op": "insert",
747        "table": "a",
748        "row": {"a2b": ["set", [["uuid", "b516b960-5b19-4fc2-bb82-fe1cbd6d0241"]]]}}]]],
749    [[["constraints",
750       {"op": "delete",
751        "table": "a",
752        "where": [["a", "==", 0]]}]]],
753    [[["constraints",
754       {"op": "delete",
755        "table": "b",
756        "where": [["b", "==", 1]]}]]],
757    dnl Try the deletions again to make sure that the refcounts got rolled back.
758    [[["constraints",
759       {"op": "delete",
760        "table": "a",
761        "where": [["a", "==", 0]]}]]],
762    [[["constraints",
763       {"op": "delete",
764        "table": "b",
765        "where": [["b", "==", 1]]}]]],
766    [[["constraints",
767       {"op": "delete",
768        "table": "a",
769        "where": [["a", "==", 0]]},
770       {"op": "delete",
771        "table": "b",
772        "where": [["b", "==", 1]]}]]]],
773   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]
774 [{"uuid":["uuid","<2>"]},{"details":"Table a column a2b row <2> references nonexistent row <3> in table b.","error":"referential integrity violation"}]
775 [{"count":1},{"details":"cannot delete a row <0> because of 1 remaining reference(s)","error":"referential integrity violation"}]
776 [{"count":1},{"details":"cannot delete b row <1> because of 1 remaining reference(s)","error":"referential integrity violation"}]
777 [{"count":1},{"details":"cannot delete a row <0> because of 1 remaining reference(s)","error":"referential integrity violation"}]
778 [{"count":1},{"details":"cannot delete b row <1> because of 1 remaining reference(s)","error":"referential integrity violation"}]
779 [{"count":1},{"count":1}]
780 ]])
781
782 OVSDB_CHECK_EXECUTION([weak references],
783   [weak_schema],
784   [[[["weak",
785       {"op": "insert",
786        "table": "a",
787        "row": {"a": 0,
788                "a2a": ["set", [["named-uuid", "row1"],
789                                ["named-uuid", "row2"],
790                                ["uuid", "0e767b36-6822-4044-8307-d58467e04669"]]],
791                "a2a1": ["named-uuid", "row1"],
792                "a2b": ["named-uuid", "row3"]},
793        "uuid-name": "row1"},
794       {"op": "insert",
795        "table": "a",
796        "row": {"a": 1,
797                "a2a": ["set", [["named-uuid", "row1"],
798                                ["named-uuid", "row2"]]],
799                "a2a1": ["named-uuid", "row2"],
800                "a2b": ["named-uuid", "row3"]},
801        "uuid-name": "row2"},
802       {"op": "insert",
803        "table": "a",
804        "row": {"a": 2,
805                "a2a": ["set", [["named-uuid", "row1"],
806                                ["named-uuid", "row2"]]],
807                "a2a1": ["named-uuid", "row2"],
808                "a2b": ["named-uuid", "row4"]}},
809       {"op": "insert",
810        "table": "b",
811        "row": {"b": 2,
812                "b2a": ["named-uuid", "row1"]},
813        "uuid-name": "row3"},
814       {"op": "insert",
815        "table": "b",
816        "row": {"b": 3,
817                "b2a": ["named-uuid", "row2"]},
818        "uuid-name": "row4"}]]],
819    dnl Check that the nonexistent row UUID we added to row a0 was deleted,
820    dnl and that other rows were inserted as requested.
821    [[["weak",
822       {"op": "select",
823        "table": "a",
824        "where": [],
825        "columns": ["_uuid", "a2a", "a2a1", "a2b"],
826        "sort": ["a"]}]]],
827    [[["weak",
828       {"op": "select",
829        "table": "b",
830        "where": [],
831        "columns": ["_uuid", "b", "b2a"],
832        "sort": ["b"]}]]],
833    dnl Try to insert invalid all-zeros weak reference (the default) into
834    dnl "a2b", which requires exactly one value.
835    [[["weak",
836       {"op": "insert",
837        "table": "a",
838        "row": {"a2a1": ["named-uuid", "me"]},
839        "uuid-name": "me"}]]],
840    dnl Try to delete row from "b" that is referred to by weak references
841    dnl from "a" table "a2b" column that requires exactly one value.
842    [[["weak",
843       {"op": "delete",
844        "table": "b",
845        "where": [["b", "==", 3]]}]]],
846    dnl Try to delete row from "a" that is referred to by weak references
847    dnl from "a" table "a2a1" column that requires exactly one value.
848    [[["weak",
849       {"op": "delete",
850        "table": "a",
851        "where": [["a", "==", 1]]}]]],
852    dnl Delete the row that had the reference that caused the previous
853    dnl deletion to fail, then check that other rows are unchanged.
854    [[["weak",
855       {"op": "delete",
856        "table": "a",
857        "where": [["a", "==", 2]]}]]],
858    [[["weak",
859       {"op": "select",
860        "table": "a",
861        "where": [],
862        "columns": ["_uuid", "a2a", "a2a1", "a2b"],
863        "sort": ["a"]}]]],
864    [[["weak",
865       {"op": "select",
866        "table": "b",
867        "where": [],
868        "columns": ["_uuid", "b", "b2a"],
869        "sort": ["b"]}]]],
870    dnl Delete row a0 then check that references to it were removed.
871    [[["weak",
872       {"op": "delete",
873        "table": "a",
874        "where": [["a", "==", 0]]}]]],
875    [[["weak",
876       {"op": "select",
877        "table": "a",
878        "where": [],
879        "columns": ["_uuid", "a2a", "a2a1", "a2b"],
880        "sort": ["a"]}]]],
881    [[["weak",
882       {"op": "select",
883        "table": "b",
884        "where": [],
885        "columns": ["_uuid", "b", "b2a"],
886        "sort": ["b"]}]]],
887    dnl Delete row a1 then check that references to it were removed.
888    [[["weak",
889       {"op": "delete",
890        "table": "a",
891        "where": [["a", "==", 1]]}]]],
892    [[["weak",
893       {"op": "select",
894        "table": "a",
895        "where": [],
896        "columns": ["_uuid", "a2a", "a2a1", "a2b"],
897        "sort": ["a"]}]]],
898    [[["weak",
899       {"op": "select",
900        "table": "b",
901        "where": [],
902        "columns": ["_uuid", "b", "b2a"],
903        "sort": ["b"]}]]]],
904   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]},{"uuid":["uuid","<4>"]}]
905 [{"rows":[{"_uuid":["uuid","<0>"],"a2a":["set",[["uuid","<0>"],["uuid","<1>"]]],"a2a1":["uuid","<0>"],"a2b":["uuid","<3>"]},{"_uuid":["uuid","<1>"],"a2a":["set",[["uuid","<0>"],["uuid","<1>"]]],"a2a1":["uuid","<1>"],"a2b":["uuid","<3>"]},{"_uuid":["uuid","<2>"],"a2a":["set",[["uuid","<0>"],["uuid","<1>"]]],"a2a1":["uuid","<1>"],"a2b":["uuid","<4>"]}]}]
906 [{"rows":[{"_uuid":["uuid","<3>"],"b":2,"b2a":["uuid","<0>"]},{"_uuid":["uuid","<4>"],"b":3,"b2a":["uuid","<1>"]}]}]
907 [{"uuid":["uuid","<5>"]},{"details":"Weak reference column \"a2b\" in \"a\" row <5> (inserted within this transaction) contained all-zeros UUID (probably as the default value for this column) but deleting this value caused a constraint volation because this column is not allowed to be empty.","error":"constraint violation"}]
908 [{"count":1},{"details":"Deletion of 1 weak reference(s) to deleted (or never-existing) rows from column \"a2b\" in \"a\" row <2> caused this column to become empty, but constraints on this column disallow an empty column.","error":"constraint violation"}]
909 [{"count":1},{"details":"Deletion of 1 weak reference(s) to deleted (or never-existing) rows from column \"a2a1\" in \"a\" row <2> caused this column to become empty, but constraints on this column disallow an empty column.","error":"constraint violation"}]
910 [{"count":1}]
911 [{"rows":[{"_uuid":["uuid","<0>"],"a2a":["set",[["uuid","<0>"],["uuid","<1>"]]],"a2a1":["uuid","<0>"],"a2b":["uuid","<3>"]},{"_uuid":["uuid","<1>"],"a2a":["set",[["uuid","<0>"],["uuid","<1>"]]],"a2a1":["uuid","<1>"],"a2b":["uuid","<3>"]}]}]
912 [{"rows":[{"_uuid":["uuid","<3>"],"b":2,"b2a":["uuid","<0>"]},{"_uuid":["uuid","<4>"],"b":3,"b2a":["uuid","<1>"]}]}]
913 [{"count":1}]
914 [{"rows":[{"_uuid":["uuid","<1>"],"a2a":["uuid","<1>"],"a2a1":["uuid","<1>"],"a2b":["uuid","<3>"]}]}]
915 [{"rows":[{"_uuid":["uuid","<3>"],"b":2,"b2a":["set",[]]},{"_uuid":["uuid","<4>"],"b":3,"b2a":["uuid","<1>"]}]}]
916 [{"count":1}]
917 [{"rows":[]}]
918 [{"rows":[{"_uuid":["uuid","<3>"],"b":2,"b2a":["set",[]]},{"_uuid":["uuid","<4>"],"b":3,"b2a":["set",[]]}]}]
919 ]])
920
921 OVSDB_CHECK_EXECUTION([immutable columns],
922   [immutable_schema],
923   [[[["immutable",
924       {"op": "insert",
925        "table": "a",
926        "row": {"i": 5},
927        "uuid-name": "row1"}]]],
928    [[["immutable",
929       {"op": "update",
930        "table": "a",
931        "row": {"i": 10},
932        "where": []}]]],
933    [[["immutable",
934       {"op": "update",
935        "table": "a",
936        "row": {"i": 5},
937        "where": []}]]],
938    [[["immutable",
939       {"op": "mutate",
940        "table": "a",
941        "where": [],
942        "mutations": [["i", "-=", 5]]}]]],
943    [[["immutable",
944       {"op": "mutate",
945        "table": "a",
946        "where": [],
947        "mutations": [["i", "*=", 1]]}]]]],
948   [[[{"uuid":["uuid","<0>"]}]
949 [{"details":"Cannot update immutable column i in table a.","error":"constraint violation","syntax":"{\"op\":\"update\",\"row\":{\"i\":10},\"table\":\"a\",\"where\":[]}"}]
950 [{"details":"Cannot update immutable column i in table a.","error":"constraint violation","syntax":"{\"op\":\"update\",\"row\":{\"i\":5},\"table\":\"a\",\"where\":[]}"}]
951 [{"details":"Cannot mutate immutable column i in table a.","error":"constraint violation","syntax":"[\"i\",\"-=\",5]"}]
952 [{"details":"Cannot mutate immutable column i in table a.","error":"constraint violation","syntax":"[\"i\",\"*=\",1]"}]
953 ]])
954
955 OVSDB_CHECK_EXECUTION([garbage collection],
956   [gc_schema],
957   [dnl Check that inserting a row without any references is a no-op.
958    [[["gc",
959       {"op": "insert",
960        "table": "a",
961        "row": {"a": 0}}]]],
962    [[["gc",
963       {"op": "select",
964        "table": "a",
965        "where": [],
966        "columns": ["a"]}]]],
967    dnl Check that inserting a chain of rows that reference each other
968    dnl in turn is also a no-op.
969    [[["gc",
970       {"op": "insert",
971        "table": "a",
972        "row": {"a": 0, "a2a": ["named-uuid", "row1"]},
973        "uuid-name": "row0"},
974       {"op": "insert",
975        "table": "a",
976        "row": {"a": 1, "a2a": ["named-uuid", "row2"]},
977        "uuid-name": "row1"},
978       {"op": "insert",
979        "table": "a",
980        "row": {"a": 2, "a2a": ["named-uuid", "row3"]},
981        "uuid-name": "row2"},
982       {"op": "insert",
983        "table": "a",
984        "row": {"a": 3},
985        "uuid-name": "row3"}]]],
986    [[["gc",
987       {"op": "select",
988        "table": "a",
989        "where": [],
990        "columns": ["a"]}]]],
991    dnl Check that inserting a pair of rows that mutually reference each
992    dnl other causes the rows to be retained.
993    [[["gc",
994       {"op": "insert",
995        "table": "a",
996        "row": {"a": 4, "a2a": ["named-uuid", "row5"]},
997        "uuid-name": "row4"},
998       {"op": "insert",
999        "table": "a",
1000        "row": {"a": 5, "a2a": ["named-uuid", "row4"]},
1001        "uuid-name": "row5"}]]],
1002    [[["gc",
1003       {"op": "select",
1004        "table": "a",
1005        "where": [],
1006        "columns": ["a"],
1007        "sort": ["a"]}]]],
1008    dnl Check that unreferencing one of the rows causes the other to be deleted.
1009    [[["gc",
1010       {"op": "update",
1011        "table": "a",
1012        "where": [["a", "==", 4]],
1013        "row": {"a2a": ["set", []]}}]]],
1014    [[["gc",
1015       {"op": "select",
1016        "table": "a",
1017        "where": [],
1018        "columns": ["a"]}]]],
1019    dnl Check that inserting a pair of rows that mutually weak reference each
1020    dnl other is a no-op.
1021    [[["gc",
1022       {"op": "insert",
1023        "table": "a",
1024        "row": {"a": 6, "wa2a": ["named-uuid", "row7"]},
1025        "uuid-name": "row6"},
1026       {"op": "insert",
1027        "table": "a",
1028        "row": {"a": 7, "wa2a": ["named-uuid", "row6"]},
1029        "uuid-name": "row7"}]]],
1030    [[["gc",
1031       {"op": "select",
1032        "table": "a",
1033        "where": [],
1034        "columns": ["a"]}]]],
1035    dnl Check that a circular chain of rows is retained.
1036    [[["gc",
1037       {"op": "insert",
1038        "table": "a",
1039        "row": {"a": 8, "a2a": ["named-uuid", "row9"]},
1040        "uuid-name": "row8"},
1041       {"op": "insert",
1042        "table": "a",
1043        "row": {"a": 9, "a2a": ["named-uuid", "row10"]},
1044        "uuid-name": "row9"},
1045       {"op": "insert",
1046        "table": "a",
1047        "row": {"a": 10, "a2a": ["named-uuid", "row11"]},
1048        "uuid-name": "row10"},
1049       {"op": "insert",
1050        "table": "a",
1051        "row": {"a": 11, "a2a": ["named-uuid", "row8"]},
1052        "uuid-name": "row11"}]]],
1053    [[["gc",
1054       {"op": "select",
1055        "table": "a",
1056        "where": [],
1057        "columns": ["a"],
1058        "sort": ["a"]}]]],
1059    dnl Check that breaking the chain causes all of the rows to be deleted.
1060    [[["gc",
1061       {"op": "update",
1062        "table": "a",
1063        "where": [["a", "==", 9]],
1064        "row": {"a2a": ["set", []]}}]]],
1065    [[["gc",
1066       {"op": "select",
1067        "table": "a",
1068        "where": [],
1069        "columns": ["a"]}]]],
1070    dnl Check that inserting a row only referenced by itself is a no-op.
1071    [[["gc",
1072       {"op": "insert",
1073        "table": "a",
1074        "row": {"a": 12, "a2a": ["named-uuid", "self"]},
1075        "uuid-name": "self"}]]],
1076    [[["gc",
1077       {"op": "select",
1078        "table": "a",
1079        "where": [],
1080        "columns": ["a"]}]]]],
1081   [[[{"uuid":["uuid","<0>"]}]
1082 [{"rows":[]}]
1083 [{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]},{"uuid":["uuid","<4>"]}]
1084 [{"rows":[]}]
1085 [{"uuid":["uuid","<5>"]},{"uuid":["uuid","<6>"]}]
1086 [{"rows":[{"a":4},{"a":5}]}]
1087 [{"count":1}]
1088 [{"rows":[]}]
1089 [{"uuid":["uuid","<7>"]},{"uuid":["uuid","<8>"]}]
1090 [{"rows":[]}]
1091 [{"uuid":["uuid","<9>"]},{"uuid":["uuid","<10>"]},{"uuid":["uuid","<11>"]},{"uuid":["uuid","<12>"]}]
1092 [{"rows":[{"a":8},{"a":9},{"a":10},{"a":11}]}]
1093 [{"count":1}]
1094 [{"rows":[]}]
1095 [{"uuid":["uuid","<13>"]}]
1096 [{"rows":[]}]
1097 ]])])
1098
1099 EXECUTION_EXAMPLES