📄 testutils.tcl
字号:
set spl [expr $len - $n_replace] # Handle case where $n_replace > $len if { $spl < 0 } { set spl 0 } set s [string range $newstr [ expr $len - $n_replace ] end ] # Handle zero-length keys if { [string length $s] == 0 } { set s "A" } set repl [ replicate [string toupper $s] $n_add ] set newstr [chop_data $method \ [string range $newstr 0 [expr $spl - 1 ] ]$repl] set ret [eval {$db put} $txn \ {-partial [list $spl $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]]] # Middle Change set len [string length $newstr] set mid [expr $len / 2 ] set beg [expr $mid - [expr $n_replace / 2] ] set end [expr $beg + $n_replace - 1] set s [string range $newstr $beg $end] set repl [ replicate [string toupper $s] $n_add ] set newstr [chop_data $method [string range $newstr 0 \ [expr $beg - 1 ] ]$repl[string range $newstr [expr $end + 1] end]] set ret [eval {$db put} $txn {-partial [list $beg $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]]] set dvals($key) [pad_data $method $newstr]}proc replicate { str times } { set res $str for { set i 1 } { $i < $times } { set i [expr $i * 2] } { append res $res } return $res}proc repeat { str n } { set ret "" while { $n > 0 } { set ret $str$ret incr n -1 } return $ret}proc isqrt { l } { set s [expr sqrt($l)] set ndx [expr [string first "." $s] - 1] return [string range $s 0 $ndx]}# If we run watch_procs multiple times without an intervening# testdir cleanup, it's possible that old sentinel files will confuse# us. Make sure they're wiped out before we spawn any other processes.proc sentinel_init { } { source ./include.tcl set filelist {} set ret [catch {glob $testdir/begin.*} result] if { $ret == 0 } { set filelist $result } set ret [catch {glob $testdir/end.*} result] if { $ret == 0 } { set filelist [concat $filelist $result] } foreach f $filelist { fileremove $f }}proc watch_procs { pidlist {delay 30} {max 3600} {quiet 0} } { source ./include.tcl set elapsed 0 # Don't start watching the processes until a sentinel # file has been created for each one. foreach pid $pidlist { while { [file exists $testdir/begin.$pid] == 0 } { tclsleep $delay incr elapsed $delay # If pids haven't been created in one-tenth # of the time allowed for the whole test, # there's a problem. Report an error and fail. if { $elapsed > [expr {$max / 10}] } { puts "FAIL: begin.pid not created" break } } } while { 1 } { tclsleep $delay incr elapsed $delay # Find the list of processes with outstanding sentinel # files (i.e. a begin.pid and no end.pid). set beginlist {} set endlist {} set ret [catch {glob $testdir/begin.*} result] if { $ret == 0 } { set beginlist $result } set ret [catch {glob $testdir/end.*} result] if { $ret == 0 } { set endlist $result } set bpids {} catch {unset epids} foreach begfile $beginlist { lappend bpids [string range $begfile \ [string length $testdir/begin.] end] } foreach endfile $endlist { set epids([string range $endfile \ [string length $testdir/end.] end]) 1 } # The set of processes that we still want to watch, $l, # is the set of pids that have begun but not ended # according to their sentinel files. set l {} foreach p $bpids { if { [info exists epids($p)] == 0 } { lappend l $p } } set rlist {} foreach i $l { set r [ catch { exec $KILL -0 $i } result ] if { $r == 0 } { lappend rlist $i } } if { [ llength $rlist] == 0 } { break } else { puts "[timestamp] processes running: $rlist" } if { $elapsed > $max } { # We have exceeded the limit; kill processes # and report an error foreach i $l { tclkill $i } } } if { $quiet == 0 } { puts "All processes have exited." }}# These routines are all used from within the dbscript.tcl tester.proc db_init { dbp do_data } { global a_keys global l_keys source ./include.tcl set txn "" set nk 0 set lastkey "" set a_keys() BLANK set l_keys "" set c [$dbp cursor] for {set d [$c get -first] } { [llength $d] != 0 } { set d [$c get -next] } { set k [lindex [lindex $d 0] 0] set d2 [lindex [lindex $d 0] 1] incr nk if { $do_data == 1 } { if { [info exists a_keys($k)] } { lappend a_keys($k) $d2] } else { set a_keys($k) $d2 } } lappend l_keys $k } error_check_good curs_close [$c close] 0 return $nk}proc pick_op { min max n } { if { $n == 0 } { return add } set x [berkdb random_int 1 12] if {$n < $min} { if { $x <= 4 } { return put } elseif { $x <= 8} { return get } else { return add } } elseif {$n > $max} { if { $x <= 4 } { return put } elseif { $x <= 8 } { return get } else { return del } } elseif { $x <= 3 } { return del } elseif { $x <= 6 } { return get } elseif { $x <= 9 } { return put } else { return add }}# random_data: Generate a string of random characters.# If recno is 0 - Use average to pick a length between 1 and 2 * avg.# If recno is non-0, generate a number between 1 and 2 ^ (avg * 2),# that will fit into a 32-bit integer.# If the unique flag is 1, then make sure that the string is unique# in the array "where".proc random_data { avg unique where {recno 0} } { upvar #0 $where arr global debug_on set min 1 set max [expr $avg+$avg-1] if { $recno } { # # Tcl seems to have problems with values > 30. # if { $max > 30 } { set max 30 } set maxnum [expr int(pow(2, $max))] } while {1} { set len [berkdb random_int $min $max] set s "" if {$recno} { set s [berkdb random_int 1 $maxnum] } else { for {set i 0} {$i < $len} {incr i} { append s [int_to_char [berkdb random_int 0 25]] } } if { $unique == 0 || [info exists arr($s)] == 0 } { break } } return $s}proc random_key { } { global l_keys global nkeys set x [berkdb random_int 0 [expr $nkeys - 1]] return [lindex $l_keys $x]}proc is_err { desired } { set x [berkdb random_int 1 100] if { $x <= $desired } { return 1 } else { return 0 }}proc pick_cursput { } { set x [berkdb random_int 1 4] switch $x { 1 { return "-keylast" } 2 { return "-keyfirst" } 3 { return "-before" } 4 { return "-after" } }}proc random_cursor { curslist } { global l_keys global nkeys set x [berkdb random_int 0 [expr [llength $curslist] - 1]] set dbc [lindex $curslist $x] # We want to randomly set the cursor. Pick a key. set k [random_key] set r [$dbc get "-set" $k] error_check_good cursor_get:$k [is_substr Error $r] 0 # Now move forward or backward some hops to randomly # position the cursor. set dist [berkdb random_int -10 10] set dir "-next" set boundary "-first" if { $dist < 0 } { set dir "-prev" set boundary "-last" set dist [expr 0 - $dist] } for { set i 0 } { $i < $dist } { incr i } { set r [ record $dbc get $dir $k ] if { [llength $d] == 0 } { set r [ record $dbc get $k $boundary ] } error_check_bad dbcget [llength $r] 0 } return { [linsert r 0 $dbc] }}proc record { args } {# Recording every operation makes tests ridiculously slow on# NT, so we are commenting this out; for debugging purposes,# it will undoubtedly be useful to uncomment this.# puts $args# flush stdout return [eval $args]}proc newpair { k data } { global l_keys global a_keys global nkeys set a_keys($k) $data lappend l_keys $k incr nkeys}proc rempair { k } { global l_keys global a_keys global nkeys unset a_keys($k) set n [lsearch $l_keys $k] error_check_bad rempair:$k $n -1 set l_keys [lreplace $l_keys $n $n] incr nkeys -1}proc changepair { k data } { global l_keys global a_keys global nkeys set a_keys($k) $data}proc changedup { k olddata newdata } { global l_keys global a_keys global nkeys set d $a_keys($k) error_check_bad changedup:$k [llength $d] 0 set n [lsearch $d $olddata] error_check_bad changedup:$k $n -1 set a_keys($k) [lreplace $a_keys($k) $n $n $newdata]}# Insert a dup into the a_keys array with DB_KEYFIRST.proc adddup { k olddata newdata } { global l_keys global a_keys global nkeys set d $a_keys($k) if { [llength $d] == 0 } { lappend l_keys $k incr nkeys set a_keys($k) { $newdata } } set ndx 0 set d [linsert d $ndx $newdata] set a_keys($k) $d}proc remdup { k data } { global l_keys global a_keys global nkeys set d [$a_keys($k)] error_check_bad changedup:$k [llength $d] 0 set n [lsearch $d $olddata] error_check_bad changedup:$k $n -1 set a_keys($k) [lreplace $a_keys($k) $n $n]}proc dump_full_file { db txn outfile checkfunc start continue } { source ./include.tcl 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 dbcursor [is_valid_cursor $c $db] TRUE for {set d [$c get $start] } { [string length $d] != 0 } { set d [$c get $continue] } { set k [lindex [lindex $d 0] 0] set d2 [lindex [lindex $d 0] 1] $checkfunc $k $d2 puts $outf "$k\t$d2" } close $outf error_check_good curs_close [$c close] 0}proc int_to_char { i } { global alphabet return [string index $alphabet $i]}proc dbcheck { key data } { global l_keys global a_keys global nkeys global check_array if { [lsearch $l_keys $key] == -1 } { error "FAIL: Key |$key| not in list of valid keys" } set d $a_keys($key) if { [info exists check_array($key) ] } { set check $check_array($key) } else { set check {} } if { [llength $d] > 1 } { if { [llength $check] != [llength $d] } { # Make the check array the right length for { set i [llength $check] } { $i < [llength $d] } \ {incr i} { lappend check 0 } set check_array($key) $check } # Find this data's index set ndx [lsearch $d $data] if { $ndx == -1 } { error "FAIL: \ Data |$data| not found for key $key. Found |$d|" } # Set the bit in the check array set check_array($key) [lreplace $check_array($key) $ndx $ndx 1] } elseif { [string compare $d $data] != 0 } { error "FAIL: \ Invalid data |$data| for key |$key|. Expected |$d|." } else { set check_array($key) 1 }}# Dump out the file and verify itproc filecheck { file txn } { global check_array global l_keys global nkeys global a_keys source ./include.tcl if { [info exists check_array] == 1 } { unset check_array } open_and_dump_file $file NULL $file.dump dbcheck dump_full_file \ "-first" "-next" # Check that everything we checked had all its data foreach i [array names check_array] { set count 0 foreach j $check_array($i) { if { $j != 1 } { puts -nonewline "Key |$i| never found datum" puts " [lindex $a_keys($i) $count]" } incr count } } # Check that all keys appeared in the checked array set count 0 foreach k $l_keys { if { [info exists check_array($k)] == 0 } { puts "filecheck: key |$k| not found. Data: $a_keys($k)" } incr count } if { $count != $nkeys } { puts "filecheck: Got $count keys; expected $nkeys" }}proc cleanup { dir env { quiet 0 } } { global gen_upgrade global is_qnx_test global old_encrypt global passwd global upgrade_dir global upgrade_be global upgrade_method global upgrade_name source ./include.tcl if { $gen_upgrade == 1 } { set vers [berkdb version]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -