summaryrefslogtreecommitdiff
path: root/test/foputils.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'test/foputils.tcl')
-rw-r--r--test/foputils.tcl484
1 files changed, 484 insertions, 0 deletions
diff --git a/test/foputils.tcl b/test/foputils.tcl
new file mode 100644
index 0000000..fc0d301
--- /dev/null
+++ b/test/foputils.tcl
@@ -0,0 +1,484 @@
+# See the file LICENSE for redistribution information.
+#
+# Copyright (c) 2003-2009 Oracle. All rights reserved.
+#
+# $Id$
+#
+proc do_op {omethod op names txn env {largs ""}} {
+ switch -exact $op {
+ delete { do_delete $names }
+ rename { do_rename $names $txn $env }
+ remove { do_remove $names $txn $env }
+ noop { do_noop }
+ open_create { do_create $omethod $names $txn $env $largs }
+ open { do_open $omethod $names $txn $env $largs }
+ open_excl { do_create_excl $omethod $names $txn $env $largs }
+ truncate { do_truncate $omethod $names $txn $env $largs }
+ default { puts "FAIL: operation $op not recognized" }
+ }
+}
+
+proc do_subdb_op {omethod op names txn env {largs ""}} {
+ #
+ # The 'noop' and 'delete' actions are the same
+ # for subdbs as for regular db files.
+ #
+ switch -exact $op {
+ delete { do_delete $names }
+ rename { do_subdb_rename $names $txn $env }
+ remove { do_subdb_remove $names $txn $env }
+ noop { do_noop }
+ default { puts "FAIL: operation $op not recognized" }
+ }
+}
+
+proc do_inmem_op {omethod op names txn env {largs ""}} {
+ #
+ # The in-memory versions of do_op are different in
+ # that we don't need to pass in the filename, just
+ # the subdb names.
+ #
+ switch -exact $op {
+ delete { do_delete $names }
+ rename { do_inmem_rename $names $txn $env }
+ remove { do_inmem_remove $names $txn $env }
+ noop { do_noop }
+ open_create { do_inmem_create $omethod $names $txn $env $largs }
+ open { do_inmem_open $omethod $names $txn $env $largs }
+ open_excl { do_inmem_create_excl $omethod $names $txn $env $largs }
+ truncate { do_inmem_truncate $omethod $names $txn $env $largs }
+ default { puts "FAIL: operation $op not recognized" }
+ }
+}
+
+proc do_delete {names} {
+ #
+ # This is the odd man out among the ops -- it's not a Berkeley
+ # DB file operation, but mimics an operation done externally,
+ # as if a user deleted a file with "rm" or "erase".
+ #
+ # We assume the file is found in $testdir.
+ #
+ global testdir
+
+ if {[catch [fileremove -f $testdir/$names] result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_noop { } {
+ # Do nothing. Report success.
+ return 0
+}
+
+proc do_rename {names txn env} {
+ # Pull db names out of $names
+ set oldname [lindex $names 0]
+ set newname [lindex $names 1]
+
+ if {[catch {eval $env dbrename -txn $txn \
+ $oldname $newname} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_subdb_rename {names txn env} {
+ # Pull db and subdb names out of $names
+ set filename [lindex $names 0]
+ set oldsname [lindex $names 1]
+ set newsname [lindex $names 2]
+
+ if {[catch {eval $env dbrename -txn $txn $filename \
+ $oldsname $newsname} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_inmem_rename {names txn env} {
+ # Pull db and subdb names out of $names
+ set filename ""
+ set oldsname [lindex $names 0]
+ set newsname [lindex $names 1]
+ if {[catch {eval $env dbrename -txn $txn {$filename} \
+ $oldsname $newsname} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+
+proc do_remove {names txn env} {
+ if {[catch {eval $env dbremove -txn $txn $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_subdb_remove {names txn env} {
+ set filename [lindex $names 0]
+ set subname [lindex $names 1]
+ if {[catch {eval $env dbremove -txn $txn $filename $subname} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_inmem_remove {names txn env} {
+ if {[catch {eval $env dbremove -txn $txn {""} $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_create {omethod names txn env {largs ""}} {
+ if {[catch {eval berkdb_open -create $omethod $largs -env $env \
+ -txn $txn $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_inmem_create {omethod names txn env {largs ""}} {
+ if {[catch {eval berkdb_open -create $omethod $largs -env $env \
+ -txn $txn "" $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_open {omethod names txn env {largs ""}} {
+ if {[catch {eval berkdb_open $omethod $largs -env $env \
+ -txn $txn $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_inmem_open {omethod names txn env {largs ""}} {
+ if {[catch {eval berkdb_open $omethod $largs -env $env \
+ -txn $txn {""} $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_create_excl {omethod names txn env {largs ""}} {
+ if {[catch {eval berkdb_open -create -excl $omethod $largs -env $env \
+ -txn $txn $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_inmem_create_excl {omethod names txn env {largs ""}} {
+ if {[catch {eval berkdb_open -create -excl $omethod $largs -env $env \
+ -txn $txn {""} $names} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_truncate {omethod names txn env {largs ""}} {
+ # First we have to get a handle. We omit the -create flag
+ # because testing of truncate is meaningful only in cases
+ # where the database already exists.
+ set db [eval {berkdb_open $omethod} $largs {-env $env -txn $txn $names}]
+ error_check_good db_open [is_valid_db $db] TRUE
+
+ if {[catch {$db truncate -txn $txn} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc do_inmem_truncate {omethod names txn env {largs ""}} {
+ set db [eval {berkdb_open $omethod} $largs {-env $env -txn $txn "" $names}]
+ error_check_good db_open [is_valid_db $db] TRUE
+
+ if {[catch {$db truncate -txn $txn} result]} {
+ return $result
+ } else {
+ return 0
+ }
+}
+
+proc create_tests { op1 op2 exists noexist open retval { end1 "" } } {
+ set retlist {}
+ switch $op1 {
+ rename {
+ # Use first element from exists list
+ set from [lindex $exists 0]
+ # Use first element from noexist list
+ set to [lindex $noexist 0]
+
+ # This is the first operation, which should succeed
+ set op1ret [list $op1 "$from $to" 0 $end1]
+
+ # Adjust 'exists' and 'noexist' list if and only if
+ # txn1 was not aborted.
+ if { $end1 != "abort" } {
+ set exists [lreplace $exists 0 0 $to]
+ set noexist [lreplace $noexist 0 0 $from]
+ }
+ }
+ remove {
+ set from [lindex $exists 0]
+ set op1ret [list $op1 $from 0 $end1]
+
+ if { $end1 != "abort" } {
+ set exists [lreplace $exists 0 0]
+ set noexist [lreplace $noexist 0 0 $from]
+ }
+ }
+ open_create -
+ open -
+ truncate {
+ set from [lindex $exists 0]
+ set op1ret [list $op1 $from 0 $end1]
+
+ if { $end1 != "abort" } {
+ set exists [lreplace $exists 0 0]
+ set open [list $from]
+ }
+
+ # Eliminate the 1st element in noexist: it is
+ # equivalent to the 2nd element (neither ever exists).
+ set noexist [lreplace $noexist 0 0]
+ }
+ open_excl {
+ # Use first element from noexist list
+ set from [lindex $noexist 0]
+ set op1ret [list $op1 $from 0 $end1]
+
+ if { $end1 != "abort" } {
+ set noexist [lreplace $noexist 0 0]
+ set open [list $from]
+ }
+
+ # Eliminate the 1st element in exists: it is
+ # equivalent to the 2nd element (both already exist).
+ set exists [lreplace $exists 0 0]
+ }
+ }
+
+ # Generate possible second operations given the return value.
+ set op2list [create_op2 $op2 $exists $noexist $open $retval]
+
+ foreach o $op2list {
+ lappend retlist [list $op1ret $o]
+ }
+ return $retlist
+}
+
+proc create_badtests { op1 op2 exists noexist open retval {end1 ""} } {
+ set retlist {}
+ switch $op1 {
+ rename {
+ # Use first element from exists list
+ set from [lindex $exists 0]
+ # Use first element from noexist list
+ set to [lindex $noexist 0]
+
+ # This is the first operation, which should fail
+ set op1list1 \
+ [list $op1 "$to $to" "no such file" $end1]
+ set op1list2 \
+ [list $op1 "$to $from" "no such file" $end1]
+ set op1list3 \
+ [list $op1 "$from $from" "file exists" $end1]
+ set op1list [list $op1list1 $op1list2 $op1list3]
+
+ # Generate second operations given the return value.
+ set op2list [create_op2 \
+ $op2 $exists $noexist $open $retval]
+ foreach op1 $op1list {
+ foreach op2 $op2list {
+ lappend retlist [list $op1 $op2]
+ }
+ }
+ return $retlist
+ }
+ remove -
+ open -
+ truncate {
+ set file [lindex $noexist 0]
+ set op1list [list $op1 $file "no such file" $end1]
+
+ set op2list [create_op2 \
+ $op2 $exists $noexist $open $retval]
+ foreach op2 $op2list {
+ lappend retlist [list $op1list $op2]
+ }
+ return $retlist
+ }
+ open_excl {
+ set file [lindex $exists 0]
+ set op1list [list $op1 $file "file exists" $end1]
+ set op2list [create_op2 \
+ $op2 $exists $noexist $open $retval]
+ foreach op2 $op2list {
+ lappend retlist [list $op1list $op2]
+ }
+ return $retlist
+ }
+ }
+}
+
+proc create_op2 { op2 exists noexist open retval } {
+ set retlist {}
+ switch $op2 {
+ rename {
+ # Successful renames arise from renaming existing
+ # to non-existing files.
+ if { $retval == 0 } {
+ set old $exists
+ set new $noexist
+ set retlist \
+ [build_retlist $op2 $old $new $retval]
+ }
+ # "File exists" errors arise from renaming existing
+ # to existing files.
+ if { $retval == "file exists" } {
+ set old $exists
+ set new $exists
+ set retlist \
+ [build_retlist $op2 $old $new $retval]
+ }
+ # "No such file" errors arise from renaming files
+ # that don't exist.
+ if { $retval == "no such file" } {
+ set old $noexist
+ set new $exists
+ set retlist1 \
+ [build_retlist $op2 $old $new $retval]
+
+ set old $noexist
+ set new $noexist
+ set retlist2 \
+ [build_retlist $op2 $old $new $retval]
+
+ set retlist [concat $retlist1 $retlist2]
+ }
+ }
+ remove {
+ # Successful removes result from removing existing
+ # files.
+ if { $retval == 0 } {
+ set file $exists
+ }
+ # "File exists" does not happen in remove.
+ if { $retval == "file exists" } {
+ return
+ }
+ # "No such file" errors arise from trying to remove
+ # files that don't exist.
+ if { $retval == "no such file" } {
+ set file $noexist
+ }
+ set retlist [build_retlist $op2 $file "" $retval]
+ }
+ open_create {
+ # Open_create should be successful with existing,
+ # open, or non-existing files.
+ if { $retval == 0 } {
+ set file [concat $exists $open $noexist]
+ }
+ # "File exists" and "no such file"
+ # do not happen in open_create.
+ if { $retval == "file exists" || \
+ $retval == "no such file" } {
+ return
+ }
+ set retlist [build_retlist $op2 $file "" $retval]
+ }
+ open {
+ # Open should be successful with existing or open files.
+ if { $retval == 0 } {
+ set file [concat $exists $open]
+ }
+ # "No such file" errors arise from trying to open
+ # non-existent files.
+ if { $retval == "no such file" } {
+ set file $noexist
+ }
+ # "File exists" errors do not happen in open.
+ if { $retval == "file exists" } {
+ return
+ }
+ set retlist [build_retlist $op2 $file "" $retval]
+ }
+ open_excl {
+ # Open_excl should be successful with non-existent files.
+ if { $retval == 0 } {
+ set file $noexist
+ }
+ # "File exists" errors arise from trying to open
+ # existing files.
+ if { $retval == "file exists" } {
+ set file [concat $exists $open]
+ }
+ # "No such file" errors do not arise in open_excl.
+ if { $retval == "no such file" } {
+ return
+ }
+ set retlist [build_retlist $op2 $file "" $retval]
+ }
+ truncate {
+ # Truncate should be successful with existing files.
+ if { $retval == 0 } {
+ set file $exists
+ }
+ # No other return values are meaningful to test since
+ # do_truncate starts with an open and we've already
+ # tested open.
+ if { $retval == "no such file" || \
+ $retval == "file exists" } {
+ return
+ }
+ set retlist [build_retlist $op2 $file "" $retval]
+ }
+ }
+ return $retlist
+}
+
+proc build_retlist { op2 file1 file2 retval } {
+ set retlist {}
+ if { $file2 == "" } {
+ foreach f1 $file1 {
+ lappend retlist [list $op2 $f1 $retval]
+ }
+ } else {
+ foreach f1 $file1 {
+ foreach f2 $file2 {
+ lappend retlist [list $op2 "$f1 $f2" $retval]
+ }
+ }
+ }
+ return $retlist
+}
+
+proc extract_error { message } {
+ if { [is_substr $message "exists"] == 1 } {
+ set message "file exists"
+ } elseif {[is_substr $message "no such file"] == 1 } {
+ set message "no such file"
+ }
+ return $message
+}