diff options
author | jbj <devnull@localhost> | 2001-10-15 03:47:21 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2001-10-15 03:47:21 +0000 |
commit | db7110722d3317cc81dd11c104dd45ac8c328e20 (patch) | |
tree | acc2fe412f5d1f7e3d3fd35993fd3fd5cc20a7f3 /db/test | |
parent | 033e2a186a797374caeb2295a00dee5eef202ffc (diff) | |
download | rpm-db7110722d3317cc81dd11c104dd45ac8c328e20.tar.gz rpm-db7110722d3317cc81dd11c104dd45ac8c328e20.tar.bz2 rpm-db7110722d3317cc81dd11c104dd45ac8c328e20.zip |
Initial revision
CVS patchset: 5110
CVS date: 2001/10/15 03:47:21
Diffstat (limited to 'db/test')
86 files changed, 8257 insertions, 0 deletions
diff --git a/db/test/dead006.tcl b/db/test/dead006.tcl new file mode 100644 index 000000000..d6ede9cb4 --- /dev/null +++ b/db/test/dead006.tcl @@ -0,0 +1,16 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 1996-2001 +# Sleepycat Software. All rights reserved. +# +# Id: dead006.tcl,v 1.3 2001/10/11 16:15:30 sandstro Exp +# +# TEST dead006 +# TEST use timeouts rather than the normal dd algorithm. +proc dead006 { { procs "2 4 10" } {tests "ring clump" } \ + {timeout 1000} {tnum 006} } { + source ./include.tcl + + dead001 $procs $tests $timeout $tnum + dead002 $procs $tests $timeout $tnum +} diff --git a/db/test/dead007.tcl b/db/test/dead007.tcl new file mode 100644 index 000000000..f7fe42c21 --- /dev/null +++ b/db/test/dead007.tcl @@ -0,0 +1,35 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 1996-2001 +# Sleepycat Software. All rights reserved. +# +# Id: dead007.tcl,v 1.1 2001/10/10 16:23:48 ubell Exp +# +# TEST dead007 +# TEST use timeouts rather than the normal dd algorithm. +proc dead007 { } { + source ./include.tcl + global lock_curid + global lock_maxid + + set save_curid $lock_curid + set save_maxid $lock_maxid + puts "Dead007.a -- wrap around" + set lock_curid [expr $lock_maxid - 2] + dead001 "2 10" + ## Oldest/youngest breaks when the id wraps + # dead003 "4 10" + dead004 + + puts "Dead007.b -- extend space" + set lock_maxid [expr $lock_maxid - 3] + set lock_curid [expr $lock_maxid - 1] + dead001 "4 10" + ## Oldest/youngest breaks when the id wraps + # dead003 "10" + dead004 + + set lock_curid $save_curid + set lock_maxid $save_maxid + puts "Dead007 -- complete" +} diff --git a/db/test/env010.tcl b/db/test/env010.tcl new file mode 100644 index 000000000..18bf1a717 --- /dev/null +++ b/db/test/env010.tcl @@ -0,0 +1,49 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 1999-2001 +# Sleepycat Software. All rights reserved. +# +# Id: env010.tcl,v 1.2 2001/08/03 16:39:24 bostic Exp +# +# TEST env010 +# TEST Run recovery in an empty directory, and then make sure we can still +# TEST create a database in that directory. +proc env010 { } { + source ./include.tcl + + puts "Env010: Test of recovery in an empty directory." + + # Create a new directory used only for this test + + if { [file exists $testdir/EMPTYDIR] != 1 } { + file mkdir $testdir/EMPTYDIR + } else { + puts "\nDirectory already exists." + } + + # Do the test twice, for regular recovery and catastrophic + # Open environment and recover, but don't create a database + + foreach rmethod {recover recover_fatal} { + + puts "\tEnv010: Creating env for $rmethod test." + env_cleanup $testdir/EMPTYDIR + set e [berkdb env -create -home $testdir/EMPTYDIR -$rmethod] + error_check_good dbenv [is_valid_env $e] TRUE + + # Open and close a database + # The method doesn't matter, so picked btree arbitrarily + + set db [eval {berkdb_open -env $e \ + -btree -create -mode 0644} ] + error_check_good dbopen [is_valid_db $db] TRUE + error_check_good db_close [$db close] 0 + + # Close environment + + error_check_good envclose [$e close] 0 + error_check_good berkdb:envremove \ + [berkdb envremove -home $testdir/EMPTYDIR] 0 + } + puts "\tEnv010 complete." +} diff --git a/db/test/lock004.tcl b/db/test/lock004.tcl new file mode 100644 index 000000000..1976ac7a0 --- /dev/null +++ b/db/test/lock004.tcl @@ -0,0 +1,49 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 1996-2001 +# Sleepycat Software. All rights reserved. +# +# Id: lock004.tcl,v 11.1 2001/10/10 16:22:10 ubell Exp +# +# TEST lock004 +# TEST Test locker ids wraping around. + +proc lock004 {} { + source ./include.tcl + global lock_curid + global lock_maxid + + puts "Lock004.a -- locker id wrapping" + locktest -S [expr $lock_maxid - 1] $lock_maxid + + puts "Lock004.b -- test out of locker ids" + env_cleanup $testdir + + # Open/create the lock region + set e [berkdb env -create -lock -home $testdir] + error_check_good env_open [is_substr $e env] 1 + + catch { $e lock_id } locker1 + error_check_good locker1 [is_valid_locker $locker1] TRUE + error_check_good lock_id_set \ + [$e lock_id_set [expr $lock_maxid - 1] $lock_maxid] 0 + + catch { $e lock_id } locker2 + error_check_good locker2 [is_valid_locker $locker2] TRUE + catch { $e lock_id } locker3 + error_check_bad locker3 [is_valid_locker $locker3] TRUE + error_check_good locker3 [string match "*wrapped*" $locker3] 1 + + catch { $e lock_id_free $locker1 } ret + error_check_good free $ret 0 + catch { $e lock_id } locker4 + error_check_good locker4 [is_valid_locker $locker4] TRUE + + catch { $e lock_id_free $locker2 } ret + error_check_good free $ret 0 + catch { $e lock_id_free $locker4 } ret + error_check_good free $ret 0 + + catch {$e close} ret + error_check_good close $ret 0 +} diff --git a/db/test/parallel.tcl b/db/test/parallel.tcl new file mode 100644 index 000000000..fdfc95d87 --- /dev/null +++ b/db/test/parallel.tcl @@ -0,0 +1,214 @@ +# Code to load up the tests in to the Queue database +# Id: parallel.tcl,v 11.9 2001/10/03 20:48:51 sandstro Exp +proc load_queue { file {dbdir RUNQUEUE} nitems } { + + puts -nonewline "Loading run queue with $nitems items..." + flush stdout + + set env [berkdb env -create -lock -home $dbdir] + error_check_good dbenv [is_valid_widget $env env] TRUE + + set db [eval {berkdb_open -env $env -create -truncate \ + -mode 0644 -len 100 -queue queue.db} ] + error_check_good dbopen [is_valid_widget $db db] TRUE + + set fid [open $file] + + set count 0 + + while { [gets $fid str] != -1 } { + set testarr($count) $str + incr count + } + + # Randomize array of tests. + set rseed [pid] + berkdb srand $rseed + puts -nonewline "randomizing..." + flush stdout + for { set i 0 } { $i < $count } { incr i } { + set j [berkdb random_int $i [expr $count - 1]] + + set tmp $testarr($i) + set testarr($i) $testarr($j) + set testarr($j) $tmp + } + + if { [string compare ALL $nitems] != 0 } { + set maxload $nitems + } else { + set maxload $count + } + + puts "loading..." + flush stdout + for { set i 0 } { $i < $maxload } { incr i } { + set str $testarr($i) + set ret [eval {$db put -append $str} ] + error_check_good put:$db $ret [expr $i + 1] + } + + puts "Loaded $maxload records (out of $count)." + close $fid + $db close + $env close +} + +proc init_runqueue { {dbdir RUNQUEUE} nitems } { + + if { [file exists $dbdir] != 1 } { + file mkdir $dbdir + } + puts "Creating test list..." + run_all -n + load_queue ALL.OUT $dbdir $nitems + file delete ALL.OUT +} + +proc run_parallel { nprocs {nitems ALL} } { + set basename ./PARALLEL_TESTDIR + set queuedir ./RUNQUEUE + source ./include.tcl + + mkparalleldirs $nprocs $basename $queuedir + + init_runqueue $queuedir $nitems + + set basedir [pwd] + set pidlist {} + set queuedir ../../[string range $basedir [string last "/" $basedir] end]/$queuedir + + for { set i 1 } { $i <= $nprocs } { incr i } { + fileremove -f ALL.OUT.$i + set ret [catch { + set p [exec $tclsh_path << \ + "source $test_path/test.tcl;\ + run_queue $i $basename.$i $queuedir $nitems" &] + set f [open $testdir/begin.$p w] + close $f + } res] + } + watch_procs 300 360000 + + set failed 0 + for { set i 1 } { $i <= $nprocs } { incr i } { + if { [check_failed_run ALL.OUT.$i] != 0 } { + set failed 1 + puts "Regression tests failed in process $i." + } + } + if { $failed == 0 } { + puts "Regression tests succeeded." + } +} + +proc run_queue { i rundir queuedir nitems } { + set builddir [pwd] + file delete $builddir/ALL.OUT.$i + cd $rundir + + puts "Parallel run_queue process $i (pid [pid]) starting." + + source ./include.tcl + global env + + set dbenv [berkdb env -create -lock -home $queuedir] + error_check_good dbenv [is_valid_widget $dbenv env] TRUE + + set db [eval {berkdb_open -env $dbenv \ + -mode 0644 -len 80 -queue queue.db} ] + error_check_good dbopen [is_valid_widget $db db] TRUE + + set dbc [eval $db cursor] + error_check_good cursor [is_valid_cursor $dbc $db] TRUE + + set count 0 + set waitcnt 0 + + while { $waitcnt < 5 } { + set line [$db get -consume] + if { [ llength $line ] > 0 } { + set cmd [lindex [lindex $line 0] 1] + set num [lindex [lindex $line 0] 0] + set o [open $builddir/ALL.OUT.$i a] + puts $o "\nExecuting record $num:\n" + puts $o $cmd + close $o + if { [expr {$num % 10} == 0] } { + puts "Starting test $num of $nitems" + } + #puts "Process $i, record $num:\n$cmd" + set env(PURIFYOPTIONS) \ + "-log-file=./test$num.%p -follow-child-processes -messages=first" + set env(PURECOVOPTIONS) \ + "-counts-file=./cov.pcv -log-file=./cov.log -follow-child-processes" + if [catch {exec $tclsh_path \ + << "source $test_path/test.tcl; $cmd" \ + >>& $builddir/ALL.OUT.$i } res] { + set o [open $builddir/ALL.OUT.$i a] + puts $o "FAIL: '$cmd': $res" + close $o + } + env_cleanup $testdir + incr count + } else { + incr waitcnt + tclsleep 1 + } + } + + puts "Process $i: $count commands executed" + + $dbc close + $db close + $dbenv close + + set f [open $builddir/$testdir/end.[pid] w] + close $f +} + +proc mkparalleldirs { nprocs basename queuedir } { + source ./include.tcl + set dir [pwd] + + if { $is_windows_test != 1 } { + set EXE "" + } else { + set EXE ".exe" + } + for { set i 1 } { $i <= $nprocs } { incr i } { + set destdir $basename.$i + catch {file mkdir $destdir} + if { $is_windows_test == 1 } { + catch {file mkdir $destdir/Debug} + catch {eval file copy \ + [eval glob {$dir/Debug/*.dll}] $destdir/Debug} + } + catch {eval file copy \ + [eval glob {$dir/{.libs,include.tcl}}] $destdir} + # catch {eval file copy $dir/$queuedir $destdir} + catch {eval file copy \ + [eval glob {$dir/db_{checkpoint,deadlock}$EXE} \ + {$dir/db_{dump,load,printlog,recover,stat,upgrade}$EXE} \ + {$dir/db_{archive,verify}$EXE}] \ + $destdir} + + # Create modified copies of include.tcl in parallel + # directories so paths still work. + + set infile [open ./include.tcl r] + set d [read $infile] + close $infile + + regsub {test_path } $d {test_path ../} d + regsub {src_root } $d {src_root ../} d + regsub {KILL \.} $d {KILL ..} d + set outfile [open $destdir/include.tcl w] + puts $outfile $d + close $outfile + + if { [file exists $dir/berkeley_db_svc$EXE] } { + catch {eval file copy $dir/berkeley_db_svc$EXE $destdir} + } + } +} diff --git a/db/test/recd15scr.tcl b/db/test/recd15scr.tcl new file mode 100644 index 000000000..53760e635 --- /dev/null +++ b/db/test/recd15scr.tcl @@ -0,0 +1,74 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 1996-2001 +# Sleepycat Software. All rights reserved. +# +# Id: recd15scr.tcl,v 1.3 2001/05/10 15:22:18 sue Exp +# +# Recd15 - lots of txns - txn prepare script +# Usage: recd15script envcmd dbcmd gidf numtxns +# envcmd: command to open env +# dbfile: name of database file +# gidf: name of global id file +# numtxns: number of txns to start + +source ./include.tcl +source $test_path/test.tcl +source $test_path/testutils.tcl + +set usage "recd15script envcmd dbfile gidfile numtxns" + +# Verify usage +if { $argc != 4 } { + puts stderr "FAIL:[timestamp] Usage: $usage" + exit +} + +# Initialize arguments +set envcmd [ lindex $argv 0 ] +set dbfile [ lindex $argv 1 ] +set gidfile [ lindex $argv 2 ] +set numtxns [ lindex $argv 3 ] + +set txnmax [expr $numtxns + 5] +set dbenv [eval $envcmd] +error_check_good envopen [is_valid_env $dbenv] TRUE + +set usedb 0 +if { $dbfile != "NULL" } { + set usedb 1 + set db [berkdb_open -env $dbenv $dbfile] + error_check_good dbopen [is_valid_db $db] TRUE +} + +puts "\tRecd015script.a: Begin $numtxns txns" +for {set i 0} {$i < $numtxns} {incr i} { + set t [$dbenv txn] + error_check_good txnbegin($i) [is_valid_txn $t $dbenv] TRUE + set txns($i) $t + if { $usedb } { + set dbc [$db cursor -txn $t] + error_check_good cursor($i) [is_valid_cursor $dbc $db] TRUE + set curs($i) $dbc + } +} + +puts "\tRecd015script.b: Prepare $numtxns txns" +set gfd [open $gidfile w+] +for {set i 0} {$i < $numtxns} {incr i} { + if { $usedb } { + set dbc $curs($i) + error_check_good dbc_close [$dbc close] 0 + } + set t $txns($i) + set gid [make_gid recd015script:$t] + puts $gfd $gid + error_check_good txn_prepare:$t [$t prepare $gid] 0 +} +close $gfd + +# +# We do not close the db or env, but exit with the txns outstanding. +# +puts "\tRecd015script completed successfully" +flush stdout diff --git a/db/test/rep001.tcl b/db/test/rep001.tcl new file mode 100644 index 000000000..57b9b97fb --- /dev/null +++ b/db/test/rep001.tcl @@ -0,0 +1,214 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2001 +# Sleepycat Software. All rights reserved. +# +# Id: rep001.tcl,v 11.2 2001/10/05 02:38:09 bostic Exp +# +# TEST rep001 +# TEST Replication smoke test. +# TEST +# TEST Run a modified version of test001 in a replicated master environment; +# TEST verify that the database on the client is correct. + + +proc rep001 { method args } { + source ./include.tcl + global testdir + + env_cleanup $testdir + + replsetup $testdir/REPDIR_MSGQUEUE + + set masterdir $testdir/REPDIR_MASTER + set clientdir $testdir/REPDIR_CLIENT + + file mkdir $masterdir + file mkdir $clientdir + + puts "Rep001: Replication sanity test." + + # Open a master. + repladd 1 + set masterenv [berkdb env -create \ + -home $masterdir -txn -rep_master -rep_transport [list 1 replsend]] + error_check_good master_env [is_valid_env $masterenv] TRUE + + # Open a client + repladd 2 + set clientenv [berkdb env -create \ + -home $clientdir -txn -rep_client -rep_transport [list 2 replsend]] + error_check_good client_env [is_valid_env $clientenv] TRUE + + # Run a modified test001 in the master. + puts "\tRep001.a: Running test001 in replicated env." + eval rep_test001 $method 1000 "01" -env $masterenv $args + + # Loop, processing first the master's messages, then the client's, + # until both queues are empty. + set donenow 0 + while { 1 } { + set nproced 0 + + incr nproced [replprocessqueue $masterenv 1] + incr nproced [replprocessqueue $clientenv 2] + + if { $nproced == 0 } { + break + } + } + + # Verify the database in the client dir. + puts "\tRep001.b: Verifying client database contents." + set t1 $testdir/t1 + set t2 $testdir/t2 + set t3 $testdir/t3 + open_and_dump_file test001.db $clientenv "" $testdir/t1 test001.check \ + dump_file_direction "-first" "-next" + filesort $t1 $t3 + error_check_good diff_files($t2,$t3) [filecmp $t2 $t3] 0 + + verify_dir $clientdir "\tRep001.c:" 0 0 1 +} + +proc rep_test001 { method {nentries 10000} {tnum "01"} args } { + source ./include.tcl + + set args [convert_args $method $args] + set omethod [convert_method $method] + + puts "\tRep0$tnum: $method ($args) $nentries equal key/data pairs" + + # Create the database and open the dictionary + set eindex [lsearch -exact $args "-env"] + # + # If we are using an env, then testfile should just be the db name. + # Otherwise it is the test directory and the name. + # If we are not using an external env, then test setting + # the database cache size and using multiple caches. + if { $eindex == -1 } { + set testfile $testdir/test0$tnum.db + append args " -cachesize {0 1048576 3} " + set env NULL + } else { + set testfile test0$tnum.db + incr eindex + set env [lindex $args $eindex] + } + set t1 $testdir/t1 + set t2 $testdir/t2 + set t3 $testdir/t3 + set db [eval {berkdb_open \ + -create -mode 0644} $args $omethod $testfile] + error_check_good dbopen [is_valid_db $db] TRUE + set did [open $dict] + + set pflags "" + set gflags "" + set txn "" + + if { [is_record_based $method] == 1 } { + set checkfunc test001_recno.check + append gflags " -recno" + } else { + set checkfunc test001.check + } + puts "\t\tRep0$tnum.a: put/get loop" + # Here is the loop where we put and get each key/data pair + set count 0 + while { [gets $did str] != -1 && $count < $nentries } { + if { [is_record_based $method] == 1 } { + global kvals + + set key [expr $count + 1] + if { 0xffffffff > 0 && $key > 0xffffffff } { + set key [expr $key - 0x100000000] + } + if { $key == 0 || $key - 0xffffffff == 1 } { + incr key + incr count + } + set kvals($key) [pad_data $method $str] + } else { + set key $str + set str [reverse $str] + } + set curtxn [$env txn] + set ret [eval {$db put} \ + -txn $curtxn $pflags {$key [chop_data $method $str]}] + error_check_good put $ret 0 + error_check_good txn_commit($key) [$curtxn commit] 0 + + set ret [eval {$db get} $gflags {$key}] + error_check_good \ + get $ret [list [list $key [pad_data $method $str]]] + + # Test DB_GET_BOTH for success + set ret [$db get -get_both $key [pad_data $method $str]] + error_check_good \ + getboth $ret [list [list $key [pad_data $method $str]]] + + # Test DB_GET_BOTH for failure + set ret [$db get -get_both $key [pad_data $method BAD$str]] + error_check_good getbothBAD [llength $ret] 0 + + incr count + } + close $did + # Now we will get each key from the DB and compare the results + # to the original. + puts "\t\tRep0$tnum.b: dump file" + dump_file $db $txn $t1 $checkfunc + error_check_good db_close [$db close] 0 + + # Now compare the keys to see if they match the dictionary (or ints) + if { [is_record_based $method] == 1 } { + set oid [open $t2 w] + for {set i 1} {$i <= $nentries} {incr i} { + set j [expr $i] + if { 0xffffffff > 0 && $j > 0xffffffff } { + set j [expr $j - 0x100000000] + } + if { $j == 0 } { + incr i + incr j + } + puts $oid $j + } + close $oid + } else { + set q q + filehead $nentries $dict $t2 + } + filesort $t2 $t3 + file rename -force $t3 $t2 + filesort $t1 $t3 + + error_check_good \tRep0$tnum:diff($t3,$t2) \ + [filecmp $t3 $t2] 0 + + puts "\t\tRep0$tnum.c: close, open, and dump file" + # Now, reopen the file and run the last test again. + open_and_dump_file $testfile $env $txn $t1 $checkfunc \ + dump_file_direction "-first" "-next" + if { [string compare $omethod "-recno"] != 0 } { + filesort $t1 $t3 + } + + error_check_good \tRep0$tnum:diff($t2,$t3) \ + [filecmp $t2 $t3] 0 + + # Now, reopen the file and run the last test again in the + # reverse direction. + puts "\t\tRep0$tnum.d: close, open, and dump file in reverse direction" + open_and_dump_file $testfile $env $txn $t1 $checkfunc \ + dump_file_direction "-last" "-prev" + + if { [string compare $omethod "-recno"] != 0 } { + filesort $t1 $t3 + } + + error_check_good \tRep0$tnum:diff($t3,$t2) \ + [filecmp $t3 $t2] 0 +} + diff --git a/db/test/reputils.tcl b/db/test/reputils.tcl new file mode 100644 index 000000000..71b88135c --- /dev/null +++ b/db/test/reputils.tcl @@ -0,0 +1,104 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2001 +# Sleepycat Software. All rights reserved. +# +# Id: reputils.tcl,v 11.2 2001/10/05 02:38:09 bostic Exp +# +# Replication testing utilities + +# Environment handle for the env containing the replication "communications +# structure" (really a CDB environment). +global queueenv + +# Array of DB handles, one per machine ID, for the databases that contain +# messages. +global queuedbs +global machids + +# Create a replication group for testing. +proc replsetup { queuedir } { + global queueenv queuedbs machids + + file mkdir $queuedir + set queueenv \ + [berkdb env -create -cdb -home $queuedir] + error_check_good queueenv [is_valid_env $queueenv] TRUE + + if { [info exists queuedbs] } { + unset queuedbs + } + set machids {} + + return $queueenv +} + +proc replsend { control rec fromid toid } { + global queuedbs machids + + + # XXX + # -1 is DB_BROADCAST_MID + if { $toid == -1 } { + set machlist $machids + } else { + if { [info exists queuedbs($toid)] != 1 } { + puts stderr "FAIL: replsend: machid $toid not found" + return -1 + } + set machlist [list $toid] + } + + foreach m $machlist { + # XXX should a broadcast include to "self"? + if { $m == $fromid } { + continue + } + + set db $queuedbs($m) + + $db put -append [list $control $rec $fromid] + } + + return 0 +} + +proc repladd { machid } { + global queueenv queuedbs machids + + if { [info exists queuedbs($machid)] == 1 } { + error "FAIL: repladd: machid $machid already exists" + } + + set queuedbs($machid) \ + [berkdb open -env $queueenv -create -recno repqueue$machid.db] + error_check_good repqueue_create [is_valid_db $queuedbs($machid)] TRUE + + lappend machids $machid +} + +proc replprocessqueue { dbenv machid } { + global queuedbs + + set nproced 0 + + set dbc [$queuedbs($machid) cursor -update] + error_check_good process_dbc($machid) \ + [is_valid_cursor $dbc $queuedbs($machid)] TRUE + + for { set dbt [$dbc get -first] } \ + { [llength $dbt] != 0 } \ + { set dbt [$dbc get -next] } { + set data [lindex [lindex $dbt 0] 1] + + error_check_good process_message [$dbenv rep_process_message \ + [lindex $data 2] [lindex $data 0] [lindex $data 1]] 0 + + incr nproced + + $dbc del + } + + # Return the number of messages processed. + return $nproced +} diff --git a/db/test/rsrc004.tcl b/db/test/rsrc004.tcl new file mode 100644 index 000000000..32c0cb738 --- /dev/null +++ b/db/test/rsrc004.tcl @@ -0,0 +1,52 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2001 +# Sleepycat Software. All rights reserved. +# +# Id: rsrc004.tcl,v 11.2 2001/08/03 16:39:29 bostic Exp +# +# TEST rsrc004 +# TEST Recno backing file test for EOF-terminated records. +proc rsrc004 { } { + source ./include.tcl + + foreach isfixed { 0 1 } { + cleanup $testdir NULL + + # Create the backing text file. + set oid1 [open $testdir/rsrc.txt w] + if { $isfixed == 1 } { + puts -nonewline $oid1 "record 1xxx" + puts -nonewline $oid1 "record 2xxx" + } else { + puts $oid1 "record 1xxx" + puts $oid1 "record 2xxx" + } + puts -nonewline $oid1 "record 3" + close $oid1 + + set args "-create -mode 0644 -recno -source $testdir/rsrc.txt" + if { $isfixed == 1 } { + append args " -len [string length "record 1xxx"]" + set match "record 3 " + puts "Rsrc004: EOF-terminated recs: fixed length" + } else { + puts "Rsrc004: EOF-terminated recs: variable length" + set match "record 3" + } + + puts "\tRsrc004.a: Read file, verify correctness." + set db [eval berkdb_open $args "$testdir/rsrc004.db"] + error_check_good dbopen [is_valid_db $db] TRUE + + # Read the last record + set dbc [eval {$db cursor} ""] + error_check_good db_cursor [is_valid_cursor $dbc $db] TRUE + + set rec [$dbc get -last] + error_check_good get_last $rec [list [list 3 $match]] + + error_check_good dbc_close [$dbc close] 0 + error_check_good db_close [$db close] 0 + } +} diff --git a/db/test/scr001/chk.code b/db/test/scr001/chk.code new file mode 100644 index 000000000..7dd5a549c --- /dev/null +++ b/db/test/scr001/chk.code @@ -0,0 +1,37 @@ +#!/bin/sh - +# +# Id: chk.code,v 1.8 2001/10/12 17:55:31 bostic Exp +# +# Check to make sure that the code samples in the documents build. + +d=../.. + +[ -d $d/docs_src ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} +[ -f ../libdb.a ] || make libdb.a || { + echo 'FAIL: unable to find or build libdb.a' + exit 1 +} + +for i in `find $d/docs_src -name '*.cs'`; do + echo " compiling $i" + sed -e 's/m4_include(\(.*\))/#include <\1>/g' \ + -e 's/m4_[a-z]*[(\[)]*//g' \ + -e 's/(\[//g' \ + -e '/argv/!s/])//g' \ + -e 's/dnl//g' \ + -e 's/__GT__/>/g' \ + -e 's/__LB__/[/g' \ + -e 's/__LT__/</g' \ + -e 's/__RB__/]/g' < $i > t.c + if cc -Wall -I.. t.c ../libdb.a -o t; then + : + else + echo "FAIL: unable to compile $i" + exit 1 + fi +done + +exit 0 diff --git a/db/test/scr002/chk.def b/db/test/scr002/chk.def new file mode 100644 index 000000000..508a69bb3 --- /dev/null +++ b/db/test/scr002/chk.def @@ -0,0 +1,64 @@ +#!/bin/sh - +# +# Id: chk.def,v 1.7 2001/10/12 17:55:31 bostic Exp +# +# Check to make sure we haven't forgotten to add any interfaces +# to the Win32 libdb.def file. + +d=../.. + +# Test must be run from the top-level directory, not from a test directory. +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +f=$d/build_win32/libdb.def +t1=__1 +t2=__2 + +exitv=0 + +sed '/; /d' $f | + egrep @ | + awk '{print $1}' | + sed -e '/db_xa_switch/d' \ + -e '/^__/d' -e '/^;/d' | + sort > $t1 + +egrep __P $d/include_auto/global_ext.in | + sed '/^[a-z]/!d' | + awk '{print $2}' | + sed 's/^\*//' | + sed '/^__/d' | sort > $t2 + +if cmp -s $t1 $t2 ; then + : +else + echo "<<< libdb.def >>> DB include files" + diff $t1 $t2 + echo "FAIL: missing items in libdb.def file." + exitv=1 +fi + +# Check to make sure we don't have any extras in the libdb.def file. +sed '/; /d' $f | + egrep @ | + awk '{print $1}' | + sed -e '/__db_global_values/d' > $t1 + +for i in `cat $t1`; do + if egrep $i $d/*/*.c > /dev/null; then + : + else + echo "$f: $i not found in DB sources" + fi +done > $t2 + +test -s $t2 && { + cat $t2 + echo "FAIL: found unnecessary items in libdb.def file." + exitv=1 +} + +exit $exitv diff --git a/db/test/scr003/chk.define b/db/test/scr003/chk.define new file mode 100644 index 000000000..ea47734c8 --- /dev/null +++ b/db/test/scr003/chk.define @@ -0,0 +1,76 @@ +#!/bin/sh - +# +# Id: chk.define,v 1.15 2001/10/12 17:55:32 bostic Exp +# +# Check to make sure that all #defines are actually used. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +exitv=0 +t1=__1 +t2=__2 + +egrep '^#define' $d/include/*.h $d/include/*.in | + sed -e '/db_185.in/d' -e '/xa.h/d' | + awk '{print $2}' | + sed -e '/^ALIGNP/d' \ + -e '/^B_DELETE/d' \ + -e '/^B_MAX/d' \ + -e '/^CIRCLEQ/d' \ + -e '/^DB_AM_TXN/d' \ + -e '/^DB_BTREEOLDVER/d' \ + -e '/^DB_HASHOLDVER/d' \ + -e '/^DB_LOCKVERSION/d' \ + -e '/^DB_MAX_PAGES/d' \ + -e '/^DB_QAMOLDVER/d' \ + -e '/^DB_RO_ACCESS/d' \ + -e '/^DB_TXNVERSION/d' \ + -e '/^DEFINE_DB_CLASS/d' \ + -e '/^LIST/d' \ + -e '/^LOG_OP/d' \ + -e '/^MINFILL/d' \ + -e '/^MUTEX_FIELDS/d' \ + -e '/^NCACHED2X/d' \ + -e '/^NCACHED30/d' \ + -e '/^PAIR_MASK/d' \ + -e '/^POWER_OF_TWO/d' \ + -e '/^P_16_COPY/d' \ + -e '/^P_32_COPY/d' \ + -e '/^P_32_SWAP/d' \ + -e '/^SH_CIRCLEQ/d' \ + -e '/^SH_LIST/d' \ + -e '/^SH_TAILQ/d' \ + -e '/^TAILQ/d' \ + -e '/^WRAPPED_CLASS/d' \ + -e '/^XA_$/d' \ + -e '/^__BIT_TYPES_DEFINED__/d' \ + -e '/^__DBC_INTERNAL/d' \ + -e '/_AUTO_H$/d' \ + -e '/_H_$/d' \ + -e '/_UNUSED/d' \ + -e '/^i_/d' \ + -e '/ext_h_/d' \ + -e 's/(.*//' | sort > $t1 + +for i in `cat $t1`; do + if egrep -w $i $d/*/*.c $d/*/*.cpp > /dev/null; then + :; + else + f=`egrep -l "#define.*$i" $d/include/*.h $d/include/*.in | + sed 's;\.\.\/\.\.\/include/;;' | tr -s "[:space:]" " "` + echo "FAIL: $i: $f" + fi +done | sort +1 > $t2 + +test -s $t2 && { + cat $t2 + echo "FAIL: found unused #defines" + exit 1 +} + +exit $exitv diff --git a/db/test/scr004/chk.javafiles b/db/test/scr004/chk.javafiles new file mode 100644 index 000000000..248b5570b --- /dev/null +++ b/db/test/scr004/chk.javafiles @@ -0,0 +1,31 @@ +#!/bin/sh - +# +# Id: chk.javafiles,v 1.4 2001/10/12 17:55:33 bostic Exp +# +# Check to make sure we haven't forgotten to add any Java files to the list +# of source files in the Makefile. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +f=$d/dist/Makefile.in +d=$d/java/src/com/sleepycat + +t1=__1 +t2=__2 + +find ${d}/db/ $d/examples -name \*.java -print | + sed -e 's/^.*\///' | sort > $t1 +tr ' \t' '\n' < ${f} | sed -e '/\.java$/!d' -e 's/^.*\///' | sort > $t2 + +cmp $t1 $t2 > /dev/null || { + echo "<<< java source files >>> Makefile" + diff $t1 $t2 + exit 1 +} + +exit 0 diff --git a/db/test/scr005/chk.nl b/db/test/scr005/chk.nl new file mode 100644 index 000000000..876be2f94 --- /dev/null +++ b/db/test/scr005/chk.nl @@ -0,0 +1,100 @@ +#!/bin/sh - +# +# Id: chk.nl,v 1.5 2001/10/12 17:55:33 bostic Exp +# +# Check to make sure that there are no trailing newlines in __db_err calls. + +d=../.. + +[ -f $d/README ] || { + echo "FAIL: chk.nl can't find the source directory." + exit 1 +} + +cat << END_OF_CODE > t.c +#include <sys/types.h> + +#include <errno.h> +#include <stdio.h> + +int chk(FILE *, char *); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + FILE *fp; + int exitv; + + for (exitv = 0; *++argv != NULL;) { + if ((fp = fopen(*argv, "r")) == NULL) { + fprintf(stderr, "%s: %s\n", *argv, strerror(errno)); + return (1); + } + if (chk(fp, *argv)) + exitv = 1; + (void)fclose(fp); + } + return (exitv); +} + +int +chk(fp, name) + FILE *fp; + char *name; +{ + int ch, exitv, line, q; + + exitv = 0; + for (ch = 'a', line = 1;;) { + if ((ch = getc(fp)) == EOF) + return (exitv); + if (ch == '\n') { + ++line; + continue; + } + if (ch != '_') continue; + if ((ch = getc(fp)) != '_') continue; + if ((ch = getc(fp)) != 'd') continue; + if ((ch = getc(fp)) != 'b') continue; + if ((ch = getc(fp)) != '_') continue; + if ((ch = getc(fp)) != 'e') continue; + if ((ch = getc(fp)) != 'r') continue; + if ((ch = getc(fp)) != 'r') continue; + while ((ch = getc(fp)) != '"') { + if (ch == EOF) + return (exitv); + if (ch == '\n') + ++line; + } + while ((ch = getc(fp)) != '"') { + if (ch == EOF) + return (exitv); + if (ch == '\n') + ++line; + if (ch == '\\\\') + if ((ch = getc(fp)) != 'n') + ungetc(ch, fp); + else if ((ch = getc(fp)) != '"') + ungetc(ch, fp); + else { + fprintf(stderr, + "%s: <newline> at line %d\n", name, line); + exitv = 1; + } + } + } + return (exitv); +} +END_OF_CODE + +cc t.c -o t +if ./t $d/*/*.[ch] $d/*/*.cpp $d/*/*.in ; then + : +else + echo "FAIL: found __db_err calls with newline strings." + exit 1 +fi + +exit 0 diff --git a/db/test/scr006/chk.offt b/db/test/scr006/chk.offt new file mode 100644 index 000000000..3dcc181f5 --- /dev/null +++ b/db/test/scr006/chk.offt @@ -0,0 +1,35 @@ +#!/bin/sh - +# +# Id: chk.offt,v 1.8 2001/10/12 17:55:34 bostic Exp +# +# Make sure that no off_t's have snuck into the release. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +t=__1 + +egrep -w off_t $d/*/*.[ch] $d/*/*.in | +sed -e "/#undef off_t/d" \ + -e "/mp_fopen.c:.*can't use off_t's here/d" \ + -e "/mp_fopen.c:.*size or type off_t's or/d" \ + -e "/mp_fopen.c:.*where an off_t is 32-bits/d" \ + -e "/mutex\/tm.c:/d" \ + -e "/os_map.c:.*(off_t)0))/d" \ + -e "/os_rw.c:.*(off_t)db_iop->pgno/d" \ + -e "/os_seek.c:.*off_t offset;/d" \ + -e "/os_seek.c:.*offset = /d" \ + -e "/test_server\/dbs.c:/d" \ + -e "/test_vxworks\/vx_mutex.c:/d" > $t + +test -s $t && { + cat $t + echo "FAIL: found questionable off_t usage" + exit 1 +} + +exit 0 diff --git a/db/test/scr007/chk.proto b/db/test/scr007/chk.proto new file mode 100644 index 000000000..74ce6875b --- /dev/null +++ b/db/test/scr007/chk.proto @@ -0,0 +1,44 @@ +#!/bin/sh - +# +# Id: chk.proto,v 1.6 2001/10/12 17:55:34 bostic Exp +# +# Check to make sure that prototypes are actually needed. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +t1=__1 +t2=__2 + +egrep '__P' $d/include_auto/*.h | + sed -e 's/[ ][ ]*__P.*//' \ + -e 's/^.*[ *]//' \ + -e '/__db_cprint/d' \ + -e '/__db_lprint/d' \ + -e '/__db_noop_log/d' \ + -e '/__db_prnpage/d' \ + -e '/__db_txnlist_print/d' \ + -e '/__db_util_arg/d' \ + -e '/__ham_func2/d' \ + -e '/__ham_func3/d' \ + -e '/_getpgnos/d' \ + -e '/_print$/d' \ + -e '/_read$/d' > $t1 + +for i in `cat $t1`; do + c=`egrep -low $i $d/include/*.in \ + $d/include/*.h $d/*/*.c $d/*/*.cpp | wc -l` + echo "$i: $c" +done | egrep ' 1$' > $t2 + +test -s $t2 && { + cat $t2 + echo "FAIL: found unnecessary prototypes." + exit 1 +} + +exit 0 diff --git a/db/test/scr008/chk.pubdef b/db/test/scr008/chk.pubdef new file mode 100644 index 000000000..95a30ca12 --- /dev/null +++ b/db/test/scr008/chk.pubdef @@ -0,0 +1,179 @@ +#!/bin/sh - +# +# Reconcile the list of public defines with the man pages and the Java files. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +p=$d/dist/pubdef.in + +exitv=0 + +# Check that pubdef.in has everything listed in m4.links. +f=$d/docs_src/m4/m4.links +sed -n \ + -e 's/^\$1, \(DB_[^,]*\).*/\1/p' \ + -e d < $f | +while read name; do + if `egrep -w "$name" $p > /dev/null`; then + : + else + echo "$f: $name is missing from $p" + exitv=1 + fi +done + +# Check that m4.links has everything listed in pubdef.in. +f=$d/docs_src/m4/m4.links +sed '/^#/d' $p | +while read name isdoc isinc isjava; do + if `egrep -w "^.1, $name" $f > /dev/null`; then + [ "X$isdoc" != "XD" ] && { + echo "$name should not appear in $f" + exitv=1 + } + else + [ "X$isdoc" = "XD" ] && { + echo "$name does not appear in $f" + exitv=1; + } + fi +done + +# Check that pubdef.in has everything listed in db.in. +f=$d/include/db.in +sed -n \ + -e 's/^#define[ ]*\(DB_[A-Z_]*\).*/\1/p' \ + -e 's/^[ ]*\(DB_[A-Z_]*\)=[0-9].*/\1/p' \ + -e d < $f | +while read name; do + if `egrep -w "$name" $p > /dev/null`; then + : + else + echo "$f: $name is missing from $p" + exitv=1 + fi +done + +# Check that db.in has everything listed in pubdef.in. +f=$d/include/db.in +sed '/^#/d' $p | +while read name isdoc isinc isjava; do + if `egrep -w "#define[ ]$name|[ ][ ]*$name=[0-9]" \ + $f > /dev/null`; then + [ "X$isinc" != "XI" ] && { + echo "$name should not appear in $f" + exitv=1 + } + else + [ "X$isinc" = "XI" ] && { + echo "$name does not appear in $f" + exitv=1 + } + fi +done + +# Check that pubdef.in has everything listed in DbConstants.java. +f=$d/java/src/com/sleepycat/db/DbConstants.java +sed -n -e 's/.*static final int[ ]*\([^ ]*\).*/\1/p' < $f | +while read name; do + if `egrep -w "$name" $p > /dev/null`; then + : + else + echo "$f: $name is missing from $p" + exitv=1 + fi +done + +# Check that DbConstants.java has everything listed in pubdef.in. +f=$d/java/src/com/sleepycat/db/DbConstants.java +sed '/^#/d' $p | +while read name isdoc isinc isjava; do + if `egrep -w "static final int[ ]$name =" $f > /dev/null`; then + [ "X$isjava" != "XJ" ] && { + echo "$name should not appear in $f" + exitv=1 + } + else + [ "X$isjava" = "XJ" ] && { + echo "$name does not appear in $f" + exitv=1 + } + fi +done + +# Check that pubdef.in has everything listed in Db.java. +f=$d/java/src/com/sleepycat/db/Db.java +sed -n -e 's/.*static final int[ ]*\([^ ;]*\).*/\1/p' < $f | +while read name; do + if `egrep -w "$name" $p > /dev/null`; then + : + else + echo "$f: $name is missing from $p" + exitv=1; + fi +done +sed -n -e 's/^[ ]*\([^ ]*\) = DbConstants\..*/\1/p' < $f | +while read name; do + if `egrep -w "$name" $p > /dev/null`; then + : + else + echo "$f: $name is missing from $p" + exitv=1 + fi +done + +# Check that Db.java has all of the Java case values listed in pubdef.in. +# Any J entries should appear twice -- once as a static final int, with +# no initialization value, and once assigned to the DbConstants value. Any +# C entries should appear once as a static final int, with an initialization +# value. +f=$d/java/src/com/sleepycat/db/Db.java +sed '/^#/d' $p | +while read name isdoc isinc isjava; do + if `egrep -w "static final int[ ]$name;$" $f > /dev/null`; then + [ "X$isjava" != "XJ" ] && { + echo "$name should not appear in $f" + exitv=1 + } + else + [ "X$isjava" = "XJ" ] && { + echo "$name does not appear in $f" + exitv=1 + } + fi +done +sed '/^#/d' $p | +while read name isdoc isinc isjava; do + if `egrep -w "= DbConstants.$name;" $f > /dev/null`; then + [ "X$isjava" != "XJ" ] && { + echo "$name should not appear in $f" + exitv=1 + } + else + [ "X$isjava" = "XJ" ] && { + echo "$name does not appear in $f" + exitv=1 + } + fi +done +sed '/^#/d' $p | +while read name isdoc isinc isjava; do + if `egrep "static final int[ ]$name =.*;" $f > /dev/null`; then + [ "X$isjava" != "XC" ] && { + echo "$name should not appear in $f" + exitv=1 + } + else + [ "X$isjava" = "XC" ] && { + echo "$name does not appear in $f" + exitv=1 + } + fi +done + +exit $exitv diff --git a/db/test/scr009/chk.srcfiles b/db/test/scr009/chk.srcfiles new file mode 100644 index 000000000..c9e6bff40 --- /dev/null +++ b/db/test/scr009/chk.srcfiles @@ -0,0 +1,36 @@ +#!/bin/sh - +# +# Id: chk.srcfiles,v 1.9 2001/10/12 17:55:35 bostic Exp +# +# Check to make sure we haven't forgotten to add any files to the list +# of source files Win32 uses to build its dsp files. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +f=$d/dist/srcfiles.in +t1=__1 +t2=__2 + +sed -e '/^[ #]/d' \ + -e '/^$/d' < $f | + awk '{print $1}' > $t1 +find $d -type f | + sed -e 's/^\.\.\/\.\.\///' \ + -e '/^test/d' \ + -e '/^build[^_]/d' | + egrep '\.c$|\.cpp$|\.def$|\.rc$' | + sed -e '/perl.DB_File\/version.c/d' | + sort > $t2 + +cmp $t1 $t2 > /dev/null || { + echo "<<< srcfiles.in >>> existing files" + diff $t1 $t2 + exit 1 +} + +exit 0 diff --git a/db/test/scr010/chk.str b/db/test/scr010/chk.str new file mode 100644 index 000000000..15eb9c299 --- /dev/null +++ b/db/test/scr010/chk.str @@ -0,0 +1,31 @@ +#!/bin/sh - +# +# Id: chk.str,v 1.5 2001/10/12 17:55:36 bostic Exp +# +# Check spelling in quoted strings. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +t1=__t1 + +sed -e '/^#include/d' \ + -e '/revid/d' \ + -e '/"/!d' \ + -e 's/^[^"]*//' \ + -e 's/%s/ /g' \ + -e 's/[^"]*$//' \ + -e 's/\\[nt]/ /g' $d/*/*.c $d/*/*.cpp | +spell | sort | comm -23 /dev/stdin spell.ok > $t1 + +test -s $t1 && { + cat $t1 + echo "FAIL: found questionable spelling in strings." + exit 1 +} + +exit 0 diff --git a/db/test/scr010/spell.ok b/db/test/scr010/spell.ok new file mode 100644 index 000000000..eb69020c8 --- /dev/null +++ b/db/test/scr010/spell.ok @@ -0,0 +1,723 @@ +AJVX +ALLDB +API +APP +AccessExample +Acflmo +Ahlm +BCc +BDBXXXXXX +BH +BI +BII +BINTERNAL +BTREE +BerkeleyDB +BtRecExample +Btree +CDB +CDS +CDdFILTVvX +CFILpRsv +CFh +CONFIG +CdFILTvX +DBC +DBENV +DBSDIR +DBT +DBTYPE +DBcursor +DONOTINDEX +DS +DUP +DUPMASTER +Db +DbAppendRecno +DbBtreeCompare +DbBtreePrefix +DbBtreeStat +DbDeadlockException +DbDupCompare +DbEnv +DbEnvFeedback +DbErrcall +DbException +DbFeedback +DbHash +DbHashStat +DbKeyRange +DbLock +DbLockNotGrantedException +DbLockRequest +DbLockStat +DbLogStat +DbLogc +DbLsn +DbMemoryException +DbMpoolFStat +DbMpoolFile +DbMpoolStat +DbPreplist +DbQueueStat +DbRecoveryInit +DbRepTransport +DbRunRecoveryException +DbSecondaryKeyCreate +DbTxn +DbTxnRecover +DbTxnStat +Dbc +Dbt +Dde +Deref'ing +EIO +EIRT +EIi +ENV +EnvExample +EnvInfoDelete +Exp +FIXEDLEN +Fd +Ff +FileNotFoundException +GetJoin +HOFFSET +HOLDELECTION +INDX +INIT +IREAD +ISSET +IWR +IWRITE +Ik +KEYEMPTY +KEYEXIST +KeyRange +LBTREE +LOCKDOWN +LOGC +LRECNO +LRU +LSN +Lcom +Ljava +Ll +LockExample +LogRegister +LpRsS +MEM +MMDDhhmm +MPOOL +MPOOLFILE +MapViewOfFile +Maxid +Mb +Mbytes +Metadata +Metapage +Mpool +MpoolExample +Mutex +NEWMASTER +NEWSITE +NG +NODUP +NODUPDATA +NOLOCKING +NOMMAP +NOMORE +NOORDERCHK +NOPANIC +NOSERVER +NOSYNC +NOTFOUND +NOTGRANTED +NqV +NrV +NsV +OLDVERSION +ORDERCHKONLY +Offpage +OpenFileMapping +OutputStream +PID +PREV +RECNO +RECNOSYNC +RECNUM +RINTERNAL +RMW +RPC +RT +RUNRECOVERY +Recno +RepElectResult +RepProcessMessage +SERVERPROG +SERVERVERS +SETFD +SS +Shm +Sleepycat +TDS +TESTDIR +TID +TMP +TMPDIR +TODO +TPS +TXN +TXNID +TXNs +Tcl +TempFolder +TestKeyRange +TestLogc +TpcbExample +Txn +Txns +UID +UNAVAIL +USERMEM +UnmapViewOfFile +VM +VX +Vv +VvW +Vvw +Vx +VxWorks +Waitsfor +XA +XxZ +YY +abcdef +abs +addpage +addr +addrem +adj +afterop +ahr +alldb +alloc +alsVv +amx +anum +appl +archivedir +arg +args +ata +badkey +berkdb +berkeley +bfname +bfree +bigpages +bnum +bostic +bqual +bsize +bt +btcompare +btrec +btree +buf +bylsn +bypage +byteswap +byteswapped +bytevalue +cachesize +cadjust +callpgin +cd +cdb +cdel +ceVv +ceh +celmNtV +celmNtVZ +cget +charkey +charset +chgpg +chkpoint +chkpt +chksum +ckp +clearerr +clientrun +cmdargs +cnt +compareproc +compat +conf +config +copypage +cp +crdel +creat +curadj +curlsn +datalen +db +dbc +dbclient +dbclose +dbe +dbenv +dbkill +dbm +dbmclose +dbminit +dbobj +dbopen +dbp +dbremove +dbrename +dbs +dbt +dbtruncate +dbverify +dd +def +del +delext +delim +df +dh +dir +dirfno +dist +dists +dlen +dsize +dup +dup'ed +dupcompare +dups +dupsort +efh +eid +endian +env +envid +envremove +eof +errcall +errfile +errno +errpfx +excl +extentsize +faststat +fclose +fcntl +fcreate +fd +ff +ffactor +fget +fh +fileid +fileopen +firstkey +fiv +flushcommit +foo +fopen +formatID +fput +freelist +fset +fstat +fsync +ftype +fv +gbytes +gc'ed +gen +gettime +gettimeofday +gettype +getval +gid +groupalloc +gtrid +hashproc +hcreate +hdestroy +hdr +hostname +hsearch +icursor +idletimeout +ids +idup +iitem +inc +incfirst +indx +init +inlen +inp +insdel +int +io +iread +isdeleted +itemorder +iter +iwr +iwrite +kb +kbyte +kbytes +keyfirst +keygroup +keygroups +keygrp +keylast +keyrange +killinterval +killiteration +klNprRV +klNprRs +krinsky +lM +lang +lastid +ld +len +lf +lg +libdb +lk +llsn +localhost +localtime +lockid +logc +logclean +logfile +logflush +lorder +lpgno +lsVv +lsn +lsynch +lt +lu +luB +luGB +luKB +luKb +luM +luMB +luMb +lx +mNs +machid +makedup +malloc +margo +maxcommitperflush +maxkey +maxlockers +maxlocks +maxnactive +maxnlockers +maxnlocks +maxnobjects +maxobjects +maxops +maxtimeout +maxtxns +mbytes +mem +memp +metadata +metaflags +metagroup +metalsn +metapage +metasub +methodID +mincommitperflush +minkey +minlocks +minwrite +minwrites +mis +mkdir +mlock +mmap +mmapped +mmapsize +mmetalsn +mmpgno +mp +mpf +mpgno +mpool +msg +munmap +mutex +mutexes +mutexlocks +mv +mvptr +mydrive +mydrivexxx +nO +nTV +nTt +naborts +nactive +nbegins +nbytes +ncaches +ncommits +nconflicts +ndata +ndbm +ndeadlocks +ndx +needswap +nelem +nevict +newalloc +newitem +newname +newpage +newpgno +nextdup +nextkey +nextlsn +nextnodup +nextpgno +ng +nitems +nkeys +nlockers +nlocks +nlsn +nmodes +nnext +nnextlsn +nnowaits +nobjects +nodup +nodupdata +nogrant +nolocking +nommap +noop +nooverwrite +nopanic +nosort +nosync +notfound +nowait +nowaits +npages +npgno +nrec +nrecords +nreleases +nrequests +nrestores +nsites +ntasks +nthreads +num +numdup +obj +offpage +olddata +olditem +opd +opflags +orig +os +osynch +outlen +ovfl +ovflpoint +ovflsize +ovref +pageimage +pagelsn +pageno +pagesize +pagesizes +pagfno +panic'ing +paniccall +panicstate +parentid +perfdb +pflag +pg +pgcookie +pgdbt +pget +pgfree +pgin +pgno +pgnum +pgout +pgsize +pid +pn +postdestroy +postlog +postlogmeta +postopen +postsync +prec +predestroy +preopen +prev +prevlsn +prevnodup +prheader +pri +printlog +proc +procs +pthread +pthreads +ptype +pv +qam +qs +qtest +rand +rcuradj +rdonly +readonly +realloc +rec +reclength +recno +recnum +recnums +refcount +regionmax +regop +regsize +relink +repl +revsplitoff +rf +rkey +rlsn +rm +rmw +ro +rootent +rootlsn +rpc +rsplit +runlog +rw +rwrw +rwrwrw +scount +secon +secs +sendproc +seq +setto +setval +sh +shalloc +shm +shmat +shmctl +shmdt +shmem +shmget +shr +sleepycat +splitdata +splitmeta +srand +stat +str +strdup +strerror +strlen +subdatabase +subdb +sv +svc +tV +tVZ +tas +tcl +tcp +threadID +tid +timestamp +tlen +tm +tmp +tmpdir +tmutex +tnum +tp +tpcb +treeorder +ttpcbddlk +ttpcbi +ttpcbr +ttype +tx +txn +txnarray +txnid +txns +txt +ubell +ud +uid +ulen +uncorrect +undeleting +unmap +unpinned +upd +upi +usec +usecs +usr +vZ +val +var +vec +ver +vflag +vrfy +vw +vx +vxmutex +vxtmp +waitsfor +walkdupint +walkpages +wb +wc +wcount +wordlist +writeable +wt +xa +xid +xxx +yieldcpu diff --git a/db/test/scr011/chk.tags b/db/test/scr011/chk.tags new file mode 100644 index 000000000..cfdc9b8b8 --- /dev/null +++ b/db/test/scr011/chk.tags @@ -0,0 +1,41 @@ +#!/bin/sh - +# +# Id: chk.tags,v 1.10 2001/10/12 17:55:36 bostic Exp +# +# Check to make sure we don't need any more symbolic links to tags files. + +d=../.. + +# Test must be run from the top-level directory, not from a test directory. +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +t1=__1 +t2=__2 + +(cd $d && ls -F | egrep / | sort | + sed -e 's/\///' \ + -e '/^CVS$/d' \ + -e '/^build_vxworks$/d' \ + -e '/^build_win32$/d' \ + -e '/^docs$/d' \ + -e '/^docs_book$/d' \ + -e '/^docs_src$/d' \ + -e '/^java$/d' \ + -e '/^perl$/d' \ + -e '/^test$/d' \ + -e '/^test_cxx$/d' \ + -e '/^test_purify$/d' \ + -e '/^test_thread$/d' \ + -e '/^test_vxworks$/d') > $t1 + +(cd $d && ls */tags | sed 's/\/tags$//' | sort) > $t2 +if diff $t1 $t2 > /dev/null; then + exit 0 +else + echo "<<< source tree >>> tags files" + diff $t1 $t2 + exit 1 +fi diff --git a/db/test/scr012/chk.vx_code b/db/test/scr012/chk.vx_code new file mode 100644 index 000000000..19250480d --- /dev/null +++ b/db/test/scr012/chk.vx_code @@ -0,0 +1,62 @@ +#!/bin/sh - +# +# Id: chk.vx_code,v 1.3 2001/10/12 17:55:37 bostic Exp +# +# Check to make sure the auto-generated utility code in the VxWorks build +# directory compiles. + +d=../.. + +[ -f $d/LICENSE ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} +[ -f ../libdb.a ] || (cd .. && make libdb.a) || { + echo 'FAIL: unable to find or build libdb.a' + exit 1 +} + +rm -f t.c t1.c t2.c + +header() +{ + echo "int" + echo "main(int argc, char *argv[])" + echo "{return ($1(argv[1]));}" +} + +(echo "int" + echo "main(int argc, char *argv[])" + echo "{" + echo "int i;") > t1.c + +for i in db_archive db_checkpoint db_deadlock \ + db_dump db_load db_printlog db_recover db_stat db_upgrade db_verify; do + echo " compiling build_vxworks/$i" + (cat $d/build_vxworks/$i/$i.c; header $i) > t.c + if cc -Wall -I.. -I$d/include -I$d/include_auto \ + t.c $d/clib/getopt.c $d/common/util_arg.c \ + $d/common/util_log.c $d/common/util_sig.c ../libdb.a -o t; then + : + else + echo "FAIL: unable to compile $i" + exit 1 + fi + + cat $d/build_vxworks/$i/$i.c >> t2.c + echo "i = $i(argv[1]);" >> t1.c +done + +(cat t2.c t1.c; echo "return (0); }") > t.c + +echo " compiling build_vxworks utility composite" +if cc -Dlint -Wall -I.. -I$d/include -I$d/include_auto \ + t.c $d/clib/getopt.c $d/common/util_arg.c \ + $d/common/util_log.c $d/common/util_sig.c ../libdb.a -o t; then + : +else + echo "FAIL: unable to compile utility composite" + exit 1 +fi + +exit 0 diff --git a/db/test/scr013/chk.stats b/db/test/scr013/chk.stats new file mode 100644 index 000000000..9b9299710 --- /dev/null +++ b/db/test/scr013/chk.stats @@ -0,0 +1,114 @@ +#!/bin/sh - +# +# Id: chk.stats,v 1.4 2001/10/12 17:55:37 bostic Exp +# +# Check to make sure all of the stat structure members are included in +# all of the possible formats. + +# Top-level directory. +d=../.. + +# Path names are from a top-level directory. +[ -f $d/README ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +exitv=0 +t=__tmp + +# Extract the field names for a structure from the db.h file. +inc_fields() +{ + sed -e "/struct $1 {/,/^};$/p" \ + -e d < $d/include/db.in | + sed -e 1d \ + -e '$d' \ + -e '/;/!d' \ + -e 's/;.*//' \ + -e 's/^[ ].*[ \*]//' +} + +cat << END_OF_IGNORE > IGNORE +bt_maxkey +bt_metaflags +hash_metaflags +qs_metaflags +qs_ndata +END_OF_IGNORE + +# Check to make sure the elements of a structure from db.h appear in +# the other files. +inc() +{ + for i in `inc_fields $1`; do + if egrep -w $i IGNORE > /dev/null; then + echo " $1: ignoring $i" + continue + fi + for j in $2; do + if egrep -w $i $d/$j > /dev/null; then + :; + else + echo " $1: $i not found in $j." + exitv=1 + fi + done + done +} + +inc "__db_bt_stat" \ + "tcl/tcl_db.c db_stat/db_stat.c docs_src/api_c/db_stat.so" +inc "__db_h_stat" \ + "tcl/tcl_db.c db_stat/db_stat.c docs_src/api_c/db_stat.so" +inc "__db_qam_stat" \ + "tcl/tcl_db.c db_stat/db_stat.c docs_src/api_c/db_stat.so" +inc __db_lock_stat \ + "tcl/tcl_lock.c db_stat/db_stat.c docs_src/api_c/lock_stat.so" +inc __db_log_stat \ + "tcl/tcl_log.c db_stat/db_stat.c docs_src/api_c/log_stat.so" +inc __db_mpool_stat \ + "tcl/tcl_mp.c db_stat/db_stat.c docs_src/api_c/memp_stat.so" +inc __db_txn_stat \ + "tcl/tcl_txn.c db_stat/db_stat.c docs_src/api_c/txn_stat.so" + +# Check to make sure the elements from a man page appears in db.in. +man() +{ + for i in `cat $t`; do + if egrep -w $i IGNORE > /dev/null; then + echo " $1: ignoring $i" + continue + fi + if egrep -w $i $d/include/db.in > /dev/null; then + :; + else + echo " $1: $i not found in db.h." + exitv=1 + fi + done +} + +sed -e '/m4_stat(/!d' \ + -e 's/.*m4_stat(\([^)]*\)).*/\1/' < $d/docs_src/api_c/db_stat.so > $t +man "checking db_stat.so against db.h" + +sed -e '/m4_stat(/!d' \ + -e 's/.*m4_stat(\([^)]*\)).*/\1/' \ + -e 's/.* //' < $d/docs_src/api_c/lock_stat.so > $t +man "checking lock_stat.so against db.h" + +sed -e '/m4_stat[12](/!d' \ + -e 's/.*m4_stat[12](\([^)]*\)).*/\1/' < $d/docs_src/api_c/log_stat.so > $t +man "checking log_stat.so against db.h" + +sed -e '/m4_stat[123](/!d' \ + -e 's/.*m4_stat[123](\([^)]*\)).*/\1/' < $d/docs_src/api_c/memp_stat.so > $t +man "checking memp_stat.so against db.h" + +sed -e '/m4_stat(/!d' \ + -e 's/.*m4_stat(.*, \([^)]*\)).*/\1/' \ + -e 's/__[LR]B__//g' < $d/docs_src/api_c/txn_stat.so > $t +man "checking txn_stat.so against db.h" + +exit $exitv diff --git a/db/test/scr014/chk.err b/db/test/scr014/chk.err new file mode 100644 index 000000000..e43e9206c --- /dev/null +++ b/db/test/scr014/chk.err @@ -0,0 +1,34 @@ +#!/bin/sh - +# +# Id: chk.err,v 1.2 2001/10/12 17:55:38 bostic Exp +# +# Check to make sure all of the error values have corresponding error +# message strings in db_strerror(). + +# Top-level directory. +d=../.. + +# Path names are from a top-level directory. +[ -f $d/README ] || { + echo 'FAIL: cannot find source distribution directory.' + exit 1 +} + +t1=__tmp1 +t2=__tmp2 + +egrep -- "define.*DB_.*-309" $d/include/db.in | awk '{print $2}' > $t1 +sed -e '/^db_strerror/,/^}/{' \ + -e '/ case DB_/{' \ + -e 's/:.*//' \ + -e 's/.* //' \ + -e p \ + -e '}' \ + -e '}' \ + -e d \ + < $d/common/db_err.c > $t2 + +cmp $t1 $t2 > /dev/null || +(echo "<<< db.h >>> db_strerror" && diff $t1 $t2 && exit 1) + +exit 0 diff --git a/db/test/scr015/README b/db/test/scr015/README new file mode 100644 index 000000000..9c8a42e86 --- /dev/null +++ b/db/test/scr015/README @@ -0,0 +1,36 @@ +# Id: README,v 1.1 2001/05/31 23:09:11 dda Exp + +Use the scripts testall or testone to run all, or just one of the C++ +tests. You must be in this directory to run them. For example, + + $ export LIBS="-L/usr/include/BerkeleyDB/lib" + $ export CXXFLAGS="-I/usr/include/BerkeleyDB/include" + $ export LD_LIBRARY_PATH="/usr/include/BerkeleyDB/lib" + $ ./testone TestAppendRecno + $ ./testall + +The scripts will use c++ in your path. Set environment variables $CXX +to override this. It will also honor any $CXXFLAGS and $LIBS +variables that are set, except that -c are silently removed from +$CXXFLAGS (since we do the compilation in one step). + +To run successfully, you will probably need to set $LD_LIBRARY_PATH +to be the directory containing libdb_cxx-X.Y.so + +As an alternative, use the --prefix=<DIR> option, a la configure +to set the top of the BerkeleyDB install directory. This forces +the proper options to be added to $LIBS, $CXXFLAGS $LD_LIBRARY_PATH. +For example, + + $ ./testone --prefix=/usr/include/BerkeleyDB TestAppendRecno + $ ./testall --prefix=/usr/include/BerkeleyDB + +The test framework is pretty simple. Any <name>.cpp file in this +directory that is not mentioned in the 'ignore' file represents a +test. If the test is not compiled successfully, the compiler output +is left in <name>.compileout . Otherwise, the java program is run in +a clean subdirectory using as input <name>.testin, or if that doesn't +exist, /dev/null. Output and error from the test run are put into +<name>.out, <name>.err . If <name>.testout, <name>.testerr exist, +they are used as reference files and any differences are reported. +If either of the reference files does not exist, /dev/null is used. diff --git a/db/test/scr015/TestConstruct01.cpp b/db/test/scr015/TestConstruct01.cpp new file mode 100644 index 000000000..56c595f8d --- /dev/null +++ b/db/test/scr015/TestConstruct01.cpp @@ -0,0 +1,331 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestConstruct01.cpp,v 1.3 2001/10/05 01:50:17 bostic Exp + */ + +/* + * Do some regression tests for constructors. + * Run normally (without arguments) it is a simple regression test. + * Run with a numeric argument, it repeats the regression a number + * of times, to try to determine if there are memory leaks. + */ + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <iostream.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#ifndef _MSC_VER +#include <unistd.h> +#endif +#endif + +#include <iomanip.h> +#include <db_cxx.h> + +#define ERR(a) \ + do { \ + cout << "FAIL: " << (a) << "\n"; sysexit(1); \ + } while (0) + +#define ERR2(a1,a2) \ + do { \ + cout << "FAIL: " << (a1) << ": " << (a2) << "\n"; sysexit(1); \ + } while (0) + +#define ERR3(a1,a2,a3) \ + do { \ + cout << "FAIL: " << (a1) << ": " << (a2) << ": " << (a3) << "\n"; sysexit(1); \ + } while (0) + +#define CHK(a) \ + do { \ + int _ret; \ + if ((_ret = (a)) != 0) { \ + ERR3("DB function " #a " has bad return", _ret, DbEnv::strerror(_ret)); \ + } \ + } while (0) + +#ifdef VERBOSE +#define DEBUGOUT(a) cout << a << "\n" +#else +#define DEBUGOUT(a) +#endif + +#define CONSTRUCT01_DBNAME "construct01.db" +#define CONSTRUCT01_DBDIR "." +#define CONSTRUCT01_DBFULLPATH (CONSTRUCT01_DBDIR "/" CONSTRUCT01_DBNAME) + +int itemcount; // count the number of items in the database + +// A good place to put a breakpoint... +// +void sysexit(int status) +{ + exit(status); +} + +void check_file_removed(const char *name, int fatal) +{ + unlink(name); +#if 0 + if (access(name, 0) == 0) { + if (fatal) + cout << "FAIL: "; + cout << "File \"" << name << "\" still exists after run\n"; + if (fatal) + sysexit(1); + } +#endif +} + +// Check that key/data for 0 - count-1 are already present, +// and write a key/data for count. The key and data are +// both "0123...N" where N == count-1. +// +// For some reason on Windows, we need to open using the full pathname +// of the file when there is no environment, thus the 'has_env' +// variable. +// +void rundb(Db *db, int count, int has_env) +{ + const char *name; + + if (has_env) + name = CONSTRUCT01_DBNAME; + else + name = CONSTRUCT01_DBFULLPATH; + + db->set_error_stream(&cerr); + + // We don't really care about the pagesize, but we do want + // to make sure adjusting Db specific variables works before + // opening the db. + // + CHK(db->set_pagesize(1024)); + CHK(db->open(name, NULL, DB_BTREE, + count ? 0 : DB_CREATE, 0664)); + + // The bit map of keys we've seen + long bitmap = 0; + + // The bit map of keys we expect to see + long expected = (1 << (count+1)) - 1; + + char outbuf[10]; + int i; + for (i=0; i<count; i++) { + outbuf[i] = '0' + i; + } + outbuf[i++] = '\0'; + Dbt key(outbuf, i); + Dbt data(outbuf, i); + + DEBUGOUT("Put: " << outbuf); + CHK(db->put(0, &key, &data, DB_NOOVERWRITE)); + + // Acquire a cursor for the table. + Dbc *dbcp; + CHK(db->cursor(NULL, &dbcp, 0)); + + // Walk through the table, checking + Dbt readkey; + Dbt readdata; + while (dbcp->get(&readkey, &readdata, DB_NEXT) == 0) { + char *key_string = (char *)readkey.get_data(); + char *data_string = (char *)readdata.get_data(); + DEBUGOUT("Got: " << key_string << ": " << data_string); + int len = strlen(key_string); + long bit = (1 << len); + if (len > count) { + ERR("reread length is bad"); + } + else if (strcmp(data_string, key_string) != 0) { + ERR("key/data don't match"); + } + else if ((bitmap & bit) != 0) { + ERR("key already seen"); + } + else if ((expected & bit) == 0) { + ERR("key was not expected"); + } + else { + bitmap |= bit; + expected &= ~(bit); + for (i=0; i<len; i++) { + if (key_string[i] != ('0' + i)) { + cout << " got " << key_string + << " (" << (int)key_string[i] << ")" + << ", wanted " << i + << " (" << (int)('0' + i) << ")" + << " at position " << i << "\n"; + ERR("key is corrupt"); + } + } + } + } + if (expected != 0) { + cout << " expected more keys, bitmap is: " << expected << "\n"; + ERR("missing keys in database"); + } + CHK(dbcp->close()); + CHK(db->close(0)); +} + +void t1(int except_flag) +{ + cout << " Running test 1:\n"; + Db db(0, except_flag); + rundb(&db, itemcount++, 0); + cout << " finished.\n"; +} + +void t2(int except_flag) +{ + cout << " Running test 2:\n"; + Db db(0, except_flag); + rundb(&db, itemcount++, 0); + cout << " finished.\n"; +} + +void t3(int except_flag) +{ + cout << " Running test 3:\n"; + Db db(0, except_flag); + rundb(&db, itemcount++, 0); + cout << " finished.\n"; +} + +void t4(int except_flag) +{ + cout << " Running test 4:\n"; + DbEnv env(except_flag); + CHK(env.open(CONSTRUCT01_DBDIR, DB_CREATE | DB_INIT_MPOOL, 0)); + Db db(&env, 0); + CHK(db.close(0)); + CHK(env.close(0)); + cout << " finished.\n"; +} + +void t5(int except_flag) +{ + cout << " Running test 5:\n"; + DbEnv env(except_flag); + CHK(env.open(CONSTRUCT01_DBDIR, DB_CREATE | DB_INIT_MPOOL, 0)); + Db db(&env, 0); + rundb(&db, itemcount++, 1); + // Note we cannot reuse the old Db! + Db anotherdb(&env, 0); + + anotherdb.set_errpfx("test5"); + rundb(&anotherdb, itemcount++, 1); + CHK(env.close(0)); + cout << " finished.\n"; +} + +void t6(int except_flag) +{ + cout << " Running test 6:\n"; + + /* From user [#2939] */ + int err; + + DbEnv* penv = new DbEnv(DB_CXX_NO_EXCEPTIONS); + penv->set_cachesize(0, 32 * 1024, 0); + penv->open(CONSTRUCT01_DBDIR, DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL, 0); + + //LEAK: remove this block and leak disappears + Db* pdb = new Db(penv,0); + if ((err = pdb->close(0)) != 0) { + fprintf(stderr, "Error closing Db: %s\n", db_strerror(err)); + } + delete pdb; + //LEAK: remove this block and leak disappears + + if ((err = penv->close(0)) != 0) { + fprintf(stderr, "Error closing DbEnv: %s\n", db_strerror(err)); + } + delete penv; + + // Make sure we get a message from C++ layer reminding us to close. + cerr << "expected error: "; + { + DbEnv foo(DB_CXX_NO_EXCEPTIONS); + foo.open(CONSTRUCT01_DBDIR, DB_CREATE, 0); + } + cerr << "should have received error.\n"; + cout << " finished.\n"; +} + +// remove any existing environment or database +void removeall() +{ + { + DbEnv tmpenv(DB_CXX_NO_EXCEPTIONS); + (void)tmpenv.remove(CONSTRUCT01_DBDIR, DB_FORCE); + } + + check_file_removed(CONSTRUCT01_DBFULLPATH, 1); + for (int i=0; i<8; i++) { + char buf[20]; + sprintf(buf, "__db.00%d", i); + check_file_removed(buf, 1); + } +} + +int doall(int except_flag) +{ + itemcount = 0; + try { + // before and after the run, removing any + // old environment/database. + // + removeall(); + t1(except_flag); + t2(except_flag); + t3(except_flag); + t4(except_flag); + t5(except_flag); + t6(except_flag); + + removeall(); + return 0; + } + catch (DbException &dbe) { + ERR2("EXCEPTION RECEIVED", dbe.what()); + } + return 1; +} + +int main(int argc, char *argv[]) +{ + int iterations = 1; + if (argc > 1) { + iterations = atoi(argv[1]); + if (iterations < 0) { + ERR("Usage: construct01 count"); + } + } + for (int i=0; i<iterations; i++) { + if (iterations != 0) { + cout << "(" << i << "/" << iterations << ") "; + } + cout << "construct01 running:\n"; + if (doall(DB_CXX_NO_EXCEPTIONS) != 0) { + ERR("SOME TEST FAILED FOR NO-EXCEPTION TEST"); + } + else if (doall(0) != 0) { + ERR("SOME TEST FAILED FOR EXCEPTION TEST"); + } + else { + cout << "\nALL TESTS SUCCESSFUL\n"; + } + } + return 0; +} diff --git a/db/test/scr015/TestConstruct01.testerr b/db/test/scr015/TestConstruct01.testerr new file mode 100644 index 000000000..1ba627d10 --- /dev/null +++ b/db/test/scr015/TestConstruct01.testerr @@ -0,0 +1,4 @@ +expected error: DbEnv::_destroy_check: open DbEnv object destroyed +should have received error. +expected error: DbEnv::_destroy_check: open DbEnv object destroyed +should have received error. diff --git a/db/test/scr015/TestConstruct01.testout b/db/test/scr015/TestConstruct01.testout new file mode 100644 index 000000000..9b840f9fc --- /dev/null +++ b/db/test/scr015/TestConstruct01.testout @@ -0,0 +1,27 @@ +(0/1) construct01 running: + Running test 1: + finished. + Running test 2: + finished. + Running test 3: + finished. + Running test 4: + finished. + Running test 5: + finished. + Running test 6: + finished. + Running test 1: + finished. + Running test 2: + finished. + Running test 3: + finished. + Running test 4: + finished. + Running test 5: + finished. + Running test 6: + finished. + +ALL TESTS SUCCESSFUL diff --git a/db/test/scr015/TestExceptInclude.cpp b/db/test/scr015/TestExceptInclude.cpp new file mode 100644 index 000000000..8f0c142e3 --- /dev/null +++ b/db/test/scr015/TestExceptInclude.cpp @@ -0,0 +1,25 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2001 + * Sleepycat Software. All rights reserved. + * + * Id: TestExceptInclude.cpp,v 1.1 2001/05/31 23:09:12 dda Exp + */ + +/* We should be able to include cxx_except.h without db_cxx.h, + * and use the DbException class. + * + * This program does nothing, it's just here to make sure + * the compilation works. + */ +#include "cxx_except.h" + +int main(int argc, char *argv[]) +{ + DbException *dbe = new DbException("something"); + DbMemoryException *dbme = new DbMemoryException("anything"); + + dbe = dbme; +} + diff --git a/db/test/scr015/TestGetSetMethods.cpp b/db/test/scr015/TestGetSetMethods.cpp new file mode 100644 index 000000000..f6d66dcee --- /dev/null +++ b/db/test/scr015/TestGetSetMethods.cpp @@ -0,0 +1,91 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestGetSetMethods.cpp,v 1.3 2001/10/05 01:50:17 bostic Exp + */ + +/* + * Do some regression tests for simple get/set access methods + * on DbEnv, DbTxn, Db. We don't currently test that they have + * the desired effect, only that they operate and return correctly. + */ + +#include <db_cxx.h> +#include <iostream.h> + +int main(int argc, char *argv[]) +{ + try { + DbEnv *dbenv = new DbEnv(0); + DbTxn *dbtxn; + u_int8_t conflicts[10]; + + dbenv->set_error_stream(&cerr); + dbenv->set_timeout(0x90000000, + DB_SET_LOCK_TIMEOUT); + dbenv->set_lg_bsize(0x1000); + dbenv->set_lg_dir("."); + dbenv->set_lg_max(0x10000000); + dbenv->set_lg_regionmax(0x100000); + dbenv->set_lk_conflicts(conflicts, sizeof(conflicts)); + dbenv->set_lk_detect(DB_LOCK_DEFAULT); + // exists, but is deprecated: + // dbenv->set_lk_max(0); + dbenv->set_lk_max_lockers(100); + dbenv->set_lk_max_locks(10); + dbenv->set_lk_max_objects(1000); + dbenv->set_mp_mmapsize(0x10000); + dbenv->set_tas_spins(1000); + + // Need to open the environment so we + // can get a transaction. + // + dbenv->open(".", DB_CREATE | DB_INIT_TXN | + DB_INIT_LOCK | DB_INIT_LOG | + DB_INIT_MPOOL, + 0644); + + dbenv->txn_begin(NULL, &dbtxn, DB_TXN_NOWAIT); + dbtxn->set_timeout(0xA0000000, DB_SET_TXN_TIMEOUT); + dbtxn->abort(); + + dbenv->close(0); + + // We get a db, one for each type. + // That's because once we call (for instance) + // set_bt_maxkey, DB 'knows' that this is a + // Btree Db, and it cannot be used to try Hash + // or Recno functions. + // + Db *db_bt = new Db(NULL, 0); + db_bt->set_bt_maxkey(10000); + db_bt->set_bt_minkey(100); + db_bt->set_cachesize(0, 0x100000, 0); + db_bt->close(0); + + Db *db_h = new Db(NULL, 0); + db_h->set_h_ffactor(0x10); + db_h->set_h_nelem(100); + db_h->set_lorder(0); + db_h->set_pagesize(0x10000); + db_h->close(0); + + Db *db_re = new Db(NULL, 0); + db_re->set_re_delim('@'); + db_re->set_re_pad(10); + db_re->set_re_source("re.in"); + db_re->close(0); + + Db *db_q = new Db(NULL, 0); + db_q->set_q_extentsize(200); + db_q->close(0); + + } + catch (DbException &dbe) { + cerr << "Db Exception: " << dbe.what() << "\n"; + } + return 0; +} diff --git a/db/test/scr015/TestKeyRange.cpp b/db/test/scr015/TestKeyRange.cpp new file mode 100644 index 000000000..62592aee3 --- /dev/null +++ b/db/test/scr015/TestKeyRange.cpp @@ -0,0 +1,171 @@ +/*NOTE: AccessExample changed to test Db.key_range. + * We made a global change of /AccessExample/TestKeyRange/, + * the only other changes are marked with comments that + * are notated as 'ADDED'. + */ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestKeyRange.cpp,v 1.2 2001/10/09 20:58:35 dda Exp + */ + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <iostream.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#ifndef _MSC_VER +#include <unistd.h> +#endif +#endif + +#include <iomanip.h> +#include <db_cxx.h> + +class TestKeyRange +{ +public: + TestKeyRange(); + void run(); + +private: + static const char FileName[]; + + // no need for copy and assignment + TestKeyRange(const TestKeyRange &); + void operator = (const TestKeyRange &); +}; + +static void usage(); // forward + +int main(int argc, char *argv[]) +{ + if (argc > 1) { + usage(); + } + + // Use a try block just to report any errors. + // An alternate approach to using exceptions is to + // use error models (see DbEnv::set_error_model()) so + // that error codes are returned for all Berkeley DB methods. + // + try { + TestKeyRange app; + app.run(); + return 0; + } + catch (DbException &dbe) { + cerr << "TestKeyRange: " << dbe.what() << "\n"; + return 1; + } +} + +static void usage() +{ + cerr << "usage: TestKeyRange\n"; + exit(1); +} + +const char TestKeyRange::FileName[] = "access.db"; + +TestKeyRange::TestKeyRange() +{ +} + +void TestKeyRange::run() +{ + // Remove the previous database. + (void)unlink(FileName); + + // Create the database object. + // There is no environment for this simple example. + Db db(0, 0); + + db.set_error_stream(&cerr); + db.set_errpfx("TestKeyRange"); + db.set_pagesize(1024); /* Page size: 1K. */ + db.set_cachesize(0, 32 * 1024, 0); + db.open(FileName, NULL, DB_BTREE, DB_CREATE, 0664); + + // + // Insert records into the database, where the key is the user + // input and the data is the user input in reverse order. + // + char buf[1024]; + char rbuf[1024]; + char *t; + char *p; + int ret; + int len; + Dbt *firstkey = NULL; + char firstbuf[1024]; + + for (;;) { + cout << "input>"; + cout.flush(); + + cin.getline(buf, sizeof(buf)); + if (cin.eof()) + break; + + if ((len = strlen(buf)) <= 0) + continue; + for (t = rbuf, p = buf + (len - 1); p >= buf;) + *t++ = *p--; + *t++ = '\0'; + + Dbt key(buf, len + 1); + Dbt data(rbuf, len + 1); + if (firstkey == NULL) { + strcpy(firstbuf, buf); + firstkey = new Dbt(firstbuf, len + 1); + } + + ret = db.put(0, &key, &data, DB_NOOVERWRITE); + if (ret == DB_KEYEXIST) { + cout << "Key " << buf << " already exists.\n"; + } + cout << "\n"; + } + + // We put a try block around this section of code + // to ensure that our database is properly closed + // in the event of an error. + // + try { + // Acquire a cursor for the table. + Dbc *dbcp; + db.cursor(NULL, &dbcp, 0); + + /*ADDED...*/ + DB_KEY_RANGE range; + memset(&range, 0, sizeof(range)); + + db.key_range(NULL, firstkey, &range, 0); + printf("less: %f\n", range.less); + printf("equal: %f\n", range.equal); + printf("greater: %f\n", range.greater); + /*end ADDED*/ + + Dbt key; + Dbt data; + + // Walk through the table, printing the key/data pairs. + while (dbcp->get(&key, &data, DB_NEXT) == 0) { + char *key_string = (char *)key.get_data(); + char *data_string = (char *)data.get_data(); + cout << key_string << " : " << data_string << "\n"; + } + dbcp->close(); + } + catch (DbException &dbe) { + cerr << "TestKeyRange: " << dbe.what() << "\n"; + } + + db.close(0); +} diff --git a/db/test/scr015/TestKeyRange.testin b/db/test/scr015/TestKeyRange.testin new file mode 100644 index 000000000..a2b6bd74e --- /dev/null +++ b/db/test/scr015/TestKeyRange.testin @@ -0,0 +1,8 @@ +first line is alphabetically somewhere in the middle. +Blah blah +let's have exactly eight lines of input. +stuff +more stuff +and even more stuff +lastly +but not leastly. diff --git a/db/test/scr015/TestKeyRange.testout b/db/test/scr015/TestKeyRange.testout new file mode 100644 index 000000000..25b2e1a83 --- /dev/null +++ b/db/test/scr015/TestKeyRange.testout @@ -0,0 +1,19 @@ +input> +input> +input> +input> +input> +input> +input> +input> +input>less: 0.375000 +equal: 0.125000 +greater: 0.500000 +Blah blah : halb halB +and even more stuff : ffuts erom neve dna +but not leastly. : .yltsael ton tub +first line is alphabetically somewhere in the middle. : .elddim eht ni erehwemos yllacitebahpla si enil tsrif +lastly : yltsal +let's have exactly eight lines of input. : .tupni fo senil thgie yltcaxe evah s'tel +more stuff : ffuts erom +stuff : ffuts diff --git a/db/test/scr015/TestLogc.cpp b/db/test/scr015/TestLogc.cpp new file mode 100644 index 000000000..d6d0003cd --- /dev/null +++ b/db/test/scr015/TestLogc.cpp @@ -0,0 +1,92 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestLogc.cpp,v 1.3 2001/10/12 13:02:31 dda Exp + */ + +/* + * A basic regression test for the Logc class. + */ + +#include <db_cxx.h> +#include <iostream.h> + +static void show_dbt(ostream &os, Dbt *dbt) +{ + int i; + int size = dbt->get_size(); + unsigned char *data = (unsigned char *)dbt->get_data(); + + os << "size: " << size << " data: "; + for (i=0; i<size && i<10; i++) { + os << (int)data[i] << " "; + } + if (i<size) + os << "..."; +} + +int main(int argc, char *argv[]) +{ + try { + DbEnv *env = new DbEnv(0); + env->open(".", DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL, 0); + + // Do some database activity to get something into the log. + Db *db1 = new Db(env, 0); + db1->open("first.db", NULL, DB_BTREE, DB_CREATE, 0); + Dbt *key = new Dbt((char *)"a", 1); + Dbt *data = new Dbt((char *)"b", 1); + db1->put(NULL, key, data, 0); + key->set_data((char *)"c"); + data->set_data((char *)"d"); + db1->put(NULL, key, data, 0); + db1->close(0); + + Db *db2 = new Db(env, 0); + db2->open("second.db", NULL, DB_BTREE, DB_CREATE, 0); + key->set_data((char *)"w"); + data->set_data((char *)"x"); + db2->put(NULL, key, data, 0); + key->set_data((char *)"y"); + data->set_data((char *)"z"); + db2->put(NULL, key, data, 0); + db2->close(0); + + // Now get a log cursor and walk through. + DbLogc *logc; + + env->log_cursor(&logc, 0); + int ret = 0; + DbLsn lsn; + Dbt *dbt = new Dbt(); + u_int32_t flags = DB_FIRST; + + int count = 0; + while ((ret = logc->get(&lsn, dbt, flags)) == 0) { + cout << "logc.get: " << count; + + // We ignore the contents of the log record, + // it's not portable. + // + // show_dbt(cout, dbt); + // + + cout << "\n"; + count++; + flags = DB_NEXT; + } + if (ret != DB_NOTFOUND) { + cerr << "*** Failed to get log record, returned: " + << DbEnv::strerror(ret) << "\n"; + } + logc->close(0); + cout << "TestLogc done.\n"; + } + catch (DbException &dbe) { + cerr << "Db Exception: " << dbe.what(); + } + return 0; +} diff --git a/db/test/scr015/TestLogc.testout b/db/test/scr015/TestLogc.testout new file mode 100644 index 000000000..858947464 --- /dev/null +++ b/db/test/scr015/TestLogc.testout @@ -0,0 +1,18 @@ +logc.get: 0 +logc.get: 1 +logc.get: 2 +logc.get: 3 +logc.get: 4 +logc.get: 5 +logc.get: 6 +logc.get: 7 +logc.get: 8 +logc.get: 9 +logc.get: 10 +logc.get: 11 +logc.get: 12 +logc.get: 13 +logc.get: 14 +logc.get: 15 +logc.get: 16 +TestLogc done. diff --git a/db/test/scr015/TestSimpleAccess.cpp b/db/test/scr015/TestSimpleAccess.cpp new file mode 100644 index 000000000..fb8714cff --- /dev/null +++ b/db/test/scr015/TestSimpleAccess.cpp @@ -0,0 +1,67 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestSimpleAccess.cpp,v 1.3 2001/10/05 01:50:17 bostic Exp + */ + +/* + * Do some regression tests for constructors. + * Run normally (without arguments) it is a simple regression test. + * Run with a numeric argument, it repeats the regression a number + * of times, to try to determine if there are memory leaks. + */ + +#include <db_cxx.h> +#include <iostream.h> + +int main(int argc, char *argv[]) +{ + try { + Db *db = new Db(NULL, 0); + db->open("my.db", NULL, DB_BTREE, DB_CREATE, 0644); + + // populate our massive database. + // all our strings include null for convenience. + // Note we have to cast for idiomatic + // usage, since newer gcc requires it. + Dbt *keydbt = new Dbt((char *)"key", 4); + Dbt *datadbt = new Dbt((char *)"data", 5); + db->put(NULL, keydbt, datadbt, 0); + + // Now, retrieve. We could use keydbt over again, + // but that wouldn't be typical in an application. + Dbt *goodkeydbt = new Dbt((char *)"key", 4); + Dbt *badkeydbt = new Dbt((char *)"badkey", 7); + Dbt *resultdbt = new Dbt(); + resultdbt->set_flags(DB_DBT_MALLOC); + + int ret; + + if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) { + cout << "get: " << DbEnv::strerror(ret) << "\n"; + } + else { + char *result = (char *)resultdbt->get_data(); + cout << "got data: " << result << "\n"; + } + + if ((ret = db->get(NULL, badkeydbt, resultdbt, 0)) != 0) { + // We expect this... + cout << "get using bad key: " + << DbEnv::strerror(ret) << "\n"; + } + else { + char *result = (char *)resultdbt->get_data(); + cout << "*** got data using bad key!!: " + << result << "\n"; + } + cout << "finished test\n"; + } + catch (DbException &dbe) { + cerr << "Db Exception: " << dbe.what(); + } + return 0; +} diff --git a/db/test/scr015/TestSimpleAccess.testout b/db/test/scr015/TestSimpleAccess.testout new file mode 100644 index 000000000..dc88d4788 --- /dev/null +++ b/db/test/scr015/TestSimpleAccess.testout @@ -0,0 +1,3 @@ +got data: data +get using bad key: DB_NOTFOUND: No matching key/data pair found +finished test diff --git a/db/test/scr015/TestTruncate.cpp b/db/test/scr015/TestTruncate.cpp new file mode 100644 index 000000000..49024299f --- /dev/null +++ b/db/test/scr015/TestTruncate.cpp @@ -0,0 +1,84 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestTruncate.cpp,v 1.3 2001/10/05 01:50:17 bostic Exp + */ + +/* + * Do some regression tests for constructors. + * Run normally (without arguments) it is a simple regression test. + * Run with a numeric argument, it repeats the regression a number + * of times, to try to determine if there are memory leaks. + */ + +#include <db_cxx.h> +#include <iostream.h> + +int main(int argc, char *argv[]) +{ + try { + Db *db = new Db(NULL, 0); + db->open("my.db", NULL, DB_BTREE, DB_CREATE, 0644); + + // populate our massive database. + // all our strings include null for convenience. + // Note we have to cast for idiomatic + // usage, since newer gcc requires it. + Dbt *keydbt = new Dbt((char*)"key", 4); + Dbt *datadbt = new Dbt((char*)"data", 5); + db->put(NULL, keydbt, datadbt, 0); + + // Now, retrieve. We could use keydbt over again, + // but that wouldn't be typical in an application. + Dbt *goodkeydbt = new Dbt((char*)"key", 4); + Dbt *badkeydbt = new Dbt((char*)"badkey", 7); + Dbt *resultdbt = new Dbt(); + resultdbt->set_flags(DB_DBT_MALLOC); + + int ret; + + if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) { + cout << "get: " << DbEnv::strerror(ret) << "\n"; + } + else { + char *result = (char *)resultdbt->get_data(); + cout << "got data: " << result << "\n"; + } + + if ((ret = db->get(NULL, badkeydbt, resultdbt, 0)) != 0) { + // We expect this... + cout << "get using bad key: " + << DbEnv::strerror(ret) << "\n"; + } + else { + char *result = (char *)resultdbt->get_data(); + cout << "*** got data using bad key!!: " + << result << "\n"; + } + + // Now, truncate and make sure that it's really gone. + cout << "truncating data...\n"; + u_int32_t nrecords; + db->truncate(NULL, &nrecords, 0); + cout << "truncate returns " << nrecords << "\n"; + if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) { + // We expect this... + cout << "after truncate get: " + << DbEnv::strerror(ret) << "\n"; + } + else { + char *result = (char *)resultdbt->get_data(); + cout << "got data: " << result << "\n"; + } + + db->close(0); + cout << "finished test\n"; + } + catch (DbException &dbe) { + cerr << "Db Exception: " << dbe.what(); + } + return 0; +} diff --git a/db/test/scr015/TestTruncate.testout b/db/test/scr015/TestTruncate.testout new file mode 100644 index 000000000..0a4bc9816 --- /dev/null +++ b/db/test/scr015/TestTruncate.testout @@ -0,0 +1,6 @@ +got data: data +get using bad key: DB_NOTFOUND: No matching key/data pair found +truncating data... +truncate returns 1 +after truncate get: DB_NOTFOUND: No matching key/data pair found +finished test diff --git a/db/test/scr015/chk.cxxtests b/db/test/scr015/chk.cxxtests new file mode 100644 index 000000000..84b7901aa --- /dev/null +++ b/db/test/scr015/chk.cxxtests @@ -0,0 +1,69 @@ +#!/bin/sh - +# +# Id: chk.cxxtests,v 1.2 2001/10/12 13:02:31 dda Exp +# +# Check to make sure that regression tests for C++ run. + +TEST_CXX_SRCDIR=../test/scr015 # must be a relative directory +CXX=${CXX:-c++} + +# All paths must be relative to a subdirectory of the build directory +LIBS="-L.. -ldb -ldb_cxx" +CXXFLAGS="-I.. -I../../include" + +# Test must be run from a local build directory, not from a test +# directory. +cd .. +[ -f db_config.h ] || { + echo 'FAIL: chk.cxxtests must be run from a local build directory.' + exit 1 +} +[ -d ../docs_src ] || { + echo 'FAIL: chk.cxxtests must be run from a local build directory.' + exit 1 +} +[ -f libdb.a ] || make libdb.a || { + echo 'FAIL: unable to build libdb.a' + exit 1 +} +[ -f libdb_cxx.a ] || make libdb_cxx.a || { + echo 'FAIL: unable to build libdb_cxx.a' + exit 1 +} +testnames=`cd $TEST_CXX_SRCDIR; ls *.cpp | sed -e 's/\.cpp$//'` + +for testname in $testnames; do + if grep -x $testname $TEST_CXX_SRCDIR/ignore > /dev/null; then + echo " **** cxx test $testname ignored" + continue + fi + + echo " ==== cxx test $testname" + rm -rf TESTCXX; mkdir TESTCXX + cd ./TESTCXX + testprefix=../$TEST_CXX_SRCDIR/$testname + ${CXX} ${CXXFLAGS} -o $testname $testprefix.cpp ${LIBS} > ../$testname.compileout 2>&1 || { + echo "FAIL: compilation of $testname failed, see ../$testname.compileout" + exit 1 + } + rm -f ../$testname.compileout + infile=$testprefix.testin + [ -f $infile ] || infile=/dev/null + goodoutfile=$testprefix.testout + [ -f $goodoutfile ] || goodoutfile=/dev/null + gooderrfile=$testprefix.testerr + [ -f $gooderrfile ] || gooderrfile=/dev/null + ./$testname <$infile >../$testname.out 2>../$testname.err + cmp ../$testname.out $goodoutfile > /dev/null || { + echo "FAIL: $testname output differs: see ../$testname.out, $goodoutfile" + exit 1 + } + cmp ../$testname.err $gooderrfile > /dev/null || { + echo "FAIL: $testname error differs: see ../$testname.err, $gooderrfile" + exit 1 + } + cd .. + rm -f $testname.err $testname.out +done +rm -rf TESTCXX +exit 0 diff --git a/db/test/scr015/ignore b/db/test/scr015/ignore new file mode 100644 index 000000000..cdf4c87c1 --- /dev/null +++ b/db/test/scr015/ignore @@ -0,0 +1,4 @@ +# +# Id: ignore,v 1.3 2001/10/12 13:02:32 dda Exp +# +# A list of tests to ignore diff --git a/db/test/scr015/testall b/db/test/scr015/testall new file mode 100644 index 000000000..e9883c4c3 --- /dev/null +++ b/db/test/scr015/testall @@ -0,0 +1,32 @@ +#!/bin/sh - +# Id: testall,v 1.3 2001/09/13 14:49:36 dda Exp +# +# Run all the C++ regression tests + +ecode=0 +prefixarg="" +stdinarg="" +while : +do + case "$1" in + --prefix=* ) + prefixarg="$1"; shift;; + --stdin ) + stdinarg="$1"; shift;; + * ) + break + esac +done +files="`find . -name \*.cpp -print`" +for file in $files; do + name=`echo $file | sed -e 's:^\./::' -e 's/\.cpp$//'` + if grep $name ignore > /dev/null; then + echo " **** cxx test $name ignored" + else + echo " ==== cxx test $name" + if ! sh ./testone $prefixarg $stdinarg $name; then + ecode=1 + fi + fi +done +exit $ecode diff --git a/db/test/scr015/testone b/db/test/scr015/testone new file mode 100644 index 000000000..e9e8c6b93 --- /dev/null +++ b/db/test/scr015/testone @@ -0,0 +1,121 @@ +#!/bin/sh - +# Id: testone,v 1.3 2001/09/11 19:14:16 dda Exp +# +# Run just one C++ regression test, the single argument +# is the basename of the test, e.g. TestRpcServer + +error() +{ + echo '' >&2 + echo "C++ regression error: $@" >&2 + echo '' >&2 + ecode=1 +} + +# compares the result against the good version, +# reports differences, and removes the result file +# if there are no differences. +# +compare_result() +{ + good="$1" + latest="$2" + if [ ! -e "$good" ]; then + echo "Note: $good does not exist" + return + fi + tmpout=/tmp/blddb$$.tmp + diff "$good" "$latest" > $tmpout + if [ -s $tmpout ]; then + nbad=`grep '^[0-9]' $tmpout | wc -l` + error "$good and $latest differ in $nbad places." + else + rm $latest + fi + rm -f $tmpout +} + +ecode=0 +stdinflag=n +gdbflag=n +CXX=${CXX:-c++} +LIBS=${LIBS:-} + +# remove any -c option in the CXXFLAGS +CXXFLAGS="`echo " ${CXXFLAGS} " | sed -e 's/ -c //g'`" + +# determine the prefix of the install tree +prefix="" +while : +do + case "$1" in + --prefix=* ) + prefix="`echo $1 | sed -e 's/--prefix=//'`"; shift + LIBS="-L$prefix/lib -ldb_cxx $LIBS" + CXXFLAGS="-I$prefix/include $CXXFLAGS" + export LD_LIBRARY_PATH="$prefix/lib:$LD_LIBRARY_PATH" + ;; + --stdin ) + stdinflag=y; shift + ;; + --gdb ) + CXXFLAGS="-g $CXXFLAGS" + gdbflag=y; shift + ;; + * ) + break + ;; + esac +done + +if [ "$#" = 0 ]; then + echo 'Usage: testone [ --prefix=<dir> | --stdin ] TestName' + exit 1 +fi +name="$1" + +# compile +rm -rf TESTDIR; mkdir TESTDIR +cd ./TESTDIR +${CXX} ${CXXFLAGS} -o $name ../$name.cpp ${LIBS} > ../$name.compileout 2>&1 +if [ $? != 0 -o -s ../$name.compileout ]; then + error "compilation of $name failed, see $name.compileout" + exit 1 +fi +rm -f ../$name.compileout + +# find input and error file +infile=../$name.testin +if [ ! -f $infile ]; then + infile=/dev/null +fi + +# run and diff results +rm -rf TESTDIR +if [ "$gdbflag" = y ]; then + if [ -s $infile ]; then + echo "Input file is $infile" + fi + gdb ./$name + exit 0 +elif [ "$stdinflag" = y ]; then + ./$name >../$name.out 2>../$name.err +else + ./$name <$infile >../$name.out 2>../$name.err +fi +cd .. + +testerr=$name.testerr +if [ ! -f $testerr ]; then + testerr=/dev/null +fi + +testout=$name.testout +if [ ! -f $testout ]; then + testout=/dev/null +fi + +compare_result $testout $name.out +compare_result $testerr $name.err +rm -rf TESTDIR +exit $ecode diff --git a/db/test/scr016/CallbackTest.java b/db/test/scr016/CallbackTest.java new file mode 100644 index 000000000..587e6840e --- /dev/null +++ b/db/test/scr016/CallbackTest.java @@ -0,0 +1,83 @@ +package com.sleepycat.test; +import com.sleepycat.db.*; + +public class CallbackTest +{ + public static void main(String args[]) + { + try { + Db db = new Db(null, 0); + db.set_bt_compare(new BtreeCompare()); + db.open("test.db", "", Db.DB_BTREE, Db.DB_CREATE, 0666); + StringDbt[] keys = new StringDbt[10]; + StringDbt[] datas = new StringDbt[10]; + for (int i = 0; i<10; i++) { + int val = (i * 3) % 10; + keys[i] = new StringDbt("key" + val); + datas[i] = new StringDbt("data" + val); + System.out.println("put " + val); + db.put(null, keys[i], datas[i], 0); + } + } + catch (DbException dbe) { + System.err.println("FAIL: " + dbe); + } + catch (java.io.FileNotFoundException fnfe) { + System.err.println("FAIL: " + fnfe); + } + + } + + +} + +class BtreeCompare + implements DbBtreeCompare +{ + /* A weird comparator, for example. + * In fact, it may not be legal, since it's not monotonically increasing. + */ + public int bt_compare(Db db, Dbt dbt1, Dbt dbt2) + { + System.out.println("compare function called"); + byte b1[] = dbt1.get_data(); + byte b2[] = dbt2.get_data(); + System.out.println(" " + (new String(b1)) + ", " + (new String(b2))); + int len1 = b1.length; + int len2 = b2.length; + if (len1 != len2) + return (len1 < len2) ? 1 : -1; + int value = 1; + for (int i=0; i<len1; i++) { + if (b1[i] != b2[i]) + return (b1[i] < b2[i]) ? value : -value; + value *= -1; + } + return 0; + } +} + +class StringDbt extends Dbt +{ + StringDbt() + { + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + StringDbt(String value) + { + setString(value); + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + void setString(String value) + { + set_data(value.getBytes()); + set_size(value.length()); + } + + String getString() + { + return new String(get_data(), 0, get_size()); + } +} diff --git a/db/test/scr016/CallbackTest.testout b/db/test/scr016/CallbackTest.testout new file mode 100644 index 000000000..23cd113a7 --- /dev/null +++ b/db/test/scr016/CallbackTest.testout @@ -0,0 +1,56 @@ +put 0 +put 3 +compare function called + key3, key0 +put 6 +compare function called + key6, key3 +put 9 +compare function called + key9, key6 +put 2 +compare function called + key2, key9 +compare function called + key2, key0 +compare function called + key2, key6 +compare function called + key2, key3 +compare function called + key2, key0 +put 5 +compare function called + key5, key3 +compare function called + key5, key9 +compare function called + key5, key6 +put 8 +compare function called + key8, key5 +compare function called + key8, key9 +compare function called + key8, key6 +put 1 +compare function called + key1, key5 +compare function called + key1, key2 +compare function called + key1, key0 +put 4 +compare function called + key4, key5 +compare function called + key4, key2 +compare function called + key4, key3 +put 7 +compare function called + key7, key4 +compare function called + key7, key8 +compare function called + key7, key6 diff --git a/db/test/scr016/README b/db/test/scr016/README new file mode 100644 index 000000000..0b8a87ef0 --- /dev/null +++ b/db/test/scr016/README @@ -0,0 +1,37 @@ +# Id: README,v 1.2 2001/05/31 23:09:10 dda Exp + +Use the scripts testall or testone to run all, or just one of the Java +tests. You must be in this directory to run them. For example, + + $ export LD_LIBRARY_PATH=/usr/local/Berkeley3.3/lib + $ ./testone TestAppendRecno + $ ./testall + +The scripts will use javac and java in your path. Set environment +variables $JAVAC and $JAVA to override this. It will also and honor +any $CLASSPATH that is already set, prepending ../../../../classes to +it, which is where the test .class files are put, and where the DB +.class files can normally be found after a build on Unix and Windows. +If none of these variables are set, everything will probably work +with whatever java/javac is in your path. + +To run successfully, you will probably need to set $LD_LIBRARY_PATH +to be the directory containing libdb_java-X.Y.so + +As an alternative, use the --prefix=<DIR> option, a la configure +to set the top of the BerkeleyDB install directory. This forces +the proper options to be added to $LD_LIBRARY_PATH. +For example, + + $ ./testone --prefix=/usr/include/BerkeleyDB TestAppendRecno + $ ./testall --prefix=/usr/include/BerkeleyDB + +The test framework is pretty simple. Any <name>.java file in this +directory that is not mentioned in the 'ignore' file represents a +test. If the test is not compiled successfully, the compiler output +is left in <name>.compileout . Otherwise, the java program is run in +a clean subdirectory using as input <name>.testin, or if that doesn't +exist, /dev/null. Output and error from the test run are put into +<name>.out, <name>.err . If <name>.testout, <name>.testerr exist, +they are used as reference files and any differences are reported. +If either of the reference files does not exist, /dev/null is used. diff --git a/db/test/scr016/TestAppendRecno.java b/db/test/scr016/TestAppendRecno.java new file mode 100644 index 000000000..5021ddbac --- /dev/null +++ b/db/test/scr016/TestAppendRecno.java @@ -0,0 +1,259 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestAppendRecno.java,v 1.2 2001/10/05 02:36:08 bostic Exp + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.PrintStream; + +public class TestAppendRecno + implements DbAppendRecno +{ + private static final String FileName = "access.db"; + int callback_count = 0; + Db table = null; + + public TestAppendRecno() + { + } + + private static void usage() + { + System.err.println("usage: TestAppendRecno\n"); + System.exit(1); + } + + public static void main(String argv[]) + { + try + { + TestAppendRecno app = new TestAppendRecno(); + app.run(); + } + catch (DbException dbe) + { + System.err.println("TestAppendRecno: " + dbe.toString()); + System.exit(1); + } + catch (FileNotFoundException fnfe) + { + System.err.println("TestAppendRecno: " + fnfe.toString()); + System.exit(1); + } + System.exit(0); + } + + public void run() + throws DbException, FileNotFoundException + { + // Remove the previous database. + new File(FileName).delete(); + + // Create the database object. + // There is no environment for this simple example. + table = new Db(null, 0); + table.set_error_stream(System.err); + table.set_errpfx("TestAppendRecno"); + //table.open(FileName, null, Db.DB_BTREE, Db.DB_CREATE, 0644); + table.set_append_recno(this); + + table.open(FileName, null, Db.DB_RECNO, Db.DB_CREATE, 0644); + for (int i=0; i<10; i++) { + System.out.println("\n*** Iteration " + i ); + try { + RecnoDbt key = new RecnoDbt(77+i); + StringDbt data = new StringDbt("data" + i + "_xyz"); + table.put(null, key, data, Db.DB_APPEND); + } + catch (DbException dbe) { + System.out.println("dbe: " + dbe); + } + } + + // Acquire an iterator for the table. + Dbc iterator; + iterator = table.cursor(null, 0); + + // Walk through the table, printing the key/data pairs. + // See class StringDbt defined below. + // + RecnoDbt key = new RecnoDbt(); + StringDbt data = new StringDbt(); + while (iterator.get(key, data, Db.DB_NEXT) == 0) + { + System.out.println(key.getRecno() + " : " + data.getString()); + } + iterator.close(); + table.close(0); + System.out.println("Test finished."); + } + + public void db_append_recno(Db db, Dbt dbt, int recno) + throws DbException + { + int count = callback_count++; + + System.out.println("====\ncallback #" + count); + System.out.println("db is table: " + (db == table)); + System.out.println("recno = " + recno); + + // This gives variable output. + //System.out.println("dbt = " + dbt); + if (dbt instanceof RecnoDbt) { + System.out.println("dbt = " + + ((RecnoDbt)dbt).getRecno()); + } + else if (dbt instanceof StringDbt) { + System.out.println("dbt = " + + ((StringDbt)dbt).getString()); + } + else { + // Note: the dbts are created out of whole + // cloth by Berkeley DB, not us! + System.out.println("internally created dbt: " + + new StringDbt(dbt) + ", size " + + dbt.get_size()); + } + + switch (count) { + case 0: + // nothing + break; + + case 1: + dbt.set_size(dbt.get_size() - 1); + break; + + case 2: + System.out.println("throwing..."); + throw new DbException("append_recno thrown"); + //not reached + + case 3: + // Should result in an error (size unchanged). + dbt.set_offset(1); + break; + + case 4: + dbt.set_offset(1); + dbt.set_size(dbt.get_size() - 1); + break; + + case 5: + dbt.set_offset(1); + dbt.set_size(dbt.get_size() - 2); + break; + + case 6: + dbt.set_data(new String("abc").getBytes()); + dbt.set_size(3); + break; + + case 7: + // Should result in an error. + dbt.set_data(null); + break; + + case 8: + // Should result in an error. + dbt.set_data(new String("abc").getBytes()); + dbt.set_size(4); + break; + + default: + break; + } + } + + + // Here's an example of how you can extend a Dbt to store recno's. + // + static /*inner*/ + class RecnoDbt extends Dbt + { + RecnoDbt() + { + this(0); // let other constructor do most of the work + } + + RecnoDbt(int value) + { + set_flags(Db.DB_DBT_USERMEM); // do not allocate on retrieval + arr = new byte[4]; + set_data(arr); // use our local array for data + set_ulen(4); // size of return storage + setRecno(value); + } + + public String toString() /*override*/ + { + return String.valueOf(getRecno()); + } + + void setRecno(int value) + { + set_recno_key_data(value); + set_size(arr.length); + } + + int getRecno() + { + return get_recno_key_data(); + } + + byte arr[]; + } + + // Here's an example of how you can extend a Dbt in a straightforward + // way to allow easy storage/retrieval of strings, or whatever + // kind of data you wish. We've declared it as a static inner + // class, but it need not be. + // + static /*inner*/ + class StringDbt extends Dbt + { + StringDbt(Dbt dbt) + { + set_data(dbt.get_data()); + set_size(dbt.get_size()); + } + + StringDbt() + { + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + StringDbt(String value) + { + setString(value); + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + void setString(String value) + { + set_data(value.getBytes()); + set_size(value.length()); + } + + String getString() + { + return new String(get_data(), 0, get_size()); + } + + public String toString() /*override*/ + { + return getString(); + } + } +} + diff --git a/db/test/scr016/TestAppendRecno.testout b/db/test/scr016/TestAppendRecno.testout new file mode 100644 index 000000000..970174e7a --- /dev/null +++ b/db/test/scr016/TestAppendRecno.testout @@ -0,0 +1,82 @@ + +*** Iteration 0 +==== +callback #0 +db is table: true +recno = 1 +internally created dbt: data0_xyz, size 9 + +*** Iteration 1 +==== +callback #1 +db is table: true +recno = 2 +internally created dbt: data1_xyz, size 9 + +*** Iteration 2 +==== +callback #2 +db is table: true +recno = 3 +internally created dbt: data2_xyz, size 9 +throwing... +dbe: com.sleepycat.db.DbException: append_recno thrown + +*** Iteration 3 +==== +callback #3 +db is table: true +recno = 3 +internally created dbt: data3_xyz, size 9 +dbe: com.sleepycat.db.DbException: Dbt.size + Dbt.offset greater than array length + +*** Iteration 4 +==== +callback #4 +db is table: true +recno = 3 +internally created dbt: data4_xyz, size 9 + +*** Iteration 5 +==== +callback #5 +db is table: true +recno = 4 +internally created dbt: data5_xyz, size 9 + +*** Iteration 6 +==== +callback #6 +db is table: true +recno = 5 +internally created dbt: data6_xyz, size 9 + +*** Iteration 7 +==== +callback #7 +db is table: true +recno = 6 +internally created dbt: data7_xyz, size 9 +dbe: com.sleepycat.db.DbException: Dbt.data is null + +*** Iteration 8 +==== +callback #8 +db is table: true +recno = 6 +internally created dbt: data8_xyz, size 9 +dbe: com.sleepycat.db.DbException: Dbt.size + Dbt.offset greater than array length + +*** Iteration 9 +==== +callback #9 +db is table: true +recno = 6 +internally created dbt: data9_xyz, size 9 +1 : data0_xyz +2 : data1_xy +3 : ata4_xyz +4 : ata5_xy +5 : abc +6 : data9_xyz +Test finished. diff --git a/db/test/scr016/TestAssociate.java b/db/test/scr016/TestAssociate.java new file mode 100644 index 000000000..3bf210831 --- /dev/null +++ b/db/test/scr016/TestAssociate.java @@ -0,0 +1,333 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2001 + * Sleepycat Software. All rights reserved. + * + * Id: TestAssociate.java,v 1.2 2001/10/05 02:36:08 bostic Exp + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.Reader; +import java.io.StringReader; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Hashtable; + +public class TestAssociate + implements DbDupCompare +{ + private static final String FileName = "access.db"; + public static Db saveddb1 = null; + public static Db saveddb2 = null; + + public TestAssociate() + { + } + + private static void usage() + { + System.err.println("usage: TestAssociate\n"); + System.exit(1); + } + + public static void main(String argv[]) + { + try + { + TestAssociate app = new TestAssociate(); + app.run(); + } + catch (DbException dbe) + { + System.err.println("TestAssociate: " + dbe.toString()); + System.exit(1); + } + catch (FileNotFoundException fnfe) + { + System.err.println("TestAssociate: " + fnfe.toString()); + System.exit(1); + } + System.exit(0); + } + + public static int counter = 0; + public static String results[] = { "abc", "def", "ghi", "JKL", "MNO", null }; + + // Prompts for a line, and keeps prompting until a non blank + // line is returned. Returns null on error. + // + static public String askForLine(Reader reader, + PrintStream out, String prompt) + { + /* + String result = ""; + while (result != null && result.length() == 0) { + out.print(prompt); + out.flush(); + result = getLine(reader); + } + return result; + */ + return results[counter++]; + } + + // Not terribly efficient, but does the job. + // Works for reading a line from stdin or a file. + // Returns null on EOF. If EOF appears in the middle + // of a line, returns that line, then null on next call. + // + static public String getLine(Reader reader) + { + StringBuffer b = new StringBuffer(); + int c; + try { + while ((c = reader.read()) != -1 && c != '\n') { + if (c != '\r') + b.append((char)c); + } + } + catch (IOException ioe) { + c = -1; + } + + if (c == -1 && b.length() == 0) + return null; + else + return b.toString(); + } + + static public String shownull(Object o) + { + if (o == null) + return "null"; + else + return "not null"; + } + + public void run() + throws DbException, FileNotFoundException + { + // Remove the previous database. + new File(FileName).delete(); + + // Create the database object. + // There is no environment for this simple example. + DbEnv dbenv = new DbEnv(0); + dbenv.open("./", Db.DB_CREATE|Db.DB_INIT_MPOOL, 0644); + (new java.io.File(FileName)).delete(); + Db table = new Db(dbenv, 0); + Db table2 = new Db(dbenv, 0); + table.set_dup_compare(this); + table2.set_dup_compare(this); + table2.set_flags(Db.DB_DUP | Db.DB_DUPSORT); + table.set_error_stream(System.err); + table2.set_error_stream(System.err); + table.set_errpfx("TestAssociate"); + table2.set_errpfx("TestAssociate(table2)"); + System.out.println("Primary database is " + shownull(table)); + System.out.println("Secondary database is " + shownull(table2)); + saveddb1 = table; + saveddb2 = table2; + table.open(FileName, null, Db.DB_BTREE, Db.DB_CREATE, 0644); + table2.open(FileName + "2", null, Db.DB_BTREE, Db.DB_CREATE, 0644); + table.associate(table2, new Capitalize(), 0); + + // + // Insert records into the database, where the key is the user + // input and the data is the user input in reverse order. + // + Reader reader = new StringReader("abc\ndef\njhi"); + + for (;;) { + String line = askForLine(reader, System.out, "input> "); + if (line == null) + break; + + String reversed = (new StringBuffer(line)).reverse().toString(); + + // See definition of StringDbt below + // + StringDbt key = new StringDbt(line); + StringDbt data = new StringDbt(reversed); + + try + { + int err; + if ((err = table.put(null, + key, data, Db.DB_NOOVERWRITE)) == Db.DB_KEYEXIST) { + System.out.println("Key " + line + " already exists."); + } + } + catch (DbException dbe) + { + System.out.println(dbe.toString()); + } + System.out.println(""); + } + + // Acquire an iterator for the table. + Dbc iterator; + iterator = table2.cursor(null, 0); + + // Walk through the table, printing the key/data pairs. + // See class StringDbt defined below. + // + StringDbt key = new StringDbt(); + StringDbt data = new StringDbt(); + StringDbt pkey = new StringDbt(); + + while (iterator.get(key, data, Db.DB_NEXT) == 0) + { + System.out.println(key.getString() + " : " + data.getString()); + } + + key.setString("BC"); + System.out.println("get BC returns " + table2.get(null, key, data, 0)); + System.out.println(" values: " + key.getString() + " : " + data.getString()); + System.out.println("pget BC returns " + table2.pget(null, key, pkey, data, 0)); + System.out.println(" values: " + key.getString() + " : " + pkey.getString() + " : " + data.getString()); + key.setString("KL"); + System.out.println("get KL returns " + table2.get(null, key, data, 0)); + System.out.println(" values: " + key.getString() + " : " + data.getString()); + System.out.println("pget KL returns " + table2.pget(null, key, pkey, data, 0)); + System.out.println(" values: " + key.getString() + " : " + pkey.getString() + " : " + data.getString()); + + iterator.close(); + table.close(0); + } + + // Here's an example of how you can extend a Dbt in a straightforward + // way to allow easy storage/retrieval of strings, or whatever + // kind of data you wish. We've declared it as a static inner + // class, but it need not be. + // + static /*inner*/ + class StringDbt extends Dbt + { + StringDbt() + { + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + StringDbt(String value) + { + setString(value); + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + void setString(String value) + { + set_data(value.getBytes()); + set_size(value.length()); + } + + String getString() + { + return new String(get_data(), 0, get_size()); + } + + public String toString() + { + return "StringDbt=" + getString(); + } + } + + /* creates a stupid secondary index as follows: + For an N letter key, we use N-1 letters starting at + position 1. If the new letters are already capitalized, + we return the old array, but with offset set to 1. + If the letters are not capitalized, we create a new, + capitalized array. This is pretty stupid for + an application, but it tests all the paths in the runtime. + */ + public static class Capitalize implements DbSecondaryKeyCreate + { + public int secondary_key_create(Db secondary, Dbt key, Dbt value, + Dbt result) + throws DbException + { + String which = "unknown db"; + if (saveddb1.equals(secondary)) { + which = "primary"; + } + else if (saveddb2.equals(secondary)) { + which = "secondary"; + } + System.out.println("secondary_key_create, Db: " + shownull(secondary) + "(" + which + "), key: " + show_dbt(key) + ", data: " + show_dbt(value)); + int len = key.get_size(); + byte[] arr = key.get_data(); + boolean capped = true; + + if (len < 1) + throw new DbException("bad key"); + + if (len < 2) + return Db.DB_DONOTINDEX; + + result.set_size(len - 1); + for (int i=1; capped && i<len; i++) { + if (!Character.isUpperCase((char)arr[i])) + capped = false; + } + if (capped) { + System.out.println(" creating key(1): " + new String(arr, 1, len-1)); + result.set_data(arr); + result.set_offset(1); + } + else { + System.out.println(" creating key(2): " + (new String(arr)).substring(1). + toUpperCase()); + result.set_data((new String(arr)).substring(1). + toUpperCase().getBytes()); + } + return 0; + } + } + + public int dup_compare(Db db, Dbt dbt1, Dbt dbt2) + { + System.out.println("compare"); + int sz1 = dbt1.get_size(); + int sz2 = dbt2.get_size(); + if (sz1 < sz2) + return -1; + if (sz1 > sz2) + return 1; + byte[] data1 = dbt1.get_data(); + byte[] data2 = dbt2.get_data(); + for (int i=0; i<sz1; i++) + if (data1[i] != data2[i]) + return (data1[i] < data2[i] ? -1 : 1); + return 0; + } + + public static int nseen = 0; + public static Hashtable ht = new Hashtable(); + + public static String show_dbt(Dbt dbt) + { + String name; + + if (dbt == null) + return "null dbt"; + + name = (String)ht.get(dbt); + if (name == null) { + name = "Dbt" + (nseen++); + ht.put(dbt, name); + } + + byte[] value = dbt.get_data(); + if (value == null) + return name + "(null)"; + else + return name + "(\"" + new String(value) + "\")"; + } +} + + diff --git a/db/test/scr016/TestAssociate.testout b/db/test/scr016/TestAssociate.testout new file mode 100644 index 000000000..34414b660 --- /dev/null +++ b/db/test/scr016/TestAssociate.testout @@ -0,0 +1,30 @@ +Primary database is not null +Secondary database is not null +secondary_key_create, Db: not null(secondary), key: Dbt0("abc"), data: Dbt1("cba") + creating key(2): BC + +secondary_key_create, Db: not null(secondary), key: Dbt2("def"), data: Dbt3("fed") + creating key(2): EF + +secondary_key_create, Db: not null(secondary), key: Dbt4("ghi"), data: Dbt5("ihg") + creating key(2): HI + +secondary_key_create, Db: not null(secondary), key: Dbt6("JKL"), data: Dbt7("LKJ") + creating key(1): KL + +secondary_key_create, Db: not null(secondary), key: Dbt8("MNO"), data: Dbt9("ONM") + creating key(1): NO + +BC : cba +EF : fed +HI : ihg +KL : LKJ +NO : ONM +get BC returns 0 + values: BC : cba +pget BC returns 0 + values: BC : abc : cba +get KL returns 0 + values: KL : LKJ +pget KL returns 0 + values: KL : JKL : LKJ diff --git a/db/test/scr016/TestClosedDb.java b/db/test/scr016/TestClosedDb.java new file mode 100644 index 000000000..67703f040 --- /dev/null +++ b/db/test/scr016/TestClosedDb.java @@ -0,0 +1,62 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestClosedDb.java,v 1.2 2001/10/05 02:36:08 bostic Exp + */ + +/* + * Close the Db, and make sure operations after that fail gracefully. + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.FileNotFoundException; + +public class TestClosedDb +{ + public static void main(String[] args) + { + try { + Db db = new Db(null, 0); + db.open("my.db", null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // populate our massive database. + Dbt keydbt = new Dbt("key".getBytes()); + Dbt datadbt = new Dbt("data".getBytes()); + db.put(null, keydbt, datadbt, 0); + + // Now, retrieve. We could use keydbt over again, + // but that wouldn't be typical in an application. + Dbt goodkeydbt = new Dbt("key".getBytes()); + Dbt badkeydbt = new Dbt("badkey".getBytes()); + Dbt resultdbt = new Dbt(); + resultdbt.set_flags(Db.DB_DBT_MALLOC); + + int ret; + + // Close the db - subsequent operations should fail + // by throwing an exception. + db.close(0); + try { + db.get(null, goodkeydbt, resultdbt, 0); + System.out.println("Error - did not expect to get this far."); + } + catch (DbException dbe) { + System.out.println("Got expected Db Exception: " + dbe); + } + System.out.println("finished test"); + } + catch (DbException dbe) { + System.err.println("Db Exception: " + dbe); + } + catch (FileNotFoundException fnfe) { + System.err.println("FileNotFoundException: " + fnfe); + } + + } + +} diff --git a/db/test/scr016/TestClosedDb.testout b/db/test/scr016/TestClosedDb.testout new file mode 100644 index 000000000..ce13883f6 --- /dev/null +++ b/db/test/scr016/TestClosedDb.testout @@ -0,0 +1,2 @@ +Got expected Db Exception: com.sleepycat.db.DbException: null object: Invalid argument +finished test diff --git a/db/test/scr016/TestConstruct01.java b/db/test/scr016/TestConstruct01.java new file mode 100644 index 000000000..e4d97f1d9 --- /dev/null +++ b/db/test/scr016/TestConstruct01.java @@ -0,0 +1,474 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestConstruct01.java,v 1.4 2001/10/05 02:36:08 bostic Exp + */ + +/* + * Do some regression tests for constructors. + * Run normally (without arguments) it is a simple regression test. + * Run with a numeric argument, it repeats the regression a number + * of times, to try to determine if there are memory leaks. + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +public class TestConstruct01 +{ + public static final String CONSTRUCT01_DBNAME = "construct01.db"; + public static final String CONSTRUCT01_DBDIR = "/tmp"; + public static final String CONSTRUCT01_DBFULLPATH = + CONSTRUCT01_DBDIR + "/" + CONSTRUCT01_DBNAME; + + private int itemcount; // count the number of items in the database + public static boolean verbose_flag = false; + + public static void ERR(String a) + { + System.out.println("FAIL: " + a); + System.err.println("FAIL: " + a); + sysexit(1); + } + + public static void DEBUGOUT(String s) + { + System.out.println(s); + } + + public static void VERBOSEOUT(String s) + { + if (verbose_flag) + System.out.println(s); + } + + public static void sysexit(int code) + { + System.exit(code); + } + + private static void check_file_removed(String name, boolean fatal, + boolean force_remove_first) + { + File f = new File(name); + if (force_remove_first) { + f.delete(); + } + if (f.exists()) { + if (fatal) + System.out.print("FAIL: "); + System.out.print("File \"" + name + "\" still exists after run\n"); + if (fatal) + sysexit(1); + } + } + + + // Check that key/data for 0 - count-1 are already present, + // and write a key/data for count. The key and data are + // both "0123...N" where N == count-1. + // + // For some reason on Windows, we need to open using the full pathname + // of the file when there is no environment, thus the 'has_env' + // variable. + // + void rundb(Db db, int count, boolean has_env, TestOptions options) + throws DbException, FileNotFoundException + { + String name; + + if (has_env) + name = CONSTRUCT01_DBNAME; + else + name = CONSTRUCT01_DBFULLPATH; + + db.set_error_stream(System.err); + + // We don't really care about the pagesize, but we do want + // to make sure adjusting Db specific variables works before + // opening the db. + // + db.set_pagesize(1024); + db.open(name, null, Db.DB_BTREE, + (count != 0) ? 0 : Db.DB_CREATE, 0664); + + + // The bit map of keys we've seen + long bitmap = 0; + + // The bit map of keys we expect to see + long expected = (1 << (count+1)) - 1; + + byte outbuf[] = new byte[count+1]; + int i; + for (i=0; i<count; i++) { + outbuf[i] = (byte)('0' + i); + //outbuf[i] = System.out.println((byte)('0' + i); + } + outbuf[i++] = (byte)'x'; + + /* + System.out.println("byte: " + ('0' + 0) + ", after: " + + (int)'0' + "=" + (int)('0' + 0) + + "," + (byte)outbuf[0]); + */ + + Dbt key = new Dbt(outbuf, 0, i); + Dbt data = new Dbt(outbuf, 0, i); + + //DEBUGOUT("Put: " + (char)outbuf[0] + ": " + new String(outbuf)); + db.put(null, key, data, Db.DB_NOOVERWRITE); + + // Acquire a cursor for the table. + Dbc dbcp = db.cursor(null, 0); + + // Walk through the table, checking + Dbt readkey = new Dbt(); + Dbt readdata = new Dbt(); + Dbt whoknows = new Dbt(); + + readkey.set_flags(options.dbt_alloc_flags); + readdata.set_flags(options.dbt_alloc_flags); + + //DEBUGOUT("Dbc.get"); + while (dbcp.get(readkey, readdata, Db.DB_NEXT) == 0) { + String key_string = new String(readkey.get_data()); + String data_string = new String(readdata.get_data()); + //DEBUGOUT("Got: " + key_string + ": " + data_string); + int len = key_string.length(); + if (len <= 0 || key_string.charAt(len-1) != 'x') { + ERR("reread terminator is bad"); + } + len--; + long bit = (1 << len); + if (len > count) { + ERR("reread length is bad: expect " + count + " got "+ len + " (" + key_string + ")" ); + } + else if (!data_string.equals(key_string)) { + ERR("key/data don't match"); + } + else if ((bitmap & bit) != 0) { + ERR("key already seen"); + } + else if ((expected & bit) == 0) { + ERR("key was not expected"); + } + else { + bitmap |= bit; + expected &= ~(bit); + for (i=0; i<len; i++) { + if (key_string.charAt(i) != ('0' + i)) { + System.out.print(" got " + key_string + + " (" + (int)key_string.charAt(i) + + "), wanted " + i + + " (" + (int)('0' + i) + + ") at position " + i + "\n"); + ERR("key is corrupt"); + } + } + } + } + if (expected != 0) { + System.out.print(" expected more keys, bitmap is: " + expected + "\n"); + ERR("missing keys in database"); + } + dbcp.close(); + db.close(0); + } + + void t1(TestOptions options) + throws DbException, FileNotFoundException + { + Db db = new Db(null, 0); + rundb(db, itemcount++, false, options); + } + + void t2(TestOptions options) + throws DbException, FileNotFoundException + { + Db db = new Db(null, 0); + rundb(db, itemcount++, false, options); + // rundb(db, itemcount++, false, options); + // rundb(db, itemcount++, false, options); + } + + void t3(TestOptions options) + throws DbException, FileNotFoundException + { + Db db = new Db(null, 0); + // rundb(db, itemcount++, false, options); + db.set_errpfx("test3"); + for (int i=0; i<100; i++) + db.set_errpfx("str" + i); + rundb(db, itemcount++, false, options); + } + + void t4(TestOptions options) + throws DbException, FileNotFoundException + { + DbEnv env = new DbEnv(0); + env.open(CONSTRUCT01_DBDIR, Db.DB_CREATE | Db.DB_INIT_MPOOL, 0); + Db db = new Db(env, 0); + /**/ + //rundb(db, itemcount++, true, options); + db.set_errpfx("test4"); + rundb(db, itemcount++, true, options); + /**/ + env.close(0); + } + + void t5(TestOptions options) + throws DbException, FileNotFoundException + { + DbEnv env = new DbEnv(0); + env.open(CONSTRUCT01_DBDIR, Db.DB_CREATE | Db.DB_INIT_MPOOL, 0); + Db db = new Db(env, 0); + // rundb(db, itemcount++, true, options); + db.set_errpfx("test5"); + rundb(db, itemcount++, true, options); + /* + env.close(0); + + // reopen the environment, don't recreate + env.open(CONSTRUCT01_DBDIR, Db.DB_INIT_MPOOL, 0); + // Note we cannot reuse the old Db! + */ + Db anotherdb = new Db(env, 0); + + // rundb(anotherdb, itemcount++, true, options); + anotherdb.set_errpfx("test5"); + rundb(anotherdb, itemcount++, true, options); + env.close(0); + } + + void t6(TestOptions options) + throws DbException, FileNotFoundException + { + Db db = new Db(null, 0); + DbEnv dbenv = new DbEnv(0); + db.close(0); + dbenv.close(0); + + System.gc(); + System.runFinalization(); + } + + // By design, t7 leaves a db and dbenv open; it should be detected. + void t7(TestOptions options) + throws DbException, FileNotFoundException + { + Db db = new Db(null, 0); + DbEnv dbenv = new DbEnv(0); + + System.gc(); + System.runFinalization(); + } + + // remove any existing environment or database + void removeall(boolean use_db) + { + { + if (use_db) { + try { + /**/ + //memory leak for this: + Db tmpdb = new Db(null, 0); + tmpdb.remove(CONSTRUCT01_DBFULLPATH, null, 0); + /**/ + DbEnv tmpenv = new DbEnv(0); + tmpenv.remove(CONSTRUCT01_DBDIR, Db.DB_FORCE); + } + catch (DbException dbe) { + System.err.println("error during remove: " + dbe); + } + catch (FileNotFoundException fnfe) { + //expected error: + // System.err.println("error during remove: " + fnfe); + } + } + } + check_file_removed(CONSTRUCT01_DBFULLPATH, true, !use_db); + for (int i=0; i<8; i++) { + String fname = "__db.00" + i; + check_file_removed(fname, true, !use_db); + } + } + + boolean doall(TestOptions options) + { + itemcount = 0; + try { + removeall((options.testmask & 1) != 0); + for (int item=1; item<32; item++) { + if ((options.testmask & (1 << item)) != 0) { + VERBOSEOUT(" Running test " + item + ":"); + switch (item) { + case 1: + t1(options); + break; + case 2: + t2(options); + break; + case 3: + t3(options); + break; + case 4: + t4(options); + break; + case 5: + t5(options); + break; + case 6: + t6(options); + break; + case 7: + t7(options); + break; + default: + ERR("unknown test case: " + item); + break; + } + VERBOSEOUT(" finished.\n"); + } + } + removeall((options.testmask & 1) != 0); + options.successcounter++; + return true; + } + catch (DbException dbe) { + ERR("EXCEPTION RECEIVED: " + dbe); + } + catch (FileNotFoundException fnfe) { + ERR("EXCEPTION RECEIVED: " + fnfe); + } + return false; + } + + public static void main(String args[]) + { + int iterations = 200; + int mask = 0x7f; + + // Make sure the database file is removed before we start. + check_file_removed(CONSTRUCT01_DBFULLPATH, true, true); + + for (int argcnt=0; argcnt<args.length; argcnt++) { + String arg = args[argcnt]; + if (arg.charAt(0) == '-') { + // keep on lower bit, which means to remove db between tests. + mask = 1; + for (int pos=1; pos<arg.length(); pos++) { + char ch = arg.charAt(pos); + if (ch >= '0' && ch <= '9') { + mask |= (1 << (ch - '0')); + } + else if (ch == 'v') { + verbose_flag = true; + } + else { + ERR("Usage: construct01 [-testdigits] count"); + } + } + VERBOSEOUT("mask = " + mask); + + } + else { + try { + iterations = Integer.parseInt(arg); + if (iterations < 0) { + ERR("Usage: construct01 [-testdigits] count"); + } + } + catch (NumberFormatException nfe) { + ERR("EXCEPTION RECEIVED: " + nfe); + } + } + } + + // Run GC before and after the test to give + // a baseline for any Java memory used. + // + System.gc(); + System.runFinalization(); + VERBOSEOUT("gc complete"); + long starttotal = Runtime.getRuntime().totalMemory(); + long startfree = Runtime.getRuntime().freeMemory(); + + TestConstruct01 con = new TestConstruct01(); + int[] dbt_flags = { 0, Db.DB_DBT_MALLOC, Db.DB_DBT_REALLOC }; + String[] dbt_flags_name = { "default", "malloc", "realloc" }; + + TestOptions options = new TestOptions(); + options.testmask = mask; + + for (int flagiter = 0; flagiter < dbt_flags.length; flagiter++) { + options.dbt_alloc_flags = dbt_flags[flagiter]; + + VERBOSEOUT("Running with DBT alloc flags: " + + dbt_flags_name[flagiter]); + for (int i=0; i<iterations; i++) { + if (iterations != 0) { + VERBOSEOUT("(" + i + "/" + iterations + ") "); + } + VERBOSEOUT("construct01 running:"); + if (!con.doall(options)) { + ERR("SOME TEST FAILED"); + } + else { + VERBOSEOUT("\nTESTS SUCCESSFUL"); + } + + // We continually run GC during the test to keep + // the Java memory usage low. That way we can + // monitor the total memory usage externally + // (e.g. via ps) and verify that we aren't leaking + // memory in the JNI or DB layer. + // + System.gc(); + System.runFinalization(); + VERBOSEOUT("gc complete"); + } + } + + if (options.successcounter == 600) { + System.out.println("ALL TESTS SUCCESSFUL"); + } + else { + System.out.println("***FAIL: " + (600 - options.successcounter) + + " tests did not complete"); + } + long endtotal = Runtime.getRuntime().totalMemory(); + long endfree = Runtime.getRuntime().freeMemory(); + + System.out.println("delta for total mem: " + magnitude(endtotal - starttotal)); + System.out.println("delta for free mem: " + magnitude(endfree - startfree)); + + return; + } + + static String magnitude(long value) + { + final long max = 10000000; + for (long scale = 10; scale <= max; scale *= 10) { + if (value < scale && value > -scale) + return "<" + scale; + } + return ">" + max; + } + +} + +class TestOptions +{ + int testmask = 0; // which tests to run + int dbt_alloc_flags = 0; // DB_DBT_* flags to use + int successcounter =0; +} + diff --git a/db/test/scr016/TestConstruct01.testerr b/db/test/scr016/TestConstruct01.testerr new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/db/test/scr016/TestConstruct01.testerr diff --git a/db/test/scr016/TestConstruct01.testout b/db/test/scr016/TestConstruct01.testout new file mode 100644 index 000000000..5d2041cd1 --- /dev/null +++ b/db/test/scr016/TestConstruct01.testout @@ -0,0 +1,3 @@ +ALL TESTS SUCCESSFUL +delta for total mem: <10 +delta for free mem: <10000 diff --git a/db/test/scr016/TestConstruct02.java b/db/test/scr016/TestConstruct02.java new file mode 100644 index 000000000..d4442ce73 --- /dev/null +++ b/db/test/scr016/TestConstruct02.java @@ -0,0 +1,367 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestConstruct02.java,v 1.3 2001/10/05 02:36:09 bostic Exp + */ + +/* + * Do some regression tests for constructors. + * Run normally (without arguments) it is a simple regression test. + * Run with a numeric argument, it repeats the regression a number + * of times, to try to determine if there are memory leaks. + */ + +package com.sleepycat.test; +import com.sleepycat.db.*; +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +public class TestConstruct02 +{ + public static final String CONSTRUCT02_DBNAME = "construct02.db"; + public static final String CONSTRUCT02_DBDIR = "./"; + public static final String CONSTRUCT02_DBFULLPATH = + CONSTRUCT02_DBDIR + "/" + CONSTRUCT02_DBNAME; + + private int itemcount; // count the number of items in the database + public static boolean verbose_flag = false; + + private DbEnv dbenv = new DbEnv(0); + + public TestConstruct02() + throws DbException, FileNotFoundException + { + dbenv.open(CONSTRUCT02_DBDIR, Db.DB_CREATE | Db.DB_INIT_MPOOL, 0666); + } + + public void close() + { + try { + dbenv.close(0); + removeall(true, true); + } + catch (DbException dbe) { + ERR("DbException: " + dbe); + } + } + + public static void ERR(String a) + { + System.out.println("FAIL: " + a); + sysexit(1); + } + + public static void DEBUGOUT(String s) + { + System.out.println(s); + } + + public static void VERBOSEOUT(String s) + { + if (verbose_flag) + System.out.println(s); + } + + public static void sysexit(int code) + { + System.exit(code); + } + + private static void check_file_removed(String name, boolean fatal, + boolean force_remove_first) + { + File f = new File(name); + if (force_remove_first) { + f.delete(); + } + if (f.exists()) { + if (fatal) + System.out.print("FAIL: "); + System.out.print("File \"" + name + "\" still exists after run\n"); + if (fatal) + sysexit(1); + } + } + + + // Check that key/data for 0 - count-1 are already present, + // and write a key/data for count. The key and data are + // both "0123...N" where N == count-1. + // + void rundb(Db db, int count) + throws DbException, FileNotFoundException + { + + // The bit map of keys we've seen + long bitmap = 0; + + // The bit map of keys we expect to see + long expected = (1 << (count+1)) - 1; + + byte outbuf[] = new byte[count+1]; + int i; + for (i=0; i<count; i++) { + outbuf[i] = (byte)('0' + i); + //outbuf[i] = System.out.println((byte)('0' + i); + } + outbuf[i++] = (byte)'x'; + + /* + System.out.println("byte: " + ('0' + 0) + ", after: " + + (int)'0' + "=" + (int)('0' + 0) + + "," + (byte)outbuf[0]); + */ + + Dbt key = new Dbt(outbuf, 0, i); + Dbt data = new Dbt(outbuf, 0, i); + + //DEBUGOUT("Put: " + (char)outbuf[0] + ": " + new String(outbuf)); + db.put(null, key, data, Db.DB_NOOVERWRITE); + + // Acquire a cursor for the table. + Dbc dbcp = db.cursor(null, 0); + + // Walk through the table, checking + Dbt readkey = new Dbt(); + Dbt readdata = new Dbt(); + Dbt whoknows = new Dbt(); + + readkey.set_flags(Db.DB_DBT_MALLOC); + readdata.set_flags(Db.DB_DBT_MALLOC); + + //DEBUGOUT("Dbc.get"); + while (dbcp.get(readkey, readdata, Db.DB_NEXT) == 0) { + String key_string = new String(readkey.get_data()); + String data_string = new String(readdata.get_data()); + + //DEBUGOUT("Got: " + key_string + ": " + data_string); + int len = key_string.length(); + if (len <= 0 || key_string.charAt(len-1) != 'x') { + ERR("reread terminator is bad"); + } + len--; + long bit = (1 << len); + if (len > count) { + ERR("reread length is bad: expect " + count + " got "+ len + " (" + key_string + ")" ); + } + else if (!data_string.equals(key_string)) { + ERR("key/data don't match"); + } + else if ((bitmap & bit) != 0) { + ERR("key already seen"); + } + else if ((expected & bit) == 0) { + ERR("key was not expected"); + } + else { + bitmap |= bit; + expected &= ~(bit); + for (i=0; i<len; i++) { + if (key_string.charAt(i) != ('0' + i)) { + System.out.print(" got " + key_string + + " (" + (int)key_string.charAt(i) + + "), wanted " + i + + " (" + (int)('0' + i) + + ") at position " + i + "\n"); + ERR("key is corrupt"); + } + } + } + } + if (expected != 0) { + System.out.print(" expected more keys, bitmap is: " + expected + "\n"); + ERR("missing keys in database"); + } + dbcp.close(); + } + + void t1() + throws DbException, FileNotFoundException + { + Db db = new Db(dbenv, 0); + db.set_error_stream(System.err); + db.set_pagesize(1024); + db.open(CONSTRUCT02_DBNAME, null, Db.DB_BTREE, + Db.DB_CREATE, 0664); + + rundb(db, itemcount++); + rundb(db, itemcount++); + rundb(db, itemcount++); + rundb(db, itemcount++); + rundb(db, itemcount++); + rundb(db, itemcount++); + db.close(0); + + // Reopen no longer allowed, so we create a new db. + db = new Db(dbenv, 0); + db.set_error_stream(System.err); + db.set_pagesize(1024); + db.open(CONSTRUCT02_DBNAME, null, Db.DB_BTREE, + Db.DB_CREATE, 0664); + rundb(db, itemcount++); + rundb(db, itemcount++); + rundb(db, itemcount++); + rundb(db, itemcount++); + db.close(0); + } + + // remove any existing environment or database + void removeall(boolean use_db, boolean remove_env) + { + { + try { + if (remove_env) { + DbEnv tmpenv = new DbEnv(0); + tmpenv.remove(CONSTRUCT02_DBDIR, Db.DB_FORCE); + } + else if (use_db) { + /**/ + //memory leak for this: + Db tmpdb = new Db(null, 0); + tmpdb.remove(CONSTRUCT02_DBFULLPATH, null, 0); + /**/ + } + } + catch (DbException dbe) { + System.err.println("error during remove: " + dbe); + } + catch (FileNotFoundException dbe) { + System.err.println("error during remove: " + dbe); + } + } + check_file_removed(CONSTRUCT02_DBFULLPATH, true, !use_db); + if (remove_env) { + for (int i=0; i<8; i++) { + String fname = "__db.00" + i; + check_file_removed(fname, true, !use_db); + } + } + } + + boolean doall(int mask) + { + itemcount = 0; + try { + for (int item=1; item<32; item++) { + if ((mask & (1 << item)) != 0) { + VERBOSEOUT(" Running test " + item + ":\n"); + switch (item) { + case 1: + t1(); + break; + default: + ERR("unknown test case: " + item); + break; + } + VERBOSEOUT(" finished.\n"); + } + } + removeall((mask & 1) != 0, false); + return true; + } + catch (DbException dbe) { + ERR("EXCEPTION RECEIVED: " + dbe); + } + catch (FileNotFoundException fnfe) { + ERR("EXCEPTION RECEIVED: " + fnfe); + } + return false; + } + + public static void main(String args[]) + { + int iterations = 200; + int mask = 0x3; + + for (int argcnt=0; argcnt<args.length; argcnt++) { + String arg = args[argcnt]; + if (arg.charAt(0) == '-') { + // keep on lower bit, which means to remove db between tests. + mask = 1; + for (int pos=1; pos<arg.length(); pos++) { + char ch = arg.charAt(pos); + if (ch >= '0' && ch <= '9') { + mask |= (1 << (ch - '0')); + } + else if (ch == 'v') { + verbose_flag = true; + } + else { + ERR("Usage: construct02 [-testdigits] count"); + } + } + System.out.println("mask = " + mask); + + } + else { + try { + iterations = Integer.parseInt(arg); + if (iterations < 0) { + ERR("Usage: construct02 [-testdigits] count"); + } + } + catch (NumberFormatException nfe) { + ERR("EXCEPTION RECEIVED: " + nfe); + } + } + } + + System.gc(); + System.runFinalization(); + VERBOSEOUT("gc complete"); + long starttotal = Runtime.getRuntime().totalMemory(); + long startfree = Runtime.getRuntime().freeMemory(); + TestConstruct02 con = null; + + try { + con = new TestConstruct02(); + } + catch (DbException dbe) { + System.err.println("Exception: " + dbe); + System.exit(1); + } + catch (java.io.FileNotFoundException fnfe) { + System.err.println("Exception: " + fnfe); + System.exit(1); + } + + for (int i=0; i<iterations; i++) { + if (iterations != 0) { + VERBOSEOUT("(" + i + "/" + iterations + ") "); + } + VERBOSEOUT("construct02 running:\n"); + if (!con.doall(mask)) { + ERR("SOME TEST FAILED"); + } + System.gc(); + System.runFinalization(); + VERBOSEOUT("gc complete"); + + } + con.close(); + + System.out.print("ALL TESTS SUCCESSFUL\n"); + + long endtotal = Runtime.getRuntime().totalMemory(); + long endfree = Runtime.getRuntime().freeMemory(); + + System.out.println("delta for total mem: " + magnitude(endtotal - starttotal)); + System.out.println("delta for free mem: " + magnitude(endfree - startfree)); + + return; + } + + static String magnitude(long value) + { + final long max = 10000000; + for (long scale = 10; scale <= max; scale *= 10) { + if (value < scale && value > -scale) + return "<" + scale; + } + return ">" + max; + } +} diff --git a/db/test/scr016/TestConstruct02.testout b/db/test/scr016/TestConstruct02.testout new file mode 100644 index 000000000..5d2041cd1 --- /dev/null +++ b/db/test/scr016/TestConstruct02.testout @@ -0,0 +1,3 @@ +ALL TESTS SUCCESSFUL +delta for total mem: <10 +delta for free mem: <10000 diff --git a/db/test/scr016/TestDbtFlags.java b/db/test/scr016/TestDbtFlags.java new file mode 100644 index 000000000..f72290a5e --- /dev/null +++ b/db/test/scr016/TestDbtFlags.java @@ -0,0 +1,237 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2001 + * Sleepycat Software. All rights reserved. + * + * Id: TestDbtFlags.java,v 1.2 2001/10/05 02:36:09 bostic Exp + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.PrintStream; + +public class TestDbtFlags +{ + private static final String FileName = "access.db"; + private int flag_value; + private int buf_size; + private int cur_input_line = 0; + + /*zippy quotes for test input*/ + static final String[] input_lines = { + "I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS", + "I pretend I'm living in a styrofoam packing crate, high in th'" + + "SWISS ALPS, still unable to accept th' idea of TOUCH-TONE DIALING!!", + "FUN is never having to say you're SUSHI!!", + "Hold the MAYO & pass the COSMIC AWARENESS...", + "What GOOD is a CARDBOARD suitcase ANYWAY?", + "My nose feels like a bad Ronald Reagan movie...", + "The LOGARITHM of an ISOCELES TRIANGLE is TUESDAY WELD!!", + }; + + public TestDbtFlags(int flag_value, int buf_size) + { + this.flag_value = flag_value; + this.buf_size = buf_size; + } + + public static void runWithFlags(int flag_value, int size) + { + String msg = "=-=-=-= Test with DBT flags " + flag_value + + " bufsize " + size; + System.out.println(msg); + System.err.println(msg); + + try + { + TestDbtFlags app = new TestDbtFlags(flag_value, size); + app.run(); + } + catch (DbException dbe) + { + System.err.println("TestDbtFlags: " + dbe.toString()); + System.exit(1); + } + catch (FileNotFoundException fnfe) + { + System.err.println("TestDbtFlags: " + fnfe.toString()); + System.exit(1); + } + } + + public static void main(String argv[]) + { + runWithFlags(Db.DB_DBT_MALLOC, -1); + runWithFlags(Db.DB_DBT_REALLOC, -1); + runWithFlags(Db.DB_DBT_USERMEM, 20); + runWithFlags(Db.DB_DBT_USERMEM, 50); + runWithFlags(Db.DB_DBT_USERMEM, 200); + runWithFlags(0, -1); + + System.exit(0); + } + + String get_input_line() + { + if (cur_input_line >= input_lines.length) + return null; + return input_lines[cur_input_line++]; + } + + public void run() + throws DbException, FileNotFoundException + { + // Remove the previous database. + new File(FileName).delete(); + + // Create the database object. + // There is no environment for this simple example. + Db table = new Db(null, 0); + table.set_error_stream(System.err); + table.set_errpfx("TestDbtFlags"); + table.open(FileName, null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // + // Insert records into the database, where the key is the user + // input and the data is the user input in reverse order. + // + for (;;) { + //System.err.println("input line " + cur_input_line); + String line = get_input_line(); + if (line == null) + break; + + String reversed = (new StringBuffer(line)).reverse().toString(); + + // See definition of StringDbt below + // + StringDbt key = new StringDbt(line, flag_value); + StringDbt data = new StringDbt(reversed, flag_value); + + try + { + int err; + if ((err = table.put(null, + key, data, Db.DB_NOOVERWRITE)) == Db.DB_KEYEXIST) { + System.out.println("Key " + line + " already exists."); + } + key.check_flags(); + data.check_flags(); + } + catch (DbException dbe) + { + System.out.println(dbe.toString()); + } + } + + // Acquire an iterator for the table. + Dbc iterator; + iterator = table.cursor(null, 0); + + // Walk through the table, printing the key/data pairs. + // See class StringDbt defined below. + // + StringDbt key = new StringDbt(flag_value, buf_size); + StringDbt data = new StringDbt(flag_value, buf_size); + + int iteration_count = 0; + int dbreturn = 0; + + while (dbreturn == 0) { + //System.err.println("iteration " + iteration_count); + try { + if ((dbreturn = iterator.get(key, data, Db.DB_NEXT)) == 0) { + System.out.println(key.get_string() + " : " + data.get_string()); + } + } + catch (DbMemoryException dme) { + /* In a real application, we'd normally increase + * the size of the buffer. Since we've created + * this error condition for testing, we'll just report it. + * We still need to skip over this record, and we don't + * want to mess with our original Dbt's, since we want + * to see more errors. So create some temporary + * mallocing Dbts to get this record. + */ + System.err.println("exception, iteration " + iteration_count + + ": " + dme); + System.err.println(" key size: " + key.get_size() + + " ulen: " + key.get_ulen()); + System.err.println(" data size: " + key.get_size() + + " ulen: " + key.get_ulen()); + + dme.get_dbt().set_size(buf_size); + StringDbt tempkey = new StringDbt(Db.DB_DBT_MALLOC, -1); + StringDbt tempdata = new StringDbt(Db.DB_DBT_MALLOC, -1); + if ((dbreturn = iterator.get(tempkey, tempdata, Db.DB_NEXT)) != 0) { + System.err.println("cannot get expected next record"); + return; + } + System.out.println(tempkey.get_string() + " : " + + tempdata.get_string()); + } + iteration_count++; + } + key.check_flags(); + data.check_flags(); + + iterator.close(); + table.close(0); + } + + // Here's an example of how you can extend a Dbt in a straightforward + // way to allow easy storage/retrieval of strings, or whatever + // kind of data you wish. We've declared it as a static inner + // class, but it need not be. + // + static /*inner*/ + class StringDbt extends Dbt + { + int saved_flags; + + StringDbt(int flags, int buf_size) + { + this.saved_flags = flags; + set_flags(saved_flags); + if (buf_size != -1) { + set_data(new byte[buf_size]); + set_ulen(buf_size); + } + } + + StringDbt(String value, int flags) + { + this.saved_flags = flags; + set_flags(saved_flags); + set_string(value); + } + + void set_string(String value) + { + set_data(value.getBytes()); + set_size(value.length()); + check_flags(); + } + + String get_string() + { + check_flags(); + return new String(get_data(), 0, get_size()); + } + + void check_flags() + { + int actual_flags = get_flags(); + if (actual_flags != saved_flags) { + System.err.println("flags botch: expected " + saved_flags + + ", got " + actual_flags); + } + } + } +} diff --git a/db/test/scr016/TestDbtFlags.testerr b/db/test/scr016/TestDbtFlags.testerr new file mode 100644 index 000000000..1f8cb2a55 --- /dev/null +++ b/db/test/scr016/TestDbtFlags.testerr @@ -0,0 +1,36 @@ +=-=-=-= Test with DBT flags 4 bufsize -1 +=-=-=-= Test with DBT flags 16 bufsize -1 +=-=-=-= Test with DBT flags 32 bufsize 20 +exception, iteration 0: Dbt not large enough for available data + key size: 41 ulen: 20 + data size: 41 ulen: 20 +exception, iteration 1: Dbt not large enough for available data + key size: 44 ulen: 20 + data size: 44 ulen: 20 +exception, iteration 2: Dbt not large enough for available data + key size: 129 ulen: 20 + data size: 129 ulen: 20 +exception, iteration 3: Dbt not large enough for available data + key size: 63 ulen: 20 + data size: 63 ulen: 20 +exception, iteration 4: Dbt not large enough for available data + key size: 47 ulen: 20 + data size: 47 ulen: 20 +exception, iteration 5: Dbt not large enough for available data + key size: 55 ulen: 20 + data size: 55 ulen: 20 +exception, iteration 6: Dbt not large enough for available data + key size: 41 ulen: 20 + data size: 41 ulen: 20 +=-=-=-= Test with DBT flags 32 bufsize 50 +exception, iteration 2: Dbt not large enough for available data + key size: 129 ulen: 50 + data size: 129 ulen: 50 +exception, iteration 3: Dbt not large enough for available data + key size: 63 ulen: 50 + data size: 63 ulen: 50 +exception, iteration 5: Dbt not large enough for available data + key size: 55 ulen: 50 + data size: 55 ulen: 50 +=-=-=-= Test with DBT flags 32 bufsize 200 +=-=-=-= Test with DBT flags 0 bufsize -1 diff --git a/db/test/scr016/TestDbtFlags.testout b/db/test/scr016/TestDbtFlags.testout new file mode 100644 index 000000000..800eebe86 --- /dev/null +++ b/db/test/scr016/TestDbtFlags.testout @@ -0,0 +1,48 @@ +=-=-=-= Test with DBT flags 4 bufsize -1 +FUN is never having to say you're SUSHI!! : !!IHSUS er'uoy yas ot gnivah reven si NUF +Hold the MAYO & pass the COSMIC AWARENESS... : ...SSENERAWA CIMSOC eht ssap & OYAM eht dloH +I pretend I'm living in a styrofoam packing crate, high in th'SWISS ALPS, still unable to accept th' idea of TOUCH-TONE DIALING!! : !!GNILAID ENOT-HCUOT fo aedi 'ht tpecca ot elbanu llits ,SPLA SSIWS'ht ni hgih ,etarc gnikcap maoforyts a ni gnivil m'I dneterp I +I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS : SGURD yna ekat t'nod I dna ..ECNEIREPXE SUOIGILER a gnivah m'I +My nose feels like a bad Ronald Reagan movie... : ...eivom nagaeR dlanoR dab a ekil sleef eson yM +The LOGARITHM of an ISOCELES TRIANGLE is TUESDAY WELD!! : !!DLEW YADSEUT si ELGNAIRT SELECOSI na fo MHTIRAGOL ehT +What GOOD is a CARDBOARD suitcase ANYWAY? : ?YAWYNA esactius DRAOBDRAC a si DOOG tahW +=-=-=-= Test with DBT flags 16 bufsize -1 +FUN is never having to say you're SUSHI!! : !!IHSUS er'uoy yas ot gnivah reven si NUF +Hold the MAYO & pass the COSMIC AWARENESS... : ...SSENERAWA CIMSOC eht ssap & OYAM eht dloH +I pretend I'm living in a styrofoam packing crate, high in th'SWISS ALPS, still unable to accept th' idea of TOUCH-TONE DIALING!! : !!GNILAID ENOT-HCUOT fo aedi 'ht tpecca ot elbanu llits ,SPLA SSIWS'ht ni hgih ,etarc gnikcap maoforyts a ni gnivil m'I dneterp I +I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS : SGURD yna ekat t'nod I dna ..ECNEIREPXE SUOIGILER a gnivah m'I +My nose feels like a bad Ronald Reagan movie... : ...eivom nagaeR dlanoR dab a ekil sleef eson yM +The LOGARITHM of an ISOCELES TRIANGLE is TUESDAY WELD!! : !!DLEW YADSEUT si ELGNAIRT SELECOSI na fo MHTIRAGOL ehT +What GOOD is a CARDBOARD suitcase ANYWAY? : ?YAWYNA esactius DRAOBDRAC a si DOOG tahW +=-=-=-= Test with DBT flags 32 bufsize 20 +FUN is never having to say you're SUSHI!! : !!IHSUS er'uoy yas ot gnivah reven si NUF +Hold the MAYO & pass the COSMIC AWARENESS... : ...SSENERAWA CIMSOC eht ssap & OYAM eht dloH +I pretend I'm living in a styrofoam packing crate, high in th'SWISS ALPS, still unable to accept th' idea of TOUCH-TONE DIALING!! : !!GNILAID ENOT-HCUOT fo aedi 'ht tpecca ot elbanu llits ,SPLA SSIWS'ht ni hgih ,etarc gnikcap maoforyts a ni gnivil m'I dneterp I +I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS : SGURD yna ekat t'nod I dna ..ECNEIREPXE SUOIGILER a gnivah m'I +My nose feels like a bad Ronald Reagan movie... : ...eivom nagaeR dlanoR dab a ekil sleef eson yM +The LOGARITHM of an ISOCELES TRIANGLE is TUESDAY WELD!! : !!DLEW YADSEUT si ELGNAIRT SELECOSI na fo MHTIRAGOL ehT +What GOOD is a CARDBOARD suitcase ANYWAY? : ?YAWYNA esactius DRAOBDRAC a si DOOG tahW +=-=-=-= Test with DBT flags 32 bufsize 50 +FUN is never having to say you're SUSHI!! : !!IHSUS er'uoy yas ot gnivah reven si NUF +Hold the MAYO & pass the COSMIC AWARENESS... : ...SSENERAWA CIMSOC eht ssap & OYAM eht dloH +I pretend I'm living in a styrofoam packing crate, high in th'SWISS ALPS, still unable to accept th' idea of TOUCH-TONE DIALING!! : !!GNILAID ENOT-HCUOT fo aedi 'ht tpecca ot elbanu llits ,SPLA SSIWS'ht ni hgih ,etarc gnikcap maoforyts a ni gnivil m'I dneterp I +I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS : SGURD yna ekat t'nod I dna ..ECNEIREPXE SUOIGILER a gnivah m'I +My nose feels like a bad Ronald Reagan movie... : ...eivom nagaeR dlanoR dab a ekil sleef eson yM +The LOGARITHM of an ISOCELES TRIANGLE is TUESDAY WELD!! : !!DLEW YADSEUT si ELGNAIRT SELECOSI na fo MHTIRAGOL ehT +What GOOD is a CARDBOARD suitcase ANYWAY? : ?YAWYNA esactius DRAOBDRAC a si DOOG tahW +=-=-=-= Test with DBT flags 32 bufsize 200 +FUN is never having to say you're SUSHI!! : !!IHSUS er'uoy yas ot gnivah reven si NUF +Hold the MAYO & pass the COSMIC AWARENESS... : ...SSENERAWA CIMSOC eht ssap & OYAM eht dloH +I pretend I'm living in a styrofoam packing crate, high in th'SWISS ALPS, still unable to accept th' idea of TOUCH-TONE DIALING!! : !!GNILAID ENOT-HCUOT fo aedi 'ht tpecca ot elbanu llits ,SPLA SSIWS'ht ni hgih ,etarc gnikcap maoforyts a ni gnivil m'I dneterp I +I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS : SGURD yna ekat t'nod I dna ..ECNEIREPXE SUOIGILER a gnivah m'I +My nose feels like a bad Ronald Reagan movie... : ...eivom nagaeR dlanoR dab a ekil sleef eson yM +The LOGARITHM of an ISOCELES TRIANGLE is TUESDAY WELD!! : !!DLEW YADSEUT si ELGNAIRT SELECOSI na fo MHTIRAGOL ehT +What GOOD is a CARDBOARD suitcase ANYWAY? : ?YAWYNA esactius DRAOBDRAC a si DOOG tahW +=-=-=-= Test with DBT flags 0 bufsize -1 +FUN is never having to say you're SUSHI!! : !!IHSUS er'uoy yas ot gnivah reven si NUF +Hold the MAYO & pass the COSMIC AWARENESS... : ...SSENERAWA CIMSOC eht ssap & OYAM eht dloH +I pretend I'm living in a styrofoam packing crate, high in th'SWISS ALPS, still unable to accept th' idea of TOUCH-TONE DIALING!! : !!GNILAID ENOT-HCUOT fo aedi 'ht tpecca ot elbanu llits ,SPLA SSIWS'ht ni hgih ,etarc gnikcap maoforyts a ni gnivil m'I dneterp I +I'm having a RELIGIOUS EXPERIENCE.. and I don't take any DRUGS : SGURD yna ekat t'nod I dna ..ECNEIREPXE SUOIGILER a gnivah m'I +My nose feels like a bad Ronald Reagan movie... : ...eivom nagaeR dlanoR dab a ekil sleef eson yM +The LOGARITHM of an ISOCELES TRIANGLE is TUESDAY WELD!! : !!DLEW YADSEUT si ELGNAIRT SELECOSI na fo MHTIRAGOL ehT +What GOOD is a CARDBOARD suitcase ANYWAY? : ?YAWYNA esactius DRAOBDRAC a si DOOG tahW diff --git a/db/test/scr016/TestGetSetMethods.java b/db/test/scr016/TestGetSetMethods.java new file mode 100644 index 000000000..d940aa2f4 --- /dev/null +++ b/db/test/scr016/TestGetSetMethods.java @@ -0,0 +1,99 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestGetSetMethods.java,v 1.2 2001/10/05 02:36:09 bostic Exp + */ + +/* + * Do some regression tests for simple get/set access methods + * on DbEnv, DbTxn, Db. We don't currently test that they have + * the desired effect, only that they operate and return correctly. + */ +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.FileNotFoundException; + +public class TestGetSetMethods +{ + public void testMethods() + throws DbException, FileNotFoundException + { + DbEnv dbenv = new DbEnv(0); + DbTxn dbtxn; + byte[][] conflicts = new byte[10][10]; + + dbenv.set_timeout(0x90000000, + Db.DB_SET_LOCK_TIMEOUT); + dbenv.set_lg_bsize(0x1000); + dbenv.set_lg_dir("."); + dbenv.set_lg_max(0x10000000); + dbenv.set_lg_regionmax(0x100000); + dbenv.set_lk_conflicts(conflicts); + dbenv.set_lk_detect(Db.DB_LOCK_DEFAULT); + // exists, but is deprecated: + // dbenv.set_lk_max(0); + dbenv.set_lk_max_lockers(100); + dbenv.set_lk_max_locks(10); + dbenv.set_lk_max_objects(1000); + dbenv.set_mp_mmapsize(0x10000); + dbenv.set_tas_spins(1000); + + // Need to open the environment so we + // can get a transaction. + // + dbenv.open(".", Db.DB_CREATE | Db.DB_INIT_TXN | + Db.DB_INIT_LOCK | Db.DB_INIT_LOG | + Db.DB_INIT_MPOOL, + 0644); + + dbtxn = dbenv.txn_begin(null, Db.DB_TXN_NOWAIT); + dbtxn.set_timeout(0xA0000000, Db.DB_SET_TXN_TIMEOUT); + dbtxn.abort(); + + dbenv.close(0); + + // We get a db, one for each type. + // That's because once we call (for instance) + // set_bt_maxkey, DB 'knows' that this is a + // Btree Db, and it cannot be used to try Hash + // or Recno functions. + // + Db db_bt = new Db(null, 0); + db_bt.set_bt_maxkey(10000); + db_bt.set_bt_minkey(100); + db_bt.set_cachesize(0, 0x100000, 0); + db_bt.close(0); + + Db db_h = new Db(null, 0); + db_h.set_h_ffactor(0x10); + db_h.set_h_nelem(100); + db_h.set_lorder(0); + db_h.set_pagesize(0x10000); + db_h.close(0); + + Db db_re = new Db(null, 0); + db_re.set_re_delim('@'); + db_re.set_re_pad(10); + db_re.set_re_source("re.in"); + db_re.close(0); + + Db db_q = new Db(null, 0); + db_q.set_q_extentsize(200); + db_q.close(0); + } + + public static void main(String[] args) + { + try { + TestGetSetMethods tester = new TestGetSetMethods(); + tester.testMethods(); + } + catch (Exception e) { + System.err.println("TestGetSetMethods: Exception: " + e); + } + } +} diff --git a/db/test/scr016/TestKeyRange.java b/db/test/scr016/TestKeyRange.java new file mode 100644 index 000000000..0981233b7 --- /dev/null +++ b/db/test/scr016/TestKeyRange.java @@ -0,0 +1,203 @@ +/*NOTE: TestKeyRange is AccessExample changed to test Db.key_range. + * See comments with ADDED for specific areas of change. + */ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestKeyRange.java,v 1.2 2001/10/09 20:58:34 dda Exp + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.StringReader; +import java.io.Reader; +import java.io.IOException; +import java.io.PrintStream; + +public class TestKeyRange +{ + private static final String FileName = "access.db"; + + public TestKeyRange() + { + } + + private static void usage() + { + System.err.println("usage: TestKeyRange\n"); + System.exit(1); + } + + public static void main(String argv[]) + { + try + { + TestKeyRange app = new TestKeyRange(); + app.run(); + } + catch (DbException dbe) + { + System.err.println("TestKeyRange: " + dbe.toString()); + System.exit(1); + } + catch (FileNotFoundException fnfe) + { + System.err.println("TestKeyRange: " + fnfe.toString()); + System.exit(1); + } + System.exit(0); + } + + // Prompts for a line, and keeps prompting until a non blank + // line is returned. Returns null on error. + // + static public String askForLine(Reader reader, + PrintStream out, String prompt) + { + String result = ""; + while (result != null && result.length() == 0) { + out.print(prompt); + out.flush(); + result = getLine(reader); + } + return result; + } + + // Not terribly efficient, but does the job. + // Works for reading a line from stdin or a file. + // Returns null on EOF. If EOF appears in the middle + // of a line, returns that line, then null on next call. + // + static public String getLine(Reader reader) + { + StringBuffer b = new StringBuffer(); + int c; + try { + while ((c = reader.read()) != -1 && c != '\n') { + if (c != '\r') + b.append((char)c); + } + } + catch (IOException ioe) { + c = -1; + } + + if (c == -1 && b.length() == 0) + return null; + else + return b.toString(); + } + + public void run() + throws DbException, FileNotFoundException + { + // Remove the previous database. + new File(FileName).delete(); + + // Create the database object. + // There is no environment for this simple example. + Db table = new Db(null, 0); + table.set_error_stream(System.err); + table.set_errpfx("TestKeyRange"); + table.open(FileName, null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // + // Insert records into the database, where the key is the user + // input and the data is the user input in reverse order. + // + Reader reader = new StringReader("abc\nmiddle\nzend\nmoremiddle\nZED\nMAMAMIA"); + + int count= 0;/*ADDED*/ + for (;;) { + String line = askForLine(reader, System.out, "input>"); + if (line == null) + break; + + String reversed = (new StringBuffer(line)).reverse().toString(); + + // See definition of StringDbt below + // + StringDbt key = new StringDbt(line); + StringDbt data = new StringDbt(reversed); + + try + { + int err; + if ((err = table.put(null, key, data, 0)) == Db.DB_KEYEXIST) { + System.out.println("Key " + line + " already exists."); + } + } + catch (DbException dbe) + { + System.out.println(dbe.toString()); + } + System.out.println(""); + + /*START ADDED*/ + { + if (count++ > 0) { + DbKeyRange range = new DbKeyRange(); + table.key_range(null, key, range, 0); + System.out.println("less: " + range.less); + System.out.println("equal: " + range.equal); + System.out.println("greater: " + range.greater); + } + } + /*END ADDED*/ + + } + + // Acquire an iterator for the table. + Dbc iterator; + iterator = table.cursor(null, 0); + + // Walk through the table, printing the key/data pairs. + // See class StringDbt defined below. + // + StringDbt key = new StringDbt(); + StringDbt data = new StringDbt(); + while (iterator.get(key, data, Db.DB_NEXT) == 0) + { + System.out.println(key.getString() + " : " + data.getString()); + } + iterator.close(); + table.close(0); + } + + // Here's an example of how you can extend a Dbt in a straightforward + // way to allow easy storage/retrieval of strings, or whatever + // kind of data you wish. We've declared it as a static inner + // class, but it need not be. + // + static /*inner*/ + class StringDbt extends Dbt + { + StringDbt() + { + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + StringDbt(String value) + { + setString(value); + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + void setString(String value) + { + set_data(value.getBytes()); + set_size(value.length()); + } + + String getString() + { + return new String(get_data(), 0, get_size()); + } + } +} diff --git a/db/test/scr016/TestKeyRange.testout b/db/test/scr016/TestKeyRange.testout new file mode 100644 index 000000000..c265f3289 --- /dev/null +++ b/db/test/scr016/TestKeyRange.testout @@ -0,0 +1,27 @@ +input> +input> +less: 0.5 +equal: 0.5 +greater: 0.0 +input> +less: 0.6666666666666666 +equal: 0.3333333333333333 +greater: 0.0 +input> +less: 0.5 +equal: 0.25 +greater: 0.25 +input> +less: 0.0 +equal: 0.2 +greater: 0.8 +input> +less: 0.0 +equal: 0.16666666666666666 +greater: 0.8333333333333334 +input>MAMAMIA : AIMAMAM +ZED : DEZ +abc : cba +middle : elddim +moremiddle : elddimerom +zend : dnez diff --git a/db/test/scr016/TestLockVec.java b/db/test/scr016/TestLockVec.java new file mode 100644 index 000000000..6b72be7c5 --- /dev/null +++ b/db/test/scr016/TestLockVec.java @@ -0,0 +1,249 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestLockVec.java,v 1.2 2001/10/05 02:36:10 bostic Exp + */ + +/* + * test of DbEnv.lock_vec() + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.FileNotFoundException; + +public class TestLockVec +{ + public static int locker1; + public static int locker2; + + public static void gdb_pause() + { + try { + System.err.println("attach gdb and type return..."); + System.in.read(new byte[10]); + } + catch (java.io.IOException ie) { + } + } + + public static void main(String[] args) + { + try { + DbEnv dbenv1 = new DbEnv(0); + DbEnv dbenv2 = new DbEnv(0); + dbenv1.open(".", + Db.DB_CREATE | Db.DB_INIT_LOCK | Db.DB_INIT_MPOOL, 0); + dbenv2.open(".", + Db.DB_CREATE | Db.DB_INIT_LOCK | Db.DB_INIT_MPOOL, 0); + locker1 = dbenv1.lock_id(); + locker2 = dbenv1.lock_id(); + Db db1 = new Db(dbenv1, 0); + db1.open("my.db", null, Db.DB_BTREE, Db.DB_CREATE, 0); + Db db2 = new Db(dbenv2, 0); + db2.open("my.db", null, Db.DB_BTREE, 0, 0); + + // populate our database, just two elements. + Dbt Akey = new Dbt("A".getBytes()); + Dbt Adata = new Dbt("Adata".getBytes()); + Dbt Bkey = new Dbt("B".getBytes()); + Dbt Bdata = new Dbt("Bdata".getBytes()); + + // We don't allow Dbts to be reused within the + // same method call, so we need some duplicates. + Dbt Akeyagain = new Dbt("A".getBytes()); + Dbt Bkeyagain = new Dbt("B".getBytes()); + + db1.put(null, Akey, Adata, 0); + db1.put(null, Bkey, Bdata, 0); + + Dbt notInDatabase = new Dbt("C".getBytes()); + + /* make sure our check mechanisms work */ + int expectedErrs = 0; + + lock_check_free(dbenv2, Akey); + try { + lock_check_held(dbenv2, Bkey, Db.DB_LOCK_READ); + } + catch (DbException dbe1) { + expectedErrs += 1; + } + DbLock tmplock = dbenv1.lock_get(locker1, Db.DB_LOCK_NOWAIT, + Akey, Db.DB_LOCK_READ); + lock_check_held(dbenv2, Akey, Db.DB_LOCK_READ); + try { + lock_check_free(dbenv2, Akey); + } + catch (DbException dbe2) { + expectedErrs += 2; + } + if (expectedErrs != 1+2) { + System.err.println("lock check mechanism is broken"); + System.exit(1); + } + dbenv1.lock_put(tmplock); + + /* Now on with the test, a series of lock_vec requests, + * with checks between each call. + */ + + System.out.println("get a few"); + /* Request: get A(W), B(R), B(R) */ + DbLockRequest[] reqs = new DbLockRequest[3]; + + reqs[0] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_WRITE, + Akey, null); + reqs[1] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_READ, + Bkey, null); + reqs[2] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_READ, + Bkeyagain, null); + + dbenv1.lock_vec(locker1, Db.DB_LOCK_NOWAIT, reqs, 0, 3); + + /* Locks held: A(W), B(R), B(R) */ + lock_check_held(dbenv2, Bkey, Db.DB_LOCK_READ); + lock_check_held(dbenv2, Akey, Db.DB_LOCK_WRITE); + + System.out.println("put a couple"); + /* Request: put A, B(first) */ + reqs[0].set_op(Db.DB_LOCK_PUT); + reqs[1].set_op(Db.DB_LOCK_PUT); + + dbenv1.lock_vec(locker1, Db.DB_LOCK_NOWAIT, reqs, 0, 2); + + /* Locks held: B(R) */ + lock_check_free(dbenv2, Akey); + lock_check_held(dbenv2, Bkey, Db.DB_LOCK_READ); + + System.out.println("put one more, test index offset"); + /* Request: put B(second) */ + reqs[2].set_op(Db.DB_LOCK_PUT); + + dbenv1.lock_vec(locker1, Db.DB_LOCK_NOWAIT, reqs, 2, 1); + + /* Locks held: <none> */ + lock_check_free(dbenv2, Akey); + lock_check_free(dbenv2, Bkey); + + System.out.println("get a few"); + /* Request: get A(R), A(R), B(R) */ + reqs[0] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_READ, + Akey, null); + reqs[1] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_READ, + Akeyagain, null); + reqs[2] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_READ, + Bkey, null); + dbenv1.lock_vec(locker1, Db.DB_LOCK_NOWAIT, reqs, 0, 3); + + /* Locks held: A(R), B(R), B(R) */ + lock_check_held(dbenv2, Akey, Db.DB_LOCK_READ); + lock_check_held(dbenv2, Bkey, Db.DB_LOCK_READ); + + System.out.println("try putobj"); + /* Request: get B(R), putobj A */ + reqs[1] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_READ, + Bkey, null); + reqs[2] = new DbLockRequest(Db.DB_LOCK_PUT_OBJ, 0, + Akey, null); + dbenv1.lock_vec(locker1, Db.DB_LOCK_NOWAIT, reqs, 1, 2); + + /* Locks held: B(R), B(R) */ + lock_check_free(dbenv2, Akey); + lock_check_held(dbenv2, Bkey, Db.DB_LOCK_READ); + + System.out.println("get one more"); + /* Request: get A(W) */ + reqs[0] = new DbLockRequest(Db.DB_LOCK_GET, Db.DB_LOCK_WRITE, + Akey, null); + dbenv1.lock_vec(locker1, Db.DB_LOCK_NOWAIT, reqs, 0, 1); + + /* Locks held: A(W), B(R), B(R) */ + lock_check_held(dbenv2, Akey, Db.DB_LOCK_WRITE); + lock_check_held(dbenv2, Bkey, Db.DB_LOCK_READ); + + System.out.println("putall"); + /* Request: putall */ + reqs[0] = new DbLockRequest(Db.DB_LOCK_PUT_ALL, 0, + null, null); + dbenv1.lock_vec(locker1, Db.DB_LOCK_NOWAIT, reqs, 0, 1); + + lock_check_free(dbenv2, Akey); + lock_check_free(dbenv2, Bkey); + db1.close(0); + dbenv1.close(0); + db2.close(0); + dbenv2.close(0); + System.out.println("done"); + } + catch (DbLockNotGrantedException nge) { + System.err.println("Db Exception: " + nge); + } + catch (DbException dbe) { + System.err.println("Db Exception: " + dbe); + } + catch (FileNotFoundException fnfe) { + System.err.println("FileNotFoundException: " + fnfe); + } + + } + + /* Verify that the lock is free, throw an exception if not. + * We do this by trying to grab a write lock (no wait). + */ + static void lock_check_free(DbEnv dbenv, Dbt dbt) + throws DbException + { + DbLock tmplock = dbenv.lock_get(locker2, Db.DB_LOCK_NOWAIT, + dbt, Db.DB_LOCK_WRITE); + dbenv.lock_put(tmplock); + } + + /* Verify that the lock is held with the mode, throw an exception if not. + * If we have a write lock, we should not be able to get the lock + * for reading. If we have a read lock, we should be able to get + * it for reading, but not writing. + */ + static void lock_check_held(DbEnv dbenv, Dbt dbt, int mode) + throws DbException + { + DbLock never = null; + + try { + if (mode == Db.DB_LOCK_WRITE) { + never = dbenv.lock_get(locker2, Db.DB_LOCK_NOWAIT, + dbt, Db.DB_LOCK_READ); + } + else if (mode == Db.DB_LOCK_READ) { + DbLock rlock = dbenv.lock_get(locker2, Db.DB_LOCK_NOWAIT, + dbt, Db.DB_LOCK_READ); + dbenv.lock_put(rlock); + never = dbenv.lock_get(locker2, Db.DB_LOCK_NOWAIT, + dbt, Db.DB_LOCK_WRITE); + } + else { + throw new DbException("lock_check_held bad mode"); + } + } + catch (DbLockNotGrantedException nge) { + /* We expect this on our last lock_get call */ + } + + /* make sure we failed */ + if (never != null) { + try { + dbenv.lock_put(never); + } + catch (DbException dbe2) { + System.err.println("Got some real troubles now"); + System.exit(1); + } + throw new DbException("lock_check_held: lock was not held"); + } + } + +} diff --git a/db/test/scr016/TestLockVec.testout b/db/test/scr016/TestLockVec.testout new file mode 100644 index 000000000..1cf16c6ac --- /dev/null +++ b/db/test/scr016/TestLockVec.testout @@ -0,0 +1,8 @@ +get a few +put a couple +put one more, test index offset +get a few +try putobj +get one more +putall +done diff --git a/db/test/scr016/TestLogc.java b/db/test/scr016/TestLogc.java new file mode 100644 index 000000000..a484ee763 --- /dev/null +++ b/db/test/scr016/TestLogc.java @@ -0,0 +1,90 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestLogc.java,v 1.4 2001/10/12 13:02:33 dda Exp + */ + +/* + * A basic regression test for the Logc class. + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.FileNotFoundException; + +public class TestLogc +{ + public static void main(String[] args) + { + try { + DbEnv env = new DbEnv(0); + env.open(".", Db.DB_CREATE | Db.DB_INIT_LOG | Db.DB_INIT_MPOOL, 0); + + // Do some database activity to get something into the log. + Db db1 = new Db(env, 0); + db1.open("first.db", null, Db.DB_BTREE, Db.DB_CREATE, 0); + db1.put(null, new Dbt("a".getBytes()), new Dbt("b".getBytes()), 0); + db1.put(null, new Dbt("c".getBytes()), new Dbt("d".getBytes()), 0); + db1.close(0); + + Db db2 = new Db(env, 0); + db2.open("second.db", null, Db.DB_BTREE, Db.DB_CREATE, 0644); + db2.put(null, new Dbt("w".getBytes()), new Dbt("x".getBytes()), 0); + db2.put(null, new Dbt("y".getBytes()), new Dbt("z".getBytes()), 0); + db2.close(0); + + // Now get a log cursor and walk through. + DbLogc logc = env.log_cursor(0); + + int ret = 0; + DbLsn lsn = new DbLsn(); + Dbt dbt = new Dbt(); + int flags = Db.DB_FIRST; + + int count = 0; + while ((ret = logc.get(lsn, dbt, flags)) == 0) { + System.out.println("logc.get: " + count); + + // We ignore the contents of the log record, + // it's not portable. + // + // System.out.println(showDbt(dbt)); + // + count++; + flags = Db.DB_NEXT; + } + if (ret != Db.DB_NOTFOUND) { + System.err.println("*** Failed to get log record, returned: " + + DbEnv.strerror(ret)); + } + logc.close(0); + System.out.println("TestLogc done."); + } + catch (DbException dbe) { + System.err.println("Db Exception: " + dbe); + } + catch (FileNotFoundException fnfe) { + System.err.println("FileNotFoundException: " + fnfe); + } + + } + + public static String showDbt(Dbt dbt) + { + StringBuffer sb = new StringBuffer(); + int size = dbt.get_size(); + byte[] data = dbt.get_data(); + int i; + for (i=0; i<size && i<10; i++) { + sb.append(Byte.toString(data[i])); + sb.append(' '); + } + if (i<size) + sb.append("..."); + return "size: " + size + " data: " + sb.toString(); + } +} diff --git a/db/test/scr016/TestLogc.testout b/db/test/scr016/TestLogc.testout new file mode 100644 index 000000000..858947464 --- /dev/null +++ b/db/test/scr016/TestLogc.testout @@ -0,0 +1,18 @@ +logc.get: 0 +logc.get: 1 +logc.get: 2 +logc.get: 3 +logc.get: 4 +logc.get: 5 +logc.get: 6 +logc.get: 7 +logc.get: 8 +logc.get: 9 +logc.get: 10 +logc.get: 11 +logc.get: 12 +logc.get: 13 +logc.get: 14 +logc.get: 15 +logc.get: 16 +TestLogc done. diff --git a/db/test/scr016/TestOpenEmpty.java b/db/test/scr016/TestOpenEmpty.java new file mode 100644 index 000000000..d16d99305 --- /dev/null +++ b/db/test/scr016/TestOpenEmpty.java @@ -0,0 +1,189 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2001 + * Sleepycat Software. All rights reserved. + * + * Id: TestOpenEmpty.java,v 1.2 2001/10/05 02:36:10 bostic Exp + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.PrintStream; + +public class TestOpenEmpty +{ + private static final String FileName = "access.db"; + + public TestOpenEmpty() + { + } + + private static void usage() + { + System.err.println("usage: TestOpenEmpty\n"); + System.exit(1); + } + + public static void main(String argv[]) + { + try + { + TestOpenEmpty app = new TestOpenEmpty(); + app.run(); + } + catch (DbException dbe) + { + System.err.println("TestOpenEmpty: " + dbe.toString()); + System.exit(1); + } + catch (FileNotFoundException fnfe) + { + System.err.println("TestOpenEmpty: " + fnfe.toString()); + System.exit(1); + } + System.exit(0); + } + + // Prompts for a line, and keeps prompting until a non blank + // line is returned. Returns null on error. + // + static public String askForLine(InputStreamReader reader, + PrintStream out, String prompt) + { + String result = ""; + while (result != null && result.length() == 0) { + out.print(prompt); + out.flush(); + result = getLine(reader); + } + return result; + } + + // Not terribly efficient, but does the job. + // Works for reading a line from stdin or a file. + // Returns null on EOF. If EOF appears in the middle + // of a line, returns that line, then null on next call. + // + static public String getLine(InputStreamReader reader) + { + StringBuffer b = new StringBuffer(); + int c; + try { + while ((c = reader.read()) != -1 && c != '\n') { + if (c != '\r') + b.append((char)c); + } + } + catch (IOException ioe) { + c = -1; + } + + if (c == -1 && b.length() == 0) + return null; + else + return b.toString(); + } + + public void run() + throws DbException, FileNotFoundException + { + // Remove the previous database. + new File(FileName).delete(); + + try { (new java.io.FileOutputStream(FileName)).close(); } + catch (IOException ioe) { } + + // Create the database object. + // There is no environment for this simple example. + Db table = new Db(null, 0); + table.set_error_stream(System.err); + table.set_errpfx("TestOpenEmpty"); + table.open(FileName, null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // + // Insert records into the database, where the key is the user + // input and the data is the user input in reverse order. + // + InputStreamReader reader = new InputStreamReader(System.in); + + for (;;) { + String line = askForLine(reader, System.out, "input> "); + if (line == null) + break; + + String reversed = (new StringBuffer(line)).reverse().toString(); + + // See definition of StringDbt below + // + StringDbt key = new StringDbt(line); + StringDbt data = new StringDbt(reversed); + + try + { + int err; + if ((err = table.put(null, + key, data, Db.DB_NOOVERWRITE)) == Db.DB_KEYEXIST) { + System.out.println("Key " + line + " already exists."); + } + } + catch (DbException dbe) + { + System.out.println(dbe.toString()); + } + System.out.println(""); + } + + // Acquire an iterator for the table. + Dbc iterator; + iterator = table.cursor(null, 0); + + // Walk through the table, printing the key/data pairs. + // See class StringDbt defined below. + // + StringDbt key = new StringDbt(); + StringDbt data = new StringDbt(); + while (iterator.get(key, data, Db.DB_NEXT) == 0) + { + System.out.println(key.getString() + " : " + data.getString()); + } + iterator.close(); + table.close(0); + } + + // Here's an example of how you can extend a Dbt in a straightforward + // way to allow easy storage/retrieval of strings, or whatever + // kind of data you wish. We've declared it as a static inner + // class, but it need not be. + // + static /*inner*/ + class StringDbt extends Dbt + { + StringDbt() + { + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + StringDbt(String value) + { + setString(value); + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + void setString(String value) + { + set_data(value.getBytes()); + set_size(value.length()); + } + + String getString() + { + return new String(get_data(), 0, get_size()); + } + } +} diff --git a/db/test/scr016/TestOpenEmpty.testerr b/db/test/scr016/TestOpenEmpty.testerr new file mode 100644 index 000000000..dd3e01c7a --- /dev/null +++ b/db/test/scr016/TestOpenEmpty.testerr @@ -0,0 +1,2 @@ +TestOpenEmpty: access.db: unexpected file type or format +TestOpenEmpty: com.sleepycat.db.DbException: Invalid argument: Invalid argument diff --git a/db/test/scr016/TestReplication.java b/db/test/scr016/TestReplication.java new file mode 100644 index 000000000..2b3780770 --- /dev/null +++ b/db/test/scr016/TestReplication.java @@ -0,0 +1,289 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestReplication.java,v 1.1 2001/10/12 13:02:33 dda Exp + */ + +/* + * Simple test of replication, merely to exercise the individual + * methods in the API. Rather than use TCP/IP, our transport + * mechanism is just an ArrayList of byte arrays. + * It's managed like a queue, and synchronization is via + * the ArrayList object itself and java's wait/notify. + * It's not terribly extensible, but it's fine for a small test. + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Vector; + +public class TestReplication extends Thread + implements DbRepTransport +{ + public static final String MASTER_ENVDIR = "./master"; + public static final String CLIENT_ENVDIR = "./client"; + + private Vector queue = new Vector(); + private DbEnv master_env; + private DbEnv client_env; + + private static void mkdir(String name) + throws IOException + { + (new File(name)).mkdir(); + } + + + // The client thread runs this + public void run() + { + try { + System.err.println("c10"); + client_env = new DbEnv(0); + System.err.println("c11"); + client_env.set_rep_transport(1, this); + System.err.println("c12"); + client_env.open(CLIENT_ENVDIR, Db.DB_CREATE | Db.DB_INIT_MPOOL, 0); + System.err.println("c13"); + Dbt myid = new Dbt("master01".getBytes()); + System.err.println("c14"); + client_env.rep_start(myid, Db.DB_REP_CLIENT); + System.err.println("c15"); + DbEnv.RepProcessMessage processMsg = new DbEnv.RepProcessMessage(); + processMsg.envid = 2; + System.err.println("c20"); + boolean running = true; + + Dbt control = new Dbt(); + Dbt rec = new Dbt(); + + while (running) { + int msgtype = 0; + + System.err.println("c30"); + synchronized (queue) { + if (queue.size() == 0) { + System.err.println("c40"); + sleepShort(); + } + else { + msgtype = ((Integer)queue.firstElement()).intValue(); + queue.removeElementAt(0); + byte[] data; + + System.err.println("c50 " + msgtype); + + switch (msgtype) { + case -1: + running = false; + break; + case 1: + data = (byte[])queue.firstElement(); + queue.removeElementAt(0); + control.set_data(data); + control.set_size(data.length); + break; + case 2: + control.set_data(null); + control.set_size(0); + break; + case 3: + data = (byte[])queue.firstElement(); + queue.removeElementAt(0); + rec.set_data(data); + rec.set_size(data.length); + break; + case 4: + rec.set_data(null); + rec.set_size(0); + break; + } + + } + } + System.err.println("c60"); + if (msgtype == 3 || msgtype == 4) { + System.out.println("cLIENT: Got message"); + client_env.rep_process_message(control, rec, + processMsg); + } + } + System.err.println("c70"); + Db db = new Db(client_env, 0); + db.open("x.db", null, Db.DB_BTREE, 0, 0); + Dbt data = new Dbt(); + System.err.println("c80"); + db.get(null, new Dbt("Hello".getBytes()), data, 0); + System.err.println("c90"); + System.out.println("Hello " + new String(data.get_data(), data.get_offset(), data.get_size())); + System.err.println("c95"); + client_env.close(0); + } + catch (Exception e) { + System.err.println("client exception: " + e); + } + } + + // Implements DbTransport + public int send(DbEnv env, Dbt control, Dbt rec, int flags, int envid) + throws DbException + { + System.out.println("Send to " + envid); + if (envid == 1) { + System.err.println("Unexpected envid = " + envid); + return 0; + } + + int nbytes = 0; + + synchronized (queue) { + System.out.println("Sending message"); + byte[] data = control.get_data(); + if (data != null && data.length > 0) { + queue.addElement(new Integer(1)); + nbytes += data.length; + byte[] newdata = new byte[data.length]; + System.arraycopy(data, 0, newdata, 0, data.length); + queue.addElement(newdata); + } + else + { + queue.addElement(new Integer(2)); + } + + data = rec.get_data(); + if (data != null && data.length > 0) { + queue.addElement(new Integer(3)); + nbytes += data.length; + byte[] newdata = new byte[data.length]; + System.arraycopy(data, 0, newdata, 0, data.length); + queue.addElement(newdata); + } + else + { + queue.addElement(new Integer(4)); + } + System.out.println("MASTER: sent message"); + } + return 0; + } + + public void sleepShort() + { + try { + sleep(100); + } + catch (InterruptedException ie) + { + } + } + + public void send_terminator() + { + synchronized (queue) { + queue.addElement(new Integer(-1)); + } + } + + public void master() + { + try { + master_env = new DbEnv(0); + master_env.set_rep_transport(2, this); + master_env.open(MASTER_ENVDIR, Db.DB_CREATE | Db.DB_INIT_MPOOL, 0644); + System.err.println("10"); + Dbt myid = new Dbt("client01".getBytes()); + master_env.rep_start(myid, Db.DB_REP_MASTER); + System.err.println("10"); + Db db = new Db(master_env, 0); + System.err.println("20"); + db.open("x.db", null, Db.DB_BTREE, Db.DB_CREATE, 0644); + System.err.println("30"); + db.put(null, new Dbt("Hello".getBytes()), + new Dbt("world".getBytes()), 0); + System.err.println("40"); + //DbEnv.RepElectResult electionResult = new DbEnv.RepElectResult(); + //master_env.rep_elect(2, 2, 3, 4, electionResult); + db.close(0); + System.err.println("50"); + master_env.close(0); + send_terminator(); + } + catch (Exception e) { + System.err.println("client exception: " + e); + } + } + + public static void main(String[] args) + { + // The test should only take a few milliseconds. + // give it 10 seconds before bailing out. + TimelimitThread t = new TimelimitThread(1000*10); + t.start(); + + try { + mkdir(CLIENT_ENVDIR); + mkdir(MASTER_ENVDIR); + + TestReplication rep = new TestReplication(); + + // Run the client as a seperate thread. + rep.start(); + + // Run the master. + rep.master(); + + // Wait for the master to finish. + rep.join(); + } + catch (Exception e) + { + System.err.println("Exception: " + e); + } + t.finished(); + } + +} + +class TimelimitThread extends Thread +{ + long nmillis; + boolean finished = false; + + TimelimitThread(long nmillis) + { + this.nmillis = nmillis; + } + + public void finished() + { + finished = true; + } + + public void run() + { + long targetTime = System.currentTimeMillis() + nmillis; + long curTime; + + while (!finished && + ((curTime = System.currentTimeMillis()) < targetTime)) { + long diff = targetTime - curTime; + if (diff > 100) + diff = 100; + try { + sleep(diff); + } + catch (InterruptedException ie) { + } + } + System.err.println(""); + System.exit(1); + } +} diff --git a/db/test/scr016/TestRpcServer.java b/db/test/scr016/TestRpcServer.java new file mode 100644 index 000000000..46294ef8d --- /dev/null +++ b/db/test/scr016/TestRpcServer.java @@ -0,0 +1,193 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997-2001 + * Sleepycat Software. All rights reserved. + * + * Id: TestRpcServer.java,v 1.2 2001/10/05 02:36:10 bostic Exp + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.Reader; +import java.io.StringReader; +import java.io.IOException; +import java.io.PrintStream; + +public class TestRpcServer +{ + private static final String FileName = "access.db"; + + public TestRpcServer() + { + } + + private static void usage() + { + System.err.println("usage: TestRpcServer\n"); + System.exit(1); + } + + public static void main(String argv[]) + { + try + { + TestRpcServer app = new TestRpcServer(); + app.run(); + } + catch (DbException dbe) + { + System.err.println("TestRpcServer: " + dbe.toString()); + System.exit(1); + } + catch (FileNotFoundException fnfe) + { + System.err.println("TestRpcServer: " + fnfe.toString()); + System.exit(1); + } + System.exit(0); + } + + // Prompts for a line, and keeps prompting until a non blank + // line is returned. Returns null on error. + // + static public String askForLine(Reader reader, + PrintStream out, String prompt) + { + String result = ""; + while (result != null && result.length() == 0) { + out.print(prompt); + out.flush(); + result = getLine(reader); + } + return result; + } + + // Not terribly efficient, but does the job. + // Works for reading a line from stdin or a file. + // Returns null on EOF. If EOF appears in the middle + // of a line, returns that line, then null on next call. + // + static public String getLine(Reader reader) + { + StringBuffer b = new StringBuffer(); + int c; + try { + while ((c = reader.read()) != -1 && c != '\n') { + if (c != '\r') + b.append((char)c); + } + } + catch (IOException ioe) { + c = -1; + } + + if (c == -1 && b.length() == 0) + return null; + else + return b.toString(); + } + + public void run() + throws DbException, FileNotFoundException + { + // Remove the previous database. + new File(FileName).delete(); + + DbEnv dbenv = new DbEnv(Db.DB_CLIENT); + dbenv.set_rpc_server(null, "localhost", 0, 0, 0); + dbenv.open(".", Db.DB_CREATE, 0644); + System.out.println("server connection set"); + + // Create the database object. + // There is no environment for this simple example. + Db table = new Db(dbenv, 0); + table.set_error_stream(System.err); + table.set_errpfx("TestRpcServer"); + table.open(FileName, null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // + // Insert records into the database, where the key is the user + // input and the data is the user input in reverse order. + // + Reader reader = + new StringReader("abc\nStuff\nmore Stuff\nlast line\n"); + + for (;;) { + String line = askForLine(reader, System.out, "input> "); + if (line == null) + break; + + String reversed = (new StringBuffer(line)).reverse().toString(); + + // See definition of StringDbt below + // + StringDbt key = new StringDbt(line); + StringDbt data = new StringDbt(reversed); + + try + { + int err; + if ((err = table.put(null, + key, data, Db.DB_NOOVERWRITE)) == Db.DB_KEYEXIST) { + System.out.println("Key " + line + " already exists."); + } + } + catch (DbException dbe) + { + System.out.println(dbe.toString()); + } + System.out.println(""); + } + + // Acquire an iterator for the table. + Dbc iterator; + iterator = table.cursor(null, 0); + + // Walk through the table, printing the key/data pairs. + // See class StringDbt defined below. + // + StringDbt key = new StringDbt(); + StringDbt data = new StringDbt(); + while (iterator.get(key, data, Db.DB_NEXT) == 0) + { + System.out.println(key.getString() + " : " + data.getString()); + } + iterator.close(); + table.close(0); + } + + // Here's an example of how you can extend a Dbt in a straightforward + // way to allow easy storage/retrieval of strings, or whatever + // kind of data you wish. We've declared it as a static inner + // class, but it need not be. + // + static /*inner*/ + class StringDbt extends Dbt + { + StringDbt() + { + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + StringDbt(String value) + { + setString(value); + set_flags(Db.DB_DBT_MALLOC); // tell Db to allocate on retrieval + } + + void setString(String value) + { + set_data(value.getBytes()); + set_size(value.length()); + } + + String getString() + { + return new String(get_data(), 0, get_size()); + } + } +} diff --git a/db/test/scr016/TestSameDbt.java b/db/test/scr016/TestSameDbt.java new file mode 100644 index 000000000..d4024b12b --- /dev/null +++ b/db/test/scr016/TestSameDbt.java @@ -0,0 +1,56 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestSameDbt.java,v 1.2 2001/10/05 02:36:10 bostic Exp + */ + +/* + * Simple test for get/put of specific values. + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.FileNotFoundException; + +public class TestSameDbt +{ + public static void main(String[] args) + { + try { + Db db = new Db(null, 0); + db.open("my.db", null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // try reusing the dbt + Dbt keydatadbt = new Dbt("stuff".getBytes()); + int gotexcept = 0; + + try { + db.put(null, keydatadbt, keydatadbt, 0); + } + catch (DbException dbe) { + System.out.println("got expected Db Exception: " + dbe); + gotexcept++; + } + + if (gotexcept != 1) { + System.err.println("Missed exception"); + System.out.println("** FAIL **"); + } + else { + System.out.println("Test succeeded."); + } + } + catch (DbException dbe) { + System.err.println("Db Exception: " + dbe); + } + catch (FileNotFoundException fnfe) { + System.err.println("FileNotFoundException: " + fnfe); + } + + } + +} diff --git a/db/test/scr016/TestSameDbt.testout b/db/test/scr016/TestSameDbt.testout new file mode 100644 index 000000000..be4bbbe59 --- /dev/null +++ b/db/test/scr016/TestSameDbt.testout @@ -0,0 +1,2 @@ +got expected Db Exception: com.sleepycat.db.DbException: Dbt is already in use +Test succeeded. diff --git a/db/test/scr016/TestSimpleAccess.java b/db/test/scr016/TestSimpleAccess.java new file mode 100644 index 000000000..7b2cf61c4 --- /dev/null +++ b/db/test/scr016/TestSimpleAccess.java @@ -0,0 +1,70 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestSimpleAccess.java,v 1.2 2001/10/05 02:36:10 bostic Exp + */ + +/* + * Simple test for get/put of specific values. + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.FileNotFoundException; + +public class TestSimpleAccess +{ + public static void main(String[] args) + { + try { + Db db = new Db(null, 0); + db.open("my.db", null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // populate our massive database. + Dbt keydbt = new Dbt("key".getBytes()); + Dbt datadbt = new Dbt("data".getBytes()); + db.put(null, keydbt, datadbt, 0); + + // Now, retrieve. We could use keydbt over again, + // but that wouldn't be typical in an application. + Dbt goodkeydbt = new Dbt("key".getBytes()); + Dbt badkeydbt = new Dbt("badkey".getBytes()); + Dbt resultdbt = new Dbt(); + resultdbt.set_flags(Db.DB_DBT_MALLOC); + + int ret; + + if ((ret = db.get(null, goodkeydbt, resultdbt, 0)) != 0) { + System.out.println("get: " + DbEnv.strerror(ret)); + } + else { + String result = + new String(resultdbt.get_data(), 0, resultdbt.get_size()); + System.out.println("got data: " + result); + } + + if ((ret = db.get(null, badkeydbt, resultdbt, 0)) != 0) { + // We expect this... + System.out.println("get using bad key: " + DbEnv.strerror(ret)); + } + else { + String result = + new String(resultdbt.get_data(), 0, resultdbt.get_size()); + System.out.println("*** got data using bad key!!: " + result); + } + System.out.println("finished test"); + } + catch (DbException dbe) { + System.err.println("Db Exception: " + dbe); + } + catch (FileNotFoundException fnfe) { + System.err.println("FileNotFoundException: " + fnfe); + } + + } + +} diff --git a/db/test/scr016/TestSimpleAccess.testout b/db/test/scr016/TestSimpleAccess.testout new file mode 100644 index 000000000..dc88d4788 --- /dev/null +++ b/db/test/scr016/TestSimpleAccess.testout @@ -0,0 +1,3 @@ +got data: data +get using bad key: DB_NOTFOUND: No matching key/data pair found +finished test diff --git a/db/test/scr016/TestTruncate.java b/db/test/scr016/TestTruncate.java new file mode 100644 index 000000000..3f74e8cd5 --- /dev/null +++ b/db/test/scr016/TestTruncate.java @@ -0,0 +1,87 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 1998, 1999, 2000 + * Sleepycat Software. All rights reserved. + * + * Id: TestTruncate.java,v 1.2 2001/10/05 02:36:11 bostic Exp + */ + +/* + * Simple test for get/put of specific values. + */ + +package com.sleepycat.test; + +import com.sleepycat.db.*; +import java.io.FileNotFoundException; + +public class TestTruncate +{ + public static void main(String[] args) + { + try { + Db db = new Db(null, 0); + db.open("my.db", null, Db.DB_BTREE, Db.DB_CREATE, 0644); + + // populate our massive database. + Dbt keydbt = new Dbt("key".getBytes()); + Dbt datadbt = new Dbt("data".getBytes()); + db.put(null, keydbt, datadbt, 0); + + // Now, retrieve. We could use keydbt over again, + // but that wouldn't be typical in an application. + Dbt goodkeydbt = new Dbt("key".getBytes()); + Dbt badkeydbt = new Dbt("badkey".getBytes()); + Dbt resultdbt = new Dbt(); + resultdbt.set_flags(Db.DB_DBT_MALLOC); + + int ret; + + if ((ret = db.get(null, goodkeydbt, resultdbt, 0)) != 0) { + System.out.println("get: " + DbEnv.strerror(ret)); + } + else { + String result = + new String(resultdbt.get_data(), 0, resultdbt.get_size()); + System.out.println("got data: " + result); + } + + if ((ret = db.get(null, badkeydbt, resultdbt, 0)) != 0) { + // We expect this... + System.out.println("get using bad key: " + DbEnv.strerror(ret)); + } + else { + String result = + new String(resultdbt.get_data(), 0, resultdbt.get_size()); + System.out.println("*** got data using bad key!!: " + result); + } + + // Now, truncate and make sure that it's really gone. + System.out.println("truncating data..."); + int nrecords = db.truncate(null, 0); + System.out.println("truncate returns " + nrecords); + if ((ret = db.get(null, goodkeydbt, resultdbt, 0)) != 0) { + // We expect this... + System.out.println("after trunctate get: " + + DbEnv.strerror(ret)); + } + else { + String result = + new String(resultdbt.get_data(), 0, resultdbt.get_size()); + System.out.println("got data: " + result); + } + + db.close(0); + System.out.println("finished test"); + } + catch (DbException dbe) { + System.err.println("Db Exception: " + dbe); + } + catch (FileNotFoundException fnfe) { + System.err.println("FileNotFoundException: " + fnfe); + } + + } + +} diff --git a/db/test/scr016/TestTruncate.testout b/db/test/scr016/TestTruncate.testout new file mode 100644 index 000000000..23f291df7 --- /dev/null +++ b/db/test/scr016/TestTruncate.testout @@ -0,0 +1,6 @@ +got data: data +get using bad key: DB_NOTFOUND: No matching key/data pair found +truncating data... +truncate returns 1 +after trunctate get: DB_NOTFOUND: No matching key/data pair found +finished test diff --git a/db/test/scr016/chk.javatests b/db/test/scr016/chk.javatests new file mode 100644 index 000000000..df845f522 --- /dev/null +++ b/db/test/scr016/chk.javatests @@ -0,0 +1,78 @@ +#!/bin/sh - +# +# Id: chk.javatests,v 1.2 2001/10/12 13:02:34 dda Exp +# +# Check to make sure that regression tests for Java run. + +TEST_JAVA_SRCDIR=../test/scr016 # must be a relative directory +JAVA=${JAVA:-java} +JAVAC=${JAVAC:-javac} + +# CLASSPATH is used by javac and java. +# We use CLASSPATH rather than the -classpath command line option +# because the latter behaves differently from JDK1.1 and JDK1.2 +export CLASSPATH="./classes:../db.jar" +export LD_LIBRARY_PATH="../.libs" + + +# All paths must be relative to a subdirectory of the build directory +LIBS="-L.. -ldb -ldb_cxx" +CXXFLAGS="-I.. -I../../include" + +# Test must be run from a local build directory, not from a test +# directory. +cd .. +[ -f db_config.h ] || { + echo 'FAIL: chk.javatests must be run from a local build directory.' + exit 1 +} +[ -d ../docs_src ] || { + echo 'FAIL: chk.javatests must be run from a local build directory.' + exit 1 +} +version=`head -1 ../README | sed -e 's/.* \([0-9]*\.[0-9]*\)\..*/\1/'` +[ -f libdb_java-$version.la ] || make libdb_java-$version.la || { + echo "FAIL: unable to build libdb_java-$version.la" + exit 1 +} +[ -f db.jar ] || make db.jar || { + echo 'FAIL: unable to build db.jar' + exit 1 +} +testnames=`cd $TEST_JAVA_SRCDIR; ls *.java | sed -e 's/\.java$//'` + +for testname in $testnames; do + if grep -x $testname $TEST_JAVA_SRCDIR/ignore > /dev/null; then + echo " **** java test $testname ignored" + continue + fi + + echo " ==== java test $testname" + rm -rf TESTJAVA; mkdir -p TESTJAVA/classes + cd ./TESTJAVA + testprefix=../$TEST_JAVA_SRCDIR/$testname + ${JAVAC} -d ./classes $testprefix.java > ../$testname.compileout 2>&1 || { + echo "FAIL: compilation of $testname failed, see ../$testname.compileout" + exit 1 + } + rm -f ../$testname.compileout + infile=$testprefix.testin + [ -f $infile ] || infile=/dev/null + goodoutfile=$testprefix.testout + [ -f $goodoutfile ] || goodoutfile=/dev/null + gooderrfile=$testprefix.testerr + [ -f $gooderrfile ] || gooderrfile=/dev/null + ${JAVA} com.sleepycat.test.$testname <$infile >../$testname.out 2>../$testname.err + cmp ../$testname.out $goodoutfile > /dev/null || { + echo "FAIL: $testname output differs: see ../$testname.out, $goodoutfile" + exit 1 + } + cmp ../$testname.err $gooderrfile > /dev/null || { + echo "FAIL: $testname error differs: see ../$testname.err, $gooderrfile" + exit 1 + } + cd .. + rm -f $testname.err $testname.out +done +rm -rf TESTJAVA +exit 0 diff --git a/db/test/scr016/ignore b/db/test/scr016/ignore new file mode 100644 index 000000000..ced56a904 --- /dev/null +++ b/db/test/scr016/ignore @@ -0,0 +1,11 @@ +# +# Id: ignore,v 1.3 2001/10/12 13:02:34 dda Exp +# +# A list of tests to ignore + +# TestRpcServer is not debugged +TestRpcServer + +# TestReplication is not debugged +TestReplication + diff --git a/db/test/scr016/testall b/db/test/scr016/testall new file mode 100644 index 000000000..5439ec22c --- /dev/null +++ b/db/test/scr016/testall @@ -0,0 +1,32 @@ +#!/bin/sh - +# Id: testall,v 1.4 2001/09/13 14:49:37 dda Exp +# +# Run all the Java regression tests + +ecode=0 +prefixarg="" +stdinarg="" +while : +do + case "$1" in + --prefix=* ) + prefixarg="$1"; shift;; + --stdin ) + stdinarg="$1"; shift;; + * ) + break + esac +done +files="`find . -name \*.java -print`" +for file in $files; do + name=`echo $file | sed -e 's:^\./::' -e 's/\.java$//'` + if grep $name ignore > /dev/null; then + echo " **** java test $name ignored" + else + echo " ==== java test $name" + if ! sh ./testone $prefixarg $stdinarg $name; then + ecode=1 + fi + fi +done +exit $ecode diff --git a/db/test/scr016/testone b/db/test/scr016/testone new file mode 100644 index 000000000..502027062 --- /dev/null +++ b/db/test/scr016/testone @@ -0,0 +1,122 @@ +#!/bin/sh - +# Id: testone,v 1.4 2001/09/20 14:40:29 dda Exp +# +# Run just one Java regression test, the single argument +# is the classname within this package. + +error() +{ + echo '' >&2 + echo "Java regression error: $@" >&2 + echo '' >&2 + ecode=1 +} + +# compares the result against the good version, +# reports differences, and removes the result file +# if there are no differences. +# +compare_result() +{ + good="$1" + latest="$2" + if [ ! -e "$good" ]; then + echo "Note: $good does not exist" + return + fi + tmpout=/tmp/blddb$$.tmp + diff "$good" "$latest" > $tmpout + if [ -s $tmpout ]; then + nbad=`grep '^[0-9]' $tmpout | wc -l` + error "$good and $latest differ in $nbad places." + else + rm $latest + fi + rm -f $tmpout +} + +ecode=0 +stdinflag=n +JAVA=${JAVA:-java} +JAVAC=${JAVAC:-javac} + +# classdir is relative to TESTDIR subdirectory +classdir=./classes + +# CLASSPATH is used by javac and java. +# We use CLASSPATH rather than the -classpath command line option +# because the latter behaves differently from JDK1.1 and JDK1.2 +export CLASSPATH="$classdir:$CLASSPATH" + +# determine the prefix of the install tree +prefix="" +while : +do + case "$1" in + --prefix=* ) + prefix="`echo $1 | sed -e 's/--prefix=//'`"; shift + export LD_LIBRARY_PATH="$prefix/lib:$LD_LIBRARY_PATH" + export CLASSPATH="$prefix/lib/db.jar:$CLASSPATH" + ;; + --stdin ) + stdinflag=y; shift + ;; + * ) + break + ;; + esac +done + +if [ "$#" = 0 ]; then + echo 'Usage: testone [ --prefix=<dir> | --stdin ] TestName' + exit 1 +fi +name="$1" + +# class must be public +if ! grep "public.*class.*$name" $name.java > /dev/null; then + error "public class $name is not declared in file $name.java" + exit 1 +fi + +# compile +rm -rf TESTDIR; mkdir TESTDIR +cd ./TESTDIR +mkdir -p $classdir +${JAVAC} -d $classdir ../$name.java > ../$name.compileout 2>&1 +if [ $? != 0 -o -s ../$name.compileout ]; then + error "compilation of $name failed, see $name.compileout" + exit 1 +fi +rm -f ../$name.compileout + +# find input and error file +infile=../$name.testin +if [ ! -f $infile ]; then + infile=/dev/null +fi + +# run and diff results +rm -rf TESTDIR +if [ "$stdinflag" = y ] +then + ${JAVA} com.sleepycat.test.$name >../$name.out 2>../$name.err +else + ${JAVA} com.sleepycat.test.$name <$infile >../$name.out 2>../$name.err +fi +cd .. + +testerr=$name.testerr +if [ ! -f $testerr ]; then + testerr=/dev/null +fi + +testout=$name.testout +if [ ! -f $testout ]; then + testout=/dev/null +fi + +compare_result $testout $name.out +compare_result $testerr $name.err +rm -rf TESTDIR +exit $ecode diff --git a/db/test/scr017/O.BH b/db/test/scr017/O.BH new file mode 100644 index 000000000..cd499d387 --- /dev/null +++ b/db/test/scr017/O.BH @@ -0,0 +1,196 @@ +abc_10_efg +abc_10_efg +abc_11_efg +abc_11_efg +abc_12_efg +abc_12_efg +abc_13_efg +abc_13_efg +abc_14_efg +abc_14_efg +abc_15_efg +abc_15_efg +abc_16_efg +abc_16_efg +abc_17_efg +abc_17_efg +abc_18_efg +abc_18_efg +abc_19_efg +abc_19_efg +abc_1_efg +abc_1_efg +abc_20_efg +abc_20_efg +abc_21_efg +abc_21_efg +abc_22_efg +abc_22_efg +abc_23_efg +abc_23_efg +abc_24_efg +abc_24_efg +abc_25_efg +abc_25_efg +abc_26_efg +abc_26_efg +abc_27_efg +abc_27_efg +abc_28_efg +abc_28_efg +abc_29_efg +abc_29_efg +abc_2_efg +abc_2_efg +abc_30_efg +abc_30_efg +abc_31_efg +abc_31_efg +abc_32_efg +abc_32_efg +abc_33_efg +abc_33_efg +abc_34_efg +abc_34_efg +abc_36_efg +abc_36_efg +abc_37_efg +abc_37_efg +abc_38_efg +abc_38_efg +abc_39_efg +abc_39_efg +abc_3_efg +abc_3_efg +abc_40_efg +abc_40_efg +abc_41_efg +abc_41_efg +abc_42_efg +abc_42_efg +abc_43_efg +abc_43_efg +abc_44_efg +abc_44_efg +abc_45_efg +abc_45_efg +abc_46_efg +abc_46_efg +abc_47_efg +abc_47_efg +abc_48_efg +abc_48_efg +abc_49_efg +abc_49_efg +abc_4_efg +abc_4_efg +abc_50_efg +abc_50_efg +abc_51_efg +abc_51_efg +abc_52_efg +abc_52_efg +abc_53_efg +abc_53_efg +abc_54_efg +abc_54_efg +abc_55_efg +abc_55_efg +abc_56_efg +abc_56_efg +abc_57_efg +abc_57_efg +abc_58_efg +abc_58_efg +abc_59_efg +abc_59_efg +abc_5_efg +abc_5_efg +abc_60_efg +abc_60_efg +abc_61_efg +abc_61_efg +abc_62_efg +abc_62_efg +abc_63_efg +abc_63_efg +abc_64_efg +abc_64_efg +abc_65_efg +abc_65_efg +abc_66_efg +abc_66_efg +abc_67_efg +abc_67_efg +abc_68_efg +abc_68_efg +abc_69_efg +abc_69_efg +abc_6_efg +abc_6_efg +abc_70_efg +abc_70_efg +abc_71_efg +abc_71_efg +abc_72_efg +abc_72_efg +abc_73_efg +abc_73_efg +abc_74_efg +abc_74_efg +abc_75_efg +abc_75_efg +abc_76_efg +abc_76_efg +abc_77_efg +abc_77_efg +abc_78_efg +abc_78_efg +abc_79_efg +abc_79_efg +abc_7_efg +abc_7_efg +abc_80_efg +abc_80_efg +abc_81_efg +abc_81_efg +abc_82_efg +abc_82_efg +abc_83_efg +abc_83_efg +abc_84_efg +abc_84_efg +abc_85_efg +abc_85_efg +abc_86_efg +abc_86_efg +abc_87_efg +abc_87_efg +abc_88_efg +abc_88_efg +abc_89_efg +abc_89_efg +abc_8_efg +abc_8_efg +abc_90_efg +abc_90_efg +abc_91_efg +abc_91_efg +abc_92_efg +abc_92_efg +abc_93_efg +abc_93_efg +abc_94_efg +abc_94_efg +abc_95_efg +abc_95_efg +abc_96_efg +abc_96_efg +abc_97_efg +abc_97_efg +abc_98_efg +abc_98_efg +abc_99_efg +abc_99_efg +abc_9_efg +abc_9_efg diff --git a/db/test/scr017/O.R b/db/test/scr017/O.R new file mode 100644 index 000000000..d78a04727 --- /dev/null +++ b/db/test/scr017/O.R @@ -0,0 +1,196 @@ +1 +abc_1_efg +2 +abc_2_efg +3 +abc_3_efg +4 +abc_4_efg +5 +abc_5_efg +6 +abc_6_efg +7 +abc_7_efg +8 +abc_8_efg +9 +abc_9_efg +10 +abc_10_efg +11 +abc_11_efg +12 +abc_12_efg +13 +abc_13_efg +14 +abc_14_efg +15 +abc_15_efg +16 +abc_16_efg +17 +abc_17_efg +18 +abc_18_efg +19 +abc_19_efg +20 +abc_20_efg +21 +abc_21_efg +22 +abc_22_efg +23 +abc_23_efg +24 +abc_24_efg +25 +abc_25_efg +26 +abc_26_efg +27 +abc_27_efg +28 +abc_28_efg +29 +abc_29_efg +30 +abc_30_efg +31 +abc_31_efg +32 +abc_32_efg +33 +abc_33_efg +34 +abc_34_efg +35 +abc_36_efg +36 +abc_37_efg +37 +abc_38_efg +38 +abc_39_efg +39 +abc_40_efg +40 +abc_41_efg +41 +abc_42_efg +42 +abc_43_efg +43 +abc_44_efg +44 +abc_45_efg +45 +abc_46_efg +46 +abc_47_efg +47 +abc_48_efg +48 +abc_49_efg +49 +abc_50_efg +50 +abc_51_efg +51 +abc_52_efg +52 +abc_53_efg +53 +abc_54_efg +54 +abc_55_efg +55 +abc_56_efg +56 +abc_57_efg +57 +abc_58_efg +58 +abc_59_efg +59 +abc_60_efg +60 +abc_61_efg +61 +abc_62_efg +62 +abc_63_efg +63 +abc_64_efg +64 +abc_65_efg +65 +abc_66_efg +66 +abc_67_efg +67 +abc_68_efg +68 +abc_69_efg +69 +abc_70_efg +70 +abc_71_efg +71 +abc_72_efg +72 +abc_73_efg +73 +abc_74_efg +74 +abc_75_efg +75 +abc_76_efg +76 +abc_77_efg +77 +abc_78_efg +78 +abc_79_efg +79 +abc_80_efg +80 +abc_81_efg +81 +abc_82_efg +82 +abc_83_efg +83 +abc_84_efg +84 +abc_85_efg +85 +abc_86_efg +86 +abc_87_efg +87 +abc_88_efg +88 +abc_89_efg +89 +abc_90_efg +90 +abc_91_efg +91 +abc_92_efg +92 +abc_93_efg +93 +abc_94_efg +94 +abc_95_efg +95 +abc_96_efg +96 +abc_97_efg +97 +abc_98_efg +98 +abc_99_efg diff --git a/db/test/scr017/chk.db185 b/db/test/scr017/chk.db185 new file mode 100644 index 000000000..810ba59b1 --- /dev/null +++ b/db/test/scr017/chk.db185 @@ -0,0 +1,26 @@ +#!/bin/sh - +# +# Id: chk.db185,v 1.2 2001/10/12 17:55:38 bostic Exp +# +# Check to make sure we can run DB 1.85 code. + +[ -f ../libdb.a ] || (cd .. && make libdb.a) || { + echo 'FAIL: unable to find or build libdb.a' + exit 1 +} + +if cc -g -Wall -I.. t.c ../libdb.a -o t; then + : +else + echo "FAIL: unable to compile test program t.c" + exit 1 +fi + +if ./t; then + : +else + echo "FAIL: test program failed" + exit 1 +fi + +exit 0 diff --git a/db/test/scr017/t.c b/db/test/scr017/t.c new file mode 100644 index 000000000..f03b33880 --- /dev/null +++ b/db/test/scr017/t.c @@ -0,0 +1,188 @@ +#include <sys/types.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "db_185.h" + +void err(char *); +int mycmp(const DBT *, const DBT *); +void ops(DB *, int); + +int +main() +{ + DB *dbp; + HASHINFO h_info; + BTREEINFO b_info; + RECNOINFO r_info; + + printf("\tBtree...\n"); + memset(&b_info, 0, sizeof(b_info)); + b_info.flags = R_DUP; + b_info.cachesize = 100 * 1024; + b_info.psize = 512; + b_info.lorder = 4321; + b_info.compare = mycmp; + (void)remove("a.db"); + if ((dbp = + dbopen("a.db", O_CREAT | O_RDWR, 0664, DB_BTREE, &b_info)) == NULL) + err("dbopen: btree"); + ops(dbp, DB_BTREE); + + printf("\tHash...\n"); + memset(&h_info, 0, sizeof(h_info)); + h_info.bsize = 512; + h_info.ffactor = 6; + h_info.nelem = 1000; + h_info.cachesize = 100 * 1024; + h_info.lorder = 1234; + (void)remove("a.db"); + if ((dbp = + dbopen("a.db", O_CREAT | O_RDWR, 0664, DB_HASH, &h_info)) == NULL) + err("dbopen: hash"); + ops(dbp, DB_HASH); + + printf("\tRecno...\n"); + memset(&r_info, 0, sizeof(r_info)); + r_info.flags = R_FIXEDLEN; + r_info.cachesize = 100 * 1024; + r_info.psize = 1024; + r_info.reclen = 37; + (void)remove("a.db"); + if ((dbp = + dbopen("a.db", O_CREAT | O_RDWR, 0664, DB_RECNO, &r_info)) == NULL) + err("dbopen: recno"); + ops(dbp, DB_RECNO); + + return (0); +} + +int +mycmp(a, b) + const DBT *a, *b; +{ + size_t len; + u_int8_t *p1, *p2; + + len = a->size > b->size ? b->size : a->size; + for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) + if (*p1 != *p2) + return ((long)*p1 - (long)*p2); + return ((long)a->size - (long)b->size); +} + +void +ops(dbp, type) + DB *dbp; + int type; +{ + FILE *outfp; + DBT key, data; + recno_t recno; + int i, ret; + char buf[64]; + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + for (i = 1; i < 100; ++i) { /* Test DB->put. */ + sprintf(buf, "abc_%d_efg", i); + if (type == DB_RECNO) { + recno = i; + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = data.data = buf; + key.size = data.size = strlen(buf); + } + + data.data = buf; + data.size = strlen(buf); + if (dbp->put(dbp, &key, &data, 0)) + err("DB->put"); + } + + if (type == DB_RECNO) { /* Test DB->get. */ + recno = 97; + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = buf; + key.size = strlen(buf); + } + sprintf(buf, "abc_%d_efg", 97); + if (dbp->get(dbp, &key, &data, 0) != 0) + err("DB->get"); + if (memcmp(data.data, buf, strlen(buf))) + err("DB->get: wrong data returned"); + + if (type == DB_RECNO) { /* Test DB->put no-overwrite. */ + recno = 42; + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = buf; + key.size = strlen(buf); + } + sprintf(buf, "abc_%d_efg", 42); + if (dbp->put(dbp, &key, &data, R_NOOVERWRITE) == 0) + err("DB->put: no-overwrite succeeded"); + + if (type == DB_RECNO) { /* Test DB->del. */ + recno = 35; + key.data = &recno; + key.size = sizeof(recno); + } else { + sprintf(buf, "abc_%d_efg", 35); + key.data = buf; + key.size = strlen(buf); + } + if (dbp->del(dbp, &key, 0)) + err("DB->del"); + + /* Test DB->seq. */ + if ((outfp = fopen("output", "w")) == NULL) + err("fopen: output"); + while ((ret = dbp->seq(dbp, &key, &data, R_NEXT)) == 0) { + if (type == DB_RECNO) + fprintf(outfp, "%d\n", *(int *)key.data); + else + fprintf(outfp, + "%.*s\n", (int)key.size, (char *)key.data); + fprintf(outfp, "%.*s\n", (int)data.size, (char *)data.data); + } + if (ret != 1) + err("DB->seq"); + fclose(outfp); + switch (type) { + case DB_BTREE: + ret = system("cmp output O.BH"); + break; + case DB_HASH: + ret = system("sort output | cmp - O.BH"); + break; + case DB_RECNO: + ret = system("cmp output O.R"); + break; + } + if (ret != 0) + err("output comparison failed"); + + if (dbp->sync(dbp, 0)) /* Test DB->sync. */ + err("DB->sync"); + + if (dbp->close(dbp)) /* Test DB->close. */ + err("DB->close"); +} + +void +err(s) + char *s; +{ + fprintf(stderr, "\t%s: %s\n", s, strerror(errno)); + exit (1); +} diff --git a/db/test/shelltest.tcl b/db/test/shelltest.tcl new file mode 100644 index 000000000..97c215acc --- /dev/null +++ b/db/test/shelltest.tcl @@ -0,0 +1,83 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2001 +# Sleepycat Software. All rights reserved. +# +# Id: shelltest.tcl,v 1.13 2001/10/12 15:54:53 bostic Exp +# +# TEST scr### +# TEST The scr### directories are shell scripts that test a variety of +# TEST things, including things about the distribution itself. These +# TEST tests won't run on most systems, so don't even try to run them. +# +# shelltest.tcl: +# Code to run shell script tests, to incorporate Java, C++, +# example compilation, etc. test scripts into the Tcl framework. +proc shelltest { { run_one 0 }} { + source ./include.tcl + global shelltest_list + + set SH /bin/sh + if { [file executable $SH] != 1 } { + puts "Shell tests require valid shell /bin/sh: not found." + puts "Skipping shell tests." + return 0 + } + + if { $run_one == 0 } { + puts "Running shell script tests..." + + foreach testpair $shelltest_list { + set dir [lindex $testpair 0] + set test [lindex $testpair 1] + + env_cleanup $testdir + shelltest_copy $test_path/$dir $testdir + shelltest_run $SH $dir $test $testdir + } + } else { + set run_one [expr $run_one - 1]; + set dir [lindex [lindex $shelltest_list $run_one] 0] + set test [lindex [lindex $shelltest_list $run_one] 1] + + env_cleanup $testdir + shelltest_copy $test_path/$dir $testdir + shelltest_run $SH $dir $test $testdir + } +} + +proc shelltest_copy { fromdir todir } { + set globall [glob $fromdir/*] + + foreach f $globall { + file copy $f $todir/ + } +} + +proc shelltest_run { sh srcdir test testdir } { + puts "Running shell script $test..." + + set ret [catch {exec $sh -c "cd $testdir && sh $test" >&@ stdout} res] + + if { $ret != 0 } { + puts "FAIL: shell test $srcdir/$test exited abnormally" + } +} + +proc scr001 {} { shelltest 1 } +proc scr002 {} { shelltest 2 } +proc scr003 {} { shelltest 3 } +proc scr004 {} { shelltest 4 } +proc scr005 {} { shelltest 5 } +proc scr006 {} { shelltest 6 } +proc scr007 {} { shelltest 7 } +proc scr008 {} { shelltest 8 } +proc scr009 {} { shelltest 9 } +proc scr010 {} { shelltest 10 } +proc scr011 {} { shelltest 11 } +proc scr012 {} { shelltest 12 } +proc scr013 {} { shelltest 13 } +proc scr014 {} { shelltest 14 } +proc scr015 {} { shelltest 15 } +proc scr016 {} { shelltest 16 } +proc scr017 {} { shelltest 17 } |