1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2004,2008 Oracle. All rights reserved. 4# 5# $Id: env012.tcl,v 12.18 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST env012 8# TEST Test DB_REGISTER. 9# TEST 10# TEST DB_REGISTER will fail on systems without fcntl. If it 11# TEST fails, make sure we got the expected DB_OPNOTSUP return. 12# TEST 13# TEST Then, the real tests: 14# TEST For each test, we start a process that opens an env with -register. 15# TEST 16# TEST 1. Verify that a 2nd process can enter the existing env with -register. 17# TEST 18# TEST 2. Kill the 1st process, and verify that the 2nd process can enter 19# TEST with "-register -recover". 20# TEST 21# TEST 3. Kill the 1st process, and verify that the 2nd process cannot 22# TEST enter with just "-register". 23# TEST 24# TEST 4. While the 1st process is still running, a 2nd process enters 25# TEST with "-register". Kill the 1st process. Verify that a 3rd process 26# TEST can enter with "-register -recover". Verify that the 3rd process, 27# TEST entering, causes process 2 to fail with the message DB_RUNRECOVERY. 28# TEST 29# TEST 5. We had a bug where recovery was always run with -register 30# TEST if there were empty slots in the process registry file. Verify 31# TEST that recovery doesn't automatically run if there is an empty slot. 32proc env012 { } { 33 source ./include.tcl 34 set tnum "012" 35 36 puts "Env$tnum: Test of DB_REGISTER." 37 38 puts "\tEnv$tnum.a: Platforms without fcntl fail with DB_OPNOTSUP." 39 env_cleanup $testdir 40 if {[catch {eval {berkdb_env} \ 41 -create -home $testdir -txn -register -recover} env]} { 42 error_check_good fail_OPNOTSUP [is_substr $env DB_OPNOTSUP] 1 43 puts "Skipping env$tnum; DB_REGISTER is not supported." 44 } 45 error_check_good env_close [$env close] 0 46 47 puts "\tEnv$tnum.b: Second process can join with -register." 48 env_cleanup $testdir 49 set testfile TESTFILE 50 set key KEY 51 set data DATA1 52 53 puts "\t\tEnv$tnum.b1: Start process 1." 54 set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 55 $testdir/env$tnum.log.p1 \ 56 $testdir $testfile PUT $key $data RECOVER 10 &] 57 58 # Wait a while so process 1 has a chance to get going. 59 tclsleep 2 60 61 puts "\t\tEnv$tnum.b2: Start process 2." 62 set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 63 $testdir/env$tnum.log.p2 \ 64 $testdir $testfile GET $key $data 0 0 &] 65 66 watch_procs $p1 1 120 67 watch_procs $p2 1 120 68 69 # Check log files for failures. 70 logcheck $testdir/env$tnum.log.p1 71 logcheck $testdir/env$tnum.log.p2 72 73 puts "\tEnv$tnum.c: Second process can join with -register\ 74 -recover after first process is killed." 75 env_cleanup $testdir 76 77 puts "\t\tEnv$tnum.c1: Start process 1." 78 set pids {} 79 set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 80 $testdir/env$tnum.log.p1 \ 81 $testdir $testfile PUT $key $data RECOVER 10 &] 82 lappend pids $p1 83 tclsleep 2 84 85 puts "\t\tEnv$tnum.c2: Kill process 1." 86 set pids [findprocessids $testdir $pids] 87 foreach pid $pids { 88 tclkill $pid 89 } 90 91 puts "\t\tEnv$tnum.c3: Start process 2." 92 set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 93 $testdir/env$tnum.log.p2 \ 94 $testdir $testfile GET $key $data RECOVER 0 &] 95 96 watch_procs $p2 1 120 97 98 # Check log files for failures. 99 logcheck $testdir/env$tnum.log.p1 100 logcheck $testdir/env$tnum.log.p2 101 102 if { $is_windows_test == 1 } { 103 puts "Skipping sections .d and .e on Windows platform." 104 } else { 105 puts "\tEnv$tnum.d: Second process cannot join without -recover\ 106 after first process is killed." 107 env_cleanup $testdir 108 109 puts "\t\tEnv$tnum.d1: Start process 1." 110 set pids {} 111 set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 112 $testdir/env$tnum.log.p1 \ 113 $testdir $testfile PUT $key $data RECOVER 10 &] 114 lappend pids $p1 115 tclsleep 2 116 117 puts "\t\tEnv$tnum.d2: Kill process 1." 118 set pids [findprocessids $testdir $pids] 119 foreach pid $pids { 120 tclkill $pid 121 } 122 123 puts "\t\tEnv$tnum.d3: Start process 2." 124 set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 125 $testdir/env$tnum.log.p2 \ 126 $testdir $testfile GET $key $data 0 0 &] 127 tclsleep 2 128 watch_procs $p2 1 120 129 130 # Check log files. Log p1 should be clean, but we 131 # expect DB_RUNRECOVERY in log p2. 132 logcheck $testdir/env$tnum.log.p1 133 logcheckfails $testdir/env$tnum.log.p2 DB_RUNRECOVERY 134 135 puts "\tEnv$tnum.e: Running registered process detects failure." 136 env_cleanup $testdir 137 138 puts "\t\tEnv$tnum.e1: Start process 1." 139 set pids {} 140 set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 141 $testdir/env$tnum.log.p1 \ 142 $testdir $testfile PUT $key $data RECOVER 10 &] 143 lappend pids $p1 144 tclsleep 2 145 146 # Identify child process to kill later. 147 set pids [findprocessids $testdir $pids] 148 149 puts "\t\tEnv$tnum.e2: Start process 2." 150 set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 151 $testdir/env$tnum.log.p2 \ 152 $testdir $testfile LOOP $key $data 0 10 &] 153 154 puts "\t\tEnv$tnum.e3: Kill process 1." 155 foreach pid $pids { 156 tclkill $pid 157 } 158 159 puts "\t\tEnv$tnum.e4: Start process 3." 160 set p3 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 161 $testdir/env$tnum.log.p3 \ 162 $testdir $testfile GET $key $data RECOVER 0 &] 163 tclsleep 2 164 165 watch_procs $p2 1 120 166 watch_procs $p3 1 120 167 168 # Check log files. Logs p1 and p3 should be clean, but we 169 # expect DB_RUNRECOVERY in log p2. 170 logcheck $testdir/env$tnum.log.p1 171 logcheckfails $testdir/env$tnum.log.p2 DB_RUNRECOVERY 172 logcheck $testdir/env$tnum.log.p3 173 } 174 175 puts "\tEnv$tnum.f: Empty slot shouldn't cause automatic recovery." 176 177 # Create 2 empty slots in the registry by letting two processes 178 # run to completion. 179 puts "\t\tEnv$tnum.f1: Start process 1." 180 set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 181 $testdir/env$tnum.log.p1 \ 182 $testdir $testfile PUT $key $data RECOVER 1 &] 183 184 puts "\t\tEnv$tnum.f2: Start process 2." 185 set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 186 $testdir/env$tnum.log.p2 \ 187 $testdir $testfile GET $key $data 0 1 &] 188 189 watch_procs $p1 1 60 190 watch_procs $p2 1 60 191 192 logcheck $testdir/env$tnum.log.p1 193 logcheck $testdir/env$tnum.log.p2 194 195 # Start two more process. Neither should signal a need for recovery. 196 puts "\t\tEnv$tnum.f3: Start process 3." 197 set p3 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 198 $testdir/env$tnum.log.p3 \ 199 $testdir $testfile GET $key $data RECOVER 10 &] 200 201 tclsleep 2 202 203 puts "\t\tEnv$tnum.f4: Start process 4." 204 set p4 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \ 205 $testdir/env$tnum.log.p4 \ 206 $testdir $testfile PUT $key $data 0 10 &] 207 208 watch_procs $p3 1 120 209 watch_procs $p4 1 120 210 211 # Check log files: neither process should have returned DB_RUNRECOVERY. 212 logcheck $testdir/env$tnum.log.p3 213 logcheck $testdir/env$tnum.log.p4 214} 215 216# Check log file and report failures with FAIL. Use this when 217# we don't expect failures. 218proc logcheck { logname } { 219 set errstrings [eval findfail $logname] 220 foreach errstring $errstrings { 221 puts "FAIL: error in $logname : $errstring" 222 } 223} 224 225# When we expect a failure, verify we find the one we expect. 226proc logcheckfails { logname message } { 227 set f [open $logname r] 228 while { [gets $f line] >= 0 } { 229 if { [is_substr $line $message] == 1 } { 230 close $f 231 return 0 232 } 233 } 234 close $f 235 puts "FAIL: Did not find expected error $message." 236} 237 238# The script wrap.tcl creates a parent and a child process. We 239# can't see the child pids, so find them by their sentinel files. 240# This creates a list where the parent pid is always listed 241# before the child pid. 242proc findprocessids { testdir plist } { 243 set beginfiles [glob $testdir/begin.*] 244 foreach b $beginfiles { 245 regsub $testdir/begin. $b {} pid 246 if { [lsearch -exact $plist $pid] == -1 } { 247 lappend plist $pid 248 } 249 } 250 return $plist 251} 252 253