]> git.proxmox.com Git - mirror_ovs.git/blame - tests/ovsdb-cluster.at
ovsdb-cluster.at: Wait until leader is elected before DB compact.
[mirror_ovs.git] / tests / ovsdb-cluster.at
CommitLineData
1b1d2e6d
BP
1OVS_START_SHELL_HELPERS
2# ovsdb_check_cluster N_SERVERS SCHEMA_FUNC OUTPUT TRANSACTION...
3ovsdb_check_cluster () {
4 local n=$1 schema_func=$2 output=$3
5 shift; shift; shift
6
7 $schema_func > schema
8 schema=`ovsdb-tool schema-name schema`
9 AT_CHECK([ovsdb-tool '-vPATTERN:console:%c|%p|%m' create-cluster s1.db schema unix:s1.raft], [0], [], [stderr])
10 AT_CHECK([grep -v 'from ephemeral to persistent' stderr], [1])
11 cid=`ovsdb-tool db-cid s1.db`
12 for i in `seq 2 $n`; do
13 AT_CHECK([ovsdb-tool join-cluster s$i.db $schema unix:s$i.raft unix:s1.raft])
14 done
15
16 on_exit 'kill `cat *.pid`'
17 for i in `seq $n`; do
5a0e4aec 18 AT_CHECK([ovsdb-server -vraft -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db])
1b1d2e6d
BP
19 done
20 for i in `seq $n`; do
d97af428 21 AT_CHECK([ovsdb_client_wait unix:s$i.ovsdb $schema connected])
1b1d2e6d
BP
22 done
23
24 for txn
25 do
15394e0f 26 AT_CHECK([ovsdb-client -vjsonrpc -vconsole:off -vsyslog:off -vvlog:off --log-file transact unix:s1.ovsdb,unix:s2.ovsdb,unix:s3.ovsdb "$txn"], [0], [stdout])
1b1d2e6d
BP
27 cat stdout >> output
28 done
29 AT_CHECK_UNQUOTED([uuidfilt output], [0], [$output])
30 for i in `seq $n`; do
5a0e4aec 31 OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid])
1b1d2e6d
BP
32 done
33
34 AT_CHECK([ovsdb-tool check-cluster s*.db])
35}
36OVS_END_SHELL_HELPERS
37
38# Test a 1-server cluster.
39AT_BANNER([OVSDB - clustered transactions (1 server)])
40m4_define([OVSDB_CHECK_EXECUTION],
41 [AT_SETUP([$1 - cluster of 1])
42 AT_KEYWORDS([ovsdb server positive unix cluster cluster1 $5])
43 ovsdb_check_cluster 1 "$2" '$4' m4_foreach([txn], [$3], ['txn' ])
44 AT_CLEANUP])
45EXECUTION_EXAMPLES
46
47# Test a 3-server cluster.
48AT_BANNER([OVSDB - clustered transactions (3 servers)])
49m4_define([OVSDB_CHECK_EXECUTION],
50 [AT_SETUP([$1 - cluster of 3])
51 AT_KEYWORDS([ovsdb server positive unix cluster cluster3 $5])
52 ovsdb_check_cluster 3 "$2" '$4' m4_foreach([txn], [$3], ['txn' ])
53 AT_CLEANUP])
54EXECUTION_EXAMPLES
55
56# Test a 5-server cluster.
57AT_BANNER([OVSDB - clustered transactions (5 servers)])
58m4_define([OVSDB_CHECK_EXECUTION],
59 [AT_SETUP([$1 - cluster of 5])
60 AT_KEYWORDS([ovsdb server positive unix cluster cluster5 $5])
61 ovsdb_check_cluster 5 "$2" '$4' m4_foreach([txn], [$3], ['txn' ])
62 AT_CLEANUP])
63EXECUTION_EXAMPLES
eb692258
HZ
64\f
65
ca367fa5
HZ
66AT_BANNER([OVSDB - disconnect from cluster])
67
89771c1e 68OVS_START_SHELL_HELPERS
923f01ca
HZ
69# ovsdb_test_cluster_disconnect N_SERVERS LEADER_OR_FOLLOWER [CHECK_FLAPPING]
70# Test server disconnected from the cluster.
71# N_SERVERS: Number of servers in the cluster.
72# LEADER_OR_FOLLOWER: The role of the server that is disconnected from the
73# cluster: "leader" or "follower".
74# CHECK_FLAPPING: Whether to check if is_disconnected flapped. "yes", "no".
89771c1e 75ovsdb_test_cluster_disconnect () {
923f01ca
HZ
76 n=$1
77 leader_or_follower=$2
78 check_flapping=$3
89771c1e
HZ
79 schema_name=`ovsdb-tool schema-name $abs_srcdir/idltest.ovsschema`
80 ordinal_schema > schema
81 AT_CHECK([ovsdb-tool '-vPATTERN:console:%c|%p|%m' create-cluster s1.db $abs_srcdir/idltest.ovsschema unix:s1.raft], [0], [], [stderr])
82 cid=`ovsdb-tool db-cid s1.db`
83 schema_name=`ovsdb-tool schema-name $abs_srcdir/idltest.ovsschema`
923f01ca 84 for i in `seq 2 $n`; do
89771c1e
HZ
85 AT_CHECK([ovsdb-tool join-cluster s$i.db $schema_name unix:s$i.raft unix:s1.raft])
86 done
87
88 on_exit 'kill `cat *.pid`'
923f01ca 89 for i in `seq $n`; do
89771c1e
HZ
90 AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db])
91 done
923f01ca 92 for i in `seq $n`; do
89771c1e
HZ
93 AT_CHECK([ovsdb_client_wait unix:s$i.ovsdb $schema_name connected])
94 done
95
96 AT_CHECK([ovsdb-client transact unix:s1.ovsdb '[["idltest",
97 {"op": "insert",
98 "table": "simple",
99 "row": {"i": 1}}]]'], [0], [ignore], [ignore])
100
101 # When a node is disconnected from the cluster, the IDL should disconnect
102 # and retry even if it uses a single remote, because the remote IP can be
103 # a VIP on a load-balance. So we use single remote to test here.
104 if test $leader_or_follower == "leader"; then
105 target=1
923f01ca
HZ
106 shutdown=`seq $(($n/2 + 1)) $n`
107 cleanup=`seq $(($n/2))`
89771c1e 108 else
923f01ca 109 target=$n
89771c1e 110
923f01ca
HZ
111 # shutdown followers before the leader (s1) so that there is no chance for
112 # s$n to become leader during the process.
113 shutdown="`seq 2 $(($n/2 + 1))` 1"
114 cleanup=`seq $(($n/2 + 2)) $n`
89771c1e 115 fi
923f01ca
HZ
116 echo shutdown=$shutdown
117 echo cleanup=$cleanup
89771c1e
HZ
118
119 # Connect to $target. Use "wait" to trigger a non-op transaction so
120 # that test-ovsdb will not quit.
121
122 test-ovsdb '-vPATTERN:console:test-ovsdb|%c|%m' -v -t10 idl unix:s$target.ovsdb '[["idltest",
123 {"op": "wait",
124 "table": "simple",
125 "where": [["i", "==", 1]],
126 "columns": ["i"],
127 "until": "==",
128 "rows": [{"i": 1}]}]]' > test-ovsdb.log 2>&1 &
129 echo $! > test-ovsdb.pid
ca367fa5 130
89771c1e 131 OVS_WAIT_UNTIL([grep "000: i=1" test-ovsdb.log])
ca367fa5 132
923f01ca
HZ
133 # Start collecting raft_is_connected logs for $target before shutting down
134 # any servers.
135 tail -f s$target.log > raft_is_connected.log &
136 echo $! > tail.pid
137
89771c1e
HZ
138 # Shutdown the other servers so that $target is disconnected from the cluster.
139 for i in $shutdown; do
140 OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid])
141 done
142
143 # The test-ovsdb should detect the disconnect and retry.
144 OVS_WAIT_UNTIL([grep disconnect test-ovsdb.log])
145
923f01ca
HZ
146 # The $target debug log should show raft_is_connected: false.
147 OVS_WAIT_UNTIL([grep "raft_is_connected: false" raft_is_connected.log])
148
149 # Save the current count of "raft_is_connected: true"
150 count_old=`grep "raft_is_connected: true" raft_is_connected.log | wc -l`
151 echo count_old $count_old
152
153 if test X$check_flapping == X"yes"; then
154 sleep 10
155 fi
156 # Make sure raft_is_connected didn't flap from false to true.
157 count_new=`grep "raft_is_connected: true" raft_is_connected.log | wc -l`
158 echo count_new $count_new
159 AT_CHECK([test $count_new == $count_old])
160
161 for i in $cleanup; do
162 OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid])
163 done
89771c1e
HZ
164}
165OVS_END_SHELL_HELPERS
166
167AT_SETUP([OVSDB cluster - follower disconnect from cluster, single remote])
168AT_KEYWORDS([ovsdb server negative unix cluster disconnect])
923f01ca 169ovsdb_test_cluster_disconnect 3 follower
89771c1e
HZ
170AT_CLEANUP
171
172AT_SETUP([OVSDB cluster - leader disconnect from cluster, single remote])
173AT_KEYWORDS([ovsdb server negative unix cluster disconnect])
923f01ca
HZ
174ovsdb_test_cluster_disconnect 3 leader
175AT_CLEANUP
176
177AT_SETUP([OVSDB cluster - leader disconnect from cluster, check flapping])
178AT_KEYWORDS([ovsdb server negative unix cluster disconnect])
179ovsdb_test_cluster_disconnect 5 leader yes
ca367fa5 180AT_CLEANUP
89771c1e 181
ca367fa5
HZ
182\f
183
8e354614
HZ
184AT_BANNER([OVSDB cluster election timer change])
185
186AT_SETUP([OVSDB cluster - election timer change])
187AT_KEYWORDS([ovsdb server positive unix cluster timer])
188
189n=3
190schema_name=`ovsdb-tool schema-name $abs_srcdir/idltest.ovsschema`
191ordinal_schema > schema
192AT_CHECK([ovsdb-tool '-vPATTERN:console:%c|%p|%m' create-cluster s1.db $abs_srcdir/idltest.ovsschema unix:s1.raft], [0], [], [stderr])
193cid=`ovsdb-tool db-cid s1.db`
194schema_name=`ovsdb-tool schema-name $abs_srcdir/idltest.ovsschema`
195for i in `seq 2 $n`; do
196 AT_CHECK([ovsdb-tool join-cluster s$i.db $schema_name unix:s$i.raft unix:s1.raft])
197done
198
199on_exit 'kill `cat *.pid`'
200for i in `seq $n`; do
201 AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db])
202done
203for i in `seq $n`; do
204 AT_CHECK([ovsdb_client_wait unix:s$i.ovsdb $schema_name connected])
205done
206
207# Change not allowed through follower.
208AT_CHECK([ovs-appctl -t "`pwd`"/s2 cluster/change-election-timer $schema_name 2000], [2], [], [ignore])
209
210# Timer cannot be changed to bigger than 2x the original value.
211AT_CHECK([ovs-appctl -t "`pwd`"/s1 cluster/change-election-timer $schema_name 4000], [2], [], [ignore])
212
213AT_CHECK([ovs-appctl -t "`pwd`"/s1 cluster/change-election-timer $schema_name 2000], [0], [dnl
214change of election timer initiated.
215], [])
216OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s1 cluster/status $schema_name | grep "Election timer: 2000"])
217OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s2 cluster/status $schema_name | grep "Election timer: 2000"])
218
219AT_CHECK([ovs-appctl -t "`pwd`"/s1 cluster/change-election-timer $schema_name 4000], [0], [dnl
220change of election timer initiated.
221], [])
222OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s1 cluster/status $schema_name | grep "Election timer: 4000"])
223OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s2 cluster/status $schema_name | grep "Election timer: 4000"])
224
225# Latest timer should be used after restart
226for i in `seq $n`; do
227 printf "\ns$i: stopping\n"
228 OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid])
229done
230for i in `seq $n`; do
231 AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db])
232done
233OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s1 cluster/status $schema_name | grep "Election timer: 4000"])
234OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s2 cluster/status $schema_name | grep "Election timer: 4000"])
235
6d034053
HZ
236# Wait until cluster is ready
237for i in `seq $n`; do
238 OVS_WAIT_WHILE([ovs-appctl -t "`pwd`"/s$i cluster/status $schema_name | grep "Leader: unknown"])
239done
240
9bfb280a
HZ
241# Latest timer should be restored after DB compact and restart.
242# This is to test the install_snapshot RPC.
243
9bfb280a
HZ
244# Compact online
245for i in `seq $n`; do
246 AT_CHECK([ovs-appctl -t "`pwd`"/s$i ovsdb-server/compact])
247done
248
249# XXX: Insert data after compact, because otherwise vote will fail after
250# cluster restart after compact. There will be error logs like:
251# raft|ERR|internal error: deferred vote_request message completed but not ready to send because message index 9 is past last synced index 0: s2 vote_request: term=6 last_log_index=9 last_log_term=4
252AT_CHECK([ovsdb-client transact unix:s1.ovsdb '[["idltest",
253 {"op": "insert",
254 "table": "simple",
255 "row": {"i": 1}}]]'], [0], [ignore], [ignore])
256
257for i in `seq $n`; do
258 printf "\ns$i: stopping\n"
259 OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid])
260done
261for i in `seq $n`; do
262 AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db])
263done
264for i in `seq $n`; do
265 OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s$i cluster/status $schema_name | grep "Election timer: 4000"])
266done
267
268# Wait until cluster is ready
269for i in `seq $n`; do
270 OVS_WAIT_WHILE([ovs-appctl -t "`pwd`"/s$i cluster/status $schema_name | grep "Leader: unknown"])
271done
272
273# Newly joined member should use latest timer value
274AT_CHECK([ovsdb-tool join-cluster s4.db $schema_name unix:s4.raft unix:s1.raft])
275AT_CHECK([ovsdb-server -v -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s4.log --pidfile=s4.pid --unixctl=s4 --remote=punix:s4.ovsdb s4.db])
276OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/s4 cluster/status $schema_name | grep "Election timer: 4000"])
277# for i in `seq 10`; do
278# ovs-appctl -t "`pwd`"/s4 cluster/status $schema_name
279# sleep 1
280# done
281
8e354614
HZ
282AT_CLEANUP
283
284\f
285
eb692258
HZ
286OVS_START_SHELL_HELPERS
287# ovsdb_cluster_failure_test SCHEMA_FUNC OUTPUT TRANSACTION...
288ovsdb_cluster_failure_test () {
289 # Initial state: s1 is leader, s2 and s3 are followers
290 remote_1=$1
291 remote_2=$2
292 crash_node=$3
293 crash_command=$4
294 if test "$crash_node" == "1"; then
295 new_leader=$5
296 fi
297
817db730 298 cp $top_srcdir/vswitchd/vswitch.ovsschema schema
eb692258
HZ
299 schema=`ovsdb-tool schema-name schema`
300 AT_CHECK([ovsdb-tool '-vPATTERN:console:%c|%p|%m' create-cluster s1.db schema unix:s1.raft], [0], [], [dnl
817db730 301ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral to persistent, including 'status' column in 'Manager' table, because clusters do not support ephemeral columns
eb692258
HZ
302])
303
304 n=3
305 join_cluster() {
306 local i=$1
307 others=
308 for j in `seq 1 $n`; do
309 if test $i != $j; then
310 others="$others unix:s$j.raft"
311 fi
312 done
313 AT_CHECK([ovsdb-tool join-cluster s$i.db $schema unix:s$i.raft $others])
314 }
315 start_server() {
316 local i=$1
317 printf "\ns$i: starting\n"
318 AT_CHECK([ovsdb-server -vjsonrpc -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db])
319 }
320 connect_server() {
321 local i=$1
322 printf "\ns$i: waiting to connect to storage\n"
323 AT_CHECK([ovsdb_client_wait --log-file=connect$i.log unix:s$i.ovsdb $schema connected])
324 }
325 cid=`ovsdb-tool db-cid s1.db`
326 for i in `seq 2 $n`; do join_cluster $i; done
327
328 on_exit 'kill `cat *.pid`'
329 for i in `seq $n`; do start_server $i; done
330 for i in `seq $n`; do connect_server $i; done
331
817db730 332 db=unix:s$remote_1.ovsdb,unix:s$remote_2.ovsdb
eb692258
HZ
333
334 # To ensure $new_leader node the new leader, we delay election timer for
335 # the other follower.
336 if test -n "$new_leader"; then
337 if test "$new_leader" == "2"; then
338 delay_election_node=3
339 else
340 delay_election_node=2
341 fi
342 AT_CHECK([ovs-appctl -t "`pwd`"/s$delay_election_node cluster/failure-test delay-election], [0], [ignore])
343 fi
344 AT_CHECK([ovs-appctl -t "`pwd`"/s$crash_node cluster/failure-test $crash_command], [0], [ignore])
15394e0f 345 AT_CHECK([ovs-vsctl -v --db="$db" --no-leader-only --no-shuffle-remotes --no-wait create QoS type=x], [0], [ignore], [ignore])
eb692258
HZ
346
347 # Make sure that the node really crashed.
348 AT_CHECK([ls s$crash_node.ovsdb], [2], [ignore], [ignore])
349 # XXX: Client will fail if remotes contains unix socket that doesn't exist (killed).
817db730
BP
350 if test "$remote_1" = "$crash_node"; then
351 db=unix:s$remote_2.ovsdb
eb692258 352 fi
817db730 353 AT_CHECK([ovs-vsctl --db="$db" --no-leader-only --no-wait --columns=type --bare list QoS], [0], [x
eb692258
HZ
354])
355}
356OVS_END_SHELL_HELPERS
357AT_BANNER([OVSDB - cluster failure with pending transaction])
358
359AT_SETUP([OVSDB cluster - txn on follower-2, leader crash before sending appendReq, follower-2 becomes leader])
360AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
eb692258
HZ
361ovsdb_cluster_failure_test 2 3 1 crash-before-sending-append-request 2
362AT_CLEANUP
363
364AT_SETUP([OVSDB cluster - txn on follower-2, leader crash before sending appendReq, follower-3 becomes leader])
365AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
366ovsdb_cluster_failure_test 2 3 1 crash-before-sending-append-request 3
367AT_CLEANUP
368
369AT_SETUP([OVSDB cluster - txn on follower-2, leader crash before sending execRep, follower-2 becomes leader])
370AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
eb692258
HZ
371ovsdb_cluster_failure_test 2 3 1 crash-before-sending-execute-command-reply 2
372AT_CLEANUP
373
374AT_SETUP([OVSDB cluster - txn on follower-2, leader crash before sending execRep, follower-3 becomes leader])
375AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
eb692258
HZ
376ovsdb_cluster_failure_test 2 3 1 crash-before-sending-execute-command-reply 3
377AT_CLEANUP
378
379AT_SETUP([OVSDB cluster - txn on follower-2, leader crash after sending execRep, follower-2 becomes leader])
380AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
eb692258
HZ
381ovsdb_cluster_failure_test 2 3 1 crash-after-sending-execute-command-reply 2
382AT_CLEANUP
383
384AT_SETUP([OVSDB cluster - txn on follower-2, leader crash after sending execRep, follower-3 becomes leader])
385AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
386ovsdb_cluster_failure_test 2 3 1 crash-after-sending-execute-command-reply 3
387AT_CLEANUP
388
389AT_SETUP([OVSDB cluster - txn on leader, leader crash before sending appendReq, follower-2 becomes leader])
390AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
eb692258
HZ
391ovsdb_cluster_failure_test 1 2 1 crash-before-sending-append-request 2
392AT_CLEANUP
393
394AT_SETUP([OVSDB cluster - txn on leader, leader crash before sending appendReq, follower-3 becomes leader])
395AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
396ovsdb_cluster_failure_test 1 2 1 crash-before-sending-append-request 3
397AT_CLEANUP
398
399AT_SETUP([OVSDB cluster - txn on leader, leader crash after sending appendReq, follower-2 becomes leader])
400AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
401# XXX: Detect and skip repeated transaction before enabling this test
402AT_CHECK([exit 77])
403ovsdb_cluster_failure_test 1 2 1 crash-after-sending-append-request 2
404AT_CLEANUP
405
406AT_SETUP([OVSDB cluster - txn on leader, leader crash after sending appendReq, follower-3 becomes leader])
407AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
408# XXX: Detect and skip repeated transaction before enabling this test
409AT_CHECK([exit 77])
410ovsdb_cluster_failure_test 1 2 1 crash-after-sending-append-request 3
411AT_CLEANUP
412
413AT_SETUP([OVSDB cluster - txn on follower-2, follower-2 crash before sending execReq, reconnect to follower-3])
414AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
415ovsdb_cluster_failure_test 2 3 2 crash-before-sending-execute-command-request
416AT_CLEANUP
417
418AT_SETUP([OVSDB cluster - txn on follower-2, follower-2 crash before sending execReq, reconnect to leader])
419AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
420ovsdb_cluster_failure_test 2 1 2 crash-before-sending-execute-command-request
421AT_CLEANUP
422
423AT_SETUP([OVSDB cluster - txn on follower-2, follower-2 crash after sending execReq, reconnect to follower-3])
424AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
425# XXX: Detect and skip repeated transaction before enabling this test
426AT_CHECK([exit 77])
427ovsdb_cluster_failure_test 2 3 2 crash-after-sending-execute-command-request
428AT_CLEANUP
429
430AT_SETUP([OVSDB cluster - txn on follower-2, follower-2 crash after sending execReq, reconnect to leader])
431AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
432# XXX: Detect and skip repeated transaction before enabling this test
433AT_CHECK([exit 77])
434ovsdb_cluster_failure_test 2 1 2 crash-after-sending-execute-command-request
435AT_CLEANUP
436
437AT_SETUP([OVSDB cluster - txn on leader, follower-2 crash after receiving appendReq for the update])
438AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
439ovsdb_cluster_failure_test 1 1 2 crash-after-receiving-append-request-update
440AT_CLEANUP
441
442AT_SETUP([OVSDB cluster - txn on follower-2, follower-3 crash after receiving appendReq for the update])
443AT_KEYWORDS([ovsdb server negative unix cluster pending-txn])
444ovsdb_cluster_failure_test 2 2 3 crash-after-receiving-append-request-update
445AT_CLEANUP
446
1b1d2e6d
BP
447\f
448AT_BANNER([OVSDB - cluster tests])
449
450# Torture test.
451OVS_START_SHELL_HELPERS
452ovsdb_torture_test () {
5a0e4aec
BP
453 local n=$1 # Number of cluster members
454 local victim=$2 # Cluster member to kill or remove
1b1d2e6d 455 local variant=$3 # 'kill' and restart or 'remove' and add
817db730 456 cp $top_srcdir/vswitchd/vswitch.ovsschema schema
1b1d2e6d
BP
457 schema=`ovsdb-tool schema-name schema`
458 AT_CHECK([ovsdb-tool '-vPATTERN:console:%c|%p|%m' create-cluster s1.db schema unix:s1.raft], [0], [], [dnl
817db730 459ovsdb|WARN|schema: changed 30 columns in 'Open_vSwitch' database from ephemeral to persistent, including 'status' column in 'Manager' table, because clusters do not support ephemeral columns
1b1d2e6d
BP
460])
461
462 join_cluster() {
463 local i=$1
5a0e4aec
BP
464 others=
465 for j in `seq 1 $n`; do
466 if test $i != $j; then
467 others="$others unix:s$j.raft"
1b1d2e6d 468 fi
5a0e4aec
BP
469 done
470 AT_CHECK([ovsdb-tool join-cluster s$i.db $schema unix:s$i.raft $others])
1b1d2e6d
BP
471 }
472
473 start_server() {
474 local i=$1
5a0e4aec
BP
475 printf "\ns$i: starting\n"
476 AT_CHECK([ovsdb-server -vjsonrpc -vconsole:off -vsyslog:off --detach --no-chdir --log-file=s$i.log --pidfile=s$i.pid --unixctl=s$i --remote=punix:s$i.ovsdb s$i.db])
1b1d2e6d
BP
477 }
478 stop_server() {
479 local i=$1
5a0e4aec 480 printf "\ns$i: stopping\n"
1b1d2e6d
BP
481 OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/s$i], [s$i.pid])
482 }
483 connect_server() {
484 local i=$1
5a0e4aec 485 printf "\ns$i: waiting to connect to storage\n"
d97af428 486 AT_CHECK([ovsdb_client_wait --log-file=connect$i.log unix:s$i.ovsdb $schema connected])
1b1d2e6d
BP
487 }
488 remove_server() {
489 local i=$1
5a0e4aec 490 printf "\ns$i: removing from cluster\n"
15394e0f 491 AT_CHECK([ovs-appctl -t "`pwd`"/s$i cluster/leave Open_vSwitch])
5a0e4aec 492 printf "\ns$i: waiting for removal to complete\n"
d97af428 493 AT_CHECK([ovsdb_client_wait --log-file=remove$i.log unix:s$i.ovsdb $schema removed])
c7b5c534 494 stop_server $i
1b1d2e6d
BP
495 }
496 add_server() {
497 local i=$1
5a0e4aec 498 rm s$i.db
1b1d2e6d 499 join_cluster $i
5a0e4aec
BP
500 start_server $i
501 connect_server $i
1b1d2e6d
BP
502 }
503
504 cid=`ovsdb-tool db-cid s1.db`
505 for i in `seq 2 $n`; do join_cluster $i; done
506
507 on_exit 'kill `cat *.pid`'
508 for i in `seq $n`; do start_server $i; done
509 for i in `seq $n`; do connect_server $i; done
510
817db730 511 db=unix:s1.ovsdb
1b1d2e6d 512 for i in `seq 2 $n`; do
817db730 513 db=$db,unix:s$i.ovsdb
1b1d2e6d 514 done
1b1d2e6d 515
0f954f32 516 n1=10 n2=5 n3=50
817db730 517 echo "starting $n1*$n2 ovs-vsctl processes..."
1b1d2e6d 518 for i in $(seq 0 $(expr $n1 - 1) ); do
5a0e4aec 519 (for j in $(seq $n2); do
1b1d2e6d 520 : > $i-$j.running
817db730 521 txn="add Open_vSwitch . external_ids $i-$j=$i-$j"
0f954f32 522 for k in $(seq $n3); do
817db730 523 txn="$txn -- add Open_vSwitch . external_ids $i-$j-$k=$i-$j-$k"
0f954f32 524 done
817db730 525 run_as "ovs-vsctl($i-$j)" ovs-vsctl "-vPATTERN:console:ovs-vsctl($i-$j)|%D{%H:%M:%S}|%05N|%c|%p|%m" --log-file=$i-$j.log -vfile -vsyslog:off -vtimeval:off --timeout=120 --db="$db" --no-leader-only --no-wait $txn
5a0e4aec
BP
526 status=$?
527 if test $status != 0; then
528 echo "$i-$j exited with status $status" > $i-$j:$status
1b1d2e6d
BP
529 fi
530 rm $i-$j.running
5a0e4aec
BP
531 done
532 : > $i.done)&
1b1d2e6d
BP
533 done
534 echo "...done"
1b1d2e6d 535
817db730 536 echo "waiting for ovs-vsctl processes to exit..."
6c8dd8ca 537 # Use file instead of var because code inside "while" runs in a subshell.
7ee9c6e0 538 echo 0 > phase
0f03ae37 539 i=0
0f954f32 540 (while :; do echo; sleep 0.1; done) | while read REPLY; do
1b1d2e6d 541 printf "t=%2d s:" $i
5a0e4aec 542 done=0
1b1d2e6d 543 for j in $(seq 0 $(expr $n1 - 1)); do
5a0e4aec
BP
544 if test -f $j.done; then
545 printf " $j"
546 done=$(expr $done + 1)
1b1d2e6d 547 fi
5a0e4aec
BP
548 done
549 printf '\n'
550 if test $done = $n1; then
551 break
1b1d2e6d
BP
552 fi
553
7ee9c6e0 554 case $(cat phase) in # (
5a0e4aec 555 0)
0f954f32 556 if test $done -ge $(expr $n1 / 10); then
5a0e4aec
BP
557 if test $variant = kill; then
558 stop_server $victim
559 else
560 remove_server $victim
561 fi
7ee9c6e0 562 echo 1 > phase
5a0e4aec 563 next=$(expr $i + 2)
1b1d2e6d 564 fi
5a0e4aec 565 ;; # (
1b1d2e6d 566 1)
5a0e4aec
BP
567 if test $i -ge $next; then
568 if test $variant = kill; then
569 start_server $victim
570 connect_server $victim
571 else
572 add_server $victim
573 fi
7ee9c6e0 574 echo 2 > phase
5a0e4aec
BP
575 fi
576 ;;
577 esac
578
579 i=$(expr $i + 1)
1b1d2e6d
BP
580 done
581 echo "...done"
7ee9c6e0 582 AT_CHECK([if test $(cat phase) != 2; then exit 77; fi])
1b1d2e6d 583
dff60a1e
BP
584 for i in $(seq 0 $(expr $n1 - 1) ); do
585 for j in `seq $n2`; do
586 echo "$i-$j=$i-$j"
0f954f32
HZ
587 for k in `seq $n3`; do
588 echo "$i-$j-$k=$i-$j-$k"
589 done
dff60a1e
BP
590 done
591 done | sort > expout
15394e0f 592 AT_CHECK([ovs-vsctl --db="$db" --no-wait --log-file=finalize.log -vtimeval:off -vfile -vsyslog:off --bare get Open_vSwitch . external-ids | tr ',' '\n' | sed 's/[[{}"" ]]//g' | sort], [0], [expout])
1b1d2e6d
BP
593
594 for i in `seq $n`; do
7ee9c6e0 595 if test $i != $victim || test $(cat phase) != 1; then
5a0e4aec
BP
596 stop_server $i
597 fi
1b1d2e6d
BP
598 done
599
600 # We ignore stdout because non-fatal warnings get printed there.
601 AT_CHECK([ovsdb-tool check-cluster s*.db], [0], [ignore])
602}
603OVS_END_SHELL_HELPERS
604
605AT_SETUP([OVSDB 3-server torture test - kill/restart leader])
606AT_KEYWORDS([ovsdb server positive unix cluster cluster3])
607ovsdb_torture_test 3 1 kill
608AT_CLEANUP
609AT_SETUP([OVSDB 3-server torture test - kill/restart follower 1])
610AT_KEYWORDS([ovsdb server positive unix cluster cluster3])
611ovsdb_torture_test 3 2 kill
612AT_CLEANUP
613AT_SETUP([OVSDB 3-server torture test - kill/restart follower 2])
614AT_KEYWORDS([ovsdb server positive unix cluster cluster3])
615ovsdb_torture_test 3 3 kill
616AT_CLEANUP
617AT_SETUP([OVSDB 5-server torture test - kill/restart leader])
618AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
619ovsdb_torture_test 5 1 kill
620AT_CLEANUP
621AT_SETUP([OVSDB 5-server torture test - kill/restart follower 1])
622AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
623ovsdb_torture_test 5 2 kill
624AT_CLEANUP
625AT_SETUP([OVSDB 5-server torture test - kill/restart follower 2])
626AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
627ovsdb_torture_test 5 3 kill
628AT_CLEANUP
629AT_SETUP([OVSDB 5-server torture test - kill/restart follower 3])
630AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
631ovsdb_torture_test 5 4 kill
632AT_CLEANUP
633AT_SETUP([OVSDB 5-server torture test - kill/restart follower 4])
634AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
635ovsdb_torture_test 5 5 kill
636AT_CLEANUP
637
638AT_SETUP([OVSDB 3-server torture test - remove/re-add leader])
639AT_KEYWORDS([ovsdb server positive unix cluster cluster3])
640ovsdb_torture_test 3 1 remove
641AT_CLEANUP
642AT_SETUP([OVSDB 3-server torture test - remove/re-add follower 1])
643AT_KEYWORDS([ovsdb server positive unix cluster cluster3])
644ovsdb_torture_test 3 2 remove
645AT_CLEANUP
646AT_SETUP([OVSDB 3-server torture test - remove/re-add follower 2])
647AT_KEYWORDS([ovsdb server positive unix cluster cluster3])
648ovsdb_torture_test 3 3 remove
649AT_CLEANUP
650AT_SETUP([OVSDB 5-server torture test - remove/re-add leader])
651AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
652ovsdb_torture_test 5 1 remove
653AT_CLEANUP
654AT_SETUP([OVSDB 5-server torture test - remove/re-add follower 1])
655AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
656ovsdb_torture_test 5 2 remove
657AT_CLEANUP
658AT_SETUP([OVSDB 5-server torture test - remove/re-add follower 2])
659AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
660ovsdb_torture_test 5 3 remove
661AT_CLEANUP
662AT_SETUP([OVSDB 5-server torture test - remove/re-add follower 3])
663AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
664ovsdb_torture_test 5 4 remove
665AT_CLEANUP
666AT_SETUP([OVSDB 5-server torture test - remove/re-add follower 4])
667AT_KEYWORDS([ovsdb server positive unix cluster cluster5])
668ovsdb_torture_test 5 5 remove
669AT_CLEANUP