The db test has been atf-ified

This commit is contained in:
pgoyette 2011-01-07 15:08:40 +00:00
parent 27aeaab683
commit a3eac7b0e8
5 changed files with 2 additions and 1547 deletions

View File

@ -1,6 +1,6 @@
# $NetBSD: Makefile,v 1.75 2011/01/07 02:51:38 pgoyette Exp $
# $NetBSD: Makefile,v 1.76 2011/01/07 15:08:40 pgoyette Exp $
SUBDIR+= citrus db divrem getaddrinfo int_fmtio locale regex rpc
SUBDIR+= citrus divrem getaddrinfo int_fmtio locale regex rpc
.include <bsd.own.mk>
.include <bsd.sys.mk>

View File

@ -1,37 +0,0 @@
# $NetBSD: Makefile,v 1.19 2009/01/24 22:11:45 christos Exp $
# @(#)Makefile 8.1 (Berkeley) 6/4/93
NOMAN= # defined
WARNS=4
PROG= dbtest
.if defined(LOCALLIBC)
SRCS= dbtest.c
SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c
SRCS+= hash_page.c ndbm.c ndbmdatum.c
SRCS+= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c
SRCS+= bt_overflow.c bt_page.c bt_put.c bt_search.c bt_seq.c bt_split.c
SRCS+= bt_utils.c
SRCS+= rec_close.c rec_delete.c rec_get.c rec_open.c rec_put.c
SRCS+= rec_search.c rec_seq.c rec_utils.c
SRCS+= db.c
SRCS+= mpool.c
.PATH.c: /usr/src/lib/libc/db/hash
.PATH.c: /usr/src/lib/libc/db/btree
.PATH.c: /usr/src/lib/libc/db/recno
.PATH.c: /usr/src/lib/libc/db/mpool
.PATH.c: /usr/src/lib/libc/db/db
# add -DSTATISTICS to CPPFLAGS to get usage statistics. Note that
# for this to work, libc must be compiled with -DSTATISTICS as well
CPPFLAGS+= -g -D__DBINTERFACE_PRIVATE
CPPFLAGS+= -I/usr/src/lib/libc/include
CPPFLAGS+= -DDEBUG -DSTATISTICS -DHASH_STATISTICS
CPPFLAGS+= -DDEBUG1 -DDEBUG2 -DDEBUG3 -DDEBUG4 -DDEBUG5 -DDIAGNOSTIC
.endif
CLEANFILES+= t1 t2 t3
regress: dbtest
${HOST_SH} ${.CURDIR}/run.test
.include <bsd.prog.mk>

View File

