1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 1999-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST test068 8# TEST Test of DB_BEFORE and DB_AFTER with partial puts. 9# TEST Make sure DB_BEFORE and DB_AFTER work properly with partial puts, and 10# TEST check that they return EINVAL if DB_DUPSORT is set or if DB_DUP is not. 11proc test068 { method args } { 12 source ./include.tcl 13 global alphabet 14 global errorCode 15 global is_je_test 16 17 set tnum "068" 18 set orig_tdir $testdir 19 20 set args [convert_args $method $args] 21 set omethod [convert_method $method] 22 23 puts "Test$tnum:\ 24 $method ($args) Test of DB_BEFORE/DB_AFTER and partial puts." 25 if { [is_record_based $method] == 1 } { 26 puts "\tTest$tnum: skipping for method $method." 27 return 28 } 29 30 set txnenv 0 31 set eindex [lsearch -exact $args "-env"] 32 # 33 # If we are using an env, then testfile should just be the db name. 34 # Otherwise it is the test directory and the name. 35 set nkeys 1000 36 if { $eindex == -1 } { 37 set testfile $testdir/test$tnum.db 38 set env NULL 39 } else { 40 set testfile test$tnum.db 41 incr eindex 42 set env [lindex $args $eindex] 43 set txnenv [is_txnenv $env] 44 if { $txnenv == 1 } { 45 append args " -auto_commit " 46 set nkeys 100 47 } 48 set testdir [get_home $env] 49 } 50 51 # Create a list of $nkeys words to insert into db. 52 puts "\tTest$tnum.a: Initialize word list." 53 set txn "" 54 set wordlist {} 55 set count 0 56 set did [open $dict] 57 while { [gets $did str] != -1 && $count < $nkeys } { 58 lappend wordlist $str 59 incr count 60 } 61 close $did 62 63 # Sanity check: did we get $nkeys words? 64 error_check_good enough_keys [llength $wordlist] $nkeys 65 66 # rbtree can't handle dups, so just test the non-dup case 67 # if it's the current method. 68 if { [is_rbtree $method] == 1 } { 69 set dupoptlist { "" } 70 } else { 71 set dupoptlist { "" "-dup" "-dup -dupsort" } 72 } 73 74 foreach dupopt $dupoptlist { 75 if { $is_je_test || [is_compressed $args] == 1 } { 76 if { $dupopt == "-dup" } { 77 continue 78 } 79 } 80 81 # Testdir might be reset in the loop by some proc sourcing 82 # include.tcl. Reset it to the env's home here, before 83 # cleanup. 84 if { $env != "NULL" } { 85 set testdir [get_home $env] 86 } 87 cleanup $testdir $env 88 set db [eval {berkdb_open_noerr -create -mode 0644 \ 89 $omethod} $args $dupopt {$testfile}] 90 error_check_good db_open [is_valid_db $db] TRUE 91 92 puts "\tTest$tnum.b ($dupopt): DB initialization: put loop." 93 foreach word $wordlist { 94 if { $txnenv == 1 } { 95 set t [$env txn] 96 error_check_good txn [is_valid_txn $t $env] TRUE 97 set txn "-txn $t" 98 } 99 set ret [eval {$db put} $txn {$word $word}] 100 error_check_good db_put $ret 0 101 if { $txnenv == 1 } { 102 error_check_good txn [$t commit] 0 103 } 104 } 105 106 puts "\tTest$tnum.c ($dupopt): get loop." 107 foreach word $wordlist { 108 # Make sure that the Nth word has been correctly 109 # inserted, and also that the Nth word is the 110 # Nth one we pull out of the database using a cursor. 111 112 set dbt [$db get $word] 113 error_check_good get_key [list [list $word $word]] $dbt 114 } 115 116 if { $txnenv == 1 } { 117 set t [$env txn] 118 error_check_good txn [is_valid_txn $t $env] TRUE 119 set txn "-txn $t" 120 } 121 set dbc [eval {$db cursor} $txn] 122 error_check_good cursor_open [is_valid_cursor $dbc $db] TRUE 123 124 puts "\tTest$tnum.d ($dupopt): DBC->put w/ DB_AFTER." 125 126 # Set cursor to the first key; make sure it succeeds. 127 # With an unsorted wordlist, we can't be sure that the 128 # first item returned will equal the first item in the 129 # wordlist, so we just make sure it got something back. 130 set dbt [eval {$dbc get -first}] 131 error_check_good \ 132 dbc_get_first [llength $dbt] 1 133 134 # If -dup is not set, or if -dupsort is set too, we 135 # need to verify that DB_BEFORE and DB_AFTER fail 136 # and then move on to the next $dupopt. 137 if { $dupopt != "-dup" } { 138 set errorCode "NONE" 139 set ret [catch {eval $dbc put -after \ 140 {-partial [list 6 0]} "after"} res] 141 error_check_good dbc_put_after_fail $ret 1 142 error_check_good dbc_put_after_einval \ 143 [is_substr $errorCode EINVAL] 1 144 puts "\tTest$tnum ($dupopt): DB_AFTER returns EINVAL." 145 set errorCode "NONE" 146 set ret [catch {eval $dbc put -before \ 147 {-partial [list 6 0]} "before"} res] 148 error_check_good dbc_put_before_fail $ret 1 149 error_check_good dbc_put_before_einval \ 150 [is_substr $errorCode EINVAL] 1 151 puts "\tTest$tnum ($dupopt): DB_BEFORE returns EINVAL." 152 puts "\tTest$tnum ($dupopt): Correct error returns,\ 153 skipping further test." 154 # continue with broad foreach 155 error_check_good dbc_close [$dbc close] 0 156 if { $txnenv == 1 } { 157 error_check_good txn [$t commit] 0 158 } 159 error_check_good db_close [$db close] 0 160 continue 161 } 162 163 puts "\tTest$tnum.e ($dupopt): DBC->put(DB_AFTER) loop." 164 foreach word $wordlist { 165 # set cursor to $word 166 set dbt [$dbc get -set $word] 167 error_check_good \ 168 dbc_get_set $dbt [list [list $word $word]] 169 # put after it 170 set ret [$dbc put -after -partial {4 0} after] 171 error_check_good dbc_put_after $ret 0 172 } 173 174 puts "\tTest$tnum.f ($dupopt): DBC->put(DB_BEFORE) loop." 175 foreach word $wordlist { 176 # set cursor to $word 177 set dbt [$dbc get -set $word] 178 error_check_good \ 179 dbc_get_set $dbt [list [list $word $word]] 180 # put before it 181 set ret [$dbc put -before -partial {6 0} before] 182 error_check_good dbc_put_before $ret 0 183 } 184 185 error_check_good dbc_close [$dbc close] 0 186 if { $txnenv == 1 } { 187 error_check_good txn [$t commit] 0 188 } 189 190 eval $db sync 191 puts "\tTest$tnum.g ($dupopt): Verify correctness." 192 193 if { $txnenv == 1 } { 194 set t [$env txn] 195 error_check_good txn [is_valid_txn $t $env] TRUE 196 set txn "-txn $t" 197 } 198 set dbc [eval {$db cursor} $txn] 199 error_check_good db_cursor [is_valid_cursor $dbc $db] TRUE 200 201 # loop through the whole db beginning to end, 202 # make sure we have, in order, {$word "\0\0\0\0\0\0before"}, 203 # {$word $word}, {$word "\0\0\0\0after"} for each word. 204 set count 0 205 while { $count < $nkeys } { 206 # Get the first item of each set of three. 207 # We don't know what the word is, but set $word to 208 # the key and check that the data is 209 # "\0\0\0\0\0\0before". 210 set dbt [$dbc get -next] 211 set word [lindex [lindex $dbt 0] 0] 212 213 error_check_good dbc_get_one $dbt \ 214 [list [list $word "\0\0\0\0\0\0before"]] 215 216 set dbt [$dbc get -next] 217 error_check_good \ 218 dbc_get_two $dbt [list [list $word $word]] 219 220 set dbt [$dbc get -next] 221 error_check_good dbc_get_three $dbt \ 222 [list [list $word "\0\0\0\0after"]] 223 224 incr count 225 } 226 error_check_good dbc_close [$dbc close] 0 227 if { $txnenv == 1 } { 228 error_check_good txn [$t commit] 0 229 } 230 error_check_good db_close [$db close] 0 231 } 232 set testdir $orig_tdir 233} 234