summaryrefslogtreecommitdiff
path: root/db-4.8.30/test/recd021.tcl
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2016-12-17 21:28:53 -0800
committerJesse Morgan <jesse@jesterpm.net>2016-12-17 21:28:53 -0800
commit54df2afaa61c6a03cbb4a33c9b90fa572b6d07b8 (patch)
tree18147b92b969d25ffbe61935fb63035cac820dd0 /db-4.8.30/test/recd021.tcl
Berkeley DB 4.8 with rust build script for linux.
Diffstat (limited to 'db-4.8.30/test/recd021.tcl')
-rw-r--r--db-4.8.30/test/recd021.tcl278
1 files changed, 278 insertions, 0 deletions
diff --git a/db-4.8.30/test/recd021.tcl b/db-4.8.30/test/recd021.tcl
new file mode 100644
index 0000000..b6eae16
--- /dev/null
+++ b/db-4.8.30/test/recd021.tcl
@@ -0,0 +1,278 @@
+# See the file LICENSE for redistribution information.
+#
+# Copyright (c) 2004-2009 Oracle. All rights reserved.
+#
+# $Id$
+#
+# TEST recd021
+# TEST Test of failed opens in recovery.
+# TEST
+# TEST If a file was deleted through the file system (and not
+# TEST within Berkeley DB), an error message should appear.
+# TEST Test for regular files and subdbs.
+
+proc recd021 { method args } {
+ source ./include.tcl
+ global util_path
+
+ set args [convert_args $method $args]
+ set omethod [convert_method $method]
+ set nentries 100
+
+ puts "\nRecd021: ($method)\
+ Test failed opens in recovery."
+
+ # The file ops "remove" and "rename" are done within
+ # Berkeley DB. A "delete" is done directly on the file
+ # system (as if the user deleted the file).
+ #
+ # First test regular files.
+ #
+ foreach op { remove rename delete noop } {
+ env_cleanup $testdir
+ puts "\tRecd021: Test $op of file in recovery."
+
+ # Create transactional environment.
+ set env [berkdb_env -create -home $testdir -txn]
+ error_check_good is_valid_env [is_valid_env $env] TRUE
+
+ # Create database
+ puts "\t\tRecd021.a.1: Create and populate file."
+
+ if { $op == "rename" } {
+ set names {A B}
+ } else {
+ set names {A}
+ }
+ set name [lindex $names 0]
+
+ set db [eval {berkdb_open \
+ -create} $omethod $args -env $env -auto_commit $name.db]
+ error_check_good dba_open [is_valid_db $db] TRUE
+
+ # Checkpoint.
+ error_check_good txn_checkpoint [$env txn_checkpoint] 0
+ for { set i 1 } { $i <= $nentries } { incr i } {
+ error_check_good dba_put [$db put $i data$i] 0
+ }
+ error_check_good dba_close [$db close] 0
+
+ # Do operation on file.
+ puts "\t\tRecd021.b: Do $op on file."
+ set txn [$env txn]
+ set ret [do_op $omethod $op $names $txn $env]
+ error_check_good do_op $ret 0
+ error_check_good txn_commit [$txn commit] 0
+ error_check_good env_close [$env close] 0
+
+ # Recover.
+ puts "\t\tRecd021.c: Recover."
+ set ret [catch {exec $util_path/db_recover -h $testdir} r]
+ if { $op == "delete" } {
+ error_check_good external_delete \
+ [is_substr $r "Warning: open failed"] 1
+ } else {
+ error_check_good $op $ret 0
+ }
+
+ # Clean up.
+ error_check_good \
+ env_remove [berkdb envremove -force -home $testdir] 0
+ fileremove -f $testdir/$name.db
+ }
+
+ # Test subdbs.
+ if { [is_queue $method] == 1 } {
+ puts "Recd021: Skipping test of subdbs for method $method."
+ return
+ }
+
+ # The first subdb test just does the op, and is comparable
+ # to the tests for regular files above.
+ set trunc 0
+ set special {}
+ foreach op { remove rename delete noop } {
+ recd021_testsubdb $method $op $nentries $special $trunc $args
+ }
+
+ # The remainder of the tests are executed first with the log intact,
+ # then with the log truncated at the __db_subdb_name record.
+ foreach trunc { 0 1 } {
+ # Test what happens if subdb2 reuses pages formerly in
+ # subdb1, after removing subdb1.
+ set special "reuse"
+ recd021_testsubdb $method remove $nentries $special $trunc $args
+
+ # Test what happens if a new subdb reuses pages formerly
+ # in subdb1, after removing subdb1.
+ set special "newdb"
+ recd021_testsubdb $method remove $nentries $special $trunc $args
+
+ # Now we test what happens if a new subdb if a different access
+ # method reuses pages formerly in subdb1, after removing subdb1.
+ set special "newtypedb"
+ recd021_testsubdb $method remove $nentries $special $trunc $args
+ }
+}
+
+proc recd021_testsubdb { method op nentries special trunc largs } {
+ source ./include.tcl
+ global util_path
+
+ set omethod [convert_method $method]
+ env_cleanup $testdir
+
+ puts "\tRecd021: \
+ Test $op of subdb in recovery ($special trunc = $trunc)."
+
+ # Create transactional environment.
+ set env [berkdb_env -create -home $testdir -txn]
+ error_check_good is_valid_env [is_valid_env $env] TRUE
+
+ # Create database with 2 subdbs
+ puts "\t\tRecd021.d: Create and populate subdbs."
+ set sname1 S1
+ set sname2 S2
+ if { $op == "rename" } {
+ set names {A S1 NEW_S1}
+ } elseif { $op == "delete" } {
+ set names {A}
+ } else {
+ set names {A S1}
+ }
+ set name [lindex $names 0]
+
+ set sdb1 [eval {berkdb_open -create} $omethod \
+ $largs -env $env -auto_commit $name.db $sname1]
+ error_check_good sdb1_open [is_valid_db $sdb1] TRUE
+ set sdb2 [eval {berkdb_open -create} $omethod \
+ $largs -env $env -auto_commit $name.db $sname2]
+ error_check_good sdb2_open [is_valid_db $sdb2] TRUE
+
+ # Checkpoint.
+ error_check_good txn_checkpoint [$env txn_checkpoint] 0
+ for { set i 1 } { $i <= $nentries } { incr i } {
+ error_check_good sdb1_put [$sdb1 put $i data$i] 0
+ }
+ set dumpfile dump.s1.$trunc
+ set ret [exec $util_path/db_dump -dar -f $dumpfile -h $testdir A.db]
+ for { set i 1 } { $i <= $nentries } { incr i } {
+ error_check_good sdb2_put [$sdb2 put $i data$i] 0
+ }
+ error_check_good sdb1_close [$sdb1 close] 0
+
+ # Do operation on subdb.
+ puts "\t\tRecd021.e: Do $op on file."
+ set txn [$env txn]
+
+ if { $trunc == 1 } {
+ # Create a log cursor to mark where we are before
+ # doing the op.
+ set logc [$env log_cursor]
+ set ret [lindex [$logc get -last] 0]
+ file copy -force $testdir/log.0000000001 $testdir/log.sav
+ }
+
+ set ret [do_subdb_op $omethod $op $names $txn $env]
+ error_check_good do_subdb_op $ret 0
+ error_check_good txn_commit [$txn commit] 0
+
+ if { $trunc == 1 } {
+ # Walk the log and find the __db_subdb_name entry.
+ set found 0
+ while { $found == 0 } {
+ set lsn [lindex [$logc get -next] 0]
+ set lfile [lindex $lsn 0]
+ set loff [lindex $lsn 1]
+ set logrec [exec $util_path/db_printlog -h $testdir \
+ -b $lfile/$loff -e $lfile/$loff]
+ if { [is_substr $logrec __db_subdb_name] == 1 } {
+ set found 1
+ }
+ }
+ # Create the truncated log, and save it for later.
+ catch [exec dd if=$testdir/log.0000000001 \
+ of=$testdir/log.sav count=$loff bs=1 >& /dev/null ] res
+ }
+
+ # Here we do the "special" thing, if any. We always
+ # have to close sdb2, but when we do so varies.
+ switch -exact -- $special {
+ "" {
+ error_check_good sdb2_close [$sdb2 close] 0
+ }
+ reuse {
+ for { set i [expr $nentries + 1] } \
+ { $i <= [expr $nentries * 2]} { incr i } {
+ error_check_good sdb2_put \
+ [$sdb2 put $i data$i] 0
+ }
+ error_check_good sdb2_close [$sdb2 close] 0
+ set dumpfile dump.s2.$trunc
+ set ret [exec $util_path/db_dump -dar \
+ -f $dumpfile -h $testdir A.db]
+ }
+ newdb {
+ error_check_good sdb2_close [$sdb2 close] 0
+ set sname3 S3
+ set sdb3 [eval {berkdb_open -create} $omethod \
+ $largs -env $env -auto_commit $name.db $sname3]
+ error_check_good sdb3_open [is_valid_db $sdb3] TRUE
+ for { set i 1 } { $i <= $nentries } { incr i } {
+ error_check_good sdb3_put \
+ [$sdb3 put $i data$i] 0
+ }
+ error_check_good sdb3_close [$sdb3 close] 0
+ }
+ newtypedb {
+ error_check_good sdb2_close [$sdb2 close] 0
+ set sname4 S4
+ set newmethod [different_method $method]
+ set args [convert_args $newmethod]
+ set omethod [convert_method $newmethod]
+ set sdb4 [eval {berkdb_open -create} $omethod \
+ $args -env $env -auto_commit $name.db $sname4]
+ error_check_good sdb4_open [is_valid_db $sdb4] TRUE
+ for { set i 1 } { $i <= $nentries } { incr i } {
+ error_check_good sdb4_put \
+ [$sdb4 put $i data$i] 0
+ }
+ error_check_good sdb4_close [$sdb4 close] 0
+ }
+ }
+
+ # Close the env.
+ error_check_good env_close [$env close] 0
+
+ if { $trunc == 1 } {
+ # Swap in the truncated log.
+ file rename -force $testdir/log.sav $testdir/log.0000000001
+ }
+
+ # Recover.
+ puts "\t\tRecd021.f: Recover."
+ set ret [catch {exec $util_path/db_recover -h $testdir} r]
+ if { $op == "delete" || $trunc == 1 && $special != "newdb" } {
+ error_check_good expect_warning \
+ [is_substr $r "Warning: open failed"] 1
+ } else {
+ error_check_good subdb_$op $ret 0
+ }
+
+ # Clean up.
+ error_check_good env_remove [berkdb envremove -force -home $testdir] 0
+ fileremove -f $testdir/$name.db
+}
+
+proc different_method { method } {
+ # Queue methods are omitted, since this is for subdb testing.
+ set methodlist { -btree -rbtree -recno -frecno -rrecno -hash }
+
+ set method [convert_method $method]
+ set newmethod $method
+ while { $newmethod == $method } {
+ set index [berkdb random_int 0 [expr [llength $methodlist] - 1]]
+ set newmethod [lindex $methodlist $index]
+ }
+ return $newmethod
+}