@ -1,68 +0,0 @@
# $NetBSD: README,v 1.5 1996/05/03 21:54:19 cgd Exp $
# @(#)README 8.8 (Berkeley) 7/31/94
To run the tests, enter "make regress".
Fairly large files (the command files) are built in this directory during
the test runs, and even larger files (the database files) are created in
"/var/tmp". If the latter directory doesn't exist, set the environmental
variable TMPDIR to a directory where the files can be built.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The script file consists of lines with an initial character which is
the command for that line, or an initial character indicating a key
or data entry for a previous command.
Legal command characters are as follows:
c: compare a record
+ must be followed by [kK][dD]; the data value in the database
associated with the specified key is compared to the specified
data value.
e: echo a string
+ writes out the rest of the line into the output file; if the
last character is not a carriage-return, a newline is appended.
f: set the flags for the next command
+ no value zero's the flags
g: do a get command
+ must be followed by [kK]
+ writes out the retrieved data DBT.
o [r]: dump [reverse]
+ dump the database out, if 'r' is set, in reverse order.
p: do a put command
+ must be followed by [kK][dD]
r: do a del command
+ must be followed by [kK] unless R_CURSOR flag set.
S: sync the database
s: do a seq command
+ must be followed by [kK] if R_CURSOR flag set.
+ writes out the retrieved data DBT.
Legal key/data characters are as follows:
D [file]: data file
+ set the current data value to the contents of the file
d [data]:
+ set the current key value to the contents of the line.
K [file]: key file
+ set the current key value to the contents of the file
k [data]:
+ set the current key value to the contents of the line.
Blank lines, lines with leading white space, and lines with leading
hash marks (#) are ignored.
Options to dbtest are as follows:
-d: Set the DB_LOCK flag.
-f: Use the file argument as the database file.
-i: Use the rest of the argument to set elements in the info
structure. If the type is btree, then "-i cachesize=10240"
will set BTREEINFO.cachesize to 10240.
-o: The rest of the argument is the output file instead of
using stdout.
-s: Don't delete the database file before opening it, i.e.
use the database file from a previous run.
Dbtest requires two arguments, the type of access "hash", "recno"
or "btree", and the script name or "-" to indicate stdin.

View File

@ -1,731 +0,0 @@
/* $NetBSD: dbtest.c,v 1.18 2009/01/25 17:00:09 nonaka Exp $ */
/*-
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94";
#else
__RCSID("$NetBSD: dbtest.c,v 1.18 2009/01/25 17:00:09 nonaka Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <err.h>
#include <db.h>
enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
static void compare(DBT *, DBT *);
static DBTYPE dbtype(const char *);
static void dump(DB *, int);
static void get(DB *, DBT *);
static void getdata(DB *, DBT *, DBT *);
static void put(DB *, DBT *, DBT *);
static void rem(DB *, DBT *);
static const char *sflags(int);
static void synk(DB *);
static void *rfile(char *, size_t *);
static void seq(DB *, DBT *);
static u_int setflags(char *);
static void *setinfo(DBTYPE, char *);
static void usage(void) __attribute__((__noreturn__));
static void *xcopy(void *, size_t);
static void chkcmd(enum S);
static void chkdata(enum S);
static void chkkey(enum S);
#ifdef STATISTICS
extern void __bt_stat(DB *);
#endif
static DBTYPE type; /* Database type. */
static void *infop; /* Iflags. */
static size_t lineno; /* Current line in test script. */
static u_int flags; /* Current DB flags. */
static int ofd = STDOUT_FILENO; /* Standard output fd. */
static DB *XXdbp; /* Global for gdb. */
static size_t XXlineno; /* Fast breakpoint for gdb. */
int
main(int argc, char *argv[])
{
extern int optind;
extern char *optarg;
enum S command = COMMAND, state;
DB *dbp;
DBT data, key, keydata;
size_t len;
int ch, oflags, sflag;
char *fname, *infoarg, *p, *t, buf[8 * 1024];
bool unlink_dbfile;
infoarg = NULL;
fname = NULL;
unlink_dbfile = false;
oflags = O_CREAT | O_RDWR;
sflag = 0;
while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1)
switch (ch) {
case 'f':
fname = optarg;
break;
case 'i':
infoarg = optarg;
break;
case 'l':
oflags |= DB_LOCK;
break;
case 'o':
if ((ofd = open(optarg,
O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
err(1, "Cannot create `%s'", optarg);
break;
case 's':
sflag = 1;
break;
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
if (argc != 2)
usage();
/* Set the type. */
type = dbtype(*argv++);
/* Open the descriptor file. */
if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
err(1, "Cannot reopen `%s'", *argv);
/* Set up the db structure as necessary. */
if (infoarg == NULL)
infop = NULL;
else
for (p = strtok(infoarg, ",\t "); p != NULL;
p = strtok(0, ",\t "))
if (*p != '\0')
infop = setinfo(type, p);
/*
* Open the DB. Delete any preexisting copy, you almost never
* want it around, and it often screws up tests.
*/
if (fname == NULL) {
const char *q = getenv("TMPDIR");
if (q == NULL)
q = "/var/tmp";
(void)snprintf(buf, sizeof(buf), "%s/__dbtest", q);
fname = buf;
(void)unlink(buf);
unlink_dbfile = true;
} else if (!sflag)
(void)unlink(fname);
if ((dbp = dbopen(fname,
oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
err(1, "Cannot dbopen `%s'", fname);
XXdbp = dbp;
if (unlink_dbfile)
(void)unlink(fname);
state = COMMAND;
for (lineno = 1;
(p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
/* Delete the newline, displaying the key/data is easier. */
if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
*t = '\0';
if ((len = strlen(buf)) == 0 || isspace((unsigned char)*p) ||
*p == '#')
continue;
/* Convenient gdb break point. */
if (XXlineno == lineno)
XXlineno = 1;
switch (*p) {
case 'c': /* compare */
chkcmd(state);
state = KEY;
command = COMPARE;
break;
case 'e': /* echo */
chkcmd(state);
/* Don't display the newline, if CR at EOL. */
if (p[len - 2] == '\r')
--len;
if ((size_t)write(ofd, p + 1, len - 1) != (len - 1) ||
write(ofd, "\n", 1) != 1)
err(1, "write failed");
break;
case 'g': /* get */
chkcmd(state);
state = KEY;
command = GET;
break;
case 'p': /* put */
chkcmd(state);
state = KEY;
command = PUT;
break;
case 'r': /* remove */
chkcmd(state);
if (flags == R_CURSOR) {
rem(dbp, &key);
state = COMMAND;
} else {
state = KEY;
command = REMOVE;
}
break;
case 'S': /* sync */
chkcmd(state);
synk(dbp);
state = COMMAND;
break;
case 's': /* seq */
chkcmd(state);
if (flags == R_CURSOR) {
state = KEY;
command = SEQ;
} else
seq(dbp, &key);
break;
case 'f':
flags = setflags(p + 1);
break;
case 'D': /* data file */
chkdata(state);
data.data = rfile(p + 1, &data.size);
goto ldata;
case 'd': /* data */
chkdata(state);
data.data = xcopy(p + 1, len - 1);
data.size = len - 1;
ldata: switch (command) {
case COMPARE:
compare(&keydata, &data);
break;
case PUT:
put(dbp, &key, &data);
break;
default:
errx(1, "line %zu: command doesn't take data",
lineno);
}
if (type != DB_RECNO)
free(key.data);
free(data.data);
state = COMMAND;
break;
case 'K': /* key file */
chkkey(state);
if (type == DB_RECNO)
errx(1, "line %zu: 'K' not available for recno",
lineno);
key.data = rfile(p + 1, &key.size);
goto lkey;
case 'k': /* key */
chkkey(state);
if (type == DB_RECNO) {
static recno_t recno;
recno = atoi(p + 1);
key.data = &recno;
key.size = sizeof(recno);
} else {
key.data = xcopy(p + 1, len - 1);
key.size = len - 1;
}
lkey: switch (command) {
case COMPARE:
getdata(dbp, &key, &keydata);
state = DATA;
break;
case GET:
get(dbp, &key);
if (type != DB_RECNO)
free(key.data);
state = COMMAND;
break;
case PUT:
state = DATA;
break;
case REMOVE:
rem(dbp, &key);
if ((type != DB_RECNO) && (flags != R_CURSOR))
free(key.data);
state = COMMAND;
break;
case SEQ:
seq(dbp, &key);
if ((type != DB_RECNO) && (flags != R_CURSOR))
free(key.data);
state = COMMAND;
break;
default:
errx(1, "line %zu: command doesn't take a key",
lineno);
}
break;
case 'o':
dump(dbp, p[1] == 'r');
break;
default:
errx(1, "line %zu: %s: unknown command character",
lineno, p);
}
}
#ifdef STATISTICS
/*
* -l must be used (DB_LOCK must be set) for this to be
* used, otherwise a page will be locked and it will fail.
*/
if (type == DB_BTREE && oflags & DB_LOCK)
__bt_stat(dbp);
#endif
if ((*dbp->close)(dbp))
err(1, "db->close failed");
(void)close(ofd);
return 0;
}
#define NOOVERWRITE "put failed, would overwrite key\n"
static void
compare(DBT *db1, DBT *db2)
{
size_t len;
u_char *p1, *p2;
if (db1->size != db2->size)
printf("compare failed: key->data len %zu != data len %zu\n",
db1->size, db2->size);
len = MIN(db1->size, db2->size);
for (p1 = db1->data, p2 = db2->data; len--;)
if (*p1++ != *p2++) {
printf("compare failed at offset %lu\n",
(unsigned long)(p1 - (u_char *)db1->data));
break;
}
}
static void
get(DB *dbp, DBT *kp)
{
DBT data;
switch ((*dbp->get)(dbp, kp, &data, flags)) {
case 0:
(void)write(ofd, data.data, data.size);
if (ofd == STDOUT_FILENO)
(void)write(ofd, "\n", 1);
break;
case -1:
err(1, "line %zu: get failed", lineno);
/* NOTREACHED */
case 1:
#define NOSUCHKEY "get failed, no such key\n"
if (ofd != STDOUT_FILENO)
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
else
(void)fprintf(stderr, "%zu: %.*s: %s",
lineno, (int)MIN(kp->size, 20),
(const char *)kp->data,
NOSUCHKEY);
#undef NOSUCHKEY
break;
}
}
static void
getdata(DB *dbp, DBT *kp, DBT *dp)
{
switch ((*dbp->get)(dbp, kp, dp, flags)) {
case 0:
return;
case -1:
err(1, "line %zu: getdata failed", lineno);
/* NOTREACHED */
case 1:
errx(1, "line %zu: getdata failed, no such key", lineno);
/* NOTREACHED */
}
}
static void
put(DB *dbp, DBT *kp, DBT *dp)
{
switch ((*dbp->put)(dbp, kp, dp, flags)) {
case 0:
break;
case -1:
err(1, "line %zu: put failed", lineno);
/* NOTREACHED */
case 1:
(void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
break;
}
}
static void
rem(DB *dbp, DBT *kp)
{
switch ((*dbp->del)(dbp, kp, flags)) {
case 0:
break;
case -1:
err(1, "line %zu: rem failed", lineno);
/* NOTREACHED */
case 1:
#define NOSUCHKEY "rem failed, no such key\n"
if (ofd != STDOUT_FILENO)
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
else if (flags != R_CURSOR)
(void)fprintf(stderr, "%zu: %.*s: %s",
lineno, (int)MIN(kp->size, 20),
(const char *)kp->data, NOSUCHKEY);
else
(void)fprintf(stderr,
"%zu: rem of cursor failed\n", lineno);
#undef NOSUCHKEY
break;
}
}
static void
synk(DB *dbp)
{
switch ((*dbp->sync)(dbp, flags)) {
case 0:
break;
case -1:
err(1, "line %zu: synk failed", lineno);
/* NOTREACHED */
}
}
static void
seq(DB *dbp, DBT *kp)
{
DBT data;
switch (dbp->seq(dbp, kp, &data, flags)) {
case 0:
(void)write(ofd, data.data, data.size);
if (ofd == STDOUT_FILENO)
(void)write(ofd, "\n", 1);
break;
case -1:
err(1, "line %zu: seq failed", lineno);
/* NOTREACHED */
case 1:
#define NOSUCHKEY "seq failed, no such key\n"
if (ofd != STDOUT_FILENO)
(void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
else if (flags == R_CURSOR)
(void)fprintf(stderr, "%zu: %.*s: %s",
lineno, (int)MIN(kp->size, 20),
(const char *)kp->data, NOSUCHKEY);
else
(void)fprintf(stderr,
"%zu: seq (%s) failed\n", lineno, sflags(flags));
#undef NOSUCHKEY
break;
}
}
static void
dump(DB *dbp, int rev)
{
DBT key, data;
int xflags, nflags;
if (rev) {
xflags = R_LAST;
nflags = R_PREV;
} else {
xflags = R_FIRST;
nflags = R_NEXT;
}
for (;; xflags = nflags)
switch (dbp->seq(dbp, &key, &data, xflags)) {
case 0:
(void)write(ofd, data.data, data.size);
if (ofd == STDOUT_FILENO)
(void)write(ofd, "\n", 1);
break;
case 1:
goto done;
case -1:
err(1, "line %zu: (dump) seq failed", lineno);
/* NOTREACHED */
}
done: return;
}
static u_int
setflags(char *s)
{
char *p;
for (; isspace((unsigned char)*s); ++s);
if (*s == '\n' || *s == '\0')
return 0;
if ((p = strchr(s, '\n')) != NULL)
*p = '\0';
if (!strcmp(s, "R_CURSOR")) return R_CURSOR;
if (!strcmp(s, "R_FIRST")) return R_FIRST;
if (!strcmp(s, "R_IAFTER")) return R_IAFTER;
if (!strcmp(s, "R_IBEFORE")) return R_IBEFORE;
if (!strcmp(s, "R_LAST")) return R_LAST;
if (!strcmp(s, "R_NEXT")) return R_NEXT;
if (!strcmp(s, "R_NOOVERWRITE")) return R_NOOVERWRITE;
if (!strcmp(s, "R_PREV")) return R_PREV;
if (!strcmp(s, "R_SETCURSOR")) return R_SETCURSOR;
errx(1, "line %zu: %s: unknown flag", lineno, s);
/* NOTREACHED */
}
static const char *
sflags(int xflags)
{
switch (xflags) {
case R_CURSOR: return "R_CURSOR";
case R_FIRST: return "R_FIRST";
case R_IAFTER: return "R_IAFTER";
case R_IBEFORE: return "R_IBEFORE";
case R_LAST: return "R_LAST";
case R_NEXT: return "R_NEXT";
case R_NOOVERWRITE: return "R_NOOVERWRITE";
case R_PREV: return "R_PREV";
case R_SETCURSOR: return "R_SETCURSOR";
}
return "UNKNOWN!";
}
static DBTYPE
dbtype(const char *s)
{
if (!strcmp(s, "btree"))
return DB_BTREE;
if (!strcmp(s, "hash"))
return DB_HASH;
if (!strcmp(s, "recno"))
return DB_RECNO;
errx(1, "%s: unknown type (use btree, hash or recno)", s);
/* NOTREACHED */
}
static void *
setinfo(DBTYPE dtype, char *s)
{
static BTREEINFO ib;
static HASHINFO ih;
static RECNOINFO rh;
char *eq;
if ((eq = strchr(s, '=')) == NULL)
errx(1, "%s: illegal structure set statement", s);
*eq++ = '\0';
if (!isdigit((unsigned char)*eq))
errx(1, "%s: structure set statement must be a number", s);
switch (dtype) {
case DB_BTREE:
if (!strcmp("flags", s)) {
ib.flags = atoi(eq);
return &ib;
}
if (!strcmp("cachesize", s)) {
ib.cachesize = atoi(eq);
return &ib;
}
if (!strcmp("maxkeypage", s)) {
ib.maxkeypage = atoi(eq);
return &ib;
}
if (!strcmp("minkeypage", s)) {
ib.minkeypage = atoi(eq);
return &ib;
}
if (!strcmp("lorder", s)) {
ib.lorder = atoi(eq);
return &ib;
}
if (!strcmp("psize", s)) {
ib.psize = atoi(eq);
return &ib;
}
break;
case DB_HASH:
if (!strcmp("bsize", s)) {
ih.bsize = atoi(eq);
return &ih;
}
if (!strcmp("ffactor", s)) {
ih.ffactor = atoi(eq);
return &ih;
}
if (!strcmp("nelem", s)) {
ih.nelem = atoi(eq);
return &ih;
}
if (!strcmp("cachesize", s)) {
ih.cachesize = atoi(eq);
return &ih;
}
if (!strcmp("lorder", s)) {
ih.lorder = atoi(eq);
return &ih;
}
break;
case DB_RECNO:
if (!strcmp("flags", s)) {
rh.flags = atoi(eq);
return &rh;
}
if (!strcmp("cachesize", s)) {
rh.cachesize = atoi(eq);
return &rh;
}
if (!strcmp("lorder", s)) {
rh.lorder = atoi(eq);
return &rh;
}
if (!strcmp("reclen", s)) {
rh.reclen = atoi(eq);
return &rh;
}
if (!strcmp("bval", s)) {
rh.bval = atoi(eq);
return &rh;
}
if (!strcmp("psize", s)) {
rh.psize = atoi(eq);
return &rh;
}
break;
}
errx(1, "%s: unknown structure value", s);
/* NOTREACHED */
}
static void *
rfile(char *name, size_t *lenp)
{
struct stat sb;
void *p;
int fd;
char *np;
for (; isspace((unsigned char)*name); ++name)
continue;
if ((np = strchr(name, '\n')) != NULL)
*np = '\0';
if ((fd = open(name, O_RDONLY, 0)) == -1 || fstat(fd, &sb) == -1)
err(1, "Cannot open `%s'", name);
#ifdef NOT_PORTABLE
if (sb.st_size > (off_t)SIZE_T_MAX) {
errno = E2BIG;
err("Cannot process `%s'", name);
}
#endif
if ((p = malloc((size_t)sb.st_size)) == NULL)
err(1, "Cannot allocate %zu bytes", (size_t)sb.st_size);
if (read(fd, p, (ssize_t)sb.st_size) != (ssize_t)sb.st_size)
err(1, "read failed");
*lenp = (size_t)sb.st_size;
(void)close(fd);
return p;
}
static void *
xcopy(void *text, size_t len)
{
void *p;
if ((p = malloc(len)) == NULL)
err(1, "Cannot allocate %zu bytes", len);
(void)memmove(p, text, len);
return p;
}
static void
chkcmd(enum S state)
{
if (state != COMMAND)
errx(1, "line %zu: not expecting command", lineno);
}
static void
chkdata(enum S state)
{
if (state != DATA)
errx(1, "line %zu: not expecting data", lineno);
}
static void
chkkey(enum S state)
{
if (state != KEY)
errx(1, "line %zu: not expecting a key", lineno);
}
static void
usage(void)
{
(void)fprintf(stderr,
"Usage: %s [-l] [-f file] [-i info] [-o file] type script\n",
getprogname());
exit(1);
}

View File

@ -1,709 +0,0 @@
#!/bin/sh -
#
# $NetBSD: run.test,v 1.11 2007/02/03 20:59:34 christos Exp $
# @(#)run.test 8.10 (Berkeley) 7/26/94
#
# db regression tests
PNAME="$(basename "$0")"
usage() {
echo "Usage: $PNAME [-p <binary>] test# ... | [hash|btree|recno]" 1>&2
exit 1
}
main()
{
PROG=./dbtest
while getopts p: f; do
case $f in
p) PROG="$OPTARG";;
*) usage;;
esac
done
shift $(expr $OPTIND - 1)
TMP1=t1
TMP2=t2
TMP3=t3
SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg"
trap "rm -f $TMP1 $TMP2 $TMP3" 0 1 2 3 15
if [ -f /usr/share/dict/words ]; then
DICT=/usr/share/dict/words
elif [ -f /usr/dict/words ]; then
DICT=/usr/dict/words
else
echo "$PNAME: no dictionary" 1>&2
exit 1
fi
if [ $# -eq 0 ]; then
for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20 21; do
test$t
done
else
while [ $# -gt 0 ]; do
case "$1" in
test*)
$1;;
[0-9]*)
test$1;;
btree)
for t in 1 2 3 7 8 9 10 12 13; do
test$t
done;;
hash)
for t in 1 2 3 8 13 20; do
test$t
done;;
recno)
for t in 1 2 3 4 5 6 7 10 11; do
test$t
done;;
*)
echo "$PNAME: unknown test $1" 1>&2
usage
esac
shift
done
fi
exit 0
}
# Take the first hundred entries in the dictionary, and make them
# be key/data pairs.
test1()
{
echo "Test 1: btree, hash: small key, small data pairs"
sed 200q $DICT > $TMP1
for type in btree hash; do
rm -f $TMP2 $TMP3
for i in `sed 200q $DICT`; do
echo p
echo k$i
echo d$i
echo g
echo k$i
done > $TMP2
$PROG -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test1: type $type: failed" 1>&2
exit 1
fi
done
echo "Test 1: recno: small key, small data pairs"
rm -f $TMP2 $TMP3
sed 200q $DICT |
awk '{
++i;
printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
}' > $TMP2
$PROG -o $TMP3 recno $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test1: type recno: failed" 1>&2
exit 1
fi
}
# Take the first 200 entries in the dictionary, and give them
# each a medium size data entry.
test2()
{
echo "Test 2: btree, hash: small key, medium data pairs"
mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
echo $mdata |
awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1
for type in hash btree; do
rm -f $TMP2 $TMP3
for i in $(sed 200q $DICT); do
echo p
echo k$i
echo d$mdata
echo g
echo k$i
done > $TMP2
$PROG -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test2: type $type: failed" 1>&2
exit 1
fi
done
echo "Test 2: recno: small key, medium data pairs"
rm -f $TMP2 $TMP3
echo $mdata |
awk '{ for (i = 1; i < 201; ++i)
printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
}' > $TMP2
$PROG -o $TMP3 recno $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test2: type recno: failed" 1>&2
exit 1
fi
}
# Insert the programs in /bin with their paths as their keys.
test3()
{
echo "Test 3: hash: small key, big data pairs"
rm -f $TMP1
(find /bin -type f -print | xargs cat) > $TMP1
for type in hash; do
rm -f $TMP2 $TMP3
for i in `find /bin -type f -print`; do
echo p
echo k$i
echo D$i
echo g
echo k$i
done > $TMP2
$PROG -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test3: $type: failed" 1>&2
exit 1
fi
done
echo "Test 3: btree: small key, big data pairs"
for psize in 512 16384 65536; do
echo " page size $psize"
for type in btree; do
rm -f $TMP2 $TMP3
for i in `find /bin -type f -print`; do
echo p
echo k$i
echo D$i
echo g
echo k$i
done > $TMP2
$PROG -i psize=$psize -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test3: $type: page size $psize: failed" 1>&2
exit 1
fi
done
done
echo "Test 3: recno: big data pairs"
rm -f $TMP2 $TMP3
find /bin -type f -print |
awk '{
++i;
printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
}' > $TMP2
for psize in 512 16384 65536; do
echo " page size $psize"
$PROG -i psize=$psize -o $TMP3 recno $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test3: recno: page size $psize: failed" 1>&2
exit 1
fi
done
}
# Do random recno entries.
test4()
{
echo "Test 4: recno: random entries"
echo $SEVEN_SEVEN |
awk '{
for (i = 37; i <= 37 + 88 * 17; i += 17) {
if (i % 41)
s = substr($0, 1, i % 41);
else
s = substr($0, 1);
printf("input key %d: %s\n", i, s);
}
for (i = 1; i <= 15; ++i) {
if (i % 41)
s = substr($0, 1, i % 41);
else
s = substr($0, 1);
printf("input key %d: %s\n", i, s);
}
for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
if (i % 41)
s = substr($0, 1, i % 41);
else
s = substr($0, 1);
printf("input key %d: %s\n", i, s);
}
exit
}' > $TMP1
rm -f $TMP2 $TMP3
cat $TMP1 |
awk 'BEGIN {
i = 37;
incr = 17;
}
{
printf("p\nk%d\nd%s\n", i, $0);
if (i == 19234 + 61 * 27)
exit;
if (i == 37 + 88 * 17) {
i = 1;
incr = 1;
} else if (i == 15) {
i = 19234;
incr = 27;
} else
i += incr;
}
END {
for (i = 37; i <= 37 + 88 * 17; i += 17)
printf("g\nk%d\n", i);
for (i = 1; i <= 15; ++i)
printf("g\nk%d\n", i);
for (i = 19234; i <= 19234 + 61 * 27; i += 27)
printf("g\nk%d\n", i);
}' > $TMP2
$PROG -o $TMP3 recno $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test4: type recno: failed" 1>&2
exit 1
fi
}
# Do reverse order recno entries.
test5()
{
echo "Test 5: recno: reverse order entries"
echo $SEVEN_SEVEN |
awk ' {
for (i = 1500; i; --i) {
if (i % 34)
s = substr($0, 1, i % 34);
else
s = substr($0, 1);
printf("input key %d: %s\n", i, s);
}
exit;
}' > $TMP1
rm -f $TMP2 $TMP3
cat $TMP1 |
awk 'BEGIN {
i = 1500;
}
{
printf("p\nk%d\nd%s\n", i, $0);
--i;
}
END {
for (i = 1500; i; --i)
printf("g\nk%d\n", i);
}' > $TMP2
$PROG -o $TMP3 recno $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test5: type recno: failed" 1>&2
exit 1
fi
}
# Do alternating order recno entries.
test6()
{
echo "Test 6: recno: alternating order entries"
echo $SEVEN_SEVEN |
awk ' {
for (i = 1; i < 1200; i += 2) {
if (i % 34)
s = substr($0, 1, i % 34);
else
s = substr($0, 1);
printf("input key %d: %s\n", i, s);
}
for (i = 2; i < 1200; i += 2) {
if (i % 34)
s = substr($0, 1, i % 34);
else
s = substr($0, 1);
printf("input key %d: %s\n", i, s);
}
exit;
}' > $TMP1
rm -f $TMP2 $TMP3
cat $TMP1 |
awk 'BEGIN {
i = 1;
even = 0;
}
{
printf("p\nk%d\nd%s\n", i, $0);
i += 2;
if (i >= 1200) {
if (even == 1)
exit;
even = 1;
i = 2;
}
}
END {
for (i = 1; i < 1200; ++i)
printf("g\nk%d\n", i);
}' > $TMP2
$PROG -o $TMP3 recno $TMP2
sort -o $TMP1 $TMP1
sort -o $TMP3 $TMP3
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test6: type recno: failed" 1>&2
exit 1
fi
}
# Delete cursor record
test7()
{
echo "Test 7: btree, recno: delete cursor record"
echo $SEVEN_SEVEN |
awk '{
for (i = 1; i <= 120; ++i)
printf("%05d: input key %d: %s\n", i, i, $0);
printf("%05d: input key %d: %s\n", 120, 120, $0);
printf("seq failed, no such key\n");
printf("%05d: input key %d: %s\n", 1, 1, $0);
printf("%05d: input key %d: %s\n", 2, 2, $0);
exit;
}' > $TMP1
rm -f $TMP2 $TMP3
for type in btree recno; do
cat $TMP1 |
awk '{
if (i == 120)
exit;
printf("p\nk%d\nd%s\n", ++i, $0);
}
END {
printf("fR_NEXT\n");
for (i = 1; i <= 120; ++i)
printf("s\n");
printf("fR_CURSOR\ns\nk120\n");
printf("r\n");
printf("fR_NEXT\ns\n");
printf("fR_CURSOR\ns\nk1\n");
printf("r\n");
printf("fR_FIRST\ns\n");
}' > $TMP2
$PROG -o $TMP3 recno $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test7: type $type: failed" 1>&2
exit 1
fi
done
}
# Make sure that overflow pages are reused.
test8()
{
echo "Test 8: btree, hash: repeated small key, big data pairs"
rm -f $TMP1
echo "" |
awk 'BEGIN {
for (i = 1; i <= 10; ++i) {
printf("p\nkkey1\nD/bin/sh\n");
printf("p\nkkey2\nD/bin/csh\n");
if (i % 8 == 0) {
printf("c\nkkey2\nD/bin/csh\n");
printf("c\nkkey1\nD/bin/sh\n");
printf("e\t%d of 10 (comparison)\n", i);
} else
printf("e\t%d of 10 \n", i);
printf("r\nkkey1\nr\nkkey2\n");
}
}' > $TMP1
$PROG btree $TMP1
# $PROG hash $TMP1
# No explicit test for success.
}
# Test btree duplicate keys
test9()
{
echo "Test 9: btree: duplicate keys"
echo $SEVEN_SEVEN |
awk '{
for (i = 1; i <= 543; ++i)
printf("%05d: input key %d: %s\n", i, i, $0);
exit;
}' > $TMP1
rm -f $TMP2 $TMP3
for type in btree; do
cat $TMP1 |
awk '{
if (i++ % 2)
printf("p\nkduplicatekey\nd%s\n", $0);
else
printf("p\nkunique%dkey\nd%s\n", i, $0);
}
END {
printf("o\n");
}' > $TMP2
$PROG -iflags=1 -o $TMP3 $type $TMP2
sort -o $TMP3 $TMP3
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test9: type $type: failed" 1>&2
exit 1
fi
done
}
# Test use of cursor flags without initialization
test10()
{
echo "Test 10: btree, recno: test cursor flag use"
echo $SEVEN_SEVEN |
awk '{
for (i = 1; i <= 20; ++i)
printf("%05d: input key %d: %s\n", i, i, $0);
exit;
}' > $TMP1
rm -f $TMP2 $TMP3
# Test that R_CURSOR doesn't succeed before cursor initialized
for type in btree recno; do
cat $TMP1 |
awk '{
if (i == 10)
exit;
printf("p\nk%d\nd%s\n", ++i, $0);
}
END {
printf("fR_CURSOR\nr\n");
printf("eR_CURSOR SHOULD HAVE FAILED\n");
}' > $TMP2
$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
if [ -s $TMP3 ] ; then
echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
exit 1
fi
done
for type in btree recno; do
cat $TMP1 |
awk '{
if (i == 10)
exit;
printf("p\nk%d\nd%s\n", ++i, $0);
}
END {
printf("fR_CURSOR\np\nk1\ndsome data\n");
printf("eR_CURSOR SHOULD HAVE FAILED\n");
}' > $TMP2
$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
if [ -s $TMP3 ] ; then
echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
exit 1
fi
done
}
# Test insert in reverse order.
test11()
{
echo "Test 11: recno: reverse order insert"
echo $SEVEN_SEVEN |
awk '{
for (i = 1; i <= 779; ++i)
printf("%05d: input key %d: %s\n", i, i, $0);
exit;
}' > $TMP1
rm -f $TMP2 $TMP3
for type in recno; do
cat $TMP1 |
awk '{
if (i == 0) {
i = 1;
printf("p\nk1\nd%s\n", $0);
printf("%s\n", "fR_IBEFORE");
} else
printf("p\nk1\nd%s\n", $0);
}
END {
printf("or\n");
}' > $TMP2
$PROG -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test11: type $type: failed" 1>&2
exit 1
fi
done
}
# Take the first 20000 entries in the dictionary, reverse them, and give
# them each a small size data entry. Use a small page size to make sure
# the btree split code gets hammered.
test12()
{
echo "Test 12: btree: lots of keys, small page size"
mdata=abcdefghijklmnopqrstuvwxy
echo $mdata |
awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
for type in btree; do
rm -f $TMP2 $TMP3
for i in `sed 20000q $DICT | rev`; do
echo p
echo k$i
echo d$mdata
echo g
echo k$i
done > $TMP2
$PROG -i psize=512 -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test12: type $type: failed" 1>&2
exit 1
fi
done
}
# Test different byte orders.
test13()
{
echo "Test 13: btree, hash: differing byte orders"
sed 50q $DICT > $TMP1
for order in 1234 4321; do
for type in btree hash; do
rm -f byte.file $TMP2 $TMP3
for i in `sed 50q $DICT`; do
echo p
echo k$i
echo d$i
echo g
echo k$i
done > $TMP2
$PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test13: $type/$order put failed" 1>&2
exit 1
fi
for i in `sed 50q $DICT`; do
echo g
echo k$i
done > $TMP2
$PROG -s \
-ilorder=$order -f byte.file -o $TMP3 $type $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test13: $type/$order get failed" 1>&2
exit 1
fi
done
done
rm -f byte.file
}
# Try a variety of bucketsizes and fill factors for hashing
test20()
{
echo\
"Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536"
echo $SEVEN_SEVEN |
awk '{
for (i = 1; i <= 10000; ++i) {
if (i % 34)
s = substr($0, 1, i % 34);
else
s = substr($0, 1);
printf("%s\n", s);
}
exit;
}' > $TMP1
sed 10000q $DICT |
awk 'BEGIN {
ds="'$SEVEN_SEVEN'"
}
{
if (++i % 34)
s = substr(ds, 1, i % 34);
else
s = substr(ds, 1);
printf("p\nk%s\nd%s\n", $0, s);
}' > $TMP2
sed 10000q $DICT |
awk '{
++i;
printf("g\nk%s\n", $0);
}' >> $TMP2
bsize=256
for ffactor in 11 14 21; do
echo " bucketsize $bsize, fill factor $ffactor"
$PROG -o$TMP3 \
-ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
hash $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test20: type hash:\
bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" 1>&2
exit 1
fi
done
bsize=512
for ffactor in 21 28 43; do
echo " bucketsize $bsize, fill factor $ffactor"
$PROG -o$TMP3 \
-ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
hash $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test20: type hash:\
bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" 1>&2
exit 1
fi
done
bsize=1024
for ffactor in 43 57 85; do
echo " bucketsize $bsize, fill factor $ffactor"
$PROG -o$TMP3 \
-ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
hash $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test20: type hash:\
bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" 1>&2
exit 1
fi
done
bsize=2048
for ffactor in 85 114 171; do
echo " bucketsize $bsize, fill factor $ffactor"
$PROG -o$TMP3 \
-ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
hash $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test20: type hash:\
bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" 1>&2
exit 1
fi
done
bsize=4096
for ffactor in 171 228 341; do
echo " bucketsize $bsize, fill factor $ffactor"
$PROG -o$TMP3 \
-ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
hash $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test20: type hash:\
bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" 1>&2
exit 1
fi
done
bsize=8192
for ffactor in 341 455 683; do
echo " bucketsize $bsize, fill factor $ffactor"
$PROG -o$TMP3 \
-ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
hash $TMP2
if ! cmp -s $TMP1 $TMP3; then
echo "$PNAME: test20: type hash:\
bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" 1>&2
exit 1
fi
done
}
test21() {
cat << _EOF | $PROG -i bsize=65536 hash /dev/stdin
p
k1234
d1234
r
k1234
_EOF
}
main "$@"