1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2001,2008 Oracle. All rights reserved. 4# 5# $Id: rep078.tcl,v 12.12 2008/04/30 19:12:50 carol Exp $ 6# 7# TEST rep078 8# TEST 9# TEST Replication and basic lease test. 10# TEST Set leases on master and 2 clients. 11# TEST Do a lease operation and process to all clients. 12# TEST Read with lease on master. Do another lease operation 13# TEST and don't process on any client. Try to read with 14# TEST on the master and verify it fails. Process the messages 15# TEST to the clients and retry the read. 16# 17proc rep078 { method { tnum "078" } args } { 18 source ./include.tcl 19 20 if { $is_windows9x_test == 1 } { 21 puts "Skipping replication test on Win9x platform." 22 return 23 } 24 25 # Valid for all access methods. Other lease tests limit the 26 # test because there is nothing method-specific being tested. 27 # Use all methods for this basic test. 28 if { $checking_valid_methods } { 29 return "ALL" 30 } 31 32 set args [convert_args $method $args] 33 set logsets [create_logsets 3] 34 35 # Run the body of the test with and without recovery, 36 # and with and without cleaning. Skip recovery with in-memory 37 # logging - it doesn't make sense. 38 # 39 # Also skip the case where the master is in-memory and at least 40 # one of the clients is on-disk. If the master is in-memory, 41 # the wrong site gets elected because on-disk envs write a log 42 # record when they create the env and in-memory ones do not 43 # and the test wants to control which env gets elected. 44 # 45 foreach r $test_recopts { 46 foreach l $logsets { 47 set logindex [lsearch -exact $l "in-memory"] 48 if { $r == "-recover" && $logindex != -1 } { 49 puts "Skipping rep$tnum for -recover\ 50 with in-memory logs." 51 continue 52 } 53 set master_logs [lindex $l 0] 54 if { $master_logs == "in-memory" } { 55 set client_logs [lsearch -exact $l "on-disk"] 56 if { $client_logs != -1 } { 57 puts "Skipping for in-memory master\ 58 and on-disk client." 59 continue 60 } 61 } 62 63 puts "Rep$tnum ($method $r):\ 64 Replication and basic master leases." 65 puts "Rep$tnum: Master logs are [lindex $l 0]" 66 puts "Rep$tnum: Client 1 logs are [lindex $l 1]" 67 puts "Rep$tnum: Client 2 logs are [lindex $l 2]" 68 rep078_sub $method $tnum $l $r $args 69 } 70 } 71} 72 73proc rep078_sub { method tnum logset recargs largs } { 74 source ./include.tcl 75 global testdir 76 global rep_verbose 77 global verbose_type 78 79 set verbargs "" 80 if { $rep_verbose == 1 } { 81 set verbargs " -verbose {$verbose_type on} " 82 } 83 84 env_cleanup $testdir 85 86 set qdir $testdir/MSGQUEUEDIR 87 replsetup $qdir 88 89 set masterdir $testdir/MASTERDIR 90 set clientdir $testdir/CLIENTDIR 91 set clientdir2 $testdir/CLIENTDIR2 92 93 file mkdir $masterdir 94 file mkdir $clientdir 95 file mkdir $clientdir2 96 97 set m_logtype [lindex $logset 0] 98 set c_logtype [lindex $logset 1] 99 set c2_logtype [lindex $logset 2] 100 101 # In-memory logs require a large log buffer, and cannot 102 # be used with -txn nosync. 103 set m_logargs [adjust_logargs $m_logtype] 104 set c_logargs [adjust_logargs $c_logtype] 105 set c2_logargs [adjust_logargs $c2_logtype] 106 set m_txnargs [adjust_txnargs $m_logtype] 107 set c_txnargs [adjust_txnargs $c_logtype] 108 set c2_txnargs [adjust_txnargs $c2_logtype] 109 110 # Set leases for 3 sites, 3 second timeout, 0% clock skew 111 set nsites 3 112 set lease_to 3000000 113 set lease_tosec [expr $lease_to / 1000000] 114 set clock_fast 0 115 set clock_slow 0 116 set testfile test.db 117 # 118 # Since we have to use elections, the election code 119 # assumes a 2-off site id scheme. 120 # Open a master. 121 repladd 2 122 set err_cmd(0) "none" 123 set crash(0) 0 124 set pri(0) 100 125 # 126 # Note that using the default clock skew should be the same 127 # as specifying "no skew" through the API. We want to 128 # test both API usages here. 129 # 130 set envcmd(0) "berkdb_env -create $m_txnargs $m_logargs \ 131 $verbargs -errpfx MASTER -home $masterdir \ 132 -rep_lease \[list $nsites $lease_to\] \ 133 -event rep_event \ 134 -rep_client -rep_transport \[list 2 replsend\]" 135 set masterenv [eval $envcmd(0) $recargs] 136 error_check_good master_env [is_valid_env $masterenv] TRUE 137 138 # Open two clients. 139 repladd 3 140 set err_cmd(1) "none" 141 set crash(1) 0 142 set pri(1) 10 143 set envcmd(1) "berkdb_env -create $c_txnargs $c_logargs \ 144 $verbargs -errpfx CLIENT -home $clientdir \ 145 -rep_lease \[list $nsites $lease_to $clock_fast $clock_slow\] \ 146 -event rep_event \ 147 -rep_client -rep_transport \[list 3 replsend\]" 148 set clientenv [eval $envcmd(1) $recargs] 149 error_check_good client_env [is_valid_env $clientenv] TRUE 150 151 repladd 4 152 set err_cmd(2) "none" 153 set crash(2) 0 154 set pri(2) 10 155 set envcmd(2) "berkdb_env -create $c2_txnargs $c2_logargs \ 156 $verbargs -errpfx CLIENT2 -home $clientdir2 \ 157 -rep_lease \[list $nsites $lease_to\] \ 158 -event rep_event \ 159 -rep_client -rep_transport \[list 4 replsend\]" 160 set clientenv2 [eval $envcmd(2) $recargs] 161 error_check_good client_env [is_valid_env $clientenv2] TRUE 162 163 # Bring the clients online by processing the startup messages. 164 set envlist "{$masterenv 2} {$clientenv 3} {$clientenv2 4}" 165 process_msgs $envlist 166 167 # 168 # Run election to get a master. Leases prevent us from 169 # simply assigning a master. 170 # 171 set msg "Rep$tnum.a" 172 puts "\tRep$tnum.a: Run initial election." 173 set nvotes $nsites 174 set winner 0 175 setpriority pri $nsites $winner 176 set elector [berkdb random_int 0 2] 177 # 178 # Note we send in a 0 for nsites because we set nsites back 179 # when we started running with leases. Master leases require 180 # that nsites be set before calling rep_start, and master leases 181 # require that the nsites arg to rep_elect be 0. 182 # 183 run_election envcmd envlist err_cmd pri crash $qdir $msg \ 184 $elector 0 $nvotes $nsites $winner 0 NULL 185 186 puts "\tRep$tnum.b: Spawn a child tclsh to do txn work." 187 set pid [exec $tclsh_path $test_path/wrap.tcl \ 188 rep078script.tcl $testdir/rep078script.log \ 189 $masterdir $testfile $method &] 190 191 # Let child run, create database and put a txn into it. 192 # Process messages while we wait for the child to complete 193 # its txn so that the clients can grant leases. 194 puts "\tRep$tnum.c: Wait for child to write txn." 195 while { 1 } { 196 if { [file exists $testdir/marker.db] == 0 } { 197 tclsleep 1 198 } else { 199 set markerenv [berkdb_env -home $testdir -txn] 200 error_check_good markerenv_open \ 201 [is_valid_env $markerenv] TRUE 202 set marker [berkdb_open -unknown -env $markerenv \ 203 -auto_commit marker.db] 204 set kd [$marker get CHILD1] 205 while { [llength $kd] == 0 } { 206 process_msgs $envlist 207 tclsleep 1 208 set kd [$marker get CHILD1] 209 } 210 process_msgs $envlist 211 # 212 # Child sends us the key it used as the data 213 # of the CHILD1 key. 214 # 215 set key [lindex [lindex $kd 0] 1] 216 break 217 } 218 } 219 set masterdb [eval \ 220 {berkdb_open_noerr -env $masterenv -rdonly $testfile}] 221 error_check_good dbopen [is_valid_db $masterdb] TRUE 222 223 process_msgs $envlist 224 set omethod [convert_method $method] 225 set clientdb [eval {berkdb_open_noerr \ 226 -env $clientenv $omethod -rdonly $testfile}] 227 error_check_good dbopen [is_valid_db $clientdb] TRUE 228 229 set uselease "" 230 set ignorelease "-nolease" 231 puts "\tRep$tnum.d.0: Read with leases." 232 check_leaseget $masterdb $key $uselease 0 233 check_leaseget $clientdb $key $uselease 0 234 puts "\tRep$tnum.d.1: Read ignoring leases." 235 check_leaseget $masterdb $key $ignorelease 0 236 check_leaseget $clientdb $key $ignorelease 0 237 # 238 # This should fail because the lease is expired and all 239 # attempts by master to refresh it will not be processed. 240 # 241 set sleep [expr $lease_tosec + 1] 242 puts "\tRep$tnum.e.0: Sleep $sleep secs to expire leases and read again." 243 tclsleep $sleep 244 # 245 # Verify the master gets REP_LEASE_EXPIRED. Verify that the 246 # read on the client ignores leases and succeeds. 247 # 248 check_leaseget $masterdb $key $uselease REP_LEASE_EXPIRED 249 check_leaseget $clientdb $key $uselease 0 250 puts "\tRep$tnum.e.1: Read ignoring leases." 251 check_leaseget $masterdb $key $ignorelease 0 252 check_leaseget $clientdb $key $ignorelease 0 253 254 error_check_good timestamp_done \ 255 [$marker put PARENT1 [timestamp -r]] 0 256 257 set kd [$marker get CHILD2] 258 while { [llength $kd] == 0 } { 259 process_msgs $envlist 260 tclsleep 1 261 set kd [$marker get CHILD2] 262 } 263 process_msgs $envlist 264 # 265 # Child sends us the key it used as the data 266 # of the CHILD2 key. 267 # 268 set key [lindex [lindex $kd 0] 1] 269 270 puts "\tRep$tnum.f: Child writes txn + ckp. Don't process msgs." 271 # 272 # Child has committed the txn and we have processed it. Now 273 # signal the child process to put a checkpoint, which we 274 # will not process. That will invalidate leases. 275 error_check_good timestamp_done \ 276 [$marker put PARENT2 [timestamp -r]] 0 277 278 set kd [$marker get CHILD3] 279 while { [llength $kd] == 0 } { 280 tclsleep 1 281 set kd [$marker get CHILD3] 282 } 283 284 puts "\tRep$tnum.f.0: Read using leases fails." 285 check_leaseget $masterdb $key $uselease REP_LEASE_EXPIRED 286 puts "\tRep$tnum.f.1: Read ignoring leases." 287 check_leaseget $masterdb $key $ignorelease 0 288 puts "\tRep$tnum.g: Process messages to clients." 289 process_msgs $envlist 290 puts "\tRep$tnum.h: Verify read with leases now succeeds." 291 check_leaseget $masterdb $key $uselease 0 292 293 watch_procs $pid 5 294 295 process_msgs $envlist 296 rep_verify $masterdir $masterenv $clientdir $clientenv 297 process_msgs $envlist 298 rep_verify $masterdir $masterenv $clientdir2 $clientenv2 0 1 0 299 300 # Clean up. 301 error_check_good marker_db_close [$marker close] 0 302 error_check_good marker_env_close [$markerenv close] 0 303 error_check_good masterdb_close [$masterdb close] 0 304 error_check_good masterdb_close [$clientdb close] 0 305 error_check_good masterenv_close [$masterenv close] 0 306 error_check_good clientenv_close [$clientenv close] 0 307 error_check_good clientenv_close [$clientenv2 close] 0 308 309 replclose $testdir/MSGQUEUEDIR 310 311 # Check log file for failures. 312 set errstrings [eval findfail $testdir/rep078script.log] 313 foreach str $errstrings { 314 puts "FAIL: error message in rep078 log file: $str" 315 } 316} 317 318