1
# See the file LICENSE for redistribution information.
3
# Copyright (c) 1996-2002
4
# Sleepycat Software. All rights reserved.
10
# TEST Test abort/commit/prepare of txns with outstanding child txns.
11
proc txn003 { {tnum "03"} } {
16
puts -nonewline "Txn0$tnum: Outstanding child transaction test"
18
if { $tnum != "03" } {
19
puts " (with ID wrap)"
24
set testfile txn003.db
26
set env_cmd "berkdb_env_noerr -create -txn -home $testdir"
27
set env [eval $env_cmd]
28
error_check_good dbenv [is_valid_env $env] TRUE
29
error_check_good txn_id_set \
30
[$env txn_id_set $txn_curid $txn_maxid] 0
32
set oflags {-auto_commit -create -btree -mode 0644 -env $env $testfile}
33
set db [eval {berkdb_open} $oflags]
34
error_check_good db_open [is_valid_db $db] TRUE
37
# Put some data so that we can check commit or abort of child
40
set origdata some_data
41
set newdata this_is_new_data
42
set newdata2 some_other_new_data
44
error_check_good db_put [$db put -auto_commit $key $origdata] 0
45
error_check_good dbclose [$db close] 0
47
set db [eval {berkdb_open} $oflags]
48
error_check_good db_open [is_valid_db $db] TRUE
50
txn003_check $db $key "Origdata" $origdata
52
puts "\tTxn0$tnum.a: Parent abort"
54
error_check_good txn_begin [is_valid_txn $parent $env] TRUE
55
set child [$env txn -parent $parent]
56
error_check_good txn_begin [is_valid_txn $child $env] TRUE
57
error_check_good db_put [$db put -txn $child $key $newdata] 0
58
error_check_good parent_abort [$parent abort] 0
59
txn003_check $db $key "parent_abort" $origdata
60
# Check child handle is invalid
61
set stat [catch {$child abort} ret]
62
error_check_good child_handle $stat 1
63
error_check_good child_h2 [is_substr $ret "invalid command name"] 1
65
puts "\tTxn0$tnum.b: Parent commit"
67
error_check_good txn_begin [is_valid_txn $parent $env] TRUE
68
set child [$env txn -parent $parent]
69
error_check_good txn_begin [is_valid_txn $child $env] TRUE
70
error_check_good db_put [$db put -txn $child $key $newdata] 0
71
error_check_good parent_commit [$parent commit] 0
72
txn003_check $db $key "parent_commit" $newdata
73
# Check child handle is invalid
74
set stat [catch {$child abort} ret]
75
error_check_good child_handle $stat 1
76
error_check_good child_h2 [is_substr $ret "invalid command name"] 1
77
error_check_good dbclose [$db close] 0
78
error_check_good env_close [$env close] 0
81
# Since the data check assumes what has come before, the 'commit'
82
# operation must be last.
94
set op [lindex $pair 0]
95
set msg [lindex $pair 1]
97
txn003_body $env_cmd $testfile $testdir $key $newdata2 $msg $op
98
set env [eval $env_cmd]
99
error_check_good dbenv [is_valid_env $env] TRUE
102
set db [eval {berkdb_open} $oflags]
103
error_check_good db_open [is_valid_db $db] TRUE
105
# For prepare we'll then just
106
# end up aborting after we test what we need to.
107
# So set gooddata to the same as abort.
110
set gooddata $newdata
113
set gooddata $newdata
116
set gooddata $newdata2
119
set gooddata $newdata
122
txn003_check $db $key "parent_$op" $gooddata
123
error_check_good dbclose [$db close] 0
124
error_check_good env_close [$env close] 0
127
# We can't do the attempted child discard on Windows
128
# because it will leave open files that can't be removed.
129
# Skip the remainder of the test for Windows.
130
if { $is_windows_test == 1 } {
131
puts "Skipping remainder of test for Windows"
134
puts "\tTxn0$tnum.g: Attempt child prepare"
135
set env [eval $env_cmd]
136
error_check_good dbenv [is_valid_env $env] TRUE
138
set db [eval {berkdb_open_noerr} $oflags]
139
error_check_good db_open [is_valid_db $db] TRUE
141
set parent [$env txn]
142
error_check_good txn_begin [is_valid_txn $parent $env] TRUE
143
set child [$env txn -parent $parent]
144
error_check_good txn_begin [is_valid_txn $child $env] TRUE
145
error_check_good db_put [$db put -txn $child $key $newdata] 0
146
set gid [make_gid child_prepare:$child]
147
set stat [catch {$child prepare $gid} ret]
148
error_check_good child_prepare $stat 1
149
error_check_good child_prep_err [is_substr $ret "txn prepare"] 1
151
puts "\tTxn0$tnum.h: Attempt child discard"
152
set stat [catch {$child discard} ret]
153
error_check_good child_discard $stat 1
155
# We just panic'd the region, so the next operations will fail.
156
# No matter, we still have to clean up all the handles.
158
set stat [catch {$parent commit} ret]
159
error_check_good parent_commit $stat 1
160
error_check_good parent_commit:fail [is_substr $ret "DB_RUNRECOVERY"] 1
162
set stat [catch {$db close} ret]
163
error_check_good db_close $stat 1
164
error_check_good db_close:fail [is_substr $ret "DB_RUNRECOVERY"] 1
166
set stat [catch {$env close} ret]
167
error_check_good env_close $stat 1
168
error_check_good env_close:fail [is_substr $ret "DB_RUNRECOVERY"] 1
171
proc txn003_body { env_cmd testfile dir key newdata2 msg op } {
176
set gidf $dir/gidfile
179
puts "$msg.0: Executing child script to prepare txns"
181
set p [exec $tclsh_path $test_path/wrap.tcl txnscript.tcl \
182
$testdir/txnout $env_cmd $testfile $gidf $key $newdata2 &]
184
watch_procs $pidlist 5
185
set f1 [open $testdir/txnout r]
189
fileremove -f $testdir/txnout
192
puts -nonewline "$msg.1: Running recovery ... "
195
set env [eval $env_cmd "-recover"]
196
error_check_good dbenv-recover [is_valid_env $env] TRUE
199
puts "$msg.2: getting txns from txn_recover"
200
set txnlist [$env txn_recover]
201
error_check_good txnlist_len [llength $txnlist] 1
202
set tpair [lindex $txnlist 0]
204
set gfd [open $gidf r]
205
set ret [gets $gfd parentgid]
207
set txn [lindex $tpair 0]
208
set gid [lindex $tpair 1]
209
if { $op == "begin" } {
210
puts "$msg.2: $op new txn"
212
puts "$msg.2: $op parent"
214
error_check_good gidcompare $gid $parentgid
215
if { $op == "prepare" } {
216
set gid [make_gid prepare_recover:$txn]
217
set stat [catch {$txn $op $gid} ret]
218
error_check_good prep_error $stat 1
219
error_check_good prep_err \
220
[is_substr $ret "transaction already prepared"] 1
221
error_check_good txn:prep_abort [$txn abort] 0
222
} elseif { $op == "begin" } {
223
set stat [catch {$env txn} ret]
224
error_check_good begin_error $stat 1
225
error_check_good begin_err \
226
[is_substr $ret "not yet committed transactions is incomplete"] 1
227
error_check_good txn:prep_abort [$txn abort] 0
229
error_check_good txn:$op [$txn $op] 0
231
error_check_good envclose [$env close] 0
234
proc txn003_check { db key msg gooddata } {
235
set kd [$db get $key]
236
set data [lindex [lindex $kd 0] 1]
237
error_check_good $msg $data $gooddata