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