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