1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2005-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST rep043 8# TEST 9# TEST Constant writes during upgrade/downgrade. 10# TEST 11# TEST Three envs take turns being master. Each env 12# TEST has a child process which does writes all the 13# TEST time. They will succeed when that env is master 14# TEST and fail when it is not. 15 16proc rep043 { method { rotations 25 } { tnum "043" } args } { 17 18 source ./include.tcl 19 global repfiles_in_memory 20 21 if { $is_windows9x_test == 1 } { 22 puts "Skipping replication test on Win 9x platform." 23 return 24 } 25 26 # Skip for record-based methods. 27 if { $checking_valid_methods } { 28 set test_methods {} 29 foreach method $valid_methods { 30 if { [is_record_based $method] != 1 } { 31 lappend test_methods $method 32 } 33 } 34 return $test_methods 35 } 36 if { [is_record_based $method] == 1 } { 37 puts "Skipping rep$tnum for record-based methods." 38 return 39 } 40 41 set args [convert_args $method $args] 42 set logsets [create_logsets 3] 43 44 set msg2 "and on-disk replication files" 45 if { $repfiles_in_memory } { 46 set msg2 "and in-memory replication files" 47 } 48 49 # Run the body of the test with and without recovery. 50 foreach r $test_recopts { 51 foreach l $logsets { 52 set logindex [lsearch -exact $l "in-memory"] 53 if { $r == "-recover" && $logindex != -1 } { 54 puts "Rep$tnum: Skipping\ 55 for in-memory logs with -recover." 56 continue 57 } 58 puts "Rep$tnum ($method $r): Constant writes with \ 59 rotating master $rotations times $msg2." 60 puts "Rep$tnum: Master logs are [lindex $l 0]" 61 puts "Rep$tnum: Client 0 logs are [lindex $l 1]" 62 puts "Rep$tnum: Client 1 logs are [lindex $l 2]" 63 rep043_sub $method $rotations $tnum $l $r $args 64 } 65 } 66} 67 68proc rep043_sub { method rotations tnum logset recargs largs } { 69 source ./include.tcl 70 global repfiles_in_memory 71 global rep_verbose 72 global verbose_type 73 74 set verbargs "" 75 if { $rep_verbose == 1 } { 76 set verbargs " -verbose {$verbose_type on} " 77 } 78 79 set repmemargs "" 80 if { $repfiles_in_memory } { 81 set repmemargs "-rep_inmem_files " 82 } 83 84 env_cleanup $testdir 85 set orig_tdir $testdir 86 87 replsetup $testdir/MSGQUEUEDIR 88 89 set masterdir $testdir/ENV0 90 set clientdir $testdir/ENV1 91 set clientdir2 $testdir/ENV2 92 file mkdir $masterdir 93 file mkdir $clientdir 94 file mkdir $clientdir2 95 96 set m_logtype [lindex $logset 0] 97 set c_logtype [lindex $logset 1] 98 set c2_logtype [lindex $logset 2] 99 100 # In-memory logs require a large log buffer, and cannot 101 # be used with -txn nosync. 102 set m_logargs [adjust_logargs $m_logtype] 103 set c_logargs [adjust_logargs $c_logtype] 104 set c2_logargs [adjust_logargs $c2_logtype] 105 set m_txnargs [adjust_txnargs $m_logtype] 106 set c_txnargs [adjust_txnargs $c_logtype] 107 set c2_txnargs [adjust_txnargs $c2_logtype] 108 109 set niter 200 110 set testfile rep043.db 111 set omethod [convert_method $method] 112 113 # Since we're constantly switching master in this test run 114 # each with a different cache size just to verify that cachesize 115 # doesn't matter for different sites. 116 117 # Open a master. 118 repladd 1 119 set ma_envcmd "berkdb_env_noerr -create $m_txnargs $repmemargs \ 120 $m_logargs -errpfx ENV0 -errfile /dev/stderr $verbargs \ 121 -cachesize {0 4194304 3} -lock_detect default \ 122 -home $masterdir -rep_transport \[list 1 replsend\]" 123 set env0 [eval $ma_envcmd $recargs -rep_master] 124 125 # Open two clients 126 repladd 2 127 set cl_envcmd "berkdb_env_noerr -create $c_txnargs $repmemargs \ 128 $c_logargs -errpfx ENV1 -errfile /dev/stderr $verbargs \ 129 -cachesize {0 2097152 2} -lock_detect default \ 130 -home $clientdir -rep_transport \[list 2 replsend\]" 131 set env1 [eval $cl_envcmd $recargs -rep_client] 132 133 repladd 3 134 set cl2_envcmd "berkdb_env_noerr -create $c2_txnargs $repmemargs \ 135 $c2_logargs -errpfx ENV2 -errfile /dev/stderr $verbargs \ 136 -cachesize {0 1048576 1} -lock_detect default \ 137 -home $clientdir2 -rep_transport \[list 3 replsend\]" 138 set env2 [eval $cl2_envcmd $recargs -rep_client] 139 140 # Bring the clients online by processing the startup messages. 141 set envlist "{$env0 1} {$env1 2} {$env2 3}" 142 process_msgs $envlist 143 144 # Set up marker file. 145 set markerenv [berkdb_env -create -home $testdir -txn] 146 error_check_good marker_open [is_valid_env $markerenv] TRUE 147 set marker [eval "berkdb_open \ 148 -create -btree -auto_commit -env $markerenv marker.db"] 149 150 # Start the 3 child processes: one for each env. 151 set pids {} 152 set dirlist "0 $masterdir 1 $clientdir 2 $clientdir2" 153 foreach { writer dir } $dirlist { 154 puts "\tRep$tnum.a: Fork child process WRITER$writer." 155 set pid [exec $tclsh_path $test_path/wrap.tcl \ 156 rep043script.tcl $testdir/rep043script.log.$writer \ 157 $dir $writer &] 158 lappend pids $pid 159 } 160 161 # For the first iteration, masterenv is $env0. 162 set masterenv $env0 163 set curdir $masterdir 164 165 # Write $niter entries to master, then rotate. 166 for { set i 0 } { $i < $rotations } { incr i } { 167 168 # Identify current master, determine next master 169 if { $masterenv == $env0 } { 170 set nextmasterenv $env1 171 set nextdir $clientdir 172 } elseif { $masterenv == $env1 } { 173 set nextmasterenv $env2 174 set nextdir $clientdir2 175 } elseif { $masterenv == $env2 } { 176 set nextmasterenv $env0 177 set nextdir $masterdir 178 } else { 179 puts "FAIL: could not identify current master" 180 return 181 } 182 183 puts "\tRep$tnum.b.$i: Open master db in $curdir." 184 set mdb [eval {berkdb_open_noerr} -env $masterenv -auto_commit \ 185 -mode 0644 $omethod -create $testfile] 186 error_check_good dbopen [is_valid_db $mdb] TRUE 187 error_check_good marker_iter [$marker put ITER $i] 0 188 189 puts "\t\tRep$tnum.c.$i: Put data to master." 190 for { set j 0 } { $j < $niter } { incr j } { 191 set key KEY.$i.$j 192 set data DATA 193 set t [$masterenv txn] 194 set stat [catch \ 195 {eval {$mdb put} -txn $t $key $data} ret] 196 if { $ret == 0 } { 197 error_check_good commit [$t commit] 0 198 } else { 199 error_check_good commit [$t abort] 0 200 } 201 } 202 error_check_good mdb_close [$mdb close] 0 203 204 # Checkpoint. 205 error_check_good checkpoint [$masterenv txn_checkpoint] 0 206 207 process_msgs $envlist 208 209 puts "\t\tRep$tnum.d.$i: Downgrade current master." 210 error_check_good downgrade [$masterenv rep_start -client] 0 211 212 puts "\t\tRep$tnum.e.$i: Upgrade next master $nextdir." 213 error_check_good upgrade [$nextmasterenv rep_start -master] 0 214 set masterenv $nextmasterenv 215 set curdir $nextdir 216 217 process_msgs $envlist 218 } 219 220 221 puts "\tRep$tnum.f: Clean up." 222 # Tell the child processes we are done. 223 error_check_good marker_done [$marker put DONE DONE] 0 224 error_check_good marker_close [$marker close] 0 225 error_check_good markerenv_close [$markerenv close] 0 226 227 error_check_good env0_close [$env0 close] 0 228 error_check_good env1_close [$env1 close] 0 229 error_check_good env2_close [$env2 close] 0 230 231 # Make sure the child processes are done. 232 watch_procs $pids 1 233 234 # Check log files for failures. 235 for { set n 0 } { $n < 3 } { incr n } { 236 set file rep043script.log.$n 237 set errstrings [eval findfail $testdir/$file] 238 foreach str $errstrings { 239 puts "FAIL: error message in file $file: $str" 240 } 241 } 242 243 replclose $testdir/MSGQUEUEDIR 244 set testdir $orig_tdir 245 return 246} 247