# @(#)README	10.15 (Sleepycat) 6/2/98

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
DB Test Suite

If you specify --enable-test when you configure DB, the DB tester will be
built (see ../build.unix/README for further information.)

All DB tests are run from the Tcl tester, "dbtest".  To start the tester,
enter:

	$ ./dbtest<carriage-return>

A percent sign prompt (%) will appear.  Some of the commands that you can
enter at the prompt are as follows:

	% # To run the entire test suite
	% run_all
	% # To run tests for a particular subsystem
	% r btree
	% r hash
	% r lock
	% r log
	% r mpool
	% r mutex
	% r recd
	% r recno
	% r txn

In the case of run_all, normal output is directed to a file named ALL.OUT,
as running all the tests can take several hours.  After the test suite
has completed, you will get a single message that indicates whether the
entire suite succeeded or failed.  If it failed, the file ALL.OUT will
contain more details describing what failed.  Any errors will appear as
output lines beginning with the word: FAIL.

For any of the other tests, a successful test will return you to the tcl
prompt (%).  On failure, you will get a message indicating the expected
and actual values.

Tests are run, by default, in the directory ./TESTDIR.  However, the test
files can be quite large.  To use a different directory for the test
directory, edit the file ".dbtestrc" in your build directory, and change
the line:

	set testdir ./TESTDIR

to a more appropriate value for your system, e.g.:

	set testdir /var/tmp/db.test

WARNING: On many platforms, the mmap(2) and/or fcntl(2) locking system
calls won't work correctly over remote filesystems (e.g., NFS and AFS),
so we strongly recommend that TESTDIR be a local filesystem.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Debugging DB

The dbtest "debug" command provides assistance for debugging tests.  If
you don't specify a parameter, e.g.:

	% debug
	% r btree

debug causes dbtest to display a running count of the calls made into the
DB library.  There is one optional argument to debug which is the number
of the operation on which you want to stop.  By using your debugger to
set a breakpoint in the function __db_loadme(), you can obtain control of
the tester immediately before a particular operation.  For example:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
mongoose:build.unix {1} gdb dbtest
(gdb) break __db_loadme
Breakpoint 1 at 0xe3f7: file ../dist/../db/db_pr.c, line 43.
(gdb) run
Starting program: /usr/src/db/build.unix/dbtest
% debug 10
10
% r btree
run_method: btree 1 19
09:29:32 (00:00:00)
Test001: DB_BTREE 10000 equal key/data pairs
     1:	Test001.a: put/get loop
    10:
Breakpoint 1, __db_loadme () at ../dist/../db/db_pr.c:43
43		getpid();
(gdb) n
44	}
(gdb) n
debug_check () at ../dist/../test/utils.c:1254
1254	}
(gdb) n
db_put_cmd (interp=0x54000, argc=6, argv=0xefbfc408, dbp=0xea080)
    at ../dist/../test/utils.c:859
859		if ((err = dbp->put(dbp, txnid, &key, &data, flags)) == 0) {
(gdb) s
__bt_put (dbp=0xea080, txn=0x0, key=0xefbfc2bc, data=0xefbfc2d4, flags=0)
    at ../dist/../btree/bt_put.c:91
91		t = dbp->internal;
(gdb) where
#0  __bt_put (dbp=0xea080, txn=0x0, key=0xefbfc2bc, data=0xefbfc2d4, flags=0)
    at ../dist/../btree/bt_put.c:91
#1  0x7691 in db_put_cmd (interp=0x54000, argc=6, argv=0xefbfc408, dbp=0xea080)
    at ../dist/../test/utils.c:859
#2  0x68b2 in dbwidget_cmd (cd_dbp=0xea080, interp=0x54000, argc=6,
    argv=0xefbfc408) at ../dist/../test/utils.c:517
#3  0x3a690 in Tcl_Eval ()
(gdb) quit
The program is running.  Quit anyway (and kill it)? (y or n) y
mongoose:build.unix {2}

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
To set a counter breakpoint from inside a debugger, set the global variable
debug_test to the counter value at which you want to stop.  For example,
you might first stop at operation 100, and then stop at operation 200 by
initially setting a breakpoint in __db_loadme, issuing a debug 100 command
and then setting debug_test to 200 in the debugger.  (Some of the trickier
bugs in DB are best solved by binary search, looking for the precise moment
at which the page contents go bad.)

If you want to stop on each iteration, set the variable debug_stop to a
non-zero value.

There are also a number of routines to help you display page and tree
contents.  These routines live in ../db/db_pr.c.  The most useful are:

	__db_prpage(page_address, dump_all)
	__db_dump(DB *, file_name, dump_all)
	__memp_debug(DB_MPOOL *, file_pointer, dump_all)

For example, you can call these from gdb as follows:

	print __db_prpage(cp->page, 1)		# Display a page's contents
	print __db_dump(dbp, "/tmp/dump", 1)	# Display the entire file
	print __memp_debug(dbp->mp, 0, 1)	# Display the memory pool.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
There are two different modes of RECNO testing, with and without renumbering.
The default (as of 2.3.0) is that RECNO does not renumber by default.  In
order to specify renumbering, all you need to do is set the DB_RENUMBER flag
as an optional parameter.  However, in order to simplify testing, the access
method type RRECNO implies RECNO with renumbering.

The DB tester currently has the following tests:

test001:	Small keys/data		HASH, BTREE, RECNO
		Put/get per key.
		Dump file, verify.
		Close, reopen.
		Dump file, verify.

