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