summaryrefslogtreecommitdiff
path: root/test/txn011.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'test/txn011.tcl')
-rw-r--r--test/txn011.tcl224
1 files changed, 224 insertions, 0 deletions
diff --git a/test/txn011.tcl b/test/txn011.tcl
new file mode 100644
index 0000000..139d130
--- /dev/null
+++ b/test/txn011.tcl
@@ -0,0 +1,224 @@
+# See the file LICENSE for redistribution information.
+#
+# Copyright (c) 2003-2009 Oracle. All rights reserved.
+#
+# $Id$
+#
+# TEST txn011
+# TEST Test durable and non-durable txns.
+# TEST Test a mixed env (with both durable and non-durable
+# TEST dbs), then a purely non-durable env. Make sure commit
+# TEST and abort work, and that only the log records we
+# TEST expect are written.
+# TEST Test that we can't get a durable handle on an open ND
+# TEST database, or vice versa. Test that all subdb's
+# TEST must be of the same type (D or ND).
+proc txn011 { {ntxns 100} } {
+ source ./include.tcl
+ global util_path
+
+ foreach envtype { "" "-private" } {
+ puts "Txn011: Non-durable txns ($envtype)."
+ env_cleanup $testdir
+
+ puts "\tTxn011.a: Persistent env recovery with -log_inmemory"
+ set lbuf [expr 8 * [expr 1024 * 1024]]
+ set env_cmd "berkdb_env -create \
+ -home $testdir -txn -log_inmemory -log_buffer $lbuf"
+ set ndenv [eval $env_cmd $envtype]
+ set db [berkdb_open -create -auto_commit \
+ -btree -env $ndenv -notdurable test.db]
+ check_log_records $testdir
+ error_check_good db_close [$db close] 0
+ error_check_good ndenv_close [$ndenv close] 0
+
+ # Run recovery with -e to retain environment.
+ set stat [catch {exec $util_path/db_recover -e -h $testdir} ret]
+ error_check_good db_printlog $stat 0
+
+ # Rejoin env and make sure that the db is still there.
+ set ndenv [berkdb_env -home $testdir]
+ set db [berkdb_open -auto_commit -env $ndenv test.db]
+ error_check_good db_close [$db close] 0
+ error_check_good ndenv_close [$ndenv close] 0
+ env_cleanup $testdir
+
+ # Start with a new env for the next test.
+ set ndenv [eval $env_cmd]
+ error_check_good env_open [is_valid_env $ndenv] TRUE
+
+ # Open/create the database.
+ set testfile notdurable.db
+ set db [eval berkdb_open -create \
+ -auto_commit -env $ndenv -notdurable -btree $testfile]
+ error_check_good dbopen [is_valid_db $db] TRUE
+
+ puts "\tTxn011.b: Abort txns in in-memory logging env."
+ txn011_runtxns $ntxns $db $ndenv abort
+ # Make sure there is nothing in the db.
+ txn011_check_empty $db $ndenv
+
+ puts "\tTxn011.c: Commit txns in in-memory logging env."
+ txn011_runtxns $ntxns $db $ndenv commit
+
+ # Make sure we haven't written any inappropriate log records
+ check_log_records $testdir
+
+ # Clean up non-durable env tests.
+ error_check_good db_close [$db close] 0
+ error_check_good ndenv_close [$ndenv close] 0
+ env_cleanup $testdir
+
+ puts "\tTxn011.d: Set up mixed durable/non-durable test."
+ # Open/create the mixed environment
+ set mixed_env_cmd "berkdb_env_noerr -create \
+ -home $testdir -txn -log_inmemory -log_buffer $lbuf"
+ set env [eval $mixed_env_cmd]
+ error_check_good env_open [is_valid_env $env] TRUE
+ check_log_records $testdir
+
+ # Open/create the non-durable database
+ set nondurfile nondurable.db
+ set ndb [berkdb_open_noerr -create\
+ -auto_commit -env $env -btree -notdurable $nondurfile]
+ error_check_good dbopen [is_valid_db $ndb] TRUE
+ check_log_records $testdir
+
+ puts "\tTxn011.e: Abort txns in non-durable db."
+ txn011_runtxns $ntxns $ndb $env abort
+ # Make sure there is nothing in the db.
+ txn011_check_empty $ndb $env
+ check_log_records $testdir
+
+ puts "\tTxn011.f: Commit txns in non-durable db."
+ txn011_runtxns $ntxns $ndb $env commit
+ check_log_records $testdir
+
+ # Open/create the durable database
+ set durfile durable.db
+ set ddb [eval berkdb_open_noerr \
+ -create -auto_commit -env $env -btree $durfile]
+ error_check_good dbopen [is_valid_db $ddb] TRUE
+
+ # Try to get a not-durable handle on the durable db.
+ puts "\tTxn011.g: Try to get a not-durable handle on\
+ an open durable db."
+ set errormsg "Cannot open DURABLE and NOT DURABLE handles"
+ catch {berkdb_open_noerr \
+ -auto_commit -env $env -notdurable $durfile} res
+ error_check_good handle_error1 [is_substr $res $errormsg] 1
+ error_check_good ddb_close [$ddb close] 0
+
+ # Try to get a not-durable handle when reopening the durable
+ # db (this should work).
+ set db [berkdb_open_noerr \
+ -auto_commit -env $env -notdurable $durfile]
+ error_check_good db_reopen [is_valid_db $db] TRUE
+ error_check_good db_close [$db close] 0
+
+ # Now reopen as durable for the remainder of the test.
+ set ddb [berkdb_open_noerr \
+ -auto_commit -env $env -btree $durfile]
+ error_check_good dbopen [is_valid_db $ddb] TRUE
+
+ puts "\tTxn011.h: Abort txns in durable db."
+ # Add items to db in several txns but abort every one.
+ txn011_runtxns $ntxns $ddb $env abort
+ # Make sure there is nothing in the db.
+ txn011_check_empty $ddb $env
+
+ puts "\tTxn011.i: Commit txns in durable db."
+ txn011_runtxns $ntxns $ddb $env commit
+
+ puts "\tTxn011.j: Subdbs must all be durable or all not durable."
+ # Ask for -notdurable on durable db/subdb
+ set sdb1 [eval berkdb_open_noerr -create -auto_commit \
+ -env $env -btree testfile1.db subdb1]
+ catch {set sdb2 [eval berkdb_open_noerr -create -auto_commit \
+ -env $env -btree -notdurable testfile1.db subdb2]} res
+ error_check_good same_type_subdb1 [is_substr $res $errormsg] 1
+ error_check_good sdb1_close [$sdb1 close] 0
+
+ # Ask for durable on notdurable db/subdb
+ set sdb3 [eval berkdb_open_noerr -create -auto_commit \
+ -env $env -btree -notdurable testfile2.db subdb3]
+ catch {set sdb4 [eval berkdb_open_noerr -create -auto_commit \
+ -env $env -btree testfile2.db subdb4]} res
+ error_check_good same_type_subdb2 [is_substr $res $errormsg] 1
+ error_check_good sdb3_close [$sdb3 close] 0
+
+ puts "\tTxn011.k: Try to get a durable handle on a\
+ not-durable db."
+ # Try to get a durable handle on a not-durable database,
+ # while open. This should fail, but getting a durable handle
+ # when re-opening should work.
+ catch {berkdb_open_noerr -auto_commit -env $env $nondurfile} res
+ error_check_good handle_error [is_substr $res $errormsg] 1
+ error_check_good ndb_close [$ndb close] 0
+
+ set ndb [berkdb_open_noerr -auto_commit -env $env $nondurfile]
+ error_check_good ndb_reopen [is_valid_db $ndb] TRUE
+ error_check_good ndb_close [$ndb close] 0
+
+ # Clean up mixed env.
+ error_check_good ddb_close [$ddb close] 0
+ error_check_good env_close [$env close] 0
+ }
+}
+
+proc txn011_runtxns { ntxns db env end } {
+ source ./include.tcl
+
+ set did [open $dict]
+ set i 0
+ while { [gets $did str] != -1 && $i < $ntxns } {
+ set txn [$env txn]
+ error_check_good txn_begin [is_valid_txn $txn $env] TRUE
+
+ error_check_good db_put_txn [$db put -txn $txn $i $str] 0
+ error_check_good txn_$end [$txn $end] 0
+ incr i
+ }
+ close $did
+}
+
+# Verify that a database is empty
+proc txn011_check_empty { db env } {
+ # Start a transaction
+ set t [$env txn]
+ error_check_good txn [is_valid_txn $t $env] TRUE
+ set txn "-txn $t"
+
+ # If a cursor get -first returns nothing, the db is empty.
+ set dbc [eval {$db cursor} $txn]
+ error_check_good db_cursor [is_substr $dbc $db] 1
+ set ret [$dbc get -first]
+ error_check_good get_on_empty [string length $ret] 0
+ error_check_good dbc_close [$dbc close] 0
+
+ # End transaction
+ error_check_good txn [$t commit] 0
+}
+
+# Some log records are still produced when we run create in a
+# non-durable db in a regular env. Just make sure we don't see
+# any unexpected types.
+proc check_log_records { dir } {
+ global util_path
+
+ set tmpfile $dir/printlog.out
+ set stat [catch {exec $util_path/db_printlog -h $dir > $tmpfile} ret]
+ error_check_good db_printlog $stat 0
+
+ set f [open $tmpfile r]
+ while { [gets $f record] >= 0 } {
+ set r [regexp {\[[^\]]*\]\[[^\]]*\]([^\:]*)\:} $record whl name]
+ if { $r == 1 && [string match *_debug $name] != 1 && \
+ [string match __txn_regop $name] != 1 && \
+ [string match __txn_child $name] != 1 } {
+ puts "FAIL: unexpected log record $name found"
+ }
+ }
+ close $f
+ fileremove $tmpfile
+}