📄 testutils.tcl
字号:
# See the file LICENSE for redistribution information.## Copyright (c) 1996-2002# Sleepycat Software. All rights reserved.## $Id: testutils.tcl,v 11.165 2002/09/05 17:54:04 sandstro Exp $## Test system utilities## Timestamp -- print time along with elapsed time since last invocation# of timestamp.proc timestamp {{opt ""}} { global __timestamp_start set now [clock seconds] # -c accurate to the click, instead of the second. # -r seconds since the Epoch # -t current time in the format expected by db_recover -t. # -w wallclock time # else wallclock plus elapsed time. if {[string compare $opt "-r"] == 0} { return $now } elseif {[string compare $opt "-t"] == 0} { return [clock format $now -format "%y%m%d%H%M.%S"] } elseif {[string compare $opt "-w"] == 0} { return [clock format $now -format "%c"] } else { if {[string compare $opt "-c"] == 0} { set printclicks 1 } else { set printclicks 0 } if {[catch {set start $__timestamp_start}] != 0} { set __timestamp_start $now } set start $__timestamp_start set elapsed [expr $now - $start] set the_time [clock format $now -format ""] set __timestamp_start $now if { $printclicks == 1 } { set pc_print [format ".%08u" [__fix_num [clock clicks]]] } else { set pc_print "" } format "%02d:%02d:%02d$pc_print (%02d:%02d:%02d)" \ [__fix_num [clock format $now -format "%H"]] \ [__fix_num [clock format $now -format "%M"]] \ [__fix_num [clock format $now -format "%S"]] \ [expr $elapsed / 3600] \ [expr ($elapsed % 3600) / 60] \ [expr ($elapsed % 3600) % 60] }}proc __fix_num { num } { set num [string trimleft $num "0"] if {[string length $num] == 0} { set num "0" } return $num}# Add a {key,data} pair to the specified database where# key=filename and data=file contents.proc put_file { db txn flags file } { source ./include.tcl set fid [open $file r] fconfigure $fid -translation binary set data [read $fid] close $fid set ret [eval {$db put} $txn $flags {$file $data}] error_check_good put_file $ret 0}# Get a {key,data} pair from the specified database where# key=filename and data=file contents and then write the# data to the specified file.proc get_file { db txn flags file outfile } { source ./include.tcl set fid [open $outfile w] fconfigure $fid -translation binary if [catch {eval {$db get} $txn $flags {$file}} data] { puts -nonewline $fid $data } else { # Data looks like {{key data}} set data [lindex [lindex $data 0] 1] puts -nonewline $fid $data } close $fid}# Add a {key,data} pair to the specified database where# key=file contents and data=file name.proc put_file_as_key { db txn flags file } { source ./include.tcl set fid [open $file r] fconfigure $fid -translation binary set filecont [read $fid] close $fid # Use not the file contents, but the file name concatenated # before the file contents, as a key, to ensure uniqueness. set data $file$filecont set ret [eval {$db put} $txn $flags {$data $file}] error_check_good put_file $ret 0}# Get a {key,data} pair from the specified database where# key=file contents and data=file nameproc get_file_as_key { db txn flags file} { source ./include.tcl set fid [open $file r] fconfigure $fid -translation binary set filecont [read $fid] close $fid set data $file$filecont return [eval {$db get} $txn $flags {$data}]}# open file and call dump_file to dumpkeys to tempfileproc open_and_dump_file { dbname env outfile checkfunc dump_func beg cont } { global encrypt global passwd source ./include.tcl set encarg "" if { $encrypt > 0 && $env == "NULL" } { set encarg "-encryptany $passwd" } set envarg "" set txn "" set txnenv 0 if { $env != "NULL" } { append envarg " -env $env " set txnenv [is_txnenv $env] if { $txnenv == 1 } { append envarg " -auto_commit " set t [$env txn] error_check_good txn [is_valid_txn $t $env] TRUE set txn "-txn $t" } } set db [eval {berkdb open} $envarg -rdonly -unknown $encarg $dbname] error_check_good dbopen [is_valid_db $db] TRUE $dump_func $db $txn $outfile $checkfunc $beg $cont if { $txnenv == 1 } { error_check_good txn [$t commit] 0 } error_check_good db_close [$db close] 0}# open file and call dump_file to dumpkeys to tempfileproc open_and_dump_subfile { dbname env outfile checkfunc dump_func beg cont subdb} { global encrypt global passwd source ./include.tcl set encarg "" if { $encrypt > 0 && $env == "NULL" } { set encarg "-encryptany $passwd" } set envarg "" set txn "" set txnenv 0 if { $env != "NULL" } { append envarg "-env $env" set txnenv [is_txnenv $env] if { $txnenv == 1 } { append envarg " -auto_commit " set t [$env txn] error_check_good txn [is_valid_txn $t $env] TRUE set txn "-txn $t" } } set db [eval {berkdb open -rdonly -unknown} \ $envarg $encarg {$dbname $subdb}] error_check_good dbopen [is_valid_db $db] TRUE $dump_func $db $txn $outfile $checkfunc $beg $cont if { $txnenv == 1 } { error_check_good txn [$t commit] 0 } error_check_good db_close [$db close] 0}# Sequentially read a file and call checkfunc on each key/data pair.# Dump the keys out to the file specified by outfile.proc dump_file { db txn outfile checkfunc } { source ./include.tcl dump_file_direction $db $txn $outfile $checkfunc "-first" "-next"}proc dump_file_direction { db txn outfile checkfunc start continue } { source ./include.tcl # Now we will get each key from the DB and dump to outfile set c [eval {$db cursor} $txn] error_check_good db_cursor [is_valid_cursor $c $db] TRUE dump_file_walk $c $outfile $checkfunc $start $continue error_check_good curs_close [$c close] 0}proc dump_file_walk { c outfile checkfunc start continue {flag ""} } { set outf [open $outfile w] for {set d [eval {$c get} $flag $start] } \ { [llength $d] != 0 } \ {set d [eval {$c get} $flag $continue] } { set kd [lindex $d 0] set k [lindex $kd 0] set d2 [lindex $kd 1] $checkfunc $k $d2 puts $outf $k # XXX: Geoff Mainland # puts $outf "$k $d2" } close $outf}proc dump_binkey_file { db txn outfile checkfunc } { source ./include.tcl dump_binkey_file_direction $db $txn $outfile $checkfunc \ "-first" "-next"}proc dump_bin_file { db txn outfile checkfunc } { source ./include.tcl dump_bin_file_direction $db $txn $outfile $checkfunc "-first" "-next"}# Note: the following procedure assumes that the binary-file-as-keys were# inserted into the database by put_file_as_key, and consist of the file# name followed by the file contents as key, to ensure uniqueness.proc dump_binkey_file_direction { db txn outfile checkfunc begin cont } { source ./include.tcl set d1 $testdir/d1 set outf [open $outfile w] # Now we will get each key from the DB and dump to outfile set c [eval {$db cursor} $txn] error_check_good db_cursor [is_valid_cursor $c $db] TRUE set inf $d1 for {set d [$c get $begin] } { [llength $d] != 0 } \ {set d [$c get $cont] } { set kd [lindex $d 0] set keyfile [lindex $kd 0] set data [lindex $kd 1] set ofid [open $d1 w] fconfigure $ofid -translation binary # Chop off the first few bytes--that's the file name, # added for uniqueness in put_file_as_key, which we don't # want in the regenerated file. set namelen [string length $data] set keyfile [string range $keyfile $namelen end] puts -nonewline $ofid $keyfile close $ofid $checkfunc $data $d1 puts $outf $data flush $outf } close $outf error_check_good curs_close [$c close] 0 fileremove $d1}proc dump_bin_file_direction { db txn outfile checkfunc begin cont } { source ./include.tcl set d1 $testdir/d1 set outf [open $outfile w] # Now we will get each key from the DB and dump to outfile set c [eval {$db cursor} $txn] for {set d [$c get $begin] } \ { [llength $d] != 0 } {set d [$c get $cont] } { set k [lindex [lindex $d 0] 0] set data [lindex [lindex $d 0] 1] set ofid [open $d1 w] fconfigure $ofid -translation binary puts -nonewline $ofid $data close $ofid $checkfunc $k $d1 puts $outf $k } close $outf error_check_good curs_close [$c close] 0 fileremove -f $d1}proc make_data_str { key } { set datastr "" for {set i 0} {$i < 10} {incr i} { append datastr $key } return $datastr}proc error_check_bad { func result bad {txn 0}} { if { [binary_compare $result $bad] == 0 } { if { $txn != 0 } { $txn abort } flush stdout flush stderr error "FAIL:[timestamp] $func returned error value $bad" }}proc error_check_good { func result desired {txn 0} } { if { [binary_compare $desired $result] != 0 } { if { $txn != 0 } { $txn abort } flush stdout flush stderr error "FAIL:[timestamp]\ $func: expected $desired, got $result" }}# Locks have the prefix of their manager.proc is_substr { str sub } { if { [string first $sub $str] == -1 } { return 0 } else { return 1 }}proc release_list { l } { # Now release all the locks foreach el $l { catch { $el put } ret error_check_good lock_put $ret 0 }}proc debug { {stop 0} } { global __debug_on global __debug_print global __debug_test set __debug_on 1 set __debug_print 1 set __debug_test $stop}# Check if each key appears exactly [llength dlist] times in the file with# the duplicate tags matching those that appear in dlist.proc dup_check { db txn tmpfile dlist {extra 0}} { source ./include.tcl set outf [open $tmpfile w] # Now we will get each key from the DB and dump to outfile set c [eval {$db cursor} $txn] set lastkey "" set done 0 while { $done != 1} { foreach did $dlist { set rec [$c get "-next"] if { [string length $rec] == 0 } { set done 1 break } set key [lindex [lindex $rec 0] 0] set fulldata [lindex [lindex $rec 0] 1] set id [id_of $fulldata] set d [data_of $fulldata] if { [string compare $key $lastkey] != 0 && \ $id != [lindex $dlist 0] } { set e [lindex $dlist 0] error "FAIL: \tKey \ $key, expected dup id $e, got $id" } error_check_good dupget.data $d $key error_check_good dupget.id $id $did set lastkey $key } # # Some tests add an extra dup (like overflow entries) # Check id if it exists. if { $extra != 0} { set okey $key set rec [$c get "-next"] if { [string length $rec] != 0 } { set key [lindex [lindex $rec 0] 0] # # If this key has no extras, go back for # next iteration. if { [string compare $key $lastkey] != 0 } { set key $okey set rec [$c get "-prev"] } else { set fulldata [lindex [lindex $rec 0] 1] set id [id_of $fulldata] set d [data_of $fulldata] error_check_bad dupget.data1 $d $key error_check_good dupget.id1 $id $extra } } } if { $done != 1 } { puts $outf $key } } close $outf error_check_good curs_close [$c close] 0}# Check if each key appears exactly [llength dlist] times in the file with# the duplicate tags matching those that appear in dlist.proc dup_file_check { db txn tmpfile dlist } { source ./include.tcl set outf [open $tmpfile w] # Now we will get each key from the DB and dump to outfile set c [eval {$db cursor} $txn] set lastkey "" set done 0 while { $done != 1} { foreach did $dlist { set rec [$c get "-next"] if { [string length $rec] == 0 } { set done 1 break } set key [lindex [lindex $rec 0] 0] if { [string compare $key $lastkey] != 0 } { # # If we changed files read in new contents. # set fid [open $key r] fconfigure $fid -translation binary set filecont [read $fid] close $fid } set fulldata [lindex [lindex $rec 0] 1] set id [id_of $fulldata] set d [data_of $fulldata] if { [string compare $key $lastkey] != 0 && \ $id != [lindex $dlist 0] } { set e [lindex $dlist 0] error "FAIL: \tKey \ $key, expected dup id $e, got $id" } error_check_good dupget.data $d $filecont error_check_good dupget.id $id $did set lastkey $key } if { $done != 1 } { puts $outf $key } } close $outf error_check_good curs_close [$c close] 0}# Parse duplicate data entries of the form N:data. Data_of returns# the data part; id_of returns the numerical partproc data_of {str} { set ndx [string first ":" $str] if { $ndx == -1 } { return "" } return [ string range $str [expr $ndx + 1] end]}proc id_of {str} { set ndx [string first ":" $str] if { $ndx == -1 } { return "" } return [ string range $str 0 [expr $ndx - 1]]}proc nop { {args} } { return}# Partial put test procedure.# Munges a data val through three different partial puts. Stores# the final munged string in the dvals array so that you can check# it later (dvals should be global). We take the characters that# are being replaced, make them capitals and then replicate them# some number of times (n_add). We do this at the beginning of the# data, at the middle and at the end. The parameters are:# db, txn, key -- as per usual. Data is the original data element# from which we are starting. n_replace is the number of characters# that we will replace. n_add is the number of times we will add# the replaced string back in.proc partial_put { method db txn gflags key data n_replace n_add } { global dvals source ./include.tcl # Here is the loop where we put and get each key/data pair # We will do the initial put and then three Partial Puts # for the beginning, middle and end of the string. eval {$db put} $txn {$key [chop_data $method $data]} # Beginning change set s [string range $data 0 [ expr $n_replace - 1 ] ] set repl [ replicate [string toupper $s] $n_add ] # This is gross, but necessary: if this is a fixed-length # method, and the chopped length of $repl is zero, # it's because the original string was zero-length and our data item # is all nulls. Set repl to something non-NULL. if { [is_fixed_length $method] && \ [string length [chop_data $method $repl]] == 0 } { set repl [replicate "." $n_add] } set newstr [chop_data $method $repl[string range $data $n_replace end]] set ret [eval {$db put} $txn {-partial [list 0 $n_replace] \ $key [chop_data $method $repl]}] error_check_good put $ret 0 set ret [eval {$db get} $gflags $txn {$key}] error_check_good get $ret [list [list $key [pad_data $method $newstr]]] # End Change set len [string length $newstr]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -