1
# See the file LICENSE for redistribution information.
4
# Sleepycat Software. All rights reserved.
9
# TEST Basic replication election test.
11
# TEST Run a modified version of test001 in a replicated master environment;
12
# TEST hold an election among a group of clients to make sure they select
13
# TEST a proper master from amongst themselves, in various scenarios.
15
proc rep002 { method { niter 10 } { nclients 3 } { tnum "02" } args } {
19
set elect_timeout 1000000
21
if { [is_record_based $method] == 1 } {
22
puts "Rep002: Skipping for method $method."
28
set qdir $testdir/MSGQUEUEDIR
31
set masterdir $testdir/MASTERDIR
34
for { set i 0 } { $i < $nclients } { incr i } {
35
set clientdir($i) $testdir/CLIENTDIR.$i
36
file mkdir $clientdir($i)
39
puts "Rep0$tnum: Replication election test with $nclients clients."
43
set env_cmd(M) "berkdb_env -create -log_max 1000000 -home \
44
$masterdir -txn -rep_master -rep_transport \[list 1 replsend\]"
45
set masterenv [eval $env_cmd(M)]
46
error_check_good master_env [is_valid_env $masterenv] TRUE
49
for { set i 0 } { $i < $nclients } { incr i } {
50
set envid [expr $i + 2]
52
set env_cmd($i) "berkdb_env -create -home $clientdir($i) \
53
-txn -rep_client -rep_transport \[list $envid replsend\]"
54
set clientenv($i) [eval $env_cmd($i)]
56
client_env($i) [is_valid_env $clientenv($i)] TRUE
59
# Run a modified test001 in the master.
60
puts "\tRep0$tnum.a: Running test001 in replicated env."
61
eval test001 $method $niter 0 $tnum 0 -env $masterenv $args
63
# Loop, processing first the master's messages, then the client's,
64
# until both queues are empty.
68
incr nproced [replprocessqueue $masterenv 1]
70
for { set i 0 } { $i < $nclients } { incr i } {
71
set envid [expr $i + 2]
72
incr nproced [replprocessqueue $clientenv($i) $envid]
75
if { $nproced == 0 } {
80
# Verify the database in the client dir.
81
for { set i 0 } { $i < $nclients } { incr i } {
82
puts "\tRep0$tnum.b: Verifying contents of client database $i."
83
set testdir [get_home $masterenv]
87
open_and_dump_file test0$tnum.db $clientenv($i) $testdir/t1 \
88
test001.check dump_file_direction "-first" "-next"
90
if { [string compare [convert_method $method] -recno] != 0 } {
93
error_check_good diff_files($t2,$t3) [filecmp $t2 $t3] 0
95
verify_dir $clientdir($i) "\tRep0$tnum.c: " 0 0 1
98
# Start an election in the first client.
99
puts "\tRep0$tnum.d: Starting election without dead master."
101
set elect_pipe(0) [start_election \
102
$qdir $env_cmd(0) [expr $nclients + 1] 20 $elect_timeout]
106
# We want to verify all the clients but the one that declared an
107
# election get the election message.
108
# We also want to verify that the master declares the election
109
# over by fiat, even if everyone uses a lower priority than 20.
110
# Loop and process all messages, keeping track of which
111
# sites got a HOLDELECTION and checking that the returned newmaster,
112
# if any, is 1 (the master's replication ID).
113
set got_hold_elect(M) 0
114
for { set i 0 } { $i < $nclients } { incr i } {
115
set got_hold_elect($i) 0
123
incr nproced [replprocessqueue $masterenv 1 0 he nm]
126
set elect_pipe(M) [start_election $qdir \
127
$env_cmd(M) [expr $nclients + 1] 0 $elect_timeout]
128
set got_hold_elect(M) 1
131
error_check_good newmaster_is_master $nm 1
134
for { set i 0 } { $i < $nclients } { incr i } {
136
set envid [expr $i + 2]
138
[replprocessqueue $clientenv($i) $envid 0 he nm]
140
# error_check_bad client(0)_in_elect $i 0
141
set elect_pipe(M) [start_election $qdir \
142
$env_cmd($i) [expr $nclients + 1] 0 \
144
set got_hold_elect($i) 1
147
error_check_good newmaster_is_master $nm 1
151
if { $nproced == 0 } {
156
error_check_good got_hold_elect(master) $got_hold_elect(M) 0
157
unset got_hold_elect(M)
158
# error_check_good got_hold_elect(0) $got_hold_elect(0) 0
159
unset got_hold_elect(0)
160
for { set i 1 } { $i < $nclients } { incr i } {
161
error_check_good got_hold_elect($i) $got_hold_elect($i) 1
162
unset got_hold_elect($i)
167
# We need multiple clients to proceed from here.
168
if { $nclients < 2 } {
169
puts "\tRep0$tnum: Skipping for less than two clients."
170
error_check_good masterenv_close [$masterenv close] 0
171
for { set i 0 } { $i < $nclients } { incr i } {
172
error_check_good clientenv_close($i) \
173
[$clientenv($i) close] 0
178
# Make sure all the clients are synced up and ready to be good
180
error_check_good master_flush [$masterenv rep_flush] 0
183
incr nproced [replprocessqueue $masterenv 1 0]
184
for { set i 0 } { $i < $nclients } { incr i } {
185
incr nproced [replprocessqueue $clientenv($i) \
189
if { $nproced == 0 } {
194
# Now hold another election in the first client, this time with
196
puts "\tRep0$tnum.e: Starting election with dead master."
197
error_check_good masterenv_close [$masterenv close] 0
199
for { set i 0 } { $i < $nclients } { incr i } {
200
replclear [expr $i + 2]
203
set elect_pipe(0) [start_election \
204
$qdir $env_cmd(0) [expr $nclients + 1] 20 $elect_timeout]
208
# Process messages, and verify that the client with the highest
209
# priority--client #1--wins.
217
for { set i 0 } { $i < $nclients } { incr i } {
219
set envid [expr $i + 2]
221
[replprocessqueue $clientenv($i) $envid 0 he nm]
224
# Client #1 has priority 100; everyone else
231
# error_check_bad client(0)_in_elect $i 0
232
set elect_pipe(M) [start_election $qdir \
233
$env_cmd($i) [expr $nclients + 1] $pri \
235
set got_hold_elect($i) 1
238
error_check_good newmaster_is_master $nm \
240
set got_newmaster $nm
242
# If this env is the new master, it needs to
243
# configure itself as such--this is a different
244
# env handle from the one that performed the
246
if { $nm == $envid } {
247
error_check_good make_master($i) \
248
[$clientenv($i) rep_start -master] \
254
# We need to wait around to make doubly sure that the
255
# election has finished...
256
if { $nproced == 0 } {
266
# Verify that client #1 is actually the winner.
267
error_check_good "client 1 wins" $got_newmaster [expr 1 + 2]
271
for { set i 0 } { $i < $nclients } { incr i } {
272
error_check_good clientenv_close($i) [$clientenv($i) close] 0
275
replclose $testdir/MSGQUEUEDIR
278
proc reptwo { args } { eval rep002 $args }