1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2000,2008 Oracle. All rights reserved. 4# 5# $Id: fop004.tcl,v 12.6 2008/01/08 20:58:53 bostic Exp $ 6# 7# TEST fop004 8# TEST Test of DB->rename(). (formerly test075) 9# TEST Test that files can be renamed from one directory to another. 10# TEST Test that files can be renamed using absolute or relative 11# TEST pathnames. 12proc fop004 { method { tnum "004" } args } { 13 global encrypt 14 global errorCode 15 global errorInfo 16 source ./include.tcl 17 18 set args [convert_args $method $args] 19 set omethod [convert_method $method] 20 21 puts "Fop$tnum: ($method $args): Test of DB->rename()" 22 23 set eindex [lsearch -exact $args "-env"] 24 if { $eindex != -1 } { 25 # If we are using an env, then skip this test. 26 # It needs its own. 27 incr eindex 28 set env [lindex $args $eindex] 29 puts "Skipping fop$tnum for env $env" 30 return 31 } 32 if { $encrypt != 0 } { 33 puts "Skipping fop$tnum for security" 34 return 35 } 36 cleanup $testdir NULL 37 38 # Define absolute pathnames 39 set curdir [pwd] 40 cd $testdir 41 set fulldir [pwd] 42 cd $curdir 43 set reldir $testdir 44 45 # Name subdirectories for renaming from one directory to another. 46 set subdira A 47 set subdirb B 48 49 # Set up absolute and relative pathnames for test 50 set paths [list "absolute $fulldir" "relative $reldir"] 51 set files [list "fop$tnum-old.db fop$tnum-new.db {name change}" \ 52 "fop$tnum.db fop$tnum.db {directory change}"] 53 54 foreach pathinfo $paths { 55 set pathtype [lindex $pathinfo 0] 56 set path [lindex $pathinfo 1] 57 foreach fileinfo $files { 58 set desc [lindex $fileinfo 2] 59 puts "Fop$tnum: Test of $pathtype path $path with $desc" 60 set env NULL 61 set envargs "" 62 63 # Loop through test using the following rename options 64 # 1. no environment, not in transaction 65 # 2. with environment, not in transaction 66 # 3. rename with auto-commit 67 # 4. rename in committed transaction 68 # 5. rename in aborted transaction 69 70 foreach op "noenv env auto commit abort" { 71 72 puts "\tFop$tnum.a: Create/rename with $op" 73 # If we are using an env, then testfile should 74 # be the db name. Otherwise it is the path we 75 # are testing and the name. 76 # 77 set old [lindex $fileinfo 0] 78 set new [lindex $fileinfo 1] 79 # Set up subdirectories if necessary. 80 if { $desc == "directory change" } { 81 file mkdir $testdir/$subdira 82 file mkdir $testdir/$subdirb 83 set oldname $subdira/$old 84 set newname $subdirb/$new 85 set oldextent $subdira/__dbq.$old.0 86 set newextent $subdirb/__dbq.$new.0 87 } else { 88 set oldname $old 89 set newname $new 90 set oldextent __dbq.$old.0 91 set newextent __dbq.$new.0 92 } 93 # If we don't have an env, we're going to 94 # operate on the file using its absolute 95 # or relative path. Tack it on the front. 96 if { $op == "noenv" } { 97 set oldfile $path/$oldname 98 set newfile $path/$newname 99 set oldextent $path/$oldextent 100 set newextent $path/$newextent 101 } else { 102 set oldfile $oldname 103 set newfile $newname 104 set txnarg "" 105 if { $op == "auto" || $op == "commit" \ 106 || $op == "abort" } { 107 set txnarg " -txn" 108 } 109 set env [eval {berkdb_env -create} \ 110 $txnarg -home $path] 111 set envargs "-env $env" 112 error_check_good \ 113 env_open [is_valid_env $env] TRUE 114 } 115 116 # Files don't exist before starting the test. 117 # 118 check_file_exist $oldfile $env $path 0 119 check_file_exist $newfile $env $path 0 120 121 puts "\t\tFop$tnum.a.1: Create file $oldfile" 122 set db [eval {berkdb_open -create -mode 0644} \ 123 $omethod $envargs $args $oldfile] 124 error_check_good dbopen [is_valid_db $db] TRUE 125 126 # Use numeric key so record-based methods 127 # don't need special treatment. 128 set key 1 129 set data data 130 131 error_check_good dbput \ 132 [$db put $key [chop_data $method $data]] 0 133 error_check_good dbclose [$db close] 0 134 135 puts "\t\tFop$tnum.a.2:\ 136 Rename file to $newfile" 137 check_file_exist $oldfile $env $path 1 138 check_file_exist $newfile $env $path 0 139 140 # Regular renames use berkdb dbrename 141 # Txn-protected renames use $env dbrename. 142 if { $op == "noenv" || $op == "env" } { 143 error_check_good rename [eval \ 144 {berkdb dbrename} $envargs \ 145 $oldfile $newfile] 0 146 } elseif { $op == "auto" } { 147 error_check_good rename [eval \ 148 {$env dbrename} -auto_commit \ 149 $oldfile $newfile] 0 150 } else { 151 # $op is "abort" or "commit" 152 set txn [$env txn] 153 error_check_good rename [eval \ 154 {$env dbrename} -txn $txn \ 155 $oldfile $newfile] 0 156 error_check_good txn_$op [$txn $op] 0 157 } 158 159 if { $op != "abort" } { 160 check_file_exist $oldfile $env $path 0 161 check_file_exist $newfile $env $path 1 162 } else { 163 check_file_exist $oldfile $env $path 1 164 check_file_exist $newfile $env $path 0 165 } 166 167 # Check that extent files moved too, unless 168 # we aborted the rename. 169 if { [is_queueext $method ] == 1 } { 170 if { $op != "abort" } { 171 check_file_exist \ 172 $oldextent $env $path 0 173 check_file_exist \ 174 $newextent $env $path 1 175 } else { 176 check_file_exist \ 177 $oldextent $env $path 1 178 check_file_exist \ 179 $newextent $env $path 0 180 } 181 } 182 183 puts "\t\tFop$tnum.a.3: Check file contents" 184 # Open again with create to make sure we're not 185 # caching. In the normal case (no env), we 186 # already know the file doesn't exist. 187 set odb [eval {berkdb_open -create -mode 0644} \ 188 $envargs $omethod $args $oldfile] 189 set ndb [eval {berkdb_open -create -mode 0644} \ 190 $envargs $omethod $args $newfile] 191 error_check_good \ 192 odb_open [is_valid_db $odb] TRUE 193 error_check_good \ 194 ndb_open [is_valid_db $ndb] TRUE 195 196 # The DBT from the "old" database should be 197 # empty, not the "new" one, except in the case 198 # of an abort. 199 set odbt [$odb get $key] 200 if { $op == "abort" } { 201 error_check_good \ 202 odbt_has_data [llength $odbt] 1 203 } else { 204 set ndbt [$ndb get $key] 205 error_check_good \ 206 odbt_empty [llength $odbt] 0 207 error_check_bad \ 208 ndbt_empty [llength $ndbt] 0 209 error_check_good ndbt \ 210 [lindex [lindex $ndbt 0] 1] \ 211 [pad_data $method $data] 212 } 213 error_check_good odb_close [$odb close] 0 214 error_check_good ndb_close [$ndb close] 0 215 216 # Now there's both an old and a new. Rename the 217 # "new" to the "old" and make sure that fails. 218 # 219 puts "\tFop$tnum.b: Make sure rename fails\ 220 instead of overwriting" 221 set envargs "" 222 if { $env != "NULL" } { 223 error_check_good \ 224 env_close [$env close] 0 225 set env [berkdb_env_noerr -home $path] 226 set envargs " -env $env" 227 error_check_good env_open2 \ 228 [is_valid_env $env] TRUE 229 } 230 set ret [catch {eval {berkdb dbrename} \ 231 $envargs $newfile $oldfile} res] 232 error_check_bad rename_overwrite $ret 0 233 error_check_good rename_overwrite_ret \ 234 [is_substr $errorCode EEXIST] 1 235 236 # Verify and then start over from a clean slate. 237 verify_dir $path "\tFop$tnum.c: " 238 verify_dir $path/$subdira "\tFop$tnum.c: " 239 verify_dir $path/$subdirb "\tFop$tnum.c: " 240 if { $env != "NULL" } { 241 error_check_good \ 242 env_close2 [$env close] 0 243 } 244 env_cleanup $path 245 check_file_exist $oldfile $env $path 0 246 check_file_exist $newfile $env $path 0 247 } 248 } 249 } 250} 251 252proc check_file_exist { filename env path expected } { 253 if { $env != "NULL" } { 254 error_check_good "$filename exists in env" \ 255 [file exists $path/$filename] $expected 256 } else { 257 error_check_good \ 258 "$filename exists" [file exists $filename] $expected 259 } 260} 261