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