1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2001-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST rep079 8# TEST Replication leases and invalid usage. 9# TEST 10# TEST Open a client without leases. Attempt to set leases after rep_start. 11# TEST Attempt to declare as master without election. 12# TEST Run an election with an nsites parameter value. 13# TEST Elect a master with leases. Put some data and send to clients. 14# TEST Cleanly shutdown master env. Restart without 15# TEST recovery and verify leases are expired and refreshed. 16# TEST Add a new client without leases to a group using leases. 17# 18proc rep079 { method { tnum "079" } args } { 19 source ./include.tcl 20 global repfiles_in_memory 21 22 if { $is_windows9x_test == 1 } { 23 puts "Skipping replication test on Win9x platform." 24 return 25 } 26 27 # Valid for all access methods, but there is no difference 28 # running it with one method over any other. Just use btree. 29 if { $checking_valid_methods } { 30 set test_methods { btree } 31 return $test_methods 32 } 33 if { [is_btree $method] == 0 } { 34 puts "Rep$tnum: Skipping for method $method." 35 return 36 } 37 38 set args [convert_args $method $args] 39 set logsets [create_logsets 4] 40 41 set msg2 "and on-disk replication files" 42 if { $repfiles_in_memory } { 43 set msg2 "and in-memory replication files" 44 } 45 46 foreach l $logsets { 47 # 48 # Skip the case where the master is in-memory and at least 49 # one of the clients is on-disk. If the master is in-memory, 50 # the wrong site gets elected because on-disk envs write a log 51 # record when they create the env and in-memory ones do not 52 # and the test wants to control which env gets elected. 53 # 54 set master_logs [lindex $l 0] 55 if { $master_logs == "in-memory" } { 56 set client_logs [lsearch -exact $l "on-disk"] 57 if { $client_logs != -1 } { 58 puts "Skipping for in-memory master\ 59 with on-disk client." 60 continue 61 } 62 } 63 puts "Rep$tnum: Replication leases and invalid usage $msg2." 64 puts "Rep$tnum: Master logs are [lindex $l 0]" 65 puts "Rep$tnum: Client logs are [lindex $l 1]" 66 puts "Rep$tnum: Client 2 logs are [lindex $l 2]" 67 puts "Rep$tnum: Client 3 logs are [lindex $l 3]" 68 rep079_sub $method $tnum $l $args 69 } 70} 71 72proc rep079_sub { method tnum logset largs } { 73 global testdir 74 global repfiles_in_memory 75 global rep_verbose 76 global verbose_type 77 78 set verbargs "" 79 if { $rep_verbose == 1 } { 80 set verbargs " -verbose {$verbose_type on} " 81 } 82 83 set repmemargs "" 84 if { $repfiles_in_memory } { 85 set repmemargs "-rep_inmem_files " 86 } 87 88 env_cleanup $testdir 89 90 set qdir $testdir/MSGQUEUEDIR 91 replsetup $qdir 92 93 set masterdir $testdir/MASTERDIR 94 set clientdir $testdir/CLIENTDIR 95 set clientdir2 $testdir/CLIENTDIR2 96 set clientdir3 $testdir/CLIENTDIR3 97 98 file mkdir $masterdir 99 file mkdir $clientdir 100 file mkdir $clientdir2 101 file mkdir $clientdir3 102 103 set m_logtype [lindex $logset 0] 104 set c_logtype [lindex $logset 1] 105 set c2_logtype [lindex $logset 2] 106 set c3_logtype [lindex $logset 3] 107 108 # In-memory logs cannot be used with -txn nosync. 109 set m_logargs [adjust_logargs $m_logtype] 110 set c_logargs [adjust_logargs $c_logtype] 111 set c2_logargs [adjust_logargs $c2_logtype] 112 set c3_logargs [adjust_logargs $c3_logtype] 113 set m_txnargs [adjust_txnargs $m_logtype] 114 set c_txnargs [adjust_txnargs $c_logtype] 115 set c2_txnargs [adjust_txnargs $c2_logtype] 116 set c3_txnargs [adjust_txnargs $c3_logtype] 117 118 # Set leases for 4 sites, 1 second timeout, 1% clock skew 119 # [NOTE: We are not adding in client3 until later so don't 120 # set it in nvotes.] 121 set nsites 4 122 set nvotes 3 123 set lease_to 1000000 124 set lease_tosec [expr $lease_to / 1000000] 125 set clock_fast 101 126 set clock_slow 100 127 128 repladd 2 129 # 130 # Use a command without setting errpfx, errfile or verbose 131 # so that error messages can be caught correctly. 132 # 133 set envcmd_err "berkdb_env_noerr -create $m_txnargs $m_logargs \ 134 $repmemargs -home $masterdir -rep_transport \[list 2 replsend\]" 135 136 # 137 # This is the real env command, but we won't use it 138 # quite yet. 139 set envcmd(0) "berkdb_env -create $m_txnargs $m_logargs \ 140 $repmemargs $verbargs -errpfx MASTER -home $masterdir \ 141 -event rep_event \ 142 -rep_transport \[list 2 replsend\]" 143 144 # 145 # Leases must be configured before rep_start is called. 146 # Open a repl env without leases. Try to configure leases 147 # after the open has already called rep_start. Open as a client. 148 # 149 puts "\tRep$tnum.a: Try to configure leases after rep_start." 150 set noleaseenv [eval $envcmd_err -rep_client] 151 set stat [catch {$noleaseenv rep_lease \ 152 [list $nsites $lease_to $clock_fast $clock_slow]} lease] 153 error_check_bad stat $stat 0 154 error_check_good menverror [is_substr $lease "timeout must be set"] 1 155 error_check_good close [$noleaseenv close] 0 156 env_cleanup $masterdir 157 158 # 159 # If leases are being used, elections must be used. A site 160 # cannot simply upgrade itself to master. Test that we cannot 161 # open as a client and then upgrade ourself to a master just 162 # by calling rep_start. 163 # 164 set upgenv [eval $envcmd_err -rep_client \ 165 -rep_lease \[list $nsites $lease_to $clock_fast $clock_slow\]] 166 puts "\tRep$tnum.b: Try to upgrade a client without election." 167 set stat [catch {$upgenv rep_start -master} ret] 168 error_check_bad upg_stat $stat 0 169 error_check_good upg_str [is_substr $ret "Cannot become master"] 1 170 error_check_good close [$upgenv close] 0 171 env_cleanup $masterdir 172 173 # 174 # Now test inconsistencies dealing with having a group that 175 # is using lease up and running. For instance, if leases are 176 # configured, the 'nsites' arg to rep_elect must be 0, etc. 177 # 178 # Open the master. Must open as a client and get elected. 179 # 180 set err_cmd(0) "none" 181 set crash(0) 0 182 set pri(0) 100 183 set masterenv [eval $envcmd(0) -rep_client \ 184 -rep_lease \[list $nsites $lease_to $clock_fast $clock_slow\]] 185 error_check_good master_env [is_valid_env $masterenv] TRUE 186 187 # Open two clients. 188 repladd 3 189 set err_cmd(1) "none" 190 set crash(1) 0 191 set pri(1) 10 192 set envcmd(1) "berkdb_env -create $c_txnargs $c_logargs \ 193 $repmemargs $verbargs -errpfx CLIENT -home $clientdir \ 194 -event rep_event \ 195 -rep_lease \[list $nsites $lease_to $clock_fast $clock_slow\] \ 196 -rep_client -rep_transport \[list 3 replsend\]" 197 set clientenv [eval $envcmd(1)] 198 error_check_good client_env [is_valid_env $clientenv] TRUE 199 200 repladd 4 201 set err_cmd(2) "none" 202 set crash(2) 0 203 set pri(2) 10 204 set envcmd(2) "berkdb_env_noerr -create $c2_txnargs $c2_logargs \ 205 $repmemargs -home $clientdir2 -event rep_event \ 206 -rep_lease \[list $nsites $lease_to $clock_fast $clock_slow\] \ 207 -rep_client -rep_transport \[list 4 replsend\]" 208 set clientenv2 [eval $envcmd(2)] 209 error_check_good client_env [is_valid_env $clientenv2] TRUE 210 211 # Bring the clients online by processing the startup messages. 212 set envlist "{$masterenv 2} {$clientenv 3} {$clientenv2 4}" 213 process_msgs $envlist 214 215 # 216 # Send a non-zero nsites value for an election. That is an error. 217 # 218 puts "\tRep$tnum.c: Try to run election with leases and nsites value." 219 # 220 # !!! We have not set -errpfx or -errfile in envcmd(2) above 221 # otherwise the error output won't be set in 'ret' below and 222 # the test will fail. Set it after this piece of the test. 223 # 224 set timeout 5000000 225 set res [catch {$clientenv2 rep_elect $nsites $nvotes $pri(2) \ 226 $timeout} ret] 227 error_check_bad catch $res 0 228 error_check_good ret [is_substr $ret "nsites must be zero"] 1 229 230 # 231 # Now we can set verbose args, errpfx, etc. Set it in the 232 # command (for elections) and also manually add it to the 233 # current env handle. 234 # 235 set envcmd(2) "$envcmd(2) $verbargs -errpfx CLIENT2" 236 if { $rep_verbose == 1 } { 237 $clientenv2 verbose $verbose_type on 238 $clientenv2 errpfx CLIENT2 239 } 240 241 # 242 # This next section will test that a replicated env that is master 243 # can cleanly close and then reopen without recovery and retain 244 # its master status. 245 # 246 set msg "Rep$tnum.d" 247 set nvotes [expr $nsites - 1] 248 set winner 0 249 setpriority pri $nsites $winner 250 set elector [berkdb random_int 0 2] 251 puts "\tRep$tnum.d: Run election for real to get master." 252 # 253 # Run election for real. Set nsites to 0 for this command. 254 # 255 repladd 5 256 set err_cmd(3) "none" 257 set crash(3) 0 258 set pri(3) 0 259 run_election envcmd envlist err_cmd pri crash $qdir $msg \ 260 $elector 0 $nvotes $nsites $winner 0 NULL 261 262 puts "\tRep$tnum.e: Write a checkpoint." 263 # 264 # Writing a checkpoint forces a PERM record which will cause 265 # the clients to grant us their leases. Then, while holding 266 # the lease grants we can do the next part of the test to 267 # close and cleanly reopen while holding leases. 268 $masterenv txn_checkpoint -force 269 270 process_msgs $envlist 271 272 puts "\tRep$tnum.f.0: Close master env." 273 error_check_good mclose [$masterenv close] 0 274 set sleep [expr $lease_tosec + 1] 275 puts "\tRep$tnum.f.1: Sleep $sleep secs to expire lease grants." 276 tclsleep $sleep 277 # 278 # We should be able to reopen the master env without running 279 # recovery and still retain our mastership. 280 set masterenv [eval $envcmd(0) -rep_master \ 281 -rep_lease \[list $nsites $lease_to $clock_fast $clock_slow\]] 282 error_check_good master_env [is_valid_env $masterenv] TRUE 283 set envlist "{$masterenv 2} {$clientenv 3} {$clientenv2 4}" 284 285 # 286 # Verify that if a non-lease site tries to join a group that 287 # is using leases, it gets an error. Configuring leases 288 # must be all-or-none across all group members. 289 # 290 puts "\tRep$tnum.g: Add client3 that does not configure leases." 291 replclear 5 292 set envcmd(3) "berkdb_env_noerr -create $c3_txnargs $c3_logargs \ 293 -home $clientdir3 -event rep_event \ 294 $repmemargs $verbargs -errpfx CLIENT3 \ 295 -rep_client -rep_transport \[list 5 replsend\]" 296 set clientenv3 [eval $envcmd(3)] 297 error_check_good client_env [is_valid_env $clientenv3] TRUE 298 299 # Bring the clients online by processing the startup messages. 300 set origlist $envlist 301 set envlist "{$masterenv 2} {$clientenv 3} \ 302 {$clientenv2 4} {$clientenv3 5}" 303 process_msgs $envlist 0 NONE err 304 305 puts "\tRep$tnum.g.1: Verify client fatal error." 306 error_check_good process_msgs_err [is_substr $err DB_RUNRECOVERY] 1 307 # 308 # Close to reclaim Tcl resources, but we want to catch/ignore 309 # the continuing DB_RUNRECOVERY error. 310 # 311 catch {$clientenv3 close} ret 312 set envlist $origlist 313 314 puts "\tRep$tnum.h: Check expired lease error on txn commit." 315 # 316 # Leases are already expired, so attempt to commit should fail. 317 # (And this will be the 'before we commit' check that returns 318 # an error, not the 'after' check that panics). 319 # 320 set txn [$masterenv txn] 321 set stat [catch {$txn commit} ret] 322 error_check_good stat $stat 1 323 error_check_good exp [is_substr $ret REP_LEASE_EXPIRED] 1 324 325 error_check_good mclose [$masterenv close] 0 326 error_check_good cclose [$clientenv close] 0 327 error_check_good c2close [$clientenv2 close] 0 328 replclose $testdir/MSGQUEUEDIR 329} 330