Fossil SCM
Do not rely on 'clock seconds' (alone) being unique between 'repo_init' calls. Make temporary directory deletion more robust. Only save the current directory on the first 'repo_init' call per test.
Commit
004b3ffd938fd87c21caf220a77e9765cc2cf582
Parent
cda4cc8b805bccc…
1 file changed
+26
-11
+26
-11
| --- test/tester.tcl | ||
| +++ test/tester.tcl | ||
| @@ -210,10 +210,27 @@ | ||
| 210 | 210 | if {[string length $fileName] == 0 || ![file exists $fileName]} { |
| 211 | 211 | error "Failed to obtain the file name of the test being run." |
| 212 | 212 | } |
| 213 | 213 | return $fileName |
| 214 | 214 | } |
| 215 | + | |
| 216 | +proc robust_delete { path {force ""} } { | |
| 217 | + set error "unknown error" | |
| 218 | + for {set try 0} {$try < 10} {incr try} { | |
| 219 | + if {$force eq "YES_DO_IT"} { | |
| 220 | + if {[catch {file delete -force $path} error] == 0} { | |
| 221 | + return | |
| 222 | + } | |
| 223 | + } else { | |
| 224 | + if {[catch {file delete $path} error] == 0} { | |
| 225 | + return | |
| 226 | + } | |
| 227 | + } | |
| 228 | + after [expr {$try * 100}] | |
| 229 | + } | |
| 230 | + error "cannot delete \"$path\": $error" | |
| 231 | +} | |
| 215 | 232 | |
| 216 | 233 | proc test_cleanup {} { |
| 217 | 234 | if {![info exists ::tempRepoPath]} {return} |
| 218 | 235 | if {![file exists $::tempRepoPath]} {return} |
| 219 | 236 | if {![file isdirectory $::tempRepoPath]} {return} |
| @@ -220,32 +237,30 @@ | ||
| 220 | 237 | set tempPathEnd [expr {[string length $::tempPath] - 1}] |
| 221 | 238 | if {[string length $::tempPath] == 0 || \ |
| 222 | 239 | [string range $::tempRepoPath 0 $tempPathEnd] ne $::tempPath} { |
| 223 | 240 | error "Temporary repository path has wrong parent during cleanup." |
| 224 | 241 | } |
| 225 | - if {[info exists ::tempSavedPwd]} { | |
| 226 | - cd $::tempSavedPwd; unset ::tempSavedPwd | |
| 227 | - } | |
| 242 | + if {[info exists ::tempSavedPwd]} {cd $::tempSavedPwd; unset ::tempSavedPwd} | |
| 228 | 243 | # First, attempt to delete the specific temporary repository directories |
| 229 | 244 | # for this test file. |
| 230 | 245 | set scriptName [file tail [get_script_or_fail]] |
| 231 | 246 | foreach repoSeed $::tempRepoSeeds { |
| 232 | 247 | set repoPath [file join $::tempRepoPath $repoSeed $scriptName] |
| 233 | - catch {file delete -force $repoPath}; # FORCE, arbitrary children. | |
| 248 | + robust_delete $repoPath YES_DO_IT; # FORCE, arbitrary children. | |
| 234 | 249 | set seedPath [file join $::tempRepoPath $repoSeed] |
| 235 | - catch {file delete $seedPath}; # NO FORCE. | |
| 250 | + robust_delete $seedPath; # NO FORCE. | |
| 236 | 251 | } |
| 237 | 252 | # Next, attempt to gracefully delete the temporary repository directory |
| 238 | 253 | # for this process. |
| 239 | - catch {file delete $::tempRepoPath} | |
| 254 | + robust_delete $::tempRepoPath | |
| 240 | 255 | # Finally, attempt to gracefully delete the temporary home directory. |
| 241 | 256 | if {$::tcl_platform(platform) eq "windows"} { |
| 242 | - catch {file delete [file join $::tempHomePath _fossil]} | |
| 257 | + robust_delete [file join $::tempHomePath _fossil] | |
| 243 | 258 | } else { |
| 244 | - catch {file delete [file join $::tempHomePath .fossil]} | |
| 259 | + robust_delete [file join $::tempHomePath .fossil] | |
| 245 | 260 | } |
| 246 | - catch {file delete $::tempHomePath} | |
| 261 | + robust_delete $::tempHomePath | |
| 247 | 262 | } |
| 248 | 263 | |
| 249 | 264 | proc is_home_elsewhere {} { |
| 250 | 265 | return [expr {[info exists ::env(FOSSIL_HOME)] && \ |
| 251 | 266 | $::env(FOSSIL_HOME) eq $::tempHomePath}] |
| @@ -263,22 +278,22 @@ | ||
| 263 | 278 | # |
| 264 | 279 | # Create and open a new Fossil repository and clean the checkout |
| 265 | 280 | # |
| 266 | 281 | proc repo_init {{filename ".rep.fossil"}} { |
| 267 | 282 | set_home_to_elsewhere |
| 268 | - set repoSeed [string trim [clock seconds] -] | |
| 269 | 283 | set ::tempRepoPath [file join $::tempPath repo_[pid]] |
| 284 | + set repoSeed [appendArgs [string trim [clock seconds] -] _ [getSeqNo]] | |
| 270 | 285 | lappend ::tempRepoSeeds $repoSeed |
| 271 | 286 | set repoPath [file join \ |
| 272 | 287 | $::tempRepoPath $repoSeed [file tail [get_script_or_fail]]] |
| 273 | 288 | if {[catch { |
| 274 | 289 | file mkdir $repoPath |
| 275 | 290 | } error] != 0} { |
| 276 | 291 | error "could not make directory \"$repoPath\",\ |
| 277 | 292 | please set TEMP variable in environment: $error" |
| 278 | 293 | } |
| 279 | - set ::tempSavedPwd [pwd]; cd $repoPath | |
| 294 | + if {![info exists ::tempSavedPwd]} {set ::tempSavedPwd [pwd]}; cd $repoPath | |
| 280 | 295 | exec $::fossilexe new $filename |
| 281 | 296 | exec $::fossilexe open $filename |
| 282 | 297 | exec $::fossilexe set mtime-changes off |
| 283 | 298 | } |
| 284 | 299 | |
| 285 | 300 |
| --- test/tester.tcl | |
| +++ test/tester.tcl | |
| @@ -210,10 +210,27 @@ | |
| 210 | if {[string length $fileName] == 0 || ![file exists $fileName]} { |
| 211 | error "Failed to obtain the file name of the test being run." |
| 212 | } |
| 213 | return $fileName |
| 214 | } |
| 215 | |
| 216 | proc test_cleanup {} { |
| 217 | if {![info exists ::tempRepoPath]} {return} |
| 218 | if {![file exists $::tempRepoPath]} {return} |
| 219 | if {![file isdirectory $::tempRepoPath]} {return} |
| @@ -220,32 +237,30 @@ | |
| 220 | set tempPathEnd [expr {[string length $::tempPath] - 1}] |
| 221 | if {[string length $::tempPath] == 0 || \ |
| 222 | [string range $::tempRepoPath 0 $tempPathEnd] ne $::tempPath} { |
| 223 | error "Temporary repository path has wrong parent during cleanup." |
| 224 | } |
| 225 | if {[info exists ::tempSavedPwd]} { |
| 226 | cd $::tempSavedPwd; unset ::tempSavedPwd |
| 227 | } |
| 228 | # First, attempt to delete the specific temporary repository directories |
| 229 | # for this test file. |
| 230 | set scriptName [file tail [get_script_or_fail]] |
| 231 | foreach repoSeed $::tempRepoSeeds { |
| 232 | set repoPath [file join $::tempRepoPath $repoSeed $scriptName] |
| 233 | catch {file delete -force $repoPath}; # FORCE, arbitrary children. |
| 234 | set seedPath [file join $::tempRepoPath $repoSeed] |
| 235 | catch {file delete $seedPath}; # NO FORCE. |
| 236 | } |
| 237 | # Next, attempt to gracefully delete the temporary repository directory |
| 238 | # for this process. |
| 239 | catch {file delete $::tempRepoPath} |
| 240 | # Finally, attempt to gracefully delete the temporary home directory. |
| 241 | if {$::tcl_platform(platform) eq "windows"} { |
| 242 | catch {file delete [file join $::tempHomePath _fossil]} |
| 243 | } else { |
| 244 | catch {file delete [file join $::tempHomePath .fossil]} |
| 245 | } |
| 246 | catch {file delete $::tempHomePath} |
| 247 | } |
| 248 | |
| 249 | proc is_home_elsewhere {} { |
| 250 | return [expr {[info exists ::env(FOSSIL_HOME)] && \ |
| 251 | $::env(FOSSIL_HOME) eq $::tempHomePath}] |
| @@ -263,22 +278,22 @@ | |
| 263 | # |
| 264 | # Create and open a new Fossil repository and clean the checkout |
| 265 | # |
| 266 | proc repo_init {{filename ".rep.fossil"}} { |
| 267 | set_home_to_elsewhere |
| 268 | set repoSeed [string trim [clock seconds] -] |
| 269 | set ::tempRepoPath [file join $::tempPath repo_[pid]] |
| 270 | lappend ::tempRepoSeeds $repoSeed |
| 271 | set repoPath [file join \ |
| 272 | $::tempRepoPath $repoSeed [file tail [get_script_or_fail]]] |
| 273 | if {[catch { |
| 274 | file mkdir $repoPath |
| 275 | } error] != 0} { |
| 276 | error "could not make directory \"$repoPath\",\ |
| 277 | please set TEMP variable in environment: $error" |
| 278 | } |
| 279 | set ::tempSavedPwd [pwd]; cd $repoPath |
| 280 | exec $::fossilexe new $filename |
| 281 | exec $::fossilexe open $filename |
| 282 | exec $::fossilexe set mtime-changes off |
| 283 | } |
| 284 | |
| 285 |
| --- test/tester.tcl | |
| +++ test/tester.tcl | |
| @@ -210,10 +210,27 @@ | |
| 210 | if {[string length $fileName] == 0 || ![file exists $fileName]} { |
| 211 | error "Failed to obtain the file name of the test being run." |
| 212 | } |
| 213 | return $fileName |
| 214 | } |
| 215 | |
| 216 | proc robust_delete { path {force ""} } { |
| 217 | set error "unknown error" |
| 218 | for {set try 0} {$try < 10} {incr try} { |
| 219 | if {$force eq "YES_DO_IT"} { |
| 220 | if {[catch {file delete -force $path} error] == 0} { |
| 221 | return |
| 222 | } |
| 223 | } else { |
| 224 | if {[catch {file delete $path} error] == 0} { |
| 225 | return |
| 226 | } |
| 227 | } |
| 228 | after [expr {$try * 100}] |
| 229 | } |
| 230 | error "cannot delete \"$path\": $error" |
| 231 | } |
| 232 | |
| 233 | proc test_cleanup {} { |
| 234 | if {![info exists ::tempRepoPath]} {return} |
| 235 | if {![file exists $::tempRepoPath]} {return} |
| 236 | if {![file isdirectory $::tempRepoPath]} {return} |
| @@ -220,32 +237,30 @@ | |
| 237 | set tempPathEnd [expr {[string length $::tempPath] - 1}] |
| 238 | if {[string length $::tempPath] == 0 || \ |
| 239 | [string range $::tempRepoPath 0 $tempPathEnd] ne $::tempPath} { |
| 240 | error "Temporary repository path has wrong parent during cleanup." |
| 241 | } |
| 242 | if {[info exists ::tempSavedPwd]} {cd $::tempSavedPwd; unset ::tempSavedPwd} |
| 243 | # First, attempt to delete the specific temporary repository directories |
| 244 | # for this test file. |
| 245 | set scriptName [file tail [get_script_or_fail]] |
| 246 | foreach repoSeed $::tempRepoSeeds { |
| 247 | set repoPath [file join $::tempRepoPath $repoSeed $scriptName] |
| 248 | robust_delete $repoPath YES_DO_IT; # FORCE, arbitrary children. |
| 249 | set seedPath [file join $::tempRepoPath $repoSeed] |
| 250 | robust_delete $seedPath; # NO FORCE. |
| 251 | } |
| 252 | # Next, attempt to gracefully delete the temporary repository directory |
| 253 | # for this process. |
| 254 | robust_delete $::tempRepoPath |
| 255 | # Finally, attempt to gracefully delete the temporary home directory. |
| 256 | if {$::tcl_platform(platform) eq "windows"} { |
| 257 | robust_delete [file join $::tempHomePath _fossil] |
| 258 | } else { |
| 259 | robust_delete [file join $::tempHomePath .fossil] |
| 260 | } |
| 261 | robust_delete $::tempHomePath |
| 262 | } |
| 263 | |
| 264 | proc is_home_elsewhere {} { |
| 265 | return [expr {[info exists ::env(FOSSIL_HOME)] && \ |
| 266 | $::env(FOSSIL_HOME) eq $::tempHomePath}] |
| @@ -263,22 +278,22 @@ | |
| 278 | # |
| 279 | # Create and open a new Fossil repository and clean the checkout |
| 280 | # |
| 281 | proc repo_init {{filename ".rep.fossil"}} { |
| 282 | set_home_to_elsewhere |
| 283 | set ::tempRepoPath [file join $::tempPath repo_[pid]] |
| 284 | set repoSeed [appendArgs [string trim [clock seconds] -] _ [getSeqNo]] |
| 285 | lappend ::tempRepoSeeds $repoSeed |
| 286 | set repoPath [file join \ |
| 287 | $::tempRepoPath $repoSeed [file tail [get_script_or_fail]]] |
| 288 | if {[catch { |
| 289 | file mkdir $repoPath |
| 290 | } error] != 0} { |
| 291 | error "could not make directory \"$repoPath\",\ |
| 292 | please set TEMP variable in environment: $error" |
| 293 | } |
| 294 | if {![info exists ::tempSavedPwd]} {set ::tempSavedPwd [pwd]}; cd $repoPath |
| 295 | exec $::fossilexe new $filename |
| 296 | exec $::fossilexe open $filename |
| 297 | exec $::fossilexe set mtime-changes off |
| 298 | } |
| 299 | |
| 300 |