test002:	Small keys/medium data	HASH, BTREE, RECNO
		Put/get per key.
		Dump file, verify.
		Close, reopen.
		Dump file, verify.

test003:	Small keys/large data	HASH, BTREE, RECNO
		Put/get per key.
		Dump file, verify.
		Close, reopen.
		Dump file, verify.

test004:	Small keys/medium data	HASH, BTREE, RECNO
		Put/get per key.
		Sequential (cursor) get/delete and verify

test005:	Small keys/medium data	HASH, BTREE, RECNO
		Put/get per key.
		Close, reopen.
		Sequential (cursor) get/delete and verify

test006:	Small keys/medium data	HASH, BTREE, RECNO
		Put/get per key.
		Keyed delete and verify

test007:	Small keys/medium data	HASH, BTREE, RECNO
		Put/get per key.
		Close, reopen.
		Keyed delete and verify

test008:	Small keys/large data	HASH, BTREE, RECNO
		Put/get per key.
		Loop through keys by steps (which change).
			delete each key at step
			add each key back
			change step.
		Tests that overflow pages are getting reused appropriately.

test009:	Same as 8; close and reopen database.

test010:	Duplicate test (small key/data pairs) (btree, hash)

test011:	Duplicate test (small key/data pairs).  Test out
		Keyfirst, Keylast, add_before and add_after.  To verify
		duplicates onto overflow pages, run with small pagesize.

test012:	Similar to test003 except we use big keys (executables)
		and small data (the executable names).

test013:	First partial put test.  Overwrite entire records using
		partial puts.  Make sure that we do not allow overwrites
		when the NOOVERWRITE flag is set.

test014:	Exercise partial puts on short data.  Run 5 combinations
		of numbers of characters to replace, and number of times
		to increase the size by.

test015:	Partial put where the key does not initially exist.

test016:	Partial put where the datum gets shorter as a result of
		the put.

test017:	Basic offpage duplicate test.

test018:	Key_{first,last,before,after} offpage duplicates.

test019:	Partial get test.

test020:	In-Memory database tests.

test021:	Btree range tests.

test022:	Test multiple data directories.

test023:	Exercise deletes and cursor operations within a duplicate set.

test024:	Test Btree/Recno get by record number tests.

test025:	Test DB_APPEND for recno.

test026:	Small keys/medium data w/duplicates HASH, BTREE
		Put/get per key.
		Loop through keys -- delete each key
			Tests that we are deleting dups correctly
			with the cursor

test027:	Call test026 with parameters to force off-page duplicates.

test028:	Test put operations after deleting through a cursor.

test029:	Record renumbering for recno and btree.

test030:	Random tester.  Runs a number of random add/delete/retrieve
		operations.  Tests both successful conditions and error
		conditions.

test031:	Multi-process random test.  Tests multiple processes running
		random operations concurrently.  Has the potential for
		deadlocks.

test032:	System integration tests.  Requires proper functioning of
		the checkpoint daemon, recovery, transactions, etc.

test033:	Get/Put/Delete operation flags (not yet completed).

parmtest:	run access method tests with a combination of parameters.

Locking Tests

lock001		Specifically checks: open, close, unlink.
lock002		Gets/Puts. Contention without waiting.
lock003		Growing a shared region.
lock004		Multi-process lock tests.
lock005		Multiprocess random lock test.

Log Tests
log001		Specifically checks: open, close, unlink.
log002		Read/write log records.
log003		Tests multiple logs, truncation, lsn comparison and file
		functionality.
log004		Verify that log_flush is flushing records when we think
		it should be.

Mpool Tests
memp001		Randomly updates pages.
memp002		Tests multiple processes accessing and modifying the same
		files.

Txn Tests
txn001		Specifically checks: open, close, unlink.
txn002		Begin, commit, abort testing.
txn003		Region growing code.

Recovery Tests

recd001		Per-operation recovery tests for non-duplicate, non-split
		messages.  Makes sure that we exercise redo, undo, and
		do-nothing condition.  Any test that appears with the
		message (change state) indicates that we've already run
		the particular test, but we are running it again so that
		we can change the state of the data base to prepare for
		the next test (this applies to all other recovery tests
		as well).

recd002		Split recovery tests.  For every known split log message,
		makes sure that we exercise redo, undo, and do-nothing
		condition.

recd003		Duplicate recovery tests.  For every known duplicate log
		message, makes sure that we exercise redo, undo, and
		do-nothing condition.

recd004		Big key test where big key gets elevated to internal page.

Deadlock detector tests

dead001		Use two different configurations to test deadlock detection
		among a variable number of processes.  One configuration has
		the processes deadlocked in a ring.  The other has the
		processes all deadlocked on a single resource.

dead002		Same test as above, but use "detect on every collision" instead
		of separate deadlockd detector.

Bug tests

bug001		Cursor maintenance in duplicates.
bug002		Cursor ops not in duplicates
bug003		Delete with cursor on a key.
bug004		Delete cursor key and re-add.
bug005		Verify that deleting and readding duplicates results in
		correct ordering.
bug006		Log prev works across log files.
bug007		Cursor ops work with a partial length of 0.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Planned tests that are not yet written:

testXXX:	Cursor locking test.

test021:	Interface test (all flags to all functions).
		db_appinit options

testXXX:	errno testing (if -1 is returned, errno should be set)
