1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2005-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST test116 8# TEST Test of basic functionality of lsn_reset. 9# TEST 10# TEST Create a database in an env. Copy it to a new file within 11# TEST the same env. Reset the page LSNs. 12proc test116 { method {tnum "116"} args } { 13 source ./include.tcl 14 global util_path 15 global passwd 16 17 set orig_tdir $testdir 18 puts "Test$tnum ($method): Test lsn_reset." 19 20 set args [convert_args $method $args] 21 set encargs "" 22 set args [split_encargs $args encargs] 23 set omethod [convert_method $method] 24 25 set testfile A.db 26 set newtag new 27 set newfile $testfile.$newtag 28 set nentries 50 29 set filenames "A B C D E" 30 31 # This test needs two envs. If one is provided, create the 32 # second under it. If no env is provided, create both. 33 set txn "" 34 set txnenv 0 35 set envargs "" 36 set resetargs "" 37 set eindex [lsearch -exact $args "-env"] 38 39 if { $eindex == -1 } { 40 puts "\tTest$tnum.a: Creating env." 41 env_cleanup $testdir 42 set env [eval {berkdb_env} \ 43 -create $encargs $envargs -home $testdir -txn] 44 append args " -auto_commit " 45 error_check_good dbenv [is_valid_env $env] TRUE 46 } else { 47 incr eindex 48 set env [lindex $args $eindex] 49 puts "\tTest$tnum.a: Using provided env $env." 50 51 # Make sure the second env we create has all the 52 # same flags the provided env does. 53 if { [is_substr [$env get_open_flags] "-thread"] } { 54 append envargs " -thread " 55 } 56 if { [is_substr $args "-encrypt"] } { 57 append envargs " -encryptaes $passwd " 58 } 59 if { [is_substr [$env get_encrypt_flags] "-encryptaes"] } { 60 append envargs " -encryptaes $passwd " 61 append resetargs " -encrypt " 62 } 63 set txn "" 64 set txnenv [is_txnenv $env] 65 if { $txnenv == 1 } { 66 append args " -auto_commit " 67 } elseif { $txnenv == 0 } { 68 puts "Skipping Test$tnum for non-transactional env." 69 return 70 } 71 set testdir [get_home $env] 72 } 73 74 foreach lorder { 1234 4321 } { 75 if { $lorder == 1234 } { 76 set pattern "i i" 77 } else { 78 set pattern "I I" 79 } 80 81 # Open database A, populate and close. 82 puts "\tTest$tnum.b: Creating database with lorder $lorder." 83 cleanup $testdir $env 84 85 # Create a second directory, and create an env there. 86 set testdir [get_home $env] 87 set newdir $testdir/NEWDIR 88 file mkdir $newdir 89 set newenv [eval {berkdb_env} \ 90 -create $encargs $envargs -home $newdir -txn] 91 error_check_good newenv [is_valid_env $newenv] TRUE 92 93 # We test with subdatabases except with the queue access 94 # method, where they are not allowed. 95 if { [is_queue $method] == 1 || [is_partitioned $args] == 1} { 96 set db [eval {berkdb_open} -env $env -lorder $lorder \ 97 $omethod $args -create -mode 0644 $testfile] 98 error_check_good dbopen [is_valid_db $db] TRUE 99 set pgsize [stat_field $db stat "Page size"] 100 if { $txnenv == 1 } { 101 set t [$env txn] 102 error_check_good txn [is_valid_txn $t $env] TRUE 103 set txn "-txn $t" 104 } 105 for { set i 1 } { $i <= $nentries } { incr i } { 106 set key $i 107 set data DATA.$i 108 error_check_good db_put [eval {$db put} \ 109 $txn $key [chop_data $method $data]] 0 110 } 111 if { $txnenv == 1 } { 112 error_check_good t_commit [$t commit] 0 113 } 114 error_check_good db_close [$db close] 0 115 } else { 116 foreach filename $filenames { 117 set db [eval {berkdb_open} -env $env \ 118 -lorder $lorder $omethod $args -create \ 119 -mode 0644 $testfile $filename] 120 error_check_good dbopen [is_valid_db $db] TRUE 121 set pgsize [stat_field $db stat "Page size"] 122 if { $txnenv == 1 } { 123 set t [$env txn] 124 error_check_good \ 125 txn [is_valid_txn $t $env] TRUE 126 set txn "-txn $t" 127 } 128 for { set i 1 } { $i <= $nentries } { incr i } { 129 set key $i 130 set data DATA.$i 131 error_check_good \ 132 db_put [eval {$db put} $txn \ 133 $key [chop_data $method $data]] 0 134 } 135 if { $txnenv == 1 } { 136 error_check_good t_commit [$t commit] 0 137 } 138 error_check_good db_close [$db close] 0 139 } 140 } 141 142 # Copy database file A. Reset LSNs on the copy. Then 143 # test that the copy is usable both in its native env 144 # and in a new env. 145 146 puts "\tTest$tnum.c: Copy database and reset its LSNs." 147 set testdir [get_home $env] 148 set newdir [get_home $newenv] 149 150 # Reset LSNs before copying. We do a little dance here: 151 # first copy the file within the same directory, then reset 152 # the fileid on the copy, then reset the LSNs on the copy, 153 # and only then copy the new file to the new env. Otherwise 154 # the LSNs would get reset on the original file. 155 156 file copy -force $testdir/$testfile $testdir/$newfile 157 # If we're using queue extents or partitions , we must 158 # copy the extents/partitions to the new file name as well. 159 set extents "" 160 if { [is_queueext $method] || [is_partitioned $args]} { 161 copy_extent_file $testdir $testfile $newtag 162 } 163 error_check_good fileid_reset [$env id_reset $newfile] 0 164 error_check_good \ 165 lsn_reset [eval {$env lsn_reset} $resetargs {$newfile}] 0 166 167 file copy -force $testdir/$newfile $newdir/$testfile 168 169 # If we're using queue extents, we must copy the extents 170 # to the new directory as well. 171 if { [is_queueext $method] || [is_partitioned $args]} { 172 set extents [get_extfiles $testdir $newfile ""] 173 foreach extent $extents { 174 set nextent [make_ext_filename \ 175 $testdir/NEWDIR $testfile $extent] 176 file copy -force $extent $nextent 177 } 178 } 179 180 # Get the LSNs and check them. 181 set npages [getlsns \ 182 $testdir $testfile $extents $pgsize orig_lsns] 183 set newpages [getlsns \ 184 $testdir $newfile $extents $pgsize new_lsns] 185 set newdirpages [getlsns \ 186 $newdir $testfile $extents $pgsize newdir_lsns] 187 error_check_good newpages_match $npages $newpages 188 error_check_good newdirpages_match $npages $newdirpages 189 for { set i 0 } { $i < $npages } { incr i } { 190 error_check_binary \ 191 new_lsns [binary format $pattern 0 1] $new_lsns($i) 192 error_check_binary \ 193 newdirlsns_match \ 194 [binary format $pattern 0 1] $newdir_lsns($i) 195 } 196 197 if { [ is_partitioned $args] } { 198 set nodump 1 199 } else { 200 set nodump 0 201 } 202 puts "\tTest$tnum.d: Verify directories with reset LSNs." 203 error_check_good \ 204 verify [verify_dir $testdir "\tTest$tnum.d: " 0 0 $nodump] 0 205 error_check_good \ 206 verify [verify_dir $newdir "\tTest$tnum.e: " 0 0 $nodump] 0 207 208 puts "\tTest$tnum.f: Open new db, check data, close db." 209 if { [is_queue $method] == 1 || [is_partitioned $args] == 1 } { 210 set db [eval {berkdb_open} -env $newenv \ 211 -lorder $lorder \ 212 $omethod $args -create -mode 0644 $testfile] 213 error_check_good dbopen [is_valid_db $db] TRUE 214 if { $txnenv == 1 } { 215 set t [$newenv txn] 216 error_check_good txn [is_valid_txn $t $newenv] TRUE 217 set txn "-txn $t" 218 } 219 for { set i 1 } { $i <= $nentries } { incr i } { 220 set key $i 221 set ret [eval {$db get} $txn $key] 222 error_check_good db_get \ 223 [lindex [lindex $ret 0] 1] \ 224 [pad_data $method DATA.$i] 225 } 226 if { $txnenv == 1 } { 227 error_check_good txn_commit [$t commit] 0 228 } 229 error_check_good db_close [$db close] 0 230 } else { 231 foreach filename $filenames { 232 set db [eval {berkdb_open} -env $newenv \ 233 -lorder $lorder $omethod $args \ 234 -create -mode 0644 $testfile $filename ] 235 error_check_good dbopen [is_valid_db $db] TRUE 236 if { $txnenv == 1 } { 237 set t [$newenv txn] 238 error_check_good \ 239 txn [is_valid_txn $t $newenv] TRUE 240 set txn "-txn $t" 241 } 242 for { set i 1 } { $i <= $nentries } { incr i } { 243 set key $i 244 set ret [eval {$db get} $txn $key] 245 error_check_good db_get \ 246 [lindex [lindex $ret 0] 1] \ 247 [pad_data $method DATA.$i] 248 } 249 if { $txnenv == 1 } { 250 error_check_good txn_commit [$t commit] 0 251 } 252 error_check_good db_close [$db close] 0 253 } 254 } 255 error_check_good newfile_rm [$env dbremove $newfile] 0 256 error_check_good newenv_close [$newenv close] 0 257 fileremove -f $newdir 258 } 259 260 set testdir $orig_tdir 261 # Close the parent env if this test created it. 262 if { $eindex == -1 } { 263 error_check_good env_close [$env close] 0 264 } 265} 266 267proc getlsns { testdir dbfile extents pgsize lsns } { 268 upvar $lsns file_lsns 269 set fid [open $testdir/$dbfile r] 270 fconfigure $fid -translation binary 271 set eof 0 272 set pg 0 273 while { $eof == 0 } { 274 set offset [expr $pg * $pgsize] 275 seek $fid $offset start 276 set file_lsns($pg) [read $fid 8] 277 set eof [eof $fid] 278 incr pg 279 } 280 close $fid 281 incr pg -1 282 foreach extent $extents { 283 set ep [getlsns $testdir \ 284 [make_ext_filename "." $dbfile $extent] \ 285 {} $pgsize elsns] 286 for {set i 0} {$i < $ep} {incr i} { 287 set file_lsns($pg) $elsns($i) 288 incr pg 289 } 290 } 291 return $pg 292} 293 294proc error_check_binary {func desired result} { 295 if { [binary_compare $desired $result] != 0 } { 296 flush stdout 297 flush stderr 298 binary scan $desired h16 d 299 binary scan $result h16 r 300 error "FAIL:[timestamp]\ 301 $func: expected $d, got $r" 302 } 303} 304