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