summaryrefslogtreecommitdiff
path: root/db/test/env012.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'db/test/env012.tcl')
-rw-r--r--db/test/env012.tcl253
1 files changed, 253 insertions, 0 deletions
diff --git a/db/test/env012.tcl b/db/test/env012.tcl
new file mode 100644
index 000000000..4f40bd28b
--- /dev/null
+++ b/db/test/env012.tcl
@@ -0,0 +1,253 @@
+# See the file LICENSE for redistribution information.
+#
+# Copyright (c) 2004-2006
+# Oracle Corporation. All rights reserved.
+#
+# $Id: env012.tcl,v 12.11 2006/09/18 19:43:26 carol Exp $
+#
+# TEST env012
+# TEST Test DB_REGISTER.
+# TEST
+# TEST DB_REGISTER will fail on systems without fcntl. If it
+# TEST fails, make sure we got the expected DB_OPNOTSUP return.
+# TEST
+# TEST Then, the real tests:
+# TEST For each test, we start a process that opens an env with -register.
+# TEST
+# TEST 1. Verify that a 2nd process can enter the existing env with -register.
+# TEST
+# TEST 2. Kill the 1st process, and verify that the 2nd process can enter
+# TEST with "-register -recover".
+# TEST
+# TEST 3. Kill the 1st process, and verify that the 2nd process cannot
+# TEST enter with just "-register".
+# TEST
+# TEST 4. While the 1st process is still running, a 2nd process enters
+# TEST with "-register". Kill the 1st process. Verify that a 3rd process
+# TEST can enter with "-register -recover". Verify that the 3rd process,
+# TEST entering, causes process 2 to fail with the message DB_RUNRECOVERY.
+# TEST
+# TEST 5. We had a bug where recovery was always run with -register
+# TEST if there were empty slots in the process registry file. Verify
+# TEST that recovery doesn't automatically run if there is an empty slot.
+proc env012 { } {
+ source ./include.tcl
+ set tnum "012"
+
+ puts "Env$tnum: Test of DB_REGISTER."
+
+ puts "\tEnv$tnum.a: Platforms without fcntl fail with DB_OPNOTSUP."
+ env_cleanup $testdir
+ if {[catch {eval {berkdb_env} \
+ -create -home $testdir -txn -register -recover} env]} {
+ error_check_good fail_OPNOTSUP [is_substr $env DB_OPNOTSUP] 1
+ puts "Skipping env$tnum; DB_REGISTER is not supported."
+ }
+ error_check_good env_close [$env close] 0
+
+ puts "\tEnv$tnum.b: Second process can join with -register."
+ env_cleanup $testdir
+ set testfile TESTFILE
+ set key KEY
+ set data DATA1
+
+ puts "\t\tEnv$tnum.b1: Start process 1."
+ set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p1 \
+ $testdir $testfile PUT $key $data RECOVER 10 &]
+
+ # Wait a while so process 1 has a chance to get going.
+ tclsleep 2
+
+ puts "\t\tEnv$tnum.b2: Start process 2."
+ set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p2 \
+ $testdir $testfile GET $key $data 0 0 &]
+
+ watch_procs $p1 1 120
+ watch_procs $p2 1 120
+
+ # Check log files for failures.
+ logcheck $testdir/env$tnum.log.p1
+ logcheck $testdir/env$tnum.log.p2
+
+ puts "\tEnv$tnum.c: Second process can join with -register\
+ -recover after first process is killed."
+ env_cleanup $testdir
+
+ puts "\t\tEnv$tnum.c1: Start process 1."
+ set pids {}
+ set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p1 \
+ $testdir $testfile PUT $key $data RECOVER 10 &]
+ lappend pids $p1
+ tclsleep 2
+
+ puts "\t\tEnv$tnum.c2: Kill process 1."
+ set pids [findprocessids $testdir $pids]
+ foreach pid $pids {
+ tclkill $pid
+ }
+
+ puts "\t\tEnv$tnum.c3: Start process 2."
+ set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p2 \
+ $testdir $testfile GET $key $data RECOVER 0 &]
+
+ watch_procs $p2 1 120
+
+ # Check log files for failures.
+ logcheck $testdir/env$tnum.log.p1
+ logcheck $testdir/env$tnum.log.p2
+
+ if { $is_windows_test == 1 } {
+ puts "Skipping sections .d and .e on Windows platform."
+ } else {
+ puts "\tEnv$tnum.d: Second process cannot join without -recover\
+ after first process is killed."
+ env_cleanup $testdir
+
+ puts "\t\tEnv$tnum.d1: Start process 1."
+ set pids {}
+ set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p1 \
+ $testdir $testfile PUT $key $data RECOVER 10 &]
+ lappend pids $p1
+ tclsleep 2
+
+ puts "\t\tEnv$tnum.d2: Kill process 1."
+ set pids [findprocessids $testdir $pids]
+ foreach pid $pids {
+ tclkill $pid
+ }
+
+ puts "\t\tEnv$tnum.d3: Start process 2."
+ set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p2 \
+ $testdir $testfile GET $key $data 0 0 &]
+ tclsleep 2
+ watch_procs $p2 1 120
+
+ # Check log files. Log p1 should be clean, but we
+ # expect DB_RUNRECOVERY in log p2.
+ logcheck $testdir/env$tnum.log.p1
+ logcheckfails $testdir/env$tnum.log.p2 DB_RUNRECOVERY
+
+ puts "\tEnv$tnum.e: Running registered process detects failure."
+ env_cleanup $testdir
+
+ puts "\t\tEnv$tnum.e1: Start process 1."
+ set pids {}
+ set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p1 \
+ $testdir $testfile PUT $key $data RECOVER 10 &]
+ lappend pids $p1
+ tclsleep 2
+
+ # Identify child process to kill later.
+ set pids [findprocessids $testdir $pids]
+
+ puts "\t\tEnv$tnum.e2: Start process 2."
+ set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p2 \
+ $testdir $testfile LOOP $key $data 0 10 &]
+
+ puts "\t\tEnv$tnum.e3: Kill process 1."
+ foreach pid $pids {
+ tclkill $pid
+ }
+
+ puts "\t\tEnv$tnum.e4: Start process 3."
+ set p3 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p3 \
+ $testdir $testfile GET $key $data RECOVER 0 &]
+ tclsleep 2
+
+ watch_procs $p2 1 120
+ watch_procs $p3 1 120
+
+ # Check log files. Logs p1 and p3 should be clean, but we
+ # expect DB_RUNRECOVERY in log p2.
+ logcheck $testdir/env$tnum.log.p1
+ logcheckfails $testdir/env$tnum.log.p2 DB_RUNRECOVERY
+ logcheck $testdir/env$tnum.log.p3
+ }
+
+ puts "\tEnv$tnum.f: Empty slot shouldn't cause automatic recovery."
+
+ # Create 2 empty slots in the registry by letting two processes
+ # run to completion.
+ puts "\t\tEnv$tnum.f1: Start process 1."
+ set p1 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p1 \
+ $testdir $testfile PUT $key $data RECOVER 1 &]
+
+ puts "\t\tEnv$tnum.f2: Start process 2."
+ set p2 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p2 \
+ $testdir $testfile GET $key $data 0 1 &]
+
+ watch_procs $p1 1 60
+ watch_procs $p2 1 60
+
+ logcheck $testdir/env$tnum.log.p1
+ logcheck $testdir/env$tnum.log.p2
+
+ # Start two more process. Neither should signal a need for recovery.
+ puts "\t\tEnv$tnum.f3: Start process 3."
+ set p3 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p3 \
+ $testdir $testfile GET $key $data RECOVER 10 &]
+
+ tclsleep 2
+
+ puts "\t\tEnv$tnum.f4: Start process 4."
+ set p4 [exec $tclsh_path $test_path/wrap.tcl envscript.tcl \
+ $testdir/env$tnum.log.p4 \
+ $testdir $testfile PUT $key $data 0 10 &]
+
+ watch_procs $p3 1 120
+ watch_procs $p4 1 120
+
+ # Check log files to verify that neither process returned DB_RUNRECOVERY.
+ logcheck $testdir/env$tnum.log.p3
+ logcheck $testdir/env$tnum.log.p4
+}
+
+# Check log file and report failures with FAIL. Use this when
+# we don't expect failures.
+proc logcheck { logname } {
+ set errstrings [eval findfail $logname]
+ foreach errstring $errstrings {
+ puts "FAIL: error in $logname : $errstring"
+ }
+}
+
+# When we expect a failure, verify we find the one we expect.
+proc logcheckfails { logname message } {
+ set f [open $logname r]
+ while { [gets $f line] >= 0 } {
+ if { [is_substr $line $message] == 1 } {
+ close $f
+ return 0
+ }
+ }
+ close $f
+ puts "FAIL: Did not find expected error $message."
+}
+
+# The script wrap.tcl creates a parent and a child process. We
+# can't see the child pids, so find them by their sentinel files.
+# This creates a list where the parent pid is always listed
+# before the child pid.
+proc findprocessids { testdir plist } {
+ set beginfiles [glob $testdir/begin.*]
+ foreach b $beginfiles {
+ regsub $testdir/begin. $b {} pid
+ if { [lsearch -exact $plist $pid] == -1 } {
+ lappend plist $pid
+ }
+ }
+ return $plist
+}
+