Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / test / tcl / test086.tcl
1 # See the file LICENSE for redistribution information.
2 #
3 # Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
4 #
5 # $Id$
6 #
7 # TEST  test086
8 # TEST  Test of cursor stability across btree splits/rsplits with
9 # TEST  subtransaction aborts (a variant of test048).  [#2373]
10 proc test086 { method args } {
11         global errorCode
12         source ./include.tcl
13
14         set tnum 086
15         set args [convert_args $method $args]
16         set encargs ""
17         set args [split_encargs $args encargs]
18         set pageargs ""
19         split_pageargs $args pageargs
20
21         if { [is_btree $method] != 1 } {
22                 puts "Test$tnum skipping for method $method."
23                 return
24         }
25
26         set method "-btree"
27
28         puts "\tTest$tnum: Test of cursor stability across aborted\
29             btree splits."
30
31         set key "key"
32         set data "data"
33         set txn ""
34         set flags ""
35
36         set eindex [lsearch -exact $args "-env"]
37         #
38         # If we are using an env, then this test won't work.
39         if { $eindex == -1 } {
40                 # But we will be using our own env...
41                 set testfile test$tnum.db
42         } else {
43                 puts "\tTest$tnum: Environment provided;  skipping test."
44                 return
45         }
46         set t1 $testdir/t1
47         env_cleanup $testdir
48
49         set env [eval \
50              {berkdb_env -create -home $testdir -txn} $pageargs $encargs]
51         error_check_good berkdb_env [is_valid_env $env] TRUE
52
53         puts "\tTest$tnum.a: Create $method database."
54         set oflags "-auto_commit -create -env $env -mode 0644 $args $method"
55         set db [eval {berkdb_open} $oflags $testfile]
56         error_check_good dbopen [is_valid_db $db] TRUE
57
58         set nkeys 5
59         # Fill page w/ small key/data pairs, keep at leaf
60         #
61         puts "\tTest$tnum.b: Fill page with $nkeys small key/data pairs."
62         set txn [$env txn]
63         error_check_good txn [is_valid_txn $txn $env] TRUE
64         for { set i 0 } { $i < $nkeys } { incr i } {
65                 set ret [$db put -txn $txn key000$i $data$i]
66                 error_check_good dbput $ret 0
67         }
68         error_check_good commit [$txn commit] 0
69
70         # get db ordering, set cursors
71         puts "\tTest$tnum.c: Set cursors on each of $nkeys pairs."
72         set txn [$env txn]
73         error_check_good txn [is_valid_txn $txn $env] TRUE
74         for {set i 0; set ret [$db get -txn $txn key000$i]} {\
75                         $i < $nkeys && [llength $ret] != 0} {\
76                         incr i; set ret [$db get -txn $txn key000$i]} {
77                 set key_set($i) [lindex [lindex $ret 0] 0]
78                 set data_set($i) [lindex [lindex $ret 0] 1]
79                 set dbc [$db cursor -txn $txn]
80                 set dbc_set($i) $dbc
81                 error_check_good db_cursor:$i [is_substr $dbc_set($i) $db] 1
82                 set ret [$dbc_set($i) get -set $key_set($i)]
83                 error_check_bad dbc_set($i)_get:set [llength $ret] 0
84         }
85
86         # Create child txn.
87         set ctxn [$env txn -parent $txn]
88         error_check_good ctxn [is_valid_txn $txn $env] TRUE
89
90         # if mkeys is above 1000, need to adjust below for lexical order
91         set mkeys 1000
92         puts "\tTest$tnum.d: Add $mkeys pairs to force split."
93         for {set i $nkeys} { $i < $mkeys } { incr i } {
94                 if { $i >= 100 } {
95                         set ret [$db put -txn $ctxn key0$i $data$i]
96                 } elseif { $i >= 10 } {
97                         set ret [$db put -txn $ctxn key00$i $data$i]
98                 } else {
99                         set ret [$db put -txn $ctxn key000$i $data$i]
100                 }
101                 error_check_good dbput:more $ret 0
102         }
103
104         puts "\tTest$tnum.e: Abort."
105         error_check_good ctxn_abort [$ctxn abort] 0
106
107         puts "\tTest$tnum.f: Check and see that cursors maintained reference."
108         for {set i 0} { $i < $nkeys } {incr i} {
109                 set ret [$dbc_set($i) get -current]
110                 error_check_bad dbc$i:get:current [llength $ret] 0
111                 set ret2 [$dbc_set($i) get -set $key_set($i)]
112                 error_check_bad dbc$i:get:set [llength $ret2] 0
113                 error_check_good dbc$i:get(match) $ret $ret2
114         }
115
116         # Put (and this time keep) the keys that caused the split.
117         # We'll delete them to test reverse splits.
118         puts "\tTest$tnum.g: Put back added keys."
119         for {set i $nkeys} { $i < $mkeys } { incr i } {
120                 if { $i >= 100 } {
121                         set ret [$db put -txn $txn key0$i $data$i]
122                 } elseif { $i >= 10 } {
123                         set ret [$db put -txn $txn key00$i $data$i]
124                 } else {
125                         set ret [$db put -txn $txn key000$i $data$i]
126                 }
127                 error_check_good dbput:more $ret 0
128         }
129
130         puts "\tTest$tnum.h: Delete added keys to force reverse split."
131         set ctxn [$env txn -parent $txn]
132         error_check_good ctxn [is_valid_txn $txn $env] TRUE
133         for {set i $nkeys} { $i < $mkeys } { incr i } {
134                 if { $i >= 100 } {
135                         error_check_good db_del:$i [$db del -txn $ctxn key0$i] 0
136                 } elseif { $i >= 10 } {
137                         error_check_good db_del:$i \
138                             [$db del -txn $ctxn key00$i] 0
139                 } else {
140                         error_check_good db_del:$i \
141                             [$db del -txn $ctxn key000$i] 0
142                 }
143         }
144
145         puts "\tTest$tnum.i: Abort."
146         error_check_good ctxn_abort [$ctxn abort] 0
147
148         puts "\tTest$tnum.j: Verify cursor reference."
149         for {set i 0} { $i < $nkeys } {incr i} {
150                 set ret [$dbc_set($i) get -current]
151                 error_check_bad dbc$i:get:current [llength $ret] 0
152                 set ret2 [$dbc_set($i) get -set $key_set($i)]
153                 error_check_bad dbc$i:get:set [llength $ret2] 0
154                 error_check_good dbc$i:get(match) $ret $ret2
155         }
156
157         puts "\tTest$tnum.j: Cleanup."
158         # close cursors
159         for {set i 0} { $i < $nkeys } {incr i} {
160                 error_check_good dbc_close:$i [$dbc_set($i) close] 0
161         }
162
163         error_check_good commit [$txn commit] 0
164         error_check_good dbclose [$db close] 0
165         error_check_good envclose [$env close] 0
166
167         puts "\tTest$tnum complete."
168 }