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