summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/lib/libc/db
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/netbsd-tests/lib/libc/db')
-rw-r--r--contrib/netbsd-tests/lib/libc/db/README66
-rw-r--r--contrib/netbsd-tests/lib/libc/db/h_db.c731
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/db/t_db.sh940
3 files changed, 1737 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/lib/libc/db/README b/contrib/netbsd-tests/lib/libc/db/README
new file mode 100644
index 0000000..68f0ec7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/README
@@ -0,0 +1,66 @@
+# $NetBSD: README,v 1.1 2011/01/07 15:05:58 pgoyette Exp $
+# @(#)README 8.8 (Berkeley) 7/31/94
+
+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.
diff --git a/contrib/netbsd-tests/lib/libc/db/h_db.c b/contrib/netbsd-tests/lib/libc/db/h_db.c
new file mode 100644
index 0000000..dfb1385
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/h_db.c
@@ -0,0 +1,731 @@
+/* $NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette 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: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette 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 (write(ofd, p + 1, len - 1) != (ssize_t)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);
+}
diff --git a/contrib/netbsd-tests/lib/libc/db/t_db.sh b/contrib/netbsd-tests/lib/libc/db/t_db.sh
new file mode 100755
index 0000000..d256508
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/t_db.sh
@@ -0,0 +1,940 @@
+# $NetBSD: t_db.sh,v 1.4 2013/07/29 10:43:15 skrll Exp $
+#
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+#
+
+prog()
+{
+ echo $(atf_get_srcdir)/h_db
+}
+
+dict()
+{
+ if [ -f /usr/share/dict/words ]; then
+ echo /usr/share/dict/words
+ elif [ -f /usr/dict/words ]; then
+ echo /usr/dict/words
+ else
+ atf_fail "no dictionary found"
+ fi
+}
+
+# Begin FreeBSD
+dict()
+{
+ if [ -f /usr/share/dict/words ]; then
+ echo /usr/share/dict/words
+ else
+ echo /nonexistent
+ atf_skip "Test requires dict/words"
+ fi
+}
+# End FreeBSD
+
+SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg"
+
+atf_test_case small_btree
+small_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ for i in `sed 200q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" btree in
+}
+
+atf_test_case small_hash
+small_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ for i in `sed 200q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" hash in
+}
+
+atf_test_case small_recno
+small_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ sed 200q $(dict) |
+ awk '{
+ ++i;
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case medium_btree
+medium_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ for i in $(sed 200q $(dict)); do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" btree in
+}
+
+atf_test_case medium_hash
+medium_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ for i in $(sed 200q $(dict)); do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" hash in
+}
+
+atf_test_case medium_recno
+medium_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i)
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case big_btree
+big_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ for psize in 512 16384 65536; do
+ echo "checking page size: $psize"
+
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check "$(prog)" -o out btree in
+ cmp -s exp out || atf_fail "test failed for page size: $psize"
+ done
+}
+
+atf_test_case big_hash
+big_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check "$(prog)" -o out hash in
+ cmp -s exp out || atf_fail "test failed"
+}
+
+atf_test_case big_recno
+big_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ find /bin -type f -print |
+ awk '{
+ ++i;
+ printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ for psize in 512 16384 65536; do
+ echo "checking page size: $psize"
+
+ atf_check "$(prog)" -o out recno in
+ cmp -s exp out || atf_fail "test failed for page size: $psize"
+ done
+}
+
+atf_test_case random_recno
+random_recno_head()
+{
+ atf_set "descr" "Checks recno database using random entries"
+}
+random_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ 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
+ }' >exp
+
+ cat exp |
+ 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);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case reverse_recno
+reverse_recno_head()
+{
+ atf_set "descr" "Checks recno database using reverse order entries"
+}
+reverse_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ 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;
+ }' >exp
+
+ cat exp |
+ 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);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case alternate_recno
+alternate_recno_head()
+{
+ atf_set "descr" "Checks recno database using alternating order entries"
+}
+alternate_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ 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;
+ }' >exp
+
+ cat exp |
+ 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);
+ }' >in
+
+ atf_check "$(prog)" -o out recno in
+
+ sort -o exp exp
+ sort -o out out
+
+ cmp -s exp out || atf_fail "test failed"
+}
+
+h_delete()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 120; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ }' >exp
+
+ cat exp |
+ awk '{
+ 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\nkXX\n");
+ printf("r\n");
+ printf("fR_NEXT\ns\n");
+ printf("fR_CURSOR\ns\nk1\n");
+ printf("r\n");
+ printf("fR_FIRST\ns\n");
+ }' >in
+
+ # For btree, the records are ordered by the string representation
+ # of the key value. So sort the expected output file accordingly,
+ # and set the seek_last key to the last expected key value.
+
+ if [ "$type" = "btree" ] ; then
+ sed -e 's/kXX/k99/' < in > tmp
+ mv tmp in
+ sort -d -k4 < exp > tmp
+ mv tmp exp
+ echo $SEVEN_SEVEN |
+ awk '{
+ printf("%05d: input key %d: %s\n", 99, 99, $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", 10, 10, $0);
+ exit;
+ }' >> exp
+ else
+ # For recno, records are ordered by numerical key value. No sort
+ # is needed, but still need to set proper seek_last key value.
+ sed -e 's/kXX/k120/' < in > tmp
+ mv tmp in
+ echo $SEVEN_SEVEN |
+ awk '{
+ 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;
+ }' >> exp
+ fi
+
+ atf_check "$(prog)" -o out $type in
+ atf_check -o file:exp cat out
+}
+
+atf_test_case delete_btree
+delete_btree_head()
+{
+ atf_set "descr" "Checks removing records in btree database"
+}
+delete_btree_body()
+{
+ h_delete btree
+}
+
+atf_test_case delete_recno
+delete_recno_head()
+{
+ atf_set "descr" "Checks removing records in recno database"
+}
+delete_recno_body()
+{
+ h_delete recno
+}
+
+h_repeated()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ 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");
+ }
+ }' >in
+
+ $(prog) btree in
+}
+
+atf_test_case repeated_btree
+repeated_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database with repeated small keys and" \
+ "big data pairs. Makes sure that overflow pages are reused"
+}
+repeated_btree_body()
+{
+ h_repeated btree
+}
+
+atf_test_case repeated_hash
+repeated_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database with repeated small keys and" \
+ "big data pairs. Makes sure that overflow pages are reused"
+}
+repeated_hash_body()
+{
+ h_repeated hash
+}
+
+atf_test_case duplicate_btree
+duplicate_btree_head()
+{
+ atf_set "descr" "Checks btree database with duplicate keys"
+}
+duplicate_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 543; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ cat exp |
+ 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");
+ }' >in
+
+ atf_check -o file:exp -x "$(prog) -iflags=1 btree in | sort"
+}
+
+h_cursor_flags()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 20; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ # Test that R_CURSOR doesn't succeed before cursor initialized
+ cat exp |
+ 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");
+ }' >in
+
+ atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in
+ atf_check -s ne:0 test -s out
+
+ cat exp |
+ 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");
+ }' >in
+
+ atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in
+ atf_check -s ne:0 test -s out
+}
+
+atf_test_case cursor_flags_btree
+cursor_flags_btree_head()
+{
+ atf_set "descr" \
+ "Checks use of cursor flags without initialization in btree database"
+}
+cursor_flags_btree_body()
+{
+ h_cursor_flags btree
+}
+
+atf_test_case cursor_flags_recno
+cursor_flags_recno_head()
+{
+ atf_set "descr" \
+ "Checks use of cursor flags without initialization in recno database"
+}
+cursor_flags_recno_body()
+{
+ h_cursor_flags recno
+}
+
+atf_test_case reverse_order_recno
+reverse_order_recno_head()
+{
+ atf_set "descr" "Checks reverse order inserts in recno database"
+}
+reverse_order_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 779; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ cat exp |
+ 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");
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case small_page_btree
+small_page_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database with lots of keys and small page" \
+ "size: takes the first 20000 entries in the dictionary," \
+ "reverses them, and gives them each a small size data" \
+ "entry. Uses a small page size to make sure the btree" \
+ "split code gets hammered."
+}
+small_page_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxy
+ echo $mdata |
+ awk '{ for (i = 1; i < 20001; ++i) print $0 }' >exp
+
+ for i in `sed 20000q $(dict) | rev`; do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -i psize=512 btree in
+}
+
+h_byte_orders()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ sed 50q $(dict) >exp
+ for order in 1234 4321; do
+ for i in `sed 50q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -ilorder=$order -f byte.file $type in
+
+ for i in `sed 50q $(dict)`; do
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -s -ilorder=$order -f byte.file $type in
+ done
+}
+
+atf_test_case byte_orders_btree
+byte_orders_btree_head()
+{
+ atf_set "descr" "Checks btree database using differing byte orders"
+}
+byte_orders_btree_body()
+{
+ h_byte_orders btree
+}
+
+atf_test_case byte_orders_hash
+byte_orders_hash_head()
+{
+ atf_set "descr" "Checks hash database using differing byte orders"
+}
+byte_orders_hash_body()
+{
+ h_byte_orders hash
+}
+
+h_bsize_ffactor()
+{
+ bsize=$1
+ ffactor=$2
+
+ echo "bucketsize $bsize, fill factor $ffactor"
+ atf_check -o file:exp "$(prog)" "-ibsize=$bsize,\
+ffactor=$ffactor,nelem=25000,cachesize=65536" hash in
+}
+
+atf_test_case bsize_ffactor
+bsize_ffactor_head()
+{
+ atf_set "timeout" "480"
+ atf_set "descr" "Checks hash database with various" \
+ "bucketsizes and fill factors"
+}
+bsize_ffactor_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ 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;
+
+ }' >exp
+
+ 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);
+ }' >in
+
+ sed 10000q $(dict) |
+ awk '{
+ ++i;
+ printf("g\nk%s\n", $0);
+ }' >>in
+
+ h_bsize_ffactor 256 11
+ h_bsize_ffactor 256 14
+ h_bsize_ffactor 256 21
+
+ h_bsize_ffactor 512 21
+ h_bsize_ffactor 512 28
+ h_bsize_ffactor 512 43
+
+ h_bsize_ffactor 1024 43
+ h_bsize_ffactor 1024 57
+ h_bsize_ffactor 1024 85
+
+ h_bsize_ffactor 2048 85
+ h_bsize_ffactor 2048 114
+ h_bsize_ffactor 2048 171
+
+ h_bsize_ffactor 4096 171
+ h_bsize_ffactor 4096 228
+ h_bsize_ffactor 4096 341
+
+ h_bsize_ffactor 8192 341
+ h_bsize_ffactor 8192 455
+ h_bsize_ffactor 8192 683
+}
+
+# FIXME: what does it test?
+atf_test_case four_char_hash
+four_char_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database with 4 char key and" \
+ "value insert on a 65536 bucket size"
+}
+four_char_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ cat >in <<EOF
+p
+k1234
+d1234
+r
+k1234
+EOF
+
+ # Begin FreeBSD
+ if true; then
+ atf_check "$(prog)" -i bsize=32768 hash in
+ else
+ # End FreeBSD
+ atf_check "$(prog)" -i bsize=65536 hash in
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case small_btree
+ atf_add_test_case small_hash
+ atf_add_test_case small_recno
+ atf_add_test_case medium_btree
+ atf_add_test_case medium_hash
+ atf_add_test_case medium_recno
+ atf_add_test_case big_btree
+ atf_add_test_case big_hash
+ atf_add_test_case big_recno
+ atf_add_test_case random_recno
+ atf_add_test_case reverse_recno
+ atf_add_test_case alternate_recno
+ atf_add_test_case delete_btree
+ atf_add_test_case delete_recno
+ atf_add_test_case repeated_btree
+ atf_add_test_case repeated_hash
+ atf_add_test_case duplicate_btree
+ atf_add_test_case cursor_flags_btree
+ atf_add_test_case cursor_flags_recno
+ atf_add_test_case reverse_order_recno
+ atf_add_test_case small_page_btree
+ atf_add_test_case byte_orders_btree
+ atf_add_test_case byte_orders_hash
+ atf_add_test_case bsize_ffactor
+ atf_add_test_case four_char_hash
+}
OpenPOWER on IntegriCloud