]> git.proxmox.com Git - mirror_ovs.git/blob - tests/ovsdb-server.at
system-afxdp.at: Add test for infinite re-addition of failed ports.
[mirror_ovs.git] / tests / ovsdb-server.at
1 AT_BANNER([OVSDB -- ovsdb-server transactions (Unix sockets)])
2
3 m4_define([OVSDB_SERVER_SHUTDOWN],
4 [OVS_APP_EXIT_AND_WAIT_BY_TARGET([ovsdb-server], [ovsdb-server.pid])])
5
6 m4_define([OVSDB_SERVER_SHUTDOWN2],
7 [cp pid2 savepid2
8 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 -e exit], [0], [ignore], [ignore])
9 OVS_WAIT_WHILE([kill -0 `cat savepid2`], [kill `cat savepid2`])])
10
11 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
12 #
13 # Creates a database with the given SCHEMA, starts an ovsdb-server on
14 # that database, and runs each of the TRANSACTIONS (which should be a
15 # quoted list of quoted strings) against it with ovsdb-client one at a
16 # time.
17 #
18 # Checks that the overall output is OUTPUT, but UUIDs in the output
19 # are replaced by markers of the form <N> where N is a number. The
20 # first unique UUID is replaced by <0>, the next by <1>, and so on.
21 # If a given UUID appears more than once it is always replaced by the
22 # same marker.
23 #
24 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
25 m4_define([OVSDB_CHECK_EXECUTION],
26 [AT_SETUP([$1])
27 AT_KEYWORDS([ovsdb server positive unix $5])
28 $2 > schema
29 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
30 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore])
31 m4_foreach([txn], [$3],
32 [AT_CHECK([ovsdb-client transact unix:socket 'txn'], [0], [stdout], [ignore],
33 [test ! -e pid || kill `cat pid`])
34 cat stdout >> output
35 ])
36 AT_CHECK([uuidfilt output], [0], [$4], [ignore],
37 [test ! -e pid || kill `cat pid`])
38 OVSDB_SERVER_SHUTDOWN
39 AT_CLEANUP])
40
41 EXECUTION_EXAMPLES
42 \f
43 AT_BANNER([ovsdb-server miscellaneous features])
44
45 AT_SETUP([truncating corrupted database log])
46 AT_KEYWORDS([ovsdb server positive unix])
47 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
48 ordinal_schema > schema
49 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
50 dnl Do one transaction and save the output.
51 AT_DATA([txnfile], [[ovsdb-client transact unix:socket \
52 '["ordinals",
53 {"op": "insert",
54 "table": "ordinals",
55 "row": {"number": 0, "name": "zero"}}]'
56 ]])
57 AT_CHECK([ovsdb-server --remote=punix:socket db --run="sh txnfile"], [0], [stdout], [])
58 cat stdout >> output
59 dnl Add some crap to the database log and run another transaction, which should
60 dnl ignore the crap and truncate it out of the log.
61 echo 'xxx' >> db
62 AT_DATA([txnfile], [[ovsdb-client transact unix:socket \
63 '["ordinals",
64 {"op": "insert",
65 "table": "ordinals",
66 "row": {"number": 1, "name": "one"}}]'
67 ]])
68 AT_CHECK([ovsdb-server --remote=punix:socket db --run="sh txnfile"], [0], [stdout], [stderr])
69 AT_CHECK([grep 'syntax error: db: parse error.* in header line "xxx"' stderr],
70 [0], [ignore])
71 cat stdout >> output
72 dnl Run a final transaction to verify that both transactions succeeeded.
73 dnl The crap that we added should have been truncated by the previous run,
74 dnl so ovsdb-server shouldn't log a warning this time.
75 AT_DATA([txnfile], [[ovsdb-client transact unix:socket \
76 '["ordinals",
77 {"op": "select",
78 "table": "ordinals",
79 "where": [],
80 "sort": ["number"]}]'
81 ]])
82 AT_CHECK([ovsdb-server --remote=punix:socket db --run="sh txnfile"], [0], [stdout], [])
83 cat stdout >> output
84 AT_CHECK([uuidfilt output], [0],
85 [[[{"uuid":["uuid","<0>"]}]
86 [{"uuid":["uuid","<1>"]}]
87 [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"zero","number":0},{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
88 ]], [],
89 [test ! -e pid || kill `cat pid`])
90 AT_CLEANUP
91
92 AT_SETUP([truncating database log with bad transaction])
93 AT_KEYWORDS([ovsdb server positive unix])
94 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
95 ordinal_schema > schema
96 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
97 dnl Do one transaction and save the output.
98 AT_DATA([txnfile], [[ovsdb-client transact unix:socket \
99 '["ordinals",
100 {"op": "insert",
101 "table": "ordinals",
102 "row": {"number": 0, "name": "zero"}}]'
103 ]])
104 AT_CHECK([ovsdb-server --remote=punix:socket db --run="sh txnfile"], [0], [stdout], [])
105 cat stdout >> output
106 dnl Add some crap to the database log and run another transaction, which should
107 dnl ignore the crap and truncate it out of the log.
108 echo 'OVSDB JSON 15 ffbcdae4b0386265f9ea3280dd7c8f0b72a20e56
109 {"invalid":{}}' >> db
110 AT_DATA([txnfile], [[ovsdb-client transact unix:socket \
111 '["ordinals",
112 {"op": "insert",
113 "table": "ordinals",
114 "row": {"number": 1, "name": "one"}}]'
115 ]])
116 AT_CHECK([ovsdb-server --remote=punix:socket db --run="sh txnfile"], [0], [stdout], [stderr])
117 AT_CHECK([grep 'syntax "{"invalid":{}}": unknown table: No table named invalid.' stderr],
118 [0], [ignore])
119 cat stdout >> output
120 dnl Run a final transaction to verify that both transactions succeeeded.
121 dnl The crap that we added should have been truncated by the previous run,
122 dnl so ovsdb-server shouldn't log a warning this time.
123 AT_DATA([txnfile], [[ovsdb-client transact unix:socket \
124 '["ordinals",
125 {"op": "select",
126 "table": "ordinals",
127 "where": [],
128 "sort": ["number"]}]'
129 ]])
130 AT_CHECK([ovsdb-server --remote=punix:socket db --run="sh txnfile"], [0], [stdout], [])
131 cat stdout >> output
132 AT_CHECK([uuidfilt output], [0],
133 [[[{"uuid":["uuid","<0>"]}]
134 [{"uuid":["uuid","<1>"]}]
135 [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"zero","number":0},{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
136 ]], [],
137 [test ! -e pid || kill `cat pid`])
138 AT_CLEANUP
139
140 dnl CHECK_DBS([databases])
141 dnl
142 dnl Checks that ovsdb-server hosts the given 'databases', each of which
143 dnl needs to be followed by a newline.
144 m4_define([CHECK_DBS],
145 [AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
146 [0], [_Server
147 $1])
148 AT_CHECK([ovsdb-client --no-headings dump _Server Database name | sort], [0], [dnl
149 Database table
150 _Server
151 $1])])
152
153 AT_SETUP([database multiplexing implementation])
154 AT_KEYWORDS([ovsdb server positive])
155 ordinal_schema > schema1
156 constraint_schema > schema2
157 AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
158 AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
159 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:db.sock db1 db2], [0], [ignore], [ignore])
160 CHECK_DBS([constraints
161 ordinals
162 ])
163 AT_CHECK(
164 [[ovstest test-jsonrpc request unix:db.sock get_schema [\"nonexistent\"]]], [0],
165 [[{"error":{"details":"get_schema request specifies unknown database nonexistent","error":"unknown database","syntax":"[\"nonexistent\"]"},"id":0,"result":null}
166 ]], [], [test ! -e pid || kill `cat pid`])
167 OVSDB_SERVER_SHUTDOWN
168 AT_CLEANUP
169
170 AT_SETUP([ovsdb-server/add-db and remove-db])
171 AT_KEYWORDS([ovsdb server positive])
172 on_exit 'kill `cat *.pid`'
173 ordinal_schema > schema1
174 constraint_schema > schema2
175 AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
176 AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
177
178 # Start ovsdb-server with just a single database - db1.
179 AT_CHECK([ovsdb-server -vfile -vvlog:off --log-file --detach --no-chdir --pidfile --remote=punix:db.sock db1], [0])
180 CHECK_DBS([ordinals
181 ])
182
183 # Remove the database.
184 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db ordinals], [0])
185 CHECK_DBS([])
186
187 # Start monitoring processes.
188 AT_CHECK([ovsdb-client --detach --no-chdir --pidfile=ovsdb-client-1.pid --no-db-change-aware --no-headings monitor _Server Database name > db-change-unaware.stdout 2> db-change-unaware.stderr])
189 AT_CHECK([ovsdb-client --detach --no-chdir --pidfile=ovsdb-client-2.pid --db-change-aware --no-headings monitor _Server Database name > db-change-aware.stdout 2> db-change-aware.stderr])
190 AT_CAPTURE_FILE([db-change-unaware.stdout])
191 AT_CAPTURE_FILE([db-change-unaware.stderr])
192 AT_CAPTURE_FILE([db-change-aware.stdout])
193 AT_CAPTURE_FILE([db-change-aware.stderr])
194
195 # Add the first database back.
196 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db1], [0])
197 CHECK_DBS([ordinals
198 ])
199
200 # Add the second database.
201 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
202 CHECK_DBS([constraints
203 ordinals
204 ])
205
206 # The databases are responsive.
207 AT_CHECK([ovsdb-client list-tables unix:db.sock constraints], [0], [ignore], [ignore])
208 AT_CHECK([ovsdb-client list-tables unix:db.sock ordinals], [0], [ignore], [ignore])
209
210 # Add an already added database.
211 if test $IS_WIN32 = "yes"; then
212 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], 2, [],
213 [I/O error: db2: failed to lock lockfile (Resource deadlock avoided)
214 ovs-appctl: ovsdb-server: server returned an error
215 ])
216 else
217 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], 2, [],
218 [ovsdb error: db2: already open
219 ovs-appctl: ovsdb-server: server returned an error
220 ])
221 fi
222
223 # Add a non-existing database.
224 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db3], 2, [], [stderr])
225 AT_CHECK([sed 's/(.*)/(...)/' stderr], [0],
226 [I/O error: db3: open failed (...)
227 ovs-appctl: ovsdb-server: server returned an error
228 ])
229
230 # Add a remote through a db path in db1.
231 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote db:ordinals,ordinals,name], [0])
232 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
233 [0], [db:ordinals,ordinals,name
234 punix:db.sock
235 ])
236
237 # Removing db1 has no effect on its remote.
238 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db ordinals], [0])
239 CHECK_DBS([constraints
240 ])
241 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
242 [0], [db:ordinals,ordinals,name
243 punix:db.sock
244 ])
245 AT_CHECK([ovsdb-client list-tables unix:db.sock ordinals], [1], [ignore], [ignore])
246
247 # Remove db2.
248 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db constraints], [0])
249 CHECK_DBS()
250 AT_CHECK([ovsdb-client list-tables unix:db.sock constraints], [1], [ignore], [ignore])
251
252 # Remove a non-existent database.
253 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db ordinals], [2],
254 [], [Failed to find the database.
255 ovs-appctl: ovsdb-server: server returned an error
256 ])
257
258 # Add a removed database.
259 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
260 CHECK_DBS([constraints
261 ])
262 AT_CHECK([ovsdb-client list-tables unix:db.sock constraints], [0], [ignore], [ignore])
263
264 # Check the monitoring results.
265 AT_CHECK([uuidfilt db-change-aware.stdout], [0], [dnl
266 <0> initial _Server
267
268 <1> insert ordinals
269
270 <2> insert constraints
271
272 <1> delete ordinals
273
274 <2> delete constraints
275
276 <3> insert constraints
277 ])
278 AT_CHECK([uuidfilt db-change-unaware.stdout], [0], [dnl
279 <0> initial _Server
280 ])
281
282 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
283 AT_CLEANUP
284
285 AT_SETUP([ovsdb-server/add-db with --monitor])
286 AT_KEYWORDS([ovsdb server positive])
287 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
288
289 # This test intentionally causes SIGSEGV, so make Address Sanitizer ignore it.
290 ASAN_OPTIONS=$ASAN_OPTIONS:handle_segv=0; export ASAN_OPTIONS
291
292 # Start ovsdb-server, initially with one db.
293 ordinal_schema > schema
294 AT_CHECK([ovsdb-tool create db1 schema], [0], [ignore], [ignore])
295 on_exit 'kill `cat *.pid`'
296 AT_CHECK([ovsdb-server -vfile -vvlog:off --monitor --detach --no-chdir --pidfile --log-file --remote=punix:db.sock db1])
297
298 # Add the second database.
299 constraint_schema > schema2
300 AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
301 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db2], [0])
302 CHECK_DBS([constraints
303 ordinals
304 ])
305
306 # Kill the daemon process, making it look like a segfault,
307 # and wait for a new daemon process to get spawned.
308 cp ovsdb-server.pid old.pid
309 AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
310 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
311 OVS_WAIT_UNTIL(
312 [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
313 OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
314 CHECK_DBS([constraints
315 ordinals
316 ])
317 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
318 AT_CLEANUP
319
320 AT_SETUP([ovsdb-server/add-db and remove-db with --monitor])
321 AT_KEYWORDS([ovsdb server positive])
322 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
323
324 # This test intentionally causes SIGSEGV, so make Address Sanitizer ignore it.
325 ASAN_OPTIONS=$ASAN_OPTIONS:handle_segv=0; export ASAN_OPTIONS
326
327 # Start ovsdb-server, initially with one db.
328 ordinal_schema > schema
329 AT_CHECK([ovsdb-tool create db1 schema], [0], [ignore], [ignore])
330 constraint_schema > schema2
331 AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
332 on_exit 'kill `cat *.pid`'
333 AT_CHECK([ovsdb-server -vfile -vvlog:off --monitor --detach --no-chdir --pidfile --log-file --remote=punix:db.sock db1 db2])
334
335 # Remove the second database.
336 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-db constraints])
337 CHECK_DBS([ordinals
338 ])
339
340 # Kill the daemon process, making it look like a segfault,
341 # and wait for a new daemon process to get spawned.
342 cp ovsdb-server.pid old.pid
343 AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
344 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
345 OVS_WAIT_UNTIL(
346 [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
347 OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
348 CHECK_DBS([ordinals
349 ])
350 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
351 AT_CLEANUP
352
353 AT_SETUP([--remote=db: implementation])
354 AT_KEYWORDS([ovsdb server positive])
355 AT_DATA([schema],
356 [[{"name": "mydb",
357 "tables": {
358 "Root": {
359 "columns": {
360 "managers": {
361 "type": {
362 "key": "string",
363 "min": 0,
364 "max": "unlimited"}},
365 "manager_options": {
366 "type": {
367 "key": {"type": "uuid", "refTable": "Manager"},
368 "min": 0,
369 "max": "unlimited"}}}},
370 "Manager": {
371 "columns": {
372 "target": {
373 "type": "string"},
374 "is_connected": {
375 "type": {
376 "key": "boolean",
377 "min": 0,
378 "max": 1}}}}}}
379 ]])
380 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
381 AT_CHECK(
382 [[ovsdb-tool transact db \
383 '["mydb",
384 {"op": "insert",
385 "table": "Root",
386 "row": {
387 "managers": "punix:socket1",
388 "manager_options": ["set", [["named-uuid", "x"]]]}},
389 {"op": "insert",
390 "table": "Manager",
391 "uuid-name": "x",
392 "row": {"target": "punix:socket2"}}]']], [0], [ignore], [ignore])
393 on_exit 'kill `cat ovsdb-server.pid`'
394 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=db:mydb,Root,managers --remote=db:mydb,Root,manager_options --log-file db], [0], [ignore], [ignore])
395 ovs-appctl -t ovsdb-server time/warp 6000 1000
396 AT_CHECK(
397 [[ovsdb-client transact unix:socket1 \
398 '["mydb",
399 {"op": "select",
400 "table": "Root",
401 "where": [],
402 "columns": ["managers"]},
403 {"op": "select",
404 "table": "Manager",
405 "where": [],
406 "columns": ["target", "is_connected"]}]']],
407 [0], [stdout], [ignore])
408 AT_CHECK(
409 [uuidfilt stdout],
410 [0],
411 [[[{"rows":[{"managers":"punix:socket1"}]},{"rows":[{"is_connected":false,"target":"punix:socket2"}]}]
412 ]],
413 [ignore])
414 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
415 AT_CLEANUP
416
417 AT_SETUP([ovsdb-server/add-remote and remove-remote])
418 AT_KEYWORDS([ovsdb server positive])
419 ordinal_schema > schema
420 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
421 on_exit 'kill `cat *.pid`'
422 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile db])
423
424 AT_CHECK([test ! -e socket1])
425 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote punix:socket1])
426 if test "$IS_WIN32" = "yes"; then
427 OVS_WAIT_UNTIL([test -e socket1])
428 else
429 OVS_WAIT_UNTIL([test -S socket1])
430 fi
431 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
432 [0], [punix:socket1
433 ])
434
435 AT_CHECK([test ! -e socket2])
436 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote punix:socket2])
437 if test "$IS_WIN32" = "yes"; then
438 OVS_WAIT_UNTIL([test -e socket2])
439 else
440 OVS_WAIT_UNTIL([test -S socket2])
441 fi
442 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
443 [0], [punix:socket1
444 punix:socket2
445 ])
446
447 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote db:x,y,z], [2],
448 [], ["db:x,y,z": no database named x
449 ovs-appctl: ovsdb-server: server returned an error
450 ])
451
452 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-remote punix:socket1])
453 OVS_WAIT_UNTIL([test ! -e socket1])
454 if test "$IS_WIN32" = "yes"; then
455 AT_CHECK([test -e socket2])
456 else
457 AT_CHECK([test -S socket2])
458 fi
459 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
460 [0], [punix:socket2
461 ])
462
463 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-remote punix:socket2])
464 OVS_WAIT_UNTIL([test ! -e socket2])
465 AT_CHECK([test ! -e socket1])
466 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes])
467 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
468 AT_CLEANUP
469
470 AT_SETUP([ovsdb-server/add-remote with --monitor])
471 AT_KEYWORDS([ovsdb server positive])
472 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
473
474 # This test intentionally causes SIGSEGV, so make Address Sanitizer ignore it.
475 ASAN_OPTIONS=$ASAN_OPTIONS:handle_segv=0; export ASAN_OPTIONS
476
477 # Start ovsdb-server, initially with no remotes.
478 ordinal_schema > schema
479 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
480 on_exit 'kill `cat *.pid`'
481 AT_CHECK([ovsdb-server -vfile -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db])
482
483 # Add a remote.
484 AT_CHECK([test ! -e socket1])
485 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote punix:socket1])
486 OVS_WAIT_UNTIL([test -S socket1])
487 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
488 [0], [punix:socket1
489 ])
490
491 # Kill the daemon process, making it look like a segfault,
492 # and wait for a new daemon process to get spawned and for it to
493 # start listening on 'socket1'.
494 cp ovsdb-server.pid old.pid
495 rm socket1
496 AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
497 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
498 OVS_WAIT_UNTIL(
499 [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
500 OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
501 OVS_WAIT_UNTIL([test -S socket1])
502 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
503 AT_CLEANUP
504
505 AT_SETUP([ovsdb-server/add-remote and remove-remote with --monitor])
506 AT_KEYWORDS([ovsdb server positive])
507 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
508
509 # This test intentionally causes SIGSEGV, so make Address Sanitizer ignore it.
510 ASAN_OPTIONS=$ASAN_OPTIONS:handle_segv=0; export ASAN_OPTIONS
511
512 # Start ovsdb-server, initially with no remotes.
513 ordinal_schema > schema
514 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
515 on_exit 'kill `cat *.pid`'
516 AT_CHECK([ovsdb-server -vfile -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db])
517
518 # Add a remote.
519 AT_CHECK([test ! -e socket1])
520 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-remote punix:socket1])
521 OVS_WAIT_UNTIL([test -S socket1])
522 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes],
523 [0], [punix:socket1
524 ])
525
526 # Remove the remote.
527 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-remote punix:socket1])
528 OVS_WAIT_UNTIL([test ! -e socket1])
529 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes])
530
531 # Kill the daemon process, making it look like a segfault,
532 # and wait for a new daemon process to get spawned and make sure that it
533 # does not listen on 'socket1'.
534 cp ovsdb-server.pid old.pid
535 AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
536 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
537 OVS_WAIT_UNTIL(
538 [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
539 OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
540 AT_CHECK([test ! -e socket1])
541 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
542 AT_CLEANUP
543
544 AT_SETUP([SSL db: implementation])
545 AT_KEYWORDS([ovsdb server positive ssl $5])
546 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
547 # For this test, we pass PKIDIR through a ovsdb-tool transact and
548 # msys on Windows does not convert the path style automatically.
549 # So, do that forcefully with a 'pwd -W' (called through pwd() function).
550 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
551 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
552 \\]"])
553 AT_DATA([schema],
554 [[{"name": "mydb",
555 "tables": {
556 "SSL": {
557 "columns": {
558 "private_key": {"type": "string"},
559 "certificate": {"type": "string"},
560 "ca_cert": {"type": "string"},
561 "ssl_protocols" : {"type": "string"},
562 "ssl_ciphers" : {"type" : "string"}}}}}
563 ]])
564 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
565 # The !ECDHE-ECDSA-AES256-GCM-SHA384 in the ssl_ciphers is so that
566 # a cipher negotiation failure can be tested for later.
567 AT_CHECK(
568 [[ovsdb-tool transact db \
569 '["mydb",
570 {"op": "insert",
571 "table": "SSL",
572 "row": {"private_key": "'"$PKIDIR/testpki-privkey2.pem"'",
573 "certificate": "'"$PKIDIR/testpki-cert2.pem"'",
574 "ca_cert": "'"$PKIDIR/testpki-cacert.pem"'",
575 "ssl_protocols": "'"TLSv1.2,TLSv1.1"'",
576 "ssl_ciphers": "'"HIGH:!aNULL:!MD5:!ECDHE-ECDSA-AES256-GCM-SHA384"'"}}]']],
577 [0], [ignore], [ignore])
578 on_exit 'kill `cat *.pid`'
579 AT_CHECK(
580 [ovsdb-server --log-file --detach --no-chdir --pidfile \
581 --private-key=db:mydb,SSL,private_key \
582 --certificate=db:mydb,SSL,certificate \
583 --ca-cert=db:mydb,SSL,ca_cert \
584 --ssl-protocols=db:mydb,SSL,ssl_protocols \
585 --ssl-ciphers=db:mydb,SSL,ssl_ciphers \
586 --remote=pssl:0:127.0.0.1 db],
587 [0], [ignore], [ignore])
588 PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
589 AT_CHECK(
590 [[ovsdb-client \
591 --private-key=$PKIDIR/testpki-privkey.pem \
592 --certificate=$PKIDIR/testpki-cert.pem \
593 --ca-cert=$PKIDIR/testpki-cacert.pem \
594 --ssl-protocols=TLSv1.2,TLSv1.1 \
595 --ssl-ciphers=HIGH:!aNULL:!MD5 \
596 transact ssl:127.0.0.1:$SSL_PORT \
597 '["mydb",
598 {"op": "select",
599 "table": "SSL",
600 "where": [],
601 "columns": ["private_key"]}]']],
602 [0], [stdout], [ignore])
603 cat stdout >> output
604 AT_CHECK_UNQUOTED(
605 [cat output], [0],
606 [[@<:@{"rows":@<:@{"private_key":"$PKIDIR/testpki-privkey2.pem"}@:>@}@:>@
607 ]], [ignore])
608 # Check that when the server has TLSv1.1+ and the client has
609 # TLSv1 that the connection fails.
610 AT_CHECK(
611 [[ovsdb-client \
612 --private-key=$PKIDIR/testpki-privkey.pem \
613 --certificate=$PKIDIR/testpki-cert.pem \
614 --ca-cert=$PKIDIR/testpki-cacert.pem \
615 --ssl-protocols=TLSv1 \
616 --ssl-ciphers=HIGH:!aNULL:!MD5 \
617 transact ssl:127.0.0.1:$SSL_PORT \
618 '["mydb",
619 {"op": "select",
620 "table": "SSL",
621 "where": [],
622 "columns": ["private_key"]}]']],
623 [1], [stdout],
624 [stderr])
625 cat stderr > output
626 AT_CHECK_UNQUOTED(
627 [sed -n "/failed to connect/s/ (.*)//p" output], [0],
628 [ovsdb-client: failed to connect to "ssl:127.0.0.1:$SSL_PORT"
629 ],
630 [ignore])
631 # Check that when ciphers are not compatible, that a negotiation
632 # failure occurs.
633 AT_CHECK(
634 [[ovsdb-client \
635 --private-key=$PKIDIR/testpki-privkey.pem \
636 --certificate=$PKIDIR/testpki-cert.pem \
637 --ca-cert=$PKIDIR/testpki-cacert.pem \
638 --ssl-protocols=TLSv1.2,TLSv1.1 \
639 --ssl-ciphers=ECDHE-ECDSA-AES256-GCM-SHA384 \
640 transact ssl:127.0.0.1:$SSL_PORT \
641 '["mydb",
642 {"op": "select",
643 "table": "SSL",
644 "where": [],
645 "columns": ["private_key"]}]']],
646 [1], [stdout],
647 [stderr])
648 cat stderr > output
649 AT_CHECK_UNQUOTED(
650 [sed -n "/failed to connect/s/ (.*)//p" output], [0],
651 [ovsdb-client: failed to connect to "ssl:127.0.0.1:$SSL_PORT"
652 ],
653 [ignore])
654 # The error message for being unable to negotiate a shared ciphersuite
655 # is 'sslv3 alert handshake failure'. This is not the clearest message.
656 AT_CHECK_UNQUOTED(
657 [grep "sslv3 alert handshake failure" output], [0],
658 [stdout],
659 [ignore])
660 OVSDB_SERVER_SHUTDOWN
661 AT_CLEANUP
662 \f
663 OVS_START_SHELL_HELPERS
664 # ovsdb_check_online_compaction MODEL
665 #
666 # where MODEL is "standalone" or "cluster"
667 ovsdb_check_online_compaction() {
668 local model=$1
669
670 ordinal_schema > schema
671 dnl Make sure that "ovsdb-tool create" works with a dangling symlink for
672 dnl the database and the lockfile, creating the target of each symlink rather
673 dnl than replacing the symlinks with regular files.
674 mkdir dir
675 if test "$IS_WIN32" = "no"; then
676 ln -s dir/db db
677 ln -s dir/.db.~lock~ .db.~lock~
678 AT_SKIP_IF([test ! -h db || test ! -h .db.~lock~])
679 fi
680 AT_CHECK([if test $model = standalone; then
681 ovsdb-tool create db schema
682 else
683 ovsdb-tool create-cluster db schema unix:s1.raft
684 fi])
685 dnl Start ovsdb-server.
686 AT_CHECK([ovsdb-server -vvlog:off -vconsole:off --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0])
687 AT_CHECK([ovsdb_client_wait unix:socket ordinals connected])
688 AT_CAPTURE_FILE([ovsdb-server.log])
689 dnl Do a bunch of random transactions that put crap in the database log.
690 AT_CHECK(
691 [[for pair in 'zero 0' 'one 1' 'two 2' 'three 3' 'four 4' 'five 5'; do
692 set -- $pair
693 ovsdb-client transact unix:socket '
694 ["ordinals",
695 {"op": "insert",
696 "table": "ordinals",
697 "row": {"name": "'$1'", "number": '$2'}},
698 {"op": "comment",
699 "comment": "add row for '"$pair"'"}]'
700 ovsdb-client transact unix:socket '
701 ["ordinals",
702 {"op": "delete",
703 "table": "ordinals",
704 "where": [["number", "==", '$2']]},
705 {"op": "comment",
706 "comment": "delete row for '"$2"'"}]'
707 ovsdb-client transact unix:socket '
708 ["ordinals",
709 {"op": "insert",
710 "table": "ordinals",
711 "row": {"name": "'$1'", "number": '$2'}},
712 {"op": "comment",
713 "comment": "add back row for '"$pair"'"}]'
714 done]],
715 [0], [stdout])
716 if test $model = standalone; then
717 dnl Check that all the crap is in fact in the database log.
718 AT_CHECK([[uuidfilt db | grep -v ^OVSDB | sed 's/"_date":[0-9]*/"_date":0/' | ovstest test-json --multiple -]], [0],
719 [[{"cksum":"12345678 9","name":"ordinals","tables":{"ordinals":{"columns":{"name":{"type":"string"},"number":{"type":"integer"}},"indexes":[["number"]]}},"version":"5.1.3"}
720 {"_comment":"add row for zero 0","_date":0,"ordinals":{"<0>":{"name":"zero"}}}
721 {"_comment":"delete row for 0","_date":0,"ordinals":{"<0>":null}}
722 {"_comment":"add back row for zero 0","_date":0,"ordinals":{"<1>":{"name":"zero"}}}
723 {"_comment":"add row for one 1","_date":0,"ordinals":{"<2>":{"name":"one","number":1}}}
724 {"_comment":"delete row for 1","_date":0,"ordinals":{"<2>":null}}
725 {"_comment":"add back row for one 1","_date":0,"ordinals":{"<3>":{"name":"one","number":1}}}
726 {"_comment":"add row for two 2","_date":0,"ordinals":{"<4>":{"name":"two","number":2}}}
727 {"_comment":"delete row for 2","_date":0,"ordinals":{"<4>":null}}
728 {"_comment":"add back row for two 2","_date":0,"ordinals":{"<5>":{"name":"two","number":2}}}
729 {"_comment":"add row for three 3","_date":0,"ordinals":{"<6>":{"name":"three","number":3}}}
730 {"_comment":"delete row for 3","_date":0,"ordinals":{"<6>":null}}
731 {"_comment":"add back row for three 3","_date":0,"ordinals":{"<7>":{"name":"three","number":3}}}
732 {"_comment":"add row for four 4","_date":0,"ordinals":{"<8>":{"name":"four","number":4}}}
733 {"_comment":"delete row for 4","_date":0,"ordinals":{"<8>":null}}
734 {"_comment":"add back row for four 4","_date":0,"ordinals":{"<9>":{"name":"four","number":4}}}
735 {"_comment":"add row for five 5","_date":0,"ordinals":{"<10>":{"name":"five","number":5}}}
736 {"_comment":"delete row for 5","_date":0,"ordinals":{"<10>":null}}
737 {"_comment":"add back row for five 5","_date":0,"ordinals":{"<11>":{"name":"five","number":5}}}
738 ]])
739 else
740 dnl Check that at least there's a lot of transactions.
741 AT_CHECK([test `wc -l < db` -gt 50])
742 fi
743 dnl Dump out and check the actual database contents.
744 AT_CHECK([ovsdb-client dump unix:socket ordinals], [0], [stdout])
745 AT_CHECK([uuidfilt stdout], [0], [dnl
746 ordinals table
747 _uuid name number
748 ------------------------------------ ----- ------
749 <0> five 5
750 <1> four 4
751 <2> one 1
752 <3> three 3
753 <4> two 2
754 <5> zero 0
755 ])
756 cp db db.pre-compaction
757 dnl Now compact the database in-place.
758 AT_CHECK([[ovs-appctl -t ovsdb-server ovsdb-server/compact]],
759 [0], [], [ignore])
760 dnl Negative test.
761 AT_CHECK([[ovs-appctl -t ovsdb-server ovsdb-server/compact _Server]],
762 [2], [], [cannot compact built-in databases
763 ovs-appctl: ovsdb-server: server returned an error
764 ])
765 dnl Make sure that "db" is still a symlink to dir/db instead of getting
766 dnl replaced by a regular file, ditto for .db.~lock~.
767 if test "$IS_WIN32" = "no"; then
768 AT_CHECK([test -h db])
769 AT_CHECK([test -h .db.~lock~])
770 AT_CHECK([test -f dir/db])
771 AT_CHECK([test -f dir/.db.~lock~])
772 fi
773
774 # We can't fully re-check the contents of the database log, because the
775 # order of the records is not predictable, but there should only be 4 lines
776 # in it now in the standalone case
777 AT_CAPTURE_FILE([db])
778 compacted_lines=`wc -l < db`
779 echo compacted_lines=$compacted_lines
780 if test $model = standalone; then
781 AT_CHECK([test $compacted_lines -eq 4])
782 fi
783
784 dnl And check that the dumped data is the same too:
785 AT_CHECK([ovsdb-client dump unix:socket ordinals], [0], [stdout])
786 AT_CHECK([uuidfilt stdout], [0], [dnl
787 ordinals table
788 _uuid name number
789 ------------------------------------ ----- ------
790 <0> five 5
791 <1> four 4
792 <2> one 1
793 <3> three 3
794 <4> two 2
795 <5> zero 0
796 ])
797 dnl Now do some more transactions.
798 AT_CHECK(
799 [[ovsdb-client transact unix:socket '
800 ["ordinals",
801 {"op": "delete",
802 "table": "ordinals",
803 "where": [["number", "<", 3]]}]']],
804 [0], [[[{"count":3}]
805 ]], [ignore])
806
807 dnl There should be 6 lines in the log now, for the standalone case,
808 dnl and for the clustered case the file should at least have grown.
809 updated_lines=`wc -l < db`
810 echo compacted_lines=$compacted_lines updated_lines=$updated_lines
811 if test $model = standalone; then
812 AT_CHECK([test $updated_lines -eq 6])
813 else
814 AT_CHECK([test $updated_lines -gt $compacted_lines])
815 fi
816
817 dnl Then check that the dumped data is correct. This time first kill
818 dnl and restart the database server to ensure that the data is correct on
819 dnl disk as well as in memory.
820 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
821 AT_CHECK([ovsdb-server -vvlog:off -vconsole:off --detach --no-chdir --pidfile --remote=punix:socket --log-file db])
822 AT_CHECK([ovsdb-client dump unix:socket ordinals], [0], [stdout])
823 AT_CHECK([uuidfilt stdout], [0], [dnl
824 ordinals table
825 _uuid name number
826 ------------------------------------ ----- ------
827 <0> five 5
828 <1> four 4
829 <2> three 3
830 ], [], [test ! -e pid || kill `cat pid`])
831 OVSDB_SERVER_SHUTDOWN
832 }
833 OVS_END_SHELL_HELPERS
834
835 AT_SETUP([compacting online - standalone])
836 AT_KEYWORDS([ovsdb server compact])
837 ovsdb_check_online_compaction standalone
838 AT_CLEANUP
839
840 AT_SETUP([compacting online - cluster])
841 AT_KEYWORDS([ovsdb server compact])
842 ovsdb_check_online_compaction cluster
843 AT_CLEANUP
844 \f
845 OVS_START_SHELL_HELPERS
846 # ovsdb_check_online_conversion MODEL
847 #
848 # where MODEL is "standalone" or "cluster"
849 ovsdb_check_online_conversion() {
850 local model=$1
851 on_exit 'kill `cat *.pid`'
852 ordinal_schema > schema
853 AT_DATA([new-schema],
854 [[{"name": "ordinals",
855 "tables": {
856 "ordinals": {
857 "columns": {
858 "number": {"type": "integer"}}}}}
859 ]])
860 dnl Make sure that "ovsdb-tool create" works with a dangling symlink for
861 dnl the database and the lockfile, creating the target of each symlink
862 dnl rather than replacing the symlinks with regular files.
863 mkdir dir
864 if test "$IS_WIN32" = "no"; then
865 ln -s dir/db db
866 ln -s dir/.db.~lock~ .db.~lock~
867 AT_SKIP_IF([test ! -h db || test ! -h .db.~lock~])
868 fi
869 AT_CHECK([if test $model = standalone; then
870 ovsdb-tool create db schema
871 else
872 ovsdb-tool create-cluster db schema unix:s1.raft
873 fi])
874
875 dnl Start the database server.
876 AT_CHECK([ovsdb-server -vfile -vvlog:off -vconsole:off --detach --no-chdir --pidfile --log-file --remote=punix:db.sock db], [0])
877 AT_CAPTURE_FILE([ovsdb-server.log])
878
879 dnl Put some data in the database.
880 AT_CHECK(
881 [[for pair in 'zero 0' 'one 1' 'two 2' 'three 3' 'four 4' 'five 5'; do
882 set -- $pair
883 ovsdb-client transact '
884 ["ordinals",
885 {"op": "insert",
886 "table": "ordinals",
887 "row": {"name": "'$1'", "number": '$2'}},
888 {"op": "comment",
889 "comment": "add row for '"$pair"'"}]'
890 done | uuidfilt]], [0],
891 [[[{"uuid":["uuid","<0>"]},{}]
892 [{"uuid":["uuid","<1>"]},{}]
893 [{"uuid":["uuid","<2>"]},{}]
894 [{"uuid":["uuid","<3>"]},{}]
895 [{"uuid":["uuid","<4>"]},{}]
896 [{"uuid":["uuid","<5>"]},{}]
897 ]], [ignore])
898
899 dnl Try "needs-conversion".
900 AT_CHECK([ovsdb-client needs-conversion schema], [0], [no
901 ])
902 AT_CHECK([ovsdb-client needs-conversion new-schema], [0], [yes
903 ])
904
905 dnl Start two monitors on the 'ordinals' db, one that is database
906 dnl change aware and one that is not.
907 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=monitor-ordinals-aware.pid --log-file=monitor-ordinals-aware.log --db-change-aware --no-headings monitor ordinals ordinals number name > monitor-ordinals-aware.stdout 2> monitor-ordinals-aware.stderr])
908 AT_CAPTURE_FILE([monitor-ordinals-aware.stdout])
909 AT_CAPTURE_FILE([monitor-ordinals-aware.log])
910 AT_CAPTURE_FILE([monitor-ordinals-aware.stderr])
911
912 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=monitor-ordinals-unaware.pid --log-file=monitor-ordinals-unaware.log --no-db-change-aware --no-headings monitor ordinals ordinals number name > monitor-ordinals-unaware.stdout 2> monitor-ordinals-unaware.stderr])
913 AT_CAPTURE_FILE([monitor-ordinals-unaware.stdout])
914 AT_CAPTURE_FILE([monitor-ordinals-unaware.log])
915 AT_CAPTURE_FILE([monitor-ordinals-unaware.stderr])
916
917 dnl Start two monitors on the '_Server' db, one that is database
918 dnl change aware and one that is not.
919 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=monitor-server-aware.pid --log-file=monitor-server-aware.log --db-change-aware --no-headings monitor _Server Database name > monitor-server-aware.stdout 2> monitor-server-aware.stderr])
920 AT_CAPTURE_FILE([monitor-server-aware.stdout])
921 AT_CAPTURE_FILE([monitor-server-aware.log])
922 AT_CAPTURE_FILE([monitor-server-aware.stderr])
923
924 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=monitor-server-unaware.pid --log-file=monitor-server-unaware.log --no-db-change-aware --no-headings monitor _Server Database name > monitor-server-unaware.stdout 2> monitor-server-unaware.stderr])
925 AT_CAPTURE_FILE([monitor-server-unaware.stdout])
926 AT_CAPTURE_FILE([monitor-server-unaware.log])
927 AT_CAPTURE_FILE([monitor-server-unaware.stderr])
928
929 dnl Start two long-running transactions (triggers) on the 'ordinals' db,
930 dnl one that is database change aware and one that is not.
931 ordinals_txn='[["ordinals",
932 {"op": "wait",
933 "table": "ordinals",
934 "where": [["name", "==", "seven"]],
935 "columns": ["name", "number"],
936 "rows": [],
937 "until": "!="}]]'
938 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=trigger-ordinals-aware.pid --log-file=trigger-ordinals-aware.log --db-change-aware transact "$ordinals_txn" > trigger-ordinals-aware.stdout 2> trigger-ordinals-aware.stderr])
939 AT_CAPTURE_FILE([trigger-ordinals-aware.stdout])
940 AT_CAPTURE_FILE([trigger-ordinals-aware.log])
941 AT_CAPTURE_FILE([trigger-ordinals-aware.stderr])
942
943 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=trigger-ordinals-unaware.pid --log-file=trigger-ordinals-unaware.log --no-db-change-aware transact "$ordinals_txn" > trigger-ordinals-unaware.stdout 2> trigger-ordinals-unaware.stderr])
944 AT_CAPTURE_FILE([trigger-ordinals-unaware.stdout])
945 AT_CAPTURE_FILE([trigger-ordinals-unaware.log])
946 AT_CAPTURE_FILE([trigger-ordinals-unaware.stderr])
947
948 dnl Start two long-running transactions (triggers) on the _Server db,
949 dnl one that is database change aware and one that is not.
950 server_txn='[["_Server",
951 {"op": "wait",
952 "table": "Database",
953 "where": [["name", "==", "xyzzy"]],
954 "columns": ["name"],
955 "rows": [],
956 "until": "!="}]]'
957 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=trigger-server-aware.pid --log-file=trigger-server-aware.log --db-change-aware transact "$server_txn" > trigger-server-aware.stdout 2> trigger-server-aware.stderr])
958 AT_CAPTURE_FILE([trigger-server-aware.stdout])
959 AT_CAPTURE_FILE([trigger-server-aware.log])
960 AT_CAPTURE_FILE([trigger-server-aware.stderr])
961
962 AT_CHECK([ovsdb-client -vfile -vvlog:off --detach --no-chdir --pidfile=trigger-server-unaware.pid --log-file=trigger-server-unaware.log --no-db-change-aware transact "$server_txn" > trigger-server-unaware.stdout 2> trigger-server-unaware.stderr])
963 AT_CAPTURE_FILE([trigger-server-unaware.stdout])
964 AT_CAPTURE_FILE([trigger-server-unaware.log])
965 AT_CAPTURE_FILE([trigger-server-unaware.stderr])
966
967 dnl Dump out and check the actual database contents.
968 AT_CHECK([ovsdb-client dump unix:db.sock ordinals], [0], [stdout])
969 AT_CHECK([uuidfilt stdout], [0], [dnl
970 ordinals table
971 _uuid name number
972 ------------------------------------ ----- ------
973 <0> five 5
974 <1> four 4
975 <2> one 1
976 <3> three 3
977 <4> two 2
978 <5> zero 0
979 ])
980
981 dnl Convert the database.
982 AT_CHECK([ovsdb-client convert new-schema])
983
984 dnl Try "needs-conversion".
985 AT_CHECK([ovsdb-client needs-conversion schema], [0], [yes
986 ])
987 AT_CHECK([ovsdb-client needs-conversion new-schema], [0], [no
988 ])
989
990 dnl Verify that the "ordinals" monitors behaved as they should have.
991 dnl Both should have exited, for different reasons.
992 for x in aware unaware; do
993 echo $x
994 OVS_WAIT_WHILE([test -e monitor-ordinals-$x.pid])
995 AT_CHECK([sort -k 3 monitor-ordinals-$x.stdout | uuidfilt], [0],
996 [<0> initial 0 zero
997 <1> initial 1 one
998 <2> initial 2 two
999 <3> initial 3 three
1000 <4> initial 4 four
1001 <5> initial 5 five
1002 ])
1003 done
1004 AT_CHECK([sed 's/.*: //' monitor-ordinals-unaware.stderr], [0], [receive failed (End of file)
1005 ])
1006 AT_CHECK([sed 's/.*: //' monitor-ordinals-aware.stderr], [0], [ordinals database was removed
1007 ])
1008
1009 dnl Verify that the _Server monitors behaved as they should have.
1010 dnl The db-aware monitor should still be running, but not the unaware one.
1011 for x in aware unaware; do
1012 AT_CHECK([sort -k 3 monitor-server-$x.stdout | uuidfilt], [0],
1013 [<0> initial _Server
1014 <1> initial ordinals
1015 ])
1016 done
1017 OVS_WAIT_WHILE([test -e monitor-server-unaware.pid])
1018 AT_CHECK([sed 's/.*: //' monitor-ordinals-unaware.stderr], [0], [receive failed (End of file)
1019 ])
1020 AT_CHECK([test -e monitor-server-aware.pid])
1021
1022 dnl Verify that the "ordinals" triggers behaved as they should have:
1023 dnl Both should have exited, for different reasons.
1024 for x in unaware aware; do
1025 OVS_WAIT_WHILE([test -e trigger-ordinals-$x.pid])
1026 AT_CHECK([cat trigger-ordinals-$x.stdout])
1027 done
1028 AT_CHECK([cat trigger-ordinals-unaware.stderr], [0], [ovsdb-client: transaction failed (End of file)
1029 ])
1030 AT_CHECK([cat trigger-ordinals-aware.stderr], [0], [ovsdb-client: transaction returned error: "canceled"
1031 ])
1032
1033 dnl Verify that the _Server triggers behaved as they should have:
1034 dnl The db-aware trigger should still be waiting, but not the unaware one.
1035 for x in aware unaware; do
1036 AT_CHECK([cat trigger-server-$x.stdout])
1037 done
1038 OVS_WAIT_WHILE([test -e trigger-server-unaware.pid])
1039 AT_CHECK([sed 's/.*: //' trigger-ordinals-unaware.stderr], [0], [transaction failed (End of file)
1040 ])
1041 AT_CHECK([test -e trigger-server-aware.pid])
1042
1043 AT_CAPTURE_FILE([db])
1044 if test $model = standalone; then
1045 dnl We can't fully re-check the contents of the database log, because the
1046 dnl order of the records is not predictable, but there should only be 4 lines
1047 dnl in it now.
1048 AT_CHECK([test `wc -l < db` -eq 4])
1049 fi
1050 dnl Check that the dumped data is the same except for the removed column:
1051 AT_CHECK([ovsdb-client dump unix:db.sock ordinals | uuidfilt], [0], [dnl
1052 ordinals table
1053 _uuid number
1054 ------------------------------------ ------
1055 <0> 0
1056 <1> 1
1057 <2> 2
1058 <3> 3
1059 <4> 4
1060 <5> 5
1061 ])
1062 dnl Now check that the converted database is still online and can be modified,
1063 dnl then check that the database log has one more record and that the data
1064 dnl is as expected.
1065 AT_CHECK(
1066 [[ovsdb-client transact '
1067 ["ordinals",
1068 {"op": "insert",
1069 "table": "ordinals",
1070 "row": {"number": 6}},
1071 {"op": "comment",
1072 "comment": "add row for 6"}]' | uuidfilt]], [0],
1073 [[[{"uuid":["uuid","<0>"]},{}]
1074 ]])
1075 if test $model = standalone; then
1076 AT_CHECK([test `wc -l < db` -eq 6])
1077 fi
1078 AT_CHECK([ovsdb-client dump unix:db.sock ordinals | uuidfilt], [0], [dnl
1079 ordinals table
1080 _uuid number
1081 ------------------------------------ ------
1082 <0> 0
1083 <1> 1
1084 <2> 2
1085 <3> 3
1086 <4> 4
1087 <5> 5
1088 <6> 6
1089 ])
1090 dnl Now kill and restart the database server to ensure that the data is
1091 dnl correct on disk as well as in memory.
1092 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1093 AT_CHECK([[ovsdb-server -vfile -vvlog:off -vconsole:off --detach --no-chdir --pidfile --log-file --remote=punix:db.sock db]],
1094 [0])
1095 AT_CHECK([ovsdb-client dump unix:db.sock ordinals | uuidfilt], [0], [dnl
1096 ordinals table
1097 _uuid number
1098 ------------------------------------ ------
1099 <0> 0
1100 <1> 1
1101 <2> 2
1102 <3> 3
1103 <4> 4
1104 <5> 5
1105 <6> 6
1106 ])
1107
1108 dnl Make sure that "db" is still a symlink to dir/db instead of getting
1109 dnl replaced by a regular file, ditto for .db.~lock~.
1110 if test "$IS_WIN32" = "no"; then
1111 AT_CHECK([test -h db])
1112 AT_CHECK([test -h .db.~lock~])
1113 AT_CHECK([test -f dir/db])
1114 AT_CHECK([test -f dir/.db.~lock~])
1115 fi
1116
1117 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1118 }
1119 OVS_END_SHELL_HELPERS
1120
1121 AT_SETUP([schema conversion online - standalone])
1122 AT_KEYWORDS([ovsdb server convert needs-conversion standalone])
1123 ovsdb_check_online_conversion standalone
1124 AT_CLEANUP
1125
1126 AT_SETUP([schema conversion online - clustered])
1127 AT_KEYWORDS([ovsdb server convert needs-conversion cluster])
1128 ovsdb_check_online_conversion cluster
1129 AT_CLEANUP
1130 \f
1131 AT_SETUP([ovsdb-server combines updates on backlogged connections])
1132 on_exit 'kill `cat *.pid`'
1133
1134 # The maximum socket receive buffer size is important for this test, which
1135 # tests behavior when the receive buffer overflows.
1136 if test -e /proc/sys/net/core/rmem_max; then
1137 # Linux
1138 rmem_max=`cat /proc/sys/net/core/rmem_max`
1139 elif rmem_max=`sysctl -n net.inet.tcp.recvbuf_max 2>/dev/null`; then
1140 : # FreeBSD, NetBSD
1141 else
1142 # Don't know how to get maximum socket receive buffer on this OS
1143 AT_SKIP_IF([:])
1144 fi
1145
1146 # Calculate the number of iterations we need to queue. Each of the
1147 # iterations we execute, by itself, yields a monitor update of about
1148 # 25 kB, so fill up that much space plus a few for luck.
1149 n_iterations=`expr $rmem_max / 25000 + 5`
1150 echo rmem_max=$rmem_max n_iterations=$n_iterations
1151
1152 # If there's too much queuing skip the test to avoid timing out.
1153 AT_SKIP_IF([test $rmem_max -gt 1048576])
1154
1155 # Calculate the exact number of monitor updates expected for $n_iterations,
1156 # assuming no updates are combined. The "extra" update is for the initial
1157 # contents of the database.
1158 n_updates=`expr $n_iterations \* 3 + 1`
1159
1160 # Start an ovsdb-server with the vswitchd schema.
1161 OVSDB_INIT([db])
1162 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --log-file --remote=punix:db.sock db],
1163 [0], [ignore], [ignore])
1164
1165 # Executes a set of transactions that add a bridge with 100 ports, and
1166 # then deletes that bridge. This yields three monitor updates that
1167 # add up to about 25 kB in size.
1168 #
1169 # The update also increments a counter held in the database so that we can
1170 # verify that the overall effect of the transactions took effect (e.g.
1171 # monitor updates at the end weren't just dropped). We add an arbitrary
1172 # string to the counter to make grepping for it more reliable.
1173 counter=0
1174 trigger_big_update () {
1175 counter=`expr $counter + 1`
1176 ovs-vsctl --no-wait -- set open_vswitch . system_version=xyzzy$counter
1177 ovs-vsctl --no-wait -- add-br br0 $add
1178 ovs-vsctl --no-wait -- del-br br0
1179 }
1180 add_ports () {
1181 for j in `seq 1 100`; do
1182 printf " -- add-port br0 p%d" $j
1183 done
1184 }
1185 add=`add_ports`
1186
1187 AT_CAPTURE_FILE([ovsdb-client.err])
1188 AT_CAPTURE_FILE([ovsdb-client-nonblock.err])
1189
1190
1191 # Start an ovsdb-client monitoring all changes to the database,
1192 # By default, it is non-blocking, and will get update message
1193 # for each ovsdb-server transaactions.
1194 AT_CHECK([ovsdb-client --detach --no-chdir --pidfile=nonblock.pid monitor ALL >ovsdb-client-nonblock.out 2>ovsdb-client-nonblock.err])
1195
1196 # Start an ovsdb-client monitoring all changes to the database,
1197 # make it block to force the buffers to fill up, and then execute
1198 # enough iterations that ovsdb-server starts combining updates.
1199 AT_CHECK([ovsdb-client --detach --no-chdir --pidfile monitor ALL >ovsdb-client.out 2>ovsdb-client.err])
1200 AT_CHECK([ovs-appctl -t ovsdb-client ovsdb-client/block])
1201 for i in `seq 1 $n_iterations`; do
1202 echo "blocked update ($i of $n_iterations)"
1203 trigger_big_update $i
1204 done
1205 AT_CHECK([ovs-appctl -t ovsdb-client ovsdb-client/unblock])
1206 OVS_WAIT_UNTIL([grep "xyzzy$counter" ovsdb-client.out])
1207 OVS_WAIT_UNTIL([grep "xyzzy$counter" ovsdb-client-nonblock.out])
1208 OVS_APP_EXIT_AND_WAIT([ovsdb-client])
1209 AT_CHECK([kill `cat nonblock.pid`])
1210
1211 # Count the number of updates in the ovsdb-client output, by counting
1212 # the number of changes to the Open_vSwitch table. (All of our
1213 # transactions modify the Open_vSwitch table.) It should be less than
1214 # $n_updates updates.
1215 #
1216 # Check that the counter is what we expect.
1217 logged_updates=`grep -c '^Open_vSwitch' ovsdb-client.out`
1218 logged_nonblock_updates=`grep -c '^Open_vSwitch' ovsdb-client-nonblock.out`
1219 echo "logged_nonblock_updates=$logged_nonblock_updates (expected less or equal to $n_updates)"
1220 echo "logged_updates=$logged_updates (expected less than $logged_nonblock_updates)"
1221 AT_CHECK([test $logged_nonblock_updates -le $n_updates])
1222 AT_CHECK([test $logged_updates -lt $logged_nonblock_updates])
1223 AT_CHECK_UNQUOTED([ovs-vsctl get open_vswitch . system_version], [0],
1224 [xyzzy$counter
1225 ])
1226 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1227 AT_CLEANUP
1228 \f
1229 AT_BANNER([OVSDB -- ovsdb-server transactions (SSL IPv4 sockets)])
1230
1231 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
1232 #
1233 # Creates a database with the given SCHEMA, starts an ovsdb-server on
1234 # that database, and runs each of the TRANSACTIONS (which should be a
1235 # quoted list of quoted strings) against it with ovsdb-client one at a
1236 # time.
1237 #
1238 # Checks that the overall output is OUTPUT, but UUIDs in the output
1239 # are replaced by markers of the form <N> where N is a number. The
1240 # first unique UUID is replaced by <0>, the next by <1>, and so on.
1241 # If a given UUID appears more than once it is always replaced by the
1242 # same marker.
1243 #
1244 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
1245 m4_define([OVSDB_CHECK_EXECUTION],
1246 [AT_SETUP([$1])
1247 AT_KEYWORDS([ovsdb server positive ssl $5])
1248 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
1249 $2 > schema
1250 PKIDIR=$abs_top_builddir/tests
1251 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
1252 AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --private-key=$PKIDIR/testpki-privkey2.pem --certificate=$PKIDIR/testpki-cert2.pem --ca-cert=$PKIDIR/testpki-cacert.pem --remote=pssl:0:127.0.0.1 db], [0], [ignore], [ignore])
1253 PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
1254 m4_foreach([txn], [$3],
1255 [AT_CHECK([ovsdb-client --private-key=$PKIDIR/testpki-privkey.pem --certificate=$PKIDIR/testpki-cert.pem --ca-cert=$PKIDIR/testpki-cacert.pem transact ssl:127.0.0.1:$SSL_PORT 'txn'], [0], [stdout], [ignore],
1256 [test ! -e pid || kill `cat pid`])
1257 cat stdout >> output
1258 ])
1259 AT_CHECK([uuidfilt output], [0], [$4], [ignore],
1260 [test ! -e pid || kill `cat pid`])
1261 OVSDB_SERVER_SHUTDOWN
1262 AT_CLEANUP])
1263
1264 EXECUTION_EXAMPLES
1265
1266 AT_BANNER([OVSDB -- ovsdb-server transactions (SSL IPv6 sockets)])
1267
1268 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
1269 #
1270 # Creates a database with the given SCHEMA, starts an ovsdb-server on
1271 # that database, and runs each of the TRANSACTIONS (which should be a
1272 # quoted list of quoted strings) against it with ovsdb-client one at a
1273 # time.
1274 #
1275 # Checks that the overall output is OUTPUT, but UUIDs in the output
1276 # are replaced by markers of the form <N> where N is a number. The
1277 # first unique UUID is replaced by <0>, the next by <1>, and so on.
1278 # If a given UUID appears more than once it is always replaced by the
1279 # same marker.
1280 #
1281 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
1282 m4_define([OVSDB_CHECK_EXECUTION],
1283 [AT_SETUP([$1])
1284 AT_KEYWORDS([ovsdb server positive ssl6 $5])
1285 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
1286 AT_SKIP_IF([test $HAVE_IPV6 = no])
1287 $2 > schema
1288 PKIDIR=$abs_top_builddir/tests
1289 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
1290 AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --private-key=$PKIDIR/testpki-privkey2.pem --certificate=$PKIDIR/testpki-cert2.pem --ca-cert=$PKIDIR/testpki-cacert.pem --remote=pssl:0:[[::1]] db], [0], [ignore], [ignore])
1291 PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
1292 m4_foreach([txn], [$3],
1293 [AT_CHECK([ovsdb-client --private-key=$PKIDIR/testpki-privkey.pem --certificate=$PKIDIR/testpki-cert.pem --ca-cert=$PKIDIR/testpki-cacert.pem transact ssl:[[::1]]:$SSL_PORT 'txn'], [0], [stdout], [ignore],
1294 [test ! -e pid || kill `cat pid`])
1295 cat stdout >> output
1296 ])
1297 AT_CHECK([uuidfilt output], [0], [$4], [ignore],
1298 [test ! -e pid || kill `cat pid`])
1299 OVSDB_SERVER_SHUTDOWN
1300 AT_CLEANUP])
1301
1302 ONE_EXECUTION_EXAMPLE
1303
1304 AT_BANNER([OVSDB -- ovsdb-server transactions (TCP IPv4 sockets)])
1305
1306 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
1307 #
1308 # Creates a database with the given SCHEMA, starts an ovsdb-server on
1309 # that database, and runs each of the TRANSACTIONS (which should be a
1310 # quoted list of quoted strings) against it with ovsdb-client one at a
1311 # time.
1312 #
1313 # Checks that the overall output is OUTPUT, but UUIDs in the output
1314 # are replaced by markers of the form <N> where N is a number. The
1315 # first unique UUID is replaced by <0>, the next by <1>, and so on.
1316 # If a given UUID appears more than once it is always replaced by the
1317 # same marker.
1318 #
1319 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
1320 m4_define([OVSDB_CHECK_EXECUTION],
1321 [AT_SETUP([$1])
1322 AT_KEYWORDS([ovsdb server positive tcp $5])
1323 $2 > schema
1324 PKIDIR=$abs_top_builddir/tests
1325 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
1326 AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --remote=ptcp:0:127.0.0.1 db], [0], [ignore], [ignore])
1327 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
1328 m4_foreach([txn], [$3],
1329 [AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT 'txn'], [0], [stdout], [ignore],
1330 [test ! -e pid || kill `cat pid`])
1331 cat stdout >> output
1332 ])
1333 AT_CHECK([uuidfilt output], [0], [$4], [ignore],
1334 [test ! -e pid || kill `cat pid`])
1335 OVSDB_SERVER_SHUTDOWN
1336 AT_CLEANUP])
1337
1338 EXECUTION_EXAMPLES
1339
1340 AT_BANNER([OVSDB -- ovsdb-server transactions (TCP IPv6 sockets)])
1341
1342 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
1343 #
1344 # Creates a database with the given SCHEMA, starts an ovsdb-server on
1345 # that database, and runs each of the TRANSACTIONS (which should be a
1346 # quoted list of quoted strings) against it with ovsdb-client one at a
1347 # time.
1348 #
1349 # Checks that the overall output is OUTPUT, but UUIDs in the output
1350 # are replaced by markers of the form <N> where N is a number. The
1351 # first unique UUID is replaced by <0>, the next by <1>, and so on.
1352 # If a given UUID appears more than once it is always replaced by the
1353 # same marker.
1354 #
1355 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
1356 m4_define([OVSDB_CHECK_EXECUTION],
1357 [AT_SETUP([$1])
1358 AT_KEYWORDS([ovsdb server positive tcp6 $5])
1359 AT_SKIP_IF([test $HAVE_IPV6 = no])
1360 $2 > schema
1361 PKIDIR=$abs_top_builddir/tests
1362 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
1363 AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --remote=ptcp:0:[[::1]] db], [0], [ignore], [ignore])
1364 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
1365 m4_foreach([txn], [$3],
1366 [AT_CHECK([ovsdb-client transact tcp:[[::1]]:$TCP_PORT 'txn'], [0], [stdout], [ignore],
1367 [test ! -e pid || kill `cat pid`])
1368 cat stdout >> output
1369 ])
1370 AT_CHECK([uuidfilt output], [0], [$4], [ignore],
1371 [test ! -e pid || kill `cat pid`])
1372 OVSDB_SERVER_SHUTDOWN
1373 AT_CLEANUP])
1374
1375 ONE_EXECUTION_EXAMPLE
1376 \f
1377 AT_BANNER([OVSDB -- transactions on transient ovsdb-server])
1378
1379 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
1380 #
1381 # Creates a database with the given SCHEMA and runs each of the
1382 # TRANSACTIONS (which should be a quoted list of quoted strings)
1383 # against it with ovsdb-client one at a time. Each ovsdb-client
1384 # is run against a separately started ovsdb-server that executes
1385 # only that single transaction. (The idea is that this should
1386 # help to ferret out any differences between what ovsdb-server has
1387 # in memory and what actually gets committed to disk.)
1388 #
1389 # Checks that the overall output is OUTPUT, but UUIDs in the output
1390 # are replaced by markers of the form <N> where N is a number. The
1391 # first unique UUID is replaced by <0>, the next by <1>, and so on.
1392 # If a given UUID appears more than once it is always replaced by the
1393 # same marker.
1394 #
1395 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
1396 m4_define([OVSDB_CHECK_EXECUTION],
1397 [AT_SETUP([$1])
1398 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
1399 AT_KEYWORDS([ovsdb server positive transient $5])
1400 $2 > schema
1401 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
1402 m4_foreach([txn], [$3],
1403 [AT_DATA([txnfile], [ovsdb-client transact unix:socket 'txn'
1404 ])
1405 AT_CHECK([ovsdb-server --remote=punix:socket db --run="sh txnfile"], [0], [stdout], [ignore])
1406 cat stdout >> output
1407 ])
1408 AT_CHECK([uuidfilt output], [0], [$4], [ignore])
1409 AT_CLEANUP])
1410
1411 EXECUTION_EXAMPLES
1412 \f
1413 AT_BANNER([OVSDB -- ovsdb-server replication])
1414
1415 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
1416 #
1417 # Creates two databases with the given SCHEMA, and starts an ovsdb-server on
1418 # each database.
1419 # Runs each of the TRANSACTIONS (which should be a quoted list of
1420 # quoted strings) against one of the servers with ovsdb-client one at a
1421 # time. The server replicates its database to the other ovsdb-server.
1422 #
1423 # Checks that the dump of both databases are the same.
1424 #
1425 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
1426 m4_define([OVSDB_CHECK_EXECUTION],
1427 [AT_SETUP([$1])
1428 AT_KEYWORDS([ovsdb server tcp replication $5])
1429 $2 > schema
1430 AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
1431 AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
1432
1433 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
1434 i
1435 on_exit 'test ! -e pid || kill `cat pid`'
1436
1437 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile=pid2 --remote=punix:db2.sock --unixctl=unixctl2 --sync-from=unix:db.sock db2], [0], [ignore], [ignore])
1438 on_exit 'test ! -e pid2 || kill `cat pid2`'
1439
1440 m4_foreach([txn], [$3],
1441 [AT_CHECK([ovsdb-client transact 'txn'], [0], [stdout], [ignore])
1442 ])
1443
1444 AT_CHECK([ovsdb-client dump], [0], [stdout], [ignore])
1445 OVS_WAIT_UNTIL([ ovsdb-client dump unix:db2.sock > dump2; diff stdout dump2])
1446
1447 OVSDB_SERVER_SHUTDOWN
1448 OVSDB_SERVER_SHUTDOWN2
1449 AT_CLEANUP])
1450
1451 EXECUTION_EXAMPLES
1452
1453 AT_BANNER([OVSDB -- ovsdb-server replication table-exclusion])
1454
1455 # OVSDB_CHECK_REPLICATION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
1456 #
1457 # Creates two databases with the given SCHEMA, and starts an
1458 # ovsdb-server on each database.
1459 # Runs each of the TRANSACTIONS (which should be a quoted list of
1460 # quoted strings) against one of the servers with ovsdb-client one at a
1461 # time. The server replicates its database to the other ovsdb-server.
1462 #
1463 # Checks that the difference between the dump of the databases is
1464 # OUTPUT, but UUIDs in the output are replaced by markers of the form
1465 # <N> where N is a number. The first unique UUID is replaced by <0>,
1466 # the next by <1>, and so on.
1467 # If a given UUID appears more than once it is always replaced by the
1468 # same marker.
1469 #
1470 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
1471 m4_define([OVSDB_CHECK_REPLICATION],
1472 [AT_SETUP([$1])
1473 AT_KEYWORDS([ovsdb server tcp replication table-exclusion])
1474 AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no])
1475 $2 > schema
1476 AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
1477 AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
1478
1479 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
1480 on_exit 'test ! -e pid || kill `cat pid`'
1481
1482 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile=pid2 --remote=punix:db2.sock --unixctl=unixctl2 --sync-from=unix:db.sock --sync-exclude-tables=mydb:b db2], [0], [ignore], [ignore])
1483 on_exit 'test ! -e pid2 || kill `cat pid2`'
1484
1485 m4_foreach([txn], [$3],
1486 [AT_CHECK([ ovsdb-client transact 'txn' ], [0], [stdout], [ignore])
1487 ])
1488
1489 AT_CHECK([ovsdb-client dump], [0], [stdout], [ignore])
1490 cat stdout > dump1
1491
1492 OVS_WAIT_UNTIL([ ovsdb-client dump unix:db2.sock | grep one ])
1493 AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout], [ignore])
1494 cat stdout > dump2
1495
1496 AT_CHECK([diff dump1 dump2], [1], [stdout], [ignore])
1497 cat stdout > output
1498
1499 AT_CHECK([uuidfilt output], [0], [$4], [ignore])
1500
1501 OVSDB_SERVER_SHUTDOWN
1502 OVSDB_SERVER_SHUTDOWN2
1503 AT_CLEANUP])
1504
1505 REPLICATION_EXAMPLES
1506
1507 AT_BANNER([OVSDB -- ovsdb-server replication runtime management commands])
1508
1509 #ovsdb-server/get-active-ovsdb-server command
1510 AT_SETUP([ovsdb-server/get-active-ovsdb-server])
1511 AT_KEYWORDS([ovsdb server replication get-active])
1512 ordinal_schema > schema
1513 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
1514 on_exit 'kill `cat *.pid`'
1515 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --sync-from=tcp:127.0.0.1:9999 db])
1516
1517 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/get-active-ovsdb-server],
1518 [0], [tcp:127.0.0.1:9999
1519 ])
1520 AT_CLEANUP
1521
1522 #*ovsdb-server/set-active-ovsdb-server command
1523 AT_SETUP([ovsdb-server/set-active-ovsdb-server])
1524 AT_KEYWORDS([ovsdb server replication set-active])
1525 ordinal_schema > schema
1526 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
1527 on_exit 'kill `cat *.pid`'
1528 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile db])
1529
1530 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/set-active-ovsdb-server tcp:127.0.0.1:9999])
1531 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/get-active-ovsdb-server],
1532 [0], [tcp:127.0.0.1:9999
1533 ])
1534 AT_CLEANUP
1535
1536 #ovsdb-server/get-sync-exclude-tables command
1537 AT_SETUP([ovsdb-server/get-sync-exclude-tables])
1538 AT_KEYWORDS([ovsdb server replication get-exclude-tables])
1539 ordinal_schema > schema
1540 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
1541 on_exit 'kill `cat *.pid`'
1542 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --sync-exclude-tables=mydb:db1,mydb:db2 db])
1543
1544 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/get-sync-exclude-tables],
1545 [0], [mydb:db1,mydb:db2
1546 ])
1547 AT_CLEANUP
1548
1549 #ovsdb-server/set-sync-exclude-tables command
1550 AT_SETUP([ovsdb-server/set-sync-exclude-tables])
1551 AT_KEYWORDS([ovsdb server replication set-exclude-tables])
1552 AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no])
1553
1554 replication_schema > schema
1555 AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
1556 AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
1557
1558 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
1559 on_exit 'test ! -e pid || kill `cat pid`'
1560
1561 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile=pid2 --remote=punix:db2.sock --unixctl=unixctl2 --sync-from=unix:db.sock db2], [0], [ignore], [ignore])
1562 on_exit 'test ! -e pid2 || kill `cat pid2`'
1563
1564 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/set-sync-exclude-tables mydb:b], [0], [ignore], [ignore], [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
1565
1566 AT_CHECK([ovsdb-client transact unix:db.sock \
1567 '[["mydb",
1568 {"op": "insert",
1569 "table": "a",
1570 "row": {"number": 0, "name": "zero"}},
1571 {"op": "insert",
1572 "table": "b",
1573 "row": {"number": 1, "name": "one"}}]]'], [0], [stdout], [ignore],
1574 [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
1575
1576 AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout], [ignore],
1577 [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
1578 cat stdout > dump1
1579 OVS_WAIT_UNTIL([ ovsdb-client dump unix:db2.sock | grep zero ])
1580 AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout], [ignore])
1581 cat stdout > dump2
1582
1583 AT_CHECK([diff dump1 dump2], [1], [stdout], [ignore])
1584 cat stdout > output
1585
1586 AT_CHECK([uuidfilt output], [0], [7,9c7,8
1587 < _uuid name number
1588 < ------------------------------------ ---- ------
1589 < <0> one 1
1590 ---
1591 > _uuid name number
1592 > ----- ---- ------
1593 ])
1594
1595 OVSDB_SERVER_SHUTDOWN
1596 OVSDB_SERVER_SHUTDOWN2
1597 AT_CLEANUP
1598
1599 #ovsdb-server/connect-active-ovsdb-server
1600 AT_SETUP([ovsdb-server/connect-active-server])
1601 AT_KEYWORDS([ovsdb server replication connect-active-server])
1602 replication_schema > schema
1603 AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
1604 AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
1605
1606 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
1607 on_exit 'test ! -e pid || kill `cat pid`'
1608
1609 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile=pid2 --remote=punix:db2.sock --unixctl=unixctl2 db2], [0], [ignore], [ignore])
1610 on_exit 'test ! -e pid2 || kill `cat pid2`'
1611
1612 dnl Try to connect without specifying the active server.
1613 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/connect-active-ovsdb-server], [0],
1614 [Unable to connect: active server is not specified.
1615 ], [ignore])
1616
1617 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/set-active-ovsdb-server unix:db.sock], [0], [stdout], [ignore])
1618
1619 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/connect-active-ovsdb-server], [0], [stdout], [ignore])
1620
1621 AT_CHECK([ovsdb-client transact unix:db.sock \
1622 '[["mydb",
1623 {"op": "insert",
1624 "table": "a",
1625 "row": {"number": 0, "name": "zero"}}]]'], [0], [stdout], [ignore])
1626
1627 AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout], [ignore])
1628 cat stdout > dump1
1629 OVS_WAIT_UNTIL([ ovsdb-client dump unix:db2.sock | grep zero ])
1630 AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout], [ignore])
1631 cat stdout > dump2
1632
1633 AT_CHECK([diff dump1 dump2], [0], [], [ignore])
1634 OVSDB_SERVER_SHUTDOWN
1635 OVSDB_SERVER_SHUTDOWN2
1636 AT_CLEANUP
1637
1638 #ovsdb-server/disconnect-active-server command
1639 AT_SETUP([ovsdb-server/disconnect-active-server])
1640 AT_KEYWORDS([ovsdb server replication disconnect-active-server])
1641 AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no])
1642
1643 replication_schema > schema
1644 AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
1645 AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
1646
1647 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
1648 on_exit 'test ! -e pid || kill `cat pid`'
1649
1650 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile=pid2 --remote=punix:db2.sock --unixctl=unixctl2 --sync-from=unix:db.sock db2], [0], [ignore], [ignore])
1651 on_exit 'test ! -e pid2 || kill `cat pid2`'
1652
1653 AT_CHECK([ovsdb-client transact unix:db.sock \
1654 '[["mydb",
1655 {"op": "insert",
1656 "table": "a",
1657 "row": {"number": 0, "name": "zero"}}]]'], [0], [stdout], [ignore])
1658
1659 dnl Make sure the transaction shows up in db2. This also tests the back up server
1660 dnl can be read.
1661 OVS_WAIT_UNTIL([ovsdb-client dump unix:db2.sock | grep zero])
1662
1663 dnl The backup server does not accept any write transaction
1664 AT_CHECK([ovsdb-client transact unix:db2.sock \
1665 '[["mydb",
1666 {"op": "insert",
1667 "table": "b",
1668 "row": {"number": 1, "name": "one"}}]]'], [0],
1669 [[[{"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}]]
1670 ])
1671
1672 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/disconnect-active-ovsdb-server], [0], [ignore], [ignore])
1673
1674 AT_CHECK([ovsdb-client transact unix:db.sock \
1675 '[["mydb",
1676 {"op": "insert",
1677 "table": "b",
1678 "row": {"number": 1, "name": "one"}}]]'], [0], [stdout], [ignore])
1679
1680 AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout], [ignore])
1681 cat stdout > dump1
1682
1683 sleep 1
1684 AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout], [ignore])
1685 cat stdout > dump2
1686
1687 AT_CHECK([diff dump1 dump2], [1], [stdout], [ignore])
1688 cat stdout > output
1689
1690 AT_CHECK([uuidfilt output], [0], [7,9c7,8
1691 < _uuid name number
1692 < ------------------------------------ ---- ------
1693 < <0> one 1
1694 ---
1695 > _uuid name number
1696 > ----- ---- ------
1697 ], [ignore], [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
1698
1699 dnl The backup server now become active, and can accept write transactions.
1700 AT_CHECK([ovsdb-client transact unix:db2.sock \
1701 '[["mydb",
1702 {"op": "insert",
1703 "table": "b",
1704 "row": {"number": 1, "name": "one"}}]]'], [0], [stdout], [ignore])
1705
1706 AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout])
1707 cat stdout > output
1708
1709 AT_CHECK([uuidfilt output], [0], [a table
1710 _uuid name number
1711 ------------------------------------ ---- ------
1712 <0> zero 0
1713
1714 b table
1715 _uuid name number
1716 ------------------------------------ ---- ------
1717 <1> one 1
1718 ])
1719
1720 OVSDB_SERVER_SHUTDOWN
1721 OVSDB_SERVER_SHUTDOWN2
1722 AT_CLEANUP
1723
1724 #ovsdb-server/active-backup-role-switching
1725 AT_SETUP([ovsdb-server/active-backup-role-switching])
1726 AT_KEYWORDS([ovsdb server replication active-backup-switching])
1727 replication_schema > schema
1728 AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
1729 AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
1730
1731 dnl Add some data to both DBs
1732 AT_CHECK([ovsdb-tool transact db1 \
1733 '[["mydb",
1734 {"op": "insert",
1735 "table": "a",
1736 "row": {"number": 9, "name": "nine"}}]]'], [0], [ignore], [ignore])
1737
1738 AT_CHECK([ovsdb-tool transact db2 \
1739 '[["mydb",
1740 {"op": "insert",
1741 "table": "a",
1742 "row": {"number": 9, "name": "nine"}}]]'], [0], [ignore], [ignore])
1743
1744 dnl Start both 'db1' and 'db2' in backup mode. Let them backup from each
1745 dnl other. This is not an supported operation state, but to simulate a start
1746 dnl up condition where an HA manger can select which one to be an active
1747 dnl server soon after.
1748 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=punix:db.sock --unixctl="`pwd`"/unixctl db1 --sync-from=unix:db2.sock --active ], [0], [ignore], [ignore])
1749 on_exit 'test ! -e pid || kill `cat pid`'
1750
1751 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/connect-active-ovsdb-server])
1752
1753 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=punix:db2.sock --unixctl="`pwd`"/unixctl2 --sync-from=unix:db.sock db2], [0], [ignore], [ignore])
1754 on_exit 'test ! -e pid2 || kill `cat pid2`'
1755
1756 dnl
1757 dnl make sure both servers reached the replication state
1758 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status |grep replicating])
1759 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/sync-status |grep replicating])
1760
1761 dnl Switch the 'db1' to active
1762 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/disconnect-active-ovsdb-server])
1763 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status], [0], [state: active
1764 ])
1765
1766 dnl Issue a transaction to 'db1'
1767 AT_CHECK([ovsdb-client transact unix:db.sock \
1768 '[["mydb",
1769 {"op": "insert",
1770 "table": "a",
1771 "row": {"number": 0, "name": "zero"}}]]'], [0], [ignore])
1772
1773 dnl It should be replicated to 'db2'
1774 OVS_WAIT_UNTIL([ovsdb-client dump unix:db2.sock | grep zero])
1775
1776 dnl Flip the role of 'db1' and 'db2'. 'db1' becomes backup, and db2 becomes active
1777 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/disconnect-active-ovsdb-server])
1778 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/connect-active-ovsdb-server])
1779
1780 dnl Verify the change happend
1781 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status |grep replicating])
1782 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/sync-status], [0], [state: active
1783 ])
1784
1785 dnl Issue an transaction to 'db2' which is now active.
1786 AT_CHECK([ovsdb-client transact unix:db2.sock \
1787 '[["mydb",
1788 {"op": "insert",
1789 "table": "b",
1790 "row": {"number": 1, "name": "one"}}]]'], [0], [ignore])
1791
1792 dnl The transaction should be replicated to 'db1'
1793 OVS_WAIT_UNTIL([ovsdb-client dump unix:db.sock | grep one])
1794
1795 dnl Both servers should have the same content.
1796 AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout])
1797 cat stdout > dump1
1798
1799 AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout])
1800 cat stdout > dump2
1801
1802 AT_CHECK([diff dump1 dump2])
1803
1804 dnl OVSDB_SERVER_SHUTDOWN
1805 dnl OVSDB_SERVER_SHUTDOWN2
1806 AT_CLEANUP
1807
1808 #ovsdb-server prevent self replicating
1809 AT_SETUP([ovsdb-server prevent self replicating])
1810 AT_KEYWORDS([ovsdb server replication])
1811 replication_schema > schema
1812 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
1813
1814 dnl Add some data to both DBs
1815 AT_CHECK([ovsdb-tool transact db \
1816 '[["mydb",
1817 {"op": "insert",
1818 "table": "a",
1819 "row": {"number": 9, "name": "nine"}}]]'], [0], [ignore], [ignore])
1820
1821 dnl Start 'db', then try to be a back up server of itself.
1822 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server.log --pidfile="`pwd`"/pid --remote=punix:db.sock --unixctl="`pwd`"/unixctl db --sync-from=unix:db.sock --active ], [0], [ignore], [ignore])
1823 on_exit 'test ! -e pid || kill `cat pid`'
1824
1825 dnl Save the current content
1826 AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout])
1827 cp stdout dump1
1828
1829 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/connect-active-ovsdb-server])
1830 dnl Check that self replicating is blocked.
1831 AT_CHECK([grep "Self replicating is not allowed" ovsdb-server.log], [0], [stdout])
1832
1833 dnl Check current DB content is preserved.
1834 AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout])
1835 cat stdout > dump2
1836
1837 AT_CHECK([diff dump1 dump2])
1838 AT_CLEANUP
1839
1840 AT_SETUP([ovsdb-server/read-only db:ptcp connection])
1841 AT_KEYWORDS([ovsdb server read-only])
1842 AT_DATA([schema],
1843 [[{"name": "mydb",
1844 "tables": {
1845 "Root": {
1846 "columns": {
1847 "managers": {
1848 "type": {
1849 "key": {"type": "uuid", "refTable": "Manager"},
1850 "min": 0,
1851 "max": "unlimited"}}}},
1852 "Manager": {
1853 "columns": {
1854 "target": {
1855 "type": "string"},
1856 "read_only": {
1857 "type": {
1858 "key": "boolean",
1859 "min": 0,
1860 "max": 1}},
1861 "is_connected": {
1862 "type": {
1863 "key": "boolean",
1864 "min": 0,
1865 "max": 1}}}},
1866 "ordinals": {
1867 "columns": {
1868 "number": {"type": "integer"},
1869 "name": {"type": "string"}},
1870 "indexes": [["number"]]}
1871 },
1872 "version": "5.1.3",
1873 "cksum": "12345678 9"
1874 }
1875 ]])
1876 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
1877 AT_CHECK(
1878 [[ovsdb-tool transact db \
1879 '["mydb",
1880 {"op": "insert",
1881 "table": "Root",
1882 "row": {
1883 "managers": ["set", [["named-uuid", "x"]]]}},
1884 {"op": "insert",
1885 "table": "Manager",
1886 "uuid-name": "x",
1887 "row": {"target": "ptcp:0:127.0.0.1",
1888 "read_only": true}}]']], [0], [ignore], [ignore])
1889
1890 AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile --remote=db:mydb,Root,managers db], [0], [ignore], [ignore])
1891 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
1892 AT_CHECK([ovsdb-client get-schema-version tcp:127.0.0.1:$TCP_PORT mydb], [0], [5.1.3
1893 ])
1894
1895 AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT \
1896 ['["mydb",
1897 {"op": "insert",
1898 "table": "ordinals",
1899 "row": {"name": "two", "number": '2'}}
1900 ]']], [0], [stdout], [ignore])
1901 cat stdout >> output
1902 AT_CHECK([uuidfilt output], [0], [[[{"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}]]
1903 ], [ignore])
1904 OVSDB_SERVER_SHUTDOWN
1905 AT_CLEANUP
1906
1907 AT_SETUP([ovsdb-server replication with schema mismatch])
1908 AT_KEYWORDS([ovsdb server replication])
1909 replication_schema > subset_schema
1910 replication_schema_v2 > superset_schema
1911
1912 AT_CHECK([ovsdb-tool create db1 subset_schema], [0], [stdout], [ignore])
1913 AT_CHECK([ovsdb-tool create db2 superset_schema], [0], [stdout], [ignore])
1914
1915 dnl Add some data to both DBs
1916 AT_CHECK([ovsdb-tool transact db1 \
1917 '[["mydb",
1918 {"op": "insert",
1919 "table": "a",
1920 "row": {"number": 9, "name": "nine"}}]]'], [0], [ignore], [ignore])
1921
1922 AT_CHECK([ovsdb-tool transact db2 \
1923 '[["mydb",
1924 {"op": "insert",
1925 "table": "a",
1926 "row": {"number": 10, "name": "ten"}}]]'], [0], [ignore], [ignore])
1927
1928 dnl Start both 'db1' and 'db2'.
1929 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=punix:db.sock --unixctl="`pwd`"/unixctl db1 --active ], [0], [ignore], [ignore])
1930 on_exit 'test ! -e pid || kill `cat pid`'
1931
1932
1933 AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=punix:db2.sock --unixctl="`pwd`"/unixctl2 db2], [0], [ignore], [ignore])
1934 on_exit 'test ! -e pid2 || kill `cat pid2`'
1935
1936 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status |grep active])
1937 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/sync-status |grep active])
1938
1939 AT_CHECK([ovsdb-client dump unix:db.sock a number name], 0, [dnl
1940 a table
1941 name number
1942 ---- ------
1943 nine 9
1944 ])
1945
1946 AT_CHECK([ovsdb-client dump unix:db2.sock a number name], 0, [dnl
1947 a table
1948 name number
1949 ---- ------
1950 ten 10
1951 ])
1952
1953 # Replicate db1 from db2. It should fail since db2 schema
1954 # doesn't match with db1 and has additional tables/columns.
1955 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/set-active-ovsdb-server unix:db2.sock])
1956 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/connect-active-ovsdb-server])
1957
1958 OVS_WAIT_UNTIL(
1959 [test 1 = `cat ovsdb-server1.log | grep "Schema version mismatch, checking if mydb can still be replicated or not" | wc -l]`
1960 )
1961
1962 OVS_WAIT_UNTIL(
1963 [test 1 = `cat ovsdb-server1.log | grep "mydb cannot be replicated" | wc -l]`
1964 )
1965
1966 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status |grep active])
1967
1968 # Replicate db2 from db1. This should be successful.
1969 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/disconnect-active-ovsdb-server])
1970 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/set-active-ovsdb-server unix:db.sock])
1971 AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/connect-active-ovsdb-server])
1972
1973 OVS_WAIT_UNTIL(
1974 [test 1 = `cat ovsdb-server2.log | grep "Schema version mismatch, checking if mydb can still be replicated or not" | wc -l]`
1975 )
1976
1977 OVS_WAIT_UNTIL(
1978 [test 1 = `cat ovsdb-server2.log | grep "mydb can be replicated" | wc -l]`
1979 )
1980
1981 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/sync-status |grep replicating])
1982
1983 AT_CHECK([ovsdb-client dump unix:db.sock a number name], 0, [dnl
1984 a table
1985 name number
1986 ---- ------
1987 nine 9
1988 ])
1989
1990 AT_CHECK([ovsdb-client dump unix:db2.sock a number name], 0, [dnl
1991 a table
1992 name number
1993 ---- ------
1994 nine 9
1995 ])
1996
1997 AT_CHECK([ovsdb-client transact unix:db.sock \
1998 '[["mydb",
1999 {"op": "insert",
2000 "table": "a",
2001 "row": {"number": 6, "name": "six"}}]]'], [0], [ignore], [ignore])
2002
2003 OVS_WAIT_UNTIL([test 1 = `ovsdb-client dump unix:db2.sock a number name | grep six | wc -l`])
2004
2005 AT_CHECK([
2006 ovsdb-client dump unix:db2.sock a number name], 0, [dnl
2007 a table
2008 name number
2009 ---- ------
2010 nine 9
2011 six 6
2012 ])
2013
2014 AT_CLEANUP