1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 1999,2008 Oracle.  All rights reserved.
4#
5# $Id: recd015.tcl,v 12.10 2008/04/01 17:59:32 carol Exp $
6#
7# TEST	recd015
8# TEST	This is a recovery test for testing lots of prepared txns.
9# TEST	This test is to force the use of txn_recover to call with the
10# TEST	DB_FIRST flag and then DB_NEXT.
11proc recd015 { method args } {
12	source ./include.tcl
13	global rand_init
14	error_check_good set_random_seed [berkdb srand $rand_init] 0
15
16	set args [convert_args $method $args]
17	set omethod [convert_method $method]
18
19	puts "Recd015: $method ($args) prepared txns test"
20
21	# Create the database and environment.
22
23	set numtxns 1
24	set testfile NULL
25
26	set env_cmd "berkdb_env -create -txn -home $testdir"
27	set msg "\tRecd015.a"
28	foreach op { abort commit discard } {
29		puts "$msg: Simple test to prepare $numtxns txn with $op "
30		env_cleanup $testdir
31		recd015_body $env_cmd $testfile $numtxns $msg $op
32	}
33
34	#
35	# Now test large numbers of prepared txns to test DB_NEXT
36	# on txn_recover.
37	#
38	set numtxns 10000
39	set txnmax [expr $numtxns + 5]
40	set env_cmd "berkdb_env -create -txn_max $txnmax \
41	    -lock_max_lockers $txnmax -txn -home $testdir"
42
43	set msg "\tRecd015.b"
44	foreach op { abort commit discard } {
45		puts "$msg: Large test to prepare $numtxns txn with $op"
46		env_cleanup $testdir
47		recd015_body $env_cmd $testfile $numtxns $msg $op
48	}
49
50	set stat [catch {exec $util_path/db_printlog -h $testdir \
51	    > $testdir/LOG } ret]
52	error_check_good db_printlog $stat 0
53	fileremove $testdir/LOG
54}
55
56proc recd015_body { env_cmd testfile numtxns msg op } {
57	source ./include.tcl
58
59	sentinel_init
60	set gidf $testdir/gidfile
61	fileremove -f $gidf
62	set pidlist {}
63	puts "$msg.0: Executing child script to prepare txns"
64	berkdb debug_check
65	set p [exec $tclsh_path $test_path/wrap.tcl recd15scr.tcl \
66	    $testdir/recdout $env_cmd $testfile $gidf $numtxns &]
67
68	lappend pidlist $p
69	watch_procs $pidlist 5
70	set f1 [open $testdir/recdout r]
71	set r [read $f1]
72	puts $r
73	close $f1
74	fileremove -f $testdir/recdout
75
76	berkdb debug_check
77	puts -nonewline "$msg.1: Running recovery ... "
78	flush stdout
79	berkdb debug_check
80	set env [eval $env_cmd -recover]
81	error_check_good dbenv-recover [is_valid_env $env] TRUE
82	puts "complete"
83
84	puts "$msg.2: getting txns from txn_recover"
85	set txnlist [$env txn_recover]
86	error_check_good txnlist_len [llength $txnlist] $numtxns
87
88	set gfd [open $gidf r]
89	set i 0
90	while { [gets $gfd gid] != -1 } {
91		set gids($i) $gid
92		incr i
93	}
94	close $gfd
95	#
96	# Make sure we have as many as we expect
97	error_check_good num_gids $i $numtxns
98
99	set i 0
100	puts "$msg.3: comparing GIDs and $op txns"
101	foreach tpair $txnlist {
102		set txn [lindex $tpair 0]
103		set gid [lindex $tpair 1]
104		error_check_good gidcompare $gid $gids($i)
105		error_check_good txn:$op [$txn $op] 0
106		incr i
107	}
108	if { $op != "discard" } {
109		error_check_good envclose [$env close] 0
110		return
111	}
112	#
113	# If we discarded, now do it again and randomly resolve some
114	# until all txns are resolved.
115	#
116	puts "$msg.4: resolving/discarding txns"
117	set txnlist [$env txn_recover]
118	set len [llength $txnlist]
119	set opval(1) "abort"
120	set opcnt(1) 0
121	set opval(2) "commit"
122	set opcnt(2) 0
123	set opval(3) "discard"
124	set opcnt(3) 0
125	while { $len != 0 } {
126		set opicnt(1) 0
127		set opicnt(2) 0
128		set opicnt(3) 0
129		#
130		# Abort/commit or discard them randomly until
131		# all are resolved.
132		#
133		for { set i 0 } { $i < $len } { incr i } {
134			set t [lindex $txnlist $i]
135			set txn [lindex $t 0]
136			set newop [berkdb random_int 1 3]
137			set ret [$txn $opval($newop)]
138			error_check_good txn_$opval($newop):$i $ret 0
139			incr opcnt($newop)
140			incr opicnt($newop)
141		}
142#		puts "$opval(1): $opicnt(1) Total: $opcnt(1)"
143#		puts "$opval(2): $opicnt(2) Total: $opcnt(2)"
144#		puts "$opval(3): $opicnt(3) Total: $opcnt(3)"
145
146		set txnlist [$env txn_recover]
147		set len [llength $txnlist]
148	}
149
150	error_check_good envclose [$env close] 0
151}
152