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