summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/db
diff options
context:
space:
mode:
authorderaadt <>1995-10-18 08:49:34 +0000
committerderaadt <>1995-10-18 08:49:34 +0000
commita4f79641824cbf9f60ca9d1168d1fcc46717a82a (patch)
tree3a9a60a6831189695ecfa7eb6904bce69aec0bcb /src/regress/lib/libc/db
parent0527d29da443886d92e9a418180c5b25a5f8d270 (diff)
downloadopenbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.tar.gz
openbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.tar.bz2
openbsd-a4f79641824cbf9f60ca9d1168d1fcc46717a82a.zip
initial import of NetBSD tree
Diffstat (limited to 'src/regress/lib/libc/db')
-rw-r--r--src/regress/lib/libc/db/Makefile17
-rw-r--r--src/regress/lib/libc/db/README54
-rw-r--r--src/regress/lib/libc/db/dbtest.c672
-rw-r--r--src/regress/lib/libc/db/run.test699
4 files changed, 1442 insertions, 0 deletions
diff --git a/src/regress/lib/libc/db/Makefile b/src/regress/lib/libc/db/Makefile
new file mode 100644
index 0000000000..5bf343bf64
--- /dev/null
+++ b/src/regress/lib/libc/db/Makefile
@@ -0,0 +1,17 @@
1# $NetBSD: Makefile,v 1.10 1995/04/20 22:39:11 cgd Exp $
2# @(#)Makefile 8.1 (Berkeley) 6/4/93
3
4PROG= dbtest
5
6# add -DSTATISTICS to CFLAGS to get usage statistics. Note that
7# for this to work, libc must be compiled with -DSTATISTICS as well
8CFLAGS= -g -D__DBINTERFACE_PRIVATE -DDEBUG
9NOMAN= noman
10CLEANFILES+= t1 t2 t3
11
12install:
13
14regress:
15 sh ${.CURDIR}/run.test
16
17.include <bsd.prog.mk>
diff --git a/src/regress/lib/libc/db/README b/src/regress/lib/libc/db/README
new file mode 100644
index 0000000000..3b290b09d8
--- /dev/null
+++ b/src/regress/lib/libc/db/README
@@ -0,0 +1,54 @@
1# $NetBSD: README,v 1.4 1995/04/20 22:39:18 cgd Exp $
2# @(#)README 8.4 (Berkeley) 6/20/94
3
4To run the tests, enter "make regress".
5
6Fairly large files (the command files) are built in this directory during
7the test runs, and even larger files (the database files) are created in
8"/var/tmp". If the latter directory doesn't exist, set the environmental
9variable TMPDIR to a directory where the files can be built.
10
11=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
12The script file consists of lines with a initial character which is
13the "command" for that line. Legal characters are as follows:
14
15c: compare a record
16 + must be followed by [kK][dD]; the data value in the database
17 associated with the specified key is compared to the specified
18 data value.
19e: echo a string
20 + writes out the rest of the line into the output file; if the
21 last character is not a carriage-return, a newline is appended.
22g: do a get command
23 + must be followed by [kK]
24 + writes out the retrieved data DBT.
25p: do a put command
26 + must be followed by [kK][dD]
27r: do a del command
28 + must be followed by [kK]
29s: do a seq command
30 + writes out the retrieved data DBT.
31f: set the flags for the next command
32 + no value zero's the flags
33D [file]: data file
34 + set the current data value to the contents of the file
35d [data]:
36 + set the current key value to the contents of the line.
37K [file]: key file
38 + set the current key value to the contents of the file
39k [data]:
40 + set the current key value to the contents of the line.
41o [r]: dump [reverse]
42 + dump the database out, if 'r' is set, in reverse order.
43
44Options to dbtest are as follows:
45
46 -f: Use the file argument as the database file.
47 -i: Use the rest of the argument to set elements in the info
48 structure. If the type is btree, then "-i cachesize=10240"
49 will set BTREEINFO.cachesize to 10240.
50 -o: The rest of the argument is the output file instead of
51 using stdout.
52
53Dbtest requires two arguments, the type of access "hash", "recno" or
54"btree", and the script name.
diff --git a/src/regress/lib/libc/db/dbtest.c b/src/regress/lib/libc/db/dbtest.c
new file mode 100644
index 0000000000..1fcf09af97
--- /dev/null
+++ b/src/regress/lib/libc/db/dbtest.c
@@ -0,0 +1,672 @@
1/* $NetBSD: dbtest.c,v 1.7 1995/04/20 22:39:22 cgd Exp $ */
2
3/*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37static char copyright[] =
38"@(#) Copyright (c) 1992, 1993\n\
39 The Regents of the University of California. All rights reserved.\n";
40#endif /* not lint */
41
42#ifndef lint
43#if 0
44static char sccsid[] = "@(#)dbtest.c 8.8 (Berkeley) 2/21/94";
45#else
46static char rcsid[] = "$NetBSD: dbtest.c,v 1.7 1995/04/20 22:39:22 cgd Exp $";
47#endif
48#endif /* not lint */
49
50#include <sys/param.h>
51#include <sys/stat.h>
52
53#include <ctype.h>
54#include <errno.h>
55#include <fcntl.h>
56#include <limits.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60#include <unistd.h>
61
62#include <db.h>
63
64enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
65
66void compare __P((DBT *, DBT *));
67DBTYPE dbtype __P((char *));
68void dump __P((DB *, int));
69void err __P((const char *, ...));
70void get __P((DB *, DBT *));
71void getdata __P((DB *, DBT *, DBT *));
72void put __P((DB *, DBT *, DBT *));
73void rem __P((DB *, DBT *));
74void *rfile __P((char *, size_t *));
75void seq __P((DB *, DBT *));
76u_int setflags __P((char *));
77void *setinfo __P((DBTYPE, char *));
78void usage __P((void));
79void *xmalloc __P((char *, size_t));
80
81DBTYPE type;
82void *infop;
83u_long lineno;
84u_int flags;
85int ofd = STDOUT_FILENO;
86
87DB *XXdbp; /* Global for gdb. */
88
89int
90main(argc, argv)
91 int argc;
92 char *argv[];
93{
94 extern int optind;
95 extern char *optarg;
96 enum S command, state;
97 DB *dbp;
98 DBT data, key, keydata;
99 size_t len;
100 int ch, oflags;
101 char *fname, *infoarg, *p, buf[8 * 1024];
102
103 infoarg = NULL;
104 fname = NULL;
105 oflags = O_CREAT | O_RDWR;
106 while ((ch = getopt(argc, argv, "f:i:lo:")) != EOF)
107 switch(ch) {
108 case 'f':
109 fname = optarg;
110 break;
111 case 'i':
112 infoarg = optarg;
113 break;
114 case 'l':
115 oflags |= DB_LOCK;
116 break;
117 case 'o':
118 if ((ofd = open(optarg,
119 O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
120 err("%s: %s", optarg, strerror(errno));
121 break;
122 case '?':
123 default:
124 usage();
125 }
126 argc -= optind;
127 argv += optind;
128
129 if (argc != 2)
130 usage();
131
132 /* Set the type. */
133 type = dbtype(*argv++);
134
135 /* Open the descriptor file. */
136 if (freopen(*argv, "r", stdin) == NULL)
137 err("%s: %s", *argv, strerror(errno));
138
139 /* Set up the db structure as necessary. */
140 if (infoarg == NULL)
141 infop = NULL;
142 else
143 for (p = strtok(infoarg, ",\t "); p != NULL;
144 p = strtok(0, ",\t "))
145 if (*p != '\0')
146 infop = setinfo(type, p);
147
148 /* Open the DB. */
149 if (fname == NULL) {
150 p = getenv("TMPDIR");
151 if (p == NULL)
152 p = "/var/tmp";
153 (void)sprintf(buf, "%s/__dbtest", p);
154 fname = buf;
155 (void)unlink(buf);
156 }
157 if ((dbp = dbopen(fname,
158 oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
159 err("dbopen: %s", strerror(errno));
160 XXdbp = dbp;
161
162 state = COMMAND;
163 for (lineno = 1;
164 (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
165 len = strlen(buf);
166 switch(*p) {
167 case 'c': /* compare */
168 if (state != COMMAND)
169 err("line %lu: not expecting command", lineno);
170 state = KEY;
171 command = COMPARE;
172 break;
173 case 'e': /* echo */
174 if (state != COMMAND)
175 err("line %lu: not expecting command", lineno);
176 /* Don't display the newline, if CR at EOL. */
177 if (p[len - 2] == '\r')
178 --len;
179 if (write(ofd, p + 1, len - 1) != len - 1)
180 err("write: %s", strerror(errno));
181 break;
182 case 'g': /* get */
183 if (state != COMMAND)
184 err("line %lu: not expecting command", lineno);
185 state = KEY;
186 command = GET;
187 break;
188 case 'p': /* put */
189 if (state != COMMAND)
190 err("line %lu: not expecting command", lineno);
191 state = KEY;
192 command = PUT;
193 break;
194 case 'r': /* remove */
195 if (state != COMMAND)
196 err("line %lu: not expecting command", lineno);
197 state = KEY;
198 command = REMOVE;
199 break;
200 case 's': /* seq */
201 if (state != COMMAND)
202 err("line %lu: not expecting command", lineno);
203 if (flags == R_CURSOR) {
204 state = KEY;
205 command = SEQ;
206 } else
207 seq(dbp, &key);
208 break;
209 case 'f':
210 flags = setflags(p + 1);
211 break;
212 case 'D': /* data file */
213 if (state != DATA)
214 err("line %lu: not expecting data", lineno);
215 data.data = rfile(p + 1, &data.size);
216 goto ldata;
217 case 'd': /* data */
218 if (state != DATA)
219 err("line %lu: not expecting data", lineno);
220 data.data = xmalloc(p + 1, len - 1);
221 data.size = len - 1;
222ldata: switch(command) {
223 case COMPARE:
224 compare(&keydata, &data);
225 break;
226 case PUT:
227 put(dbp, &key, &data);
228 break;
229 default:
230 err("line %lu: command doesn't take data",
231 lineno);
232 }
233 if (type != DB_RECNO)
234 free(key.data);
235 free(data.data);
236 state = COMMAND;
237 break;
238 case 'K': /* key file */
239 if (state != KEY)
240 err("line %lu: not expecting a key", lineno);
241 if (type == DB_RECNO)
242 err("line %lu: 'K' not available for recno",
243 lineno);
244 key.data = rfile(p + 1, &key.size);
245 goto lkey;
246 case 'k': /* key */
247 if (state != KEY)
248 err("line %lu: not expecting a key", lineno);
249 if (type == DB_RECNO) {
250 static recno_t recno;
251 recno = atoi(p + 1);
252 key.data = &recno;
253 key.size = sizeof(recno);
254 } else {
255 key.data = xmalloc(p + 1, len - 1);
256 key.size = len - 1;
257 }
258lkey: switch(command) {
259 case COMPARE:
260 getdata(dbp, &key, &keydata);
261 state = DATA;
262 break;
263 case GET:
264 get(dbp, &key);
265 if (type != DB_RECNO)
266 free(key.data);
267 state = COMMAND;
268 break;
269 case PUT:
270 state = DATA;
271 break;
272 case REMOVE:
273 rem(dbp, &key);
274 if (type != DB_RECNO)
275 free(key.data);
276 state = COMMAND;
277 break;
278 case SEQ:
279 seq(dbp, &key);
280 if (type != DB_RECNO)
281 free(key.data);
282 state = COMMAND;
283 break;
284 default:
285 err("line %lu: command doesn't take a key",
286 lineno);
287 }
288 break;
289 case 'o':
290 dump(dbp, p[1] == 'r');
291 break;
292 default:
293 err("line %lu: %s: unknown command character",
294 p, lineno);
295 }
296 }
297#ifdef STATISTICS
298 if (type == DB_BTREE)
299 __bt_stat(dbp);
300#endif
301 if (dbp->close(dbp))
302 err("db->close: %s", strerror(errno));
303 (void)close(ofd);
304 exit(0);
305}
306
307#define NOOVERWRITE "put failed, would overwrite key\n"
308#define NOSUCHKEY "get failed, no such key\n"
309
310void
311compare(db1, db2)
312 DBT *db1, *db2;
313{
314 register size_t len;
315 register u_char *p1, *p2;
316
317 if (db1->size != db2->size)
318 printf("compare failed: key->data len %lu != data len %lu\n",
319 db1->size, db2->size);
320
321 len = MIN(db1->size, db2->size);
322 for (p1 = db1->data, p2 = db2->data; len--;)
323 if (*p1++ != *p2++) {
324 printf("compare failed at offset %d\n",
325 p1 - (u_char *)db1->data);
326 break;
327 }
328}
329
330void
331get(dbp, kp)
332 DB *dbp;
333 DBT *kp;
334{
335 DBT data;
336
337 switch(dbp->get(dbp, kp, &data, flags)) {
338 case 0:
339 (void)write(ofd, data.data, data.size);
340 break;
341 case -1:
342 err("line %lu: get: %s", lineno, strerror(errno));
343 /* NOTREACHED */
344 case 1:
345 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
346 (void)fprintf(stderr, "%d: %.*s: %s\n",
347 lineno, kp->size, kp->data, NOSUCHKEY);
348 break;
349 }
350}
351
352void
353getdata(dbp, kp, dp)
354 DB *dbp;
355 DBT *kp, *dp;
356{
357 switch(dbp->get(dbp, kp, dp, flags)) {
358 case 0:
359 return;
360 case -1:
361 err("line %lu: getdata: %s", lineno, strerror(errno));
362 /* NOTREACHED */
363 case 1:
364 err("line %lu: get failed, no such key", lineno);
365 /* NOTREACHED */
366 }
367}
368
369void
370put(dbp, kp, dp)
371 DB *dbp;
372 DBT *kp, *dp;
373{
374 switch(dbp->put(dbp, kp, dp, flags)) {
375 case 0:
376 break;
377 case -1:
378 err("line %lu: put: %s", lineno, strerror(errno));
379 /* NOTREACHED */
380 case 1:
381 (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
382 break;
383 }
384}
385
386void
387rem(dbp, kp)
388 DB *dbp;
389 DBT *kp;
390{
391 switch(dbp->del(dbp, kp, flags)) {
392 case 0:
393 break;
394 case -1:
395 err("line %lu: get: %s", lineno, strerror(errno));
396 /* NOTREACHED */
397 case 1:
398 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
399 break;
400 }
401}
402
403void
404seq(dbp, kp)
405 DB *dbp;
406 DBT *kp;
407{
408 DBT data;
409
410 switch(dbp->seq(dbp, kp, &data, flags)) {
411 case 0:
412 (void)write(ofd, data.data, data.size);
413 break;
414 case -1:
415 err("line %lu: seq: %s", lineno, strerror(errno));
416 /* NOTREACHED */
417 case 1:
418 (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
419 break;
420 }
421}
422
423void
424dump(dbp, rev)
425 DB *dbp;
426 int rev;
427{
428 DBT key, data;
429 int flags, nflags;
430
431 if (rev) {
432 flags = R_LAST;
433 nflags = R_PREV;
434 } else {
435 flags = R_FIRST;
436 nflags = R_NEXT;
437 }
438 for (;; flags = nflags)
439 switch(dbp->seq(dbp, &key, &data, flags)) {
440 case 0:
441 (void)write(ofd, data.data, data.size);
442 break;
443 case 1:
444 goto done;
445 case -1:
446 err("line %lu: (dump) seq: %s",
447 lineno, strerror(errno));
448 /* NOTREACHED */
449 }
450done: return;
451}
452
453u_int
454setflags(s)
455 char *s;
456{
457 char *p, *index();
458
459 for (; isspace(*s); ++s);
460 if (*s == '\n')
461 return (0);
462 if ((p = index(s, '\n')) != NULL)
463 *p = '\0';
464 if (!strcmp(s, "R_CURSOR"))
465 return (R_CURSOR);
466 if (!strcmp(s, "R_FIRST"))
467 return (R_FIRST);
468 if (!strcmp(s, "R_IAFTER"))
469 return (R_IAFTER);
470 if (!strcmp(s, "R_IBEFORE"))
471 return (R_IBEFORE);
472 if (!strcmp(s, "R_LAST"))
473 return (R_LAST);
474 if (!strcmp(s, "R_NEXT"))
475 return (R_NEXT);
476 if (!strcmp(s, "R_NOOVERWRITE"))
477 return (R_NOOVERWRITE);
478 if (!strcmp(s, "R_PREV"))
479 return (R_PREV);
480 if (!strcmp(s, "R_SETCURSOR"))
481 return (R_SETCURSOR);
482 err("line %lu: %s: unknown flag", lineno, s);
483 /* NOTREACHED */
484}
485
486DBTYPE
487dbtype(s)
488 char *s;
489{
490 if (!strcmp(s, "btree"))
491 return (DB_BTREE);
492 if (!strcmp(s, "hash"))
493 return (DB_HASH);
494 if (!strcmp(s, "recno"))
495 return (DB_RECNO);
496 err("%s: unknown type (use btree, hash or recno)", s);
497 /* NOTREACHED */
498}
499
500void *
501setinfo(type, s)
502 DBTYPE type;
503 char *s;
504{
505 static BTREEINFO ib;
506 static HASHINFO ih;
507 static RECNOINFO rh;
508 char *eq, *index();
509
510 if ((eq = index(s, '=')) == NULL)
511 err("%s: illegal structure set statement", s);
512 *eq++ = '\0';
513 if (!isdigit(*eq))
514 err("%s: structure set statement must be a number", s);
515
516 switch(type) {
517 case DB_BTREE:
518 if (!strcmp("flags", s)) {
519 ib.flags = atoi(eq);
520 return (&ib);
521 }
522 if (!strcmp("cachesize", s)) {
523 ib.cachesize = atoi(eq);
524 return (&ib);
525 }
526 if (!strcmp("maxkeypage", s)) {
527 ib.maxkeypage = atoi(eq);
528 return (&ib);
529 }
530 if (!strcmp("minkeypage", s)) {
531 ib.minkeypage = atoi(eq);
532 return (&ib);
533 }
534 if (!strcmp("lorder", s)) {
535 ib.lorder = atoi(eq);
536 return (&ib);
537 }
538 if (!strcmp("psize", s)) {
539 ib.psize = atoi(eq);
540 return (&ib);
541 }
542 break;
543 case DB_HASH:
544 if (!strcmp("bsize", s)) {
545 ih.bsize = atoi(eq);
546 return (&ih);
547 }
548 if (!strcmp("ffactor", s)) {
549 ih.ffactor = atoi(eq);
550 return (&ih);
551 }
552 if (!strcmp("nelem", s)) {
553 ih.nelem = atoi(eq);
554 return (&ih);
555 }
556 if (!strcmp("cachesize", s)) {
557 ih.cachesize = atoi(eq);
558 return (&ih);
559 }
560 if (!strcmp("lorder", s)) {
561 ih.lorder = atoi(eq);
562 return (&ih);
563 }
564 break;
565 case DB_RECNO:
566 if (!strcmp("flags", s)) {
567 rh.flags = atoi(eq);
568 return (&rh);
569 }
570 if (!strcmp("cachesize", s)) {
571 rh.cachesize = atoi(eq);
572 return (&rh);
573 }
574 if (!strcmp("lorder", s)) {
575 rh.lorder = atoi(eq);
576 return (&rh);
577 }
578 if (!strcmp("reclen", s)) {
579 rh.reclen = atoi(eq);
580 return (&rh);
581 }
582 if (!strcmp("bval", s)) {
583 rh.bval = atoi(eq);
584 return (&rh);
585 }
586 if (!strcmp("psize", s)) {
587 rh.psize = atoi(eq);
588 return (&rh);
589 }
590 break;
591 }
592 err("%s: unknown structure value", s);
593 /* NOTREACHED */
594}
595
596void *
597rfile(name, lenp)
598 char *name;
599 size_t *lenp;
600{
601 struct stat sb;
602 void *p;
603 int fd;
604 char *np, *index();
605
606 for (; isspace(*name); ++name);
607 if ((np = index(name, '\n')) != NULL)
608 *np = '\0';
609 if ((fd = open(name, O_RDONLY, 0)) < 0 ||
610 fstat(fd, &sb))
611 err("%s: %s\n", name, strerror(errno));
612#ifdef NOT_PORTABLE
613 if (sb.st_size > (off_t)SIZE_T_MAX)
614 err("%s: %s\n", name, strerror(E2BIG));
615#endif
616 if ((p = (void *)malloc((u_int)sb.st_size)) == NULL)
617 err("%s", strerror(errno));
618 (void)read(fd, p, (int)sb.st_size);
619 *lenp = sb.st_size;
620 (void)close(fd);
621 return (p);
622}
623
624void *
625xmalloc(text, len)
626 char *text;
627 size_t len;
628{
629 void *p;
630
631 if ((p = (void *)malloc(len)) == NULL)
632 err("%s", strerror(errno));
633 memmove(p, text, len);
634 return (p);
635}
636
637void
638usage()
639{
640 (void)fprintf(stderr,
641 "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
642 exit(1);
643}
644
645#if __STDC__
646#include <stdarg.h>
647#else
648#include <varargs.h>
649#endif
650
651void
652#if __STDC__
653err(const char *fmt, ...)
654#else
655err(fmt, va_alist)
656 char *fmt;
657 va_dcl
658#endif
659{
660 va_list ap;
661#if __STDC__
662 va_start(ap, fmt);
663#else
664 va_start(ap);
665#endif
666 (void)fprintf(stderr, "dbtest: ");
667 (void)vfprintf(stderr, fmt, ap);
668 va_end(ap);
669 (void)fprintf(stderr, "\n");
670 exit(1);
671 /* NOTREACHED */
672}
diff --git a/src/regress/lib/libc/db/run.test b/src/regress/lib/libc/db/run.test
new file mode 100644
index 0000000000..4073310a31
--- /dev/null
+++ b/src/regress/lib/libc/db/run.test
@@ -0,0 +1,699 @@
1#!/bin/sh -
2# $NetBSD: run.test,v 1.7 1995/04/20 22:39:27 cgd Exp $
3#
4# @(#)run.test 8.8 (Berkeley) 6/16/94
5#
6
7# db regression tests
8main()
9{
10
11DICT=/usr/share/dict/web2
12PROG=./dbtest
13TMP1=t1
14TMP2=t2
15TMP3=t3
16
17 if [ $# -eq 0 ]; then
18 for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do
19 test$t
20 done
21 else
22 while [ $# -gt 0 ]
23 do case "$1" in
24 test*)
25 $1;;
26 [0-9]*)
27 test$1;;
28 btree)
29 for t in 1 2 3 7 8 9 10 12 13; do
30 test$t
31 done;;
32 hash)
33 for t in 1 2 3 8 13 20; do
34 test$t
35 done;;
36 recno)
37 for t in 1 2 3 4 5 6 7 10 11; do
38 test$t
39 done;;
40 *)
41 echo "run.test: unknown test $1"
42 echo "usage: run.test test# | type"
43 exit 1
44 esac
45 shift
46 done
47 fi
48 rm -f $TMP1 $TMP2 $TMP3
49 exit 0
50}
51
52# Take the first hundred entries in the dictionary, and make them
53# be key/data pairs.
54test1()
55{
56 echo "Test 1: btree, hash: small key, small data pairs"
57 sed 200q $DICT > $TMP1
58 for type in btree hash; do
59 rm -f $TMP2 $TMP3
60 for i in `sed 200q $DICT`; do
61 echo p
62 echo k$i
63 echo d$i
64 echo g
65 echo k$i
66 done > $TMP2
67 $PROG -o $TMP3 $type $TMP2
68 if (cmp -s $TMP1 $TMP3) ; then :
69 else
70 echo "test1: type $type: failed"
71 exit 1
72 fi
73 done
74 echo "Test 1: recno: small key, small data pairs"
75 rm -f $TMP2 $TMP3
76 sed 200q $DICT |
77 awk '{
78 ++i;
79 printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
80 }' > $TMP2
81 $PROG -o $TMP3 recno $TMP2
82 if (cmp -s $TMP1 $TMP3) ; then :
83 else
84 echo "test1: type recno: failed"
85 exit 1
86 fi
87}
88
89# Take the first 200 entries in the dictionary, and give them
90# each a medium size data entry.
91test2()
92{
93 echo "Test 2: btree, hash: small key, medium data pairs"
94 mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
95 echo $mdata |
96 awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1
97 for type in hash btree; do
98 rm -f $TMP2 $TMP3
99 for i in `sed 200q $DICT`; do
100 echo p
101 echo k$i
102 echo d$mdata
103 echo g
104 echo k$i
105 done > $TMP2
106 $PROG -o $TMP3 $type $TMP2
107 if (cmp -s $TMP1 $TMP3) ; then :
108 else
109 echo "test2: type $type: failed"
110 exit 1
111 fi
112 done
113 echo "Test 2: recno: small key, medium data pairs"
114 rm -f $TMP2 $TMP3
115 echo $mdata |
116 awk '{ for (i = 1; i < 201; ++i)
117 printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
118 }' > $TMP2
119 $PROG -o $TMP3 recno $TMP2
120 if (cmp -s $TMP1 $TMP3) ; then :
121 else
122 echo "test2: type recno: failed"
123 exit 1
124 fi
125}
126
127# Insert the programs in /bin with their paths as their keys.
128test3()
129{
130 echo "Test 3: hash: small key, big data pairs"
131 rm -f $TMP1
132 (find /bin -type f -print | xargs cat) > $TMP1
133 for type in hash; do
134 rm -f $TMP2 $TMP3
135 for i in `find /bin -type f -print`; do
136 echo p
137 echo k$i
138 echo D$i
139 echo g
140 echo k$i
141 done > $TMP2
142 $PROG -o $TMP3 $type $TMP2
143 if (cmp -s $TMP1 $TMP3) ; then :
144 else
145 echo "test3: $type: failed"
146 exit 1
147 fi
148 done
149 echo "Test 3: btree: small key, big data pairs"
150 for psize in 512 16384 65536; do
151 echo " page size $psize"
152 for type in btree; do
153 rm -f $TMP2 $TMP3
154 for i in `find /bin -type f -print`; do
155 echo p
156 echo k$i
157 echo D$i
158 echo g
159 echo k$i
160 done > $TMP2
161 $PROG -i psize=$psize -o $TMP3 $type $TMP2
162 if (cmp -s $TMP1 $TMP3) ; then :
163 else
164 echo "test3: $type: page size $psize: failed"
165 exit 1
166 fi
167 done
168 done
169 echo "Test 3: recno: big data pairs"
170 rm -f $TMP2 $TMP3
171 find /bin -type f -print |
172 awk '{
173 ++i;
174 printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
175 }' > $TMP2
176 for psize in 512 16384 65536; do
177 echo " page size $psize"
178 $PROG -i psize=$psize -o $TMP3 recno $TMP2
179 if (cmp -s $TMP1 $TMP3) ; then :
180 else
181 echo "test3: recno: page size $psize: failed"
182 exit 1
183 fi
184 done
185}
186
187# Do random recno entries.
188test4()
189{
190 echo "Test 4: recno: random entries"
191 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
192 awk '{
193 for (i = 37; i <= 37 + 88 * 17; i += 17) {
194 if (i % 41)
195 s = substr($0, 1, i % 41);
196 else
197 s = substr($0, 1);
198 printf("input key %d: %s\n", i, s);
199 }
200 for (i = 1; i <= 15; ++i) {
201 if (i % 41)
202 s = substr($0, 1, i % 41);
203 else
204 s = substr($0, 1);
205 printf("input key %d: %s\n", i, s);
206 }
207 for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
208 if (i % 41)
209 s = substr($0, 1, i % 41);
210 else
211 s = substr($0, 1);
212 printf("input key %d: %s\n", i, s);
213 }
214 exit
215 }' > $TMP1
216 rm -f $TMP2 $TMP3
217 cat $TMP1 |
218 awk 'BEGIN {
219 i = 37;
220 incr = 17;
221 }
222 {
223 printf("p\nk%d\nd%s\n", i, $0);
224 if (i == 19234 + 61 * 27)
225 exit;
226 if (i == 37 + 88 * 17) {
227 i = 1;
228 incr = 1;
229 } else if (i == 15) {
230 i = 19234;
231 incr = 27;
232 } else
233 i += incr;
234 }
235 END {
236 for (i = 37; i <= 37 + 88 * 17; i += 17)
237 printf("g\nk%d\n", i);
238 for (i = 1; i <= 15; ++i)
239 printf("g\nk%d\n", i);
240 for (i = 19234; i <= 19234 + 61 * 27; i += 27)
241 printf("g\nk%d\n", i);
242 }' > $TMP2
243 $PROG -o $TMP3 recno $TMP2
244 if (cmp -s $TMP1 $TMP3) ; then :
245 else
246 echo "test4: type recno: failed"
247 exit 1
248 fi
249}
250
251# Do reverse order recno entries.
252test5()
253{
254 echo "Test 5: recno: reverse order entries"
255 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
256 awk ' {
257 for (i = 1500; i; --i) {
258 if (i % 34)
259 s = substr($0, 1, i % 34);
260 else
261 s = substr($0, 1);
262 printf("input key %d: %s\n", i, s);
263 }
264 exit;
265 }' > $TMP1
266 rm -f $TMP2 $TMP3
267 cat $TMP1 |
268 awk 'BEGIN {
269 i = 1500;
270 }
271 {
272 printf("p\nk%d\nd%s\n", i, $0);
273 --i;
274 }
275 END {
276 for (i = 1500; i; --i)
277 printf("g\nk%d\n", i);
278 }' > $TMP2
279 $PROG -o $TMP3 recno $TMP2
280 if (cmp -s $TMP1 $TMP3) ; then :
281 else
282 echo "test5: type recno: failed"
283 exit 1
284 fi
285}
286
287# Do alternating order recno entries.
288test6()
289{
290 echo "Test 6: recno: alternating order entries"
291 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
292 awk ' {
293 for (i = 1; i < 1200; i += 2) {
294 if (i % 34)
295 s = substr($0, 1, i % 34);
296 else
297 s = substr($0, 1);
298 printf("input key %d: %s\n", i, s);
299 }
300 for (i = 2; i < 1200; i += 2) {
301 if (i % 34)
302 s = substr($0, 1, i % 34);
303 else
304 s = substr($0, 1);
305 printf("input key %d: %s\n", i, s);
306 }
307 exit;
308 }' > $TMP1
309 rm -f $TMP2 $TMP3
310 cat $TMP1 |
311 awk 'BEGIN {
312 i = 1;
313 even = 0;
314 }
315 {
316 printf("p\nk%d\nd%s\n", i, $0);
317 i += 2;
318 if (i >= 1200) {
319 if (even == 1)
320 exit;
321 even = 1;
322 i = 2;
323 }
324 }
325 END {
326 for (i = 1; i < 1200; ++i)
327 printf("g\nk%d\n", i);
328 }' > $TMP2
329 $PROG -o $TMP3 recno $TMP2
330 sort -o $TMP1 $TMP1
331 sort -o $TMP3 $TMP3
332 if (cmp -s $TMP1 $TMP3) ; then :
333 else
334 echo "test6: type recno: failed"
335 exit 1
336 fi
337}
338
339# Delete cursor record
340test7()
341{
342 echo "Test 7: btree, recno: delete cursor record"
343 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
344 awk '{
345 for (i = 1; i <= 120; ++i)
346 printf("%05d: input key %d: %s\n", i, i, $0);
347 printf("%05d: input key %d: %s\n", 120, 120, $0);
348 printf("get failed, no such key\n");
349 printf("%05d: input key %d: %s\n", 1, 1, $0);
350 printf("%05d: input key %d: %s\n", 2, 2, $0);
351 exit;
352 }' > $TMP1
353 rm -f $TMP2 $TMP3
354
355 for type in btree recno; do
356 cat $TMP1 |
357 awk '{
358 if (i == 120)
359 exit;
360 printf("p\nk%d\nd%s\n", ++i, $0);
361 }
362 END {
363 printf("fR_NEXT\n");
364 for (i = 1; i <= 120; ++i)
365 printf("s\n");
366 printf("fR_CURSOR\ns\nk120\n");
367 printf("r\nk120\n");
368 printf("fR_NEXT\ns\n");
369 printf("fR_CURSOR\ns\nk1\n");
370 printf("r\nk1\n");
371 printf("fR_FIRST\ns\n");
372 }' > $TMP2
373 $PROG -o $TMP3 recno $TMP2
374 if (cmp -s $TMP1 $TMP3) ; then :
375 else
376 echo "test7: type $type: failed"
377 exit 1
378 fi
379 done
380}
381
382# Make sure that overflow pages are reused.
383test8()
384{
385 echo "Test 8: btree, hash: repeated small key, big data pairs"
386 rm -f $TMP1
387 echo "" |
388 awk 'BEGIN {
389 for (i = 1; i <= 10; ++i) {
390 printf("p\nkkey1\nD/bin/sh\n");
391 printf("p\nkkey2\nD/bin/csh\n");
392 if (i % 8 == 0) {
393 printf("c\nkkey2\nD/bin/csh\n");
394 printf("c\nkkey1\nD/bin/sh\n");
395 printf("e\t%d of 10 (comparison)\n", i);
396 } else
397 printf("e\t%d of 10 \n", i);
398 printf("r\nkkey1\nr\nkkey2\n");
399 }
400 printf("e\n");
401 printf("eend of test8 run\n");
402 }' > $TMP1
403 $PROG btree $TMP1
404# $PROG hash $TMP1
405 # No explicit test for success.
406}
407
408# Test btree duplicate keys
409test9()
410{
411 echo "Test 9: btree: duplicate keys"
412 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
413 awk '{
414 for (i = 1; i <= 543; ++i)
415 printf("%05d: input key %d: %s\n", i, i, $0);
416 exit;
417 }' > $TMP1
418 rm -f $TMP2 $TMP3
419
420 for type in btree; do
421 cat $TMP1 |
422 awk '{
423 if (i++ % 2)
424 printf("p\nkduplicatekey\nd%s\n", $0);
425 else
426 printf("p\nkunique%dkey\nd%s\n", i, $0);
427 }
428 END {
429 printf("o\n");
430 }' > $TMP2
431 $PROG -iflags=1 -o $TMP3 $type $TMP2
432 sort -o $TMP3 $TMP3
433 if (cmp -s $TMP1 $TMP3) ; then :
434 else
435 echo "test9: type $type: failed"
436 exit 1
437 fi
438 done
439}
440
441# Test use of cursor flags without initialization
442test10()
443{
444 echo "Test 10: btree, recno: test cursor flag use"
445 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
446 awk '{
447 for (i = 1; i <= 20; ++i)
448 printf("%05d: input key %d: %s\n", i, i, $0);
449 exit;
450 }' > $TMP1
451 rm -f $TMP2 $TMP3
452
453 # Test that R_CURSOR doesn't succeed before cursor initialized
454 for type in btree recno; do
455 cat $TMP1 |
456 awk '{
457 if (i == 10)
458 exit;
459 printf("p\nk%d\nd%s\n", ++i, $0);
460 }
461 END {
462 printf("fR_CURSOR\nr\nk1\n");
463 printf("eR_CURSOR SHOULD HAVE FAILED\n");
464 }' > $TMP2
465 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
466 if [ -s $TMP3 ] ; then
467 echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
468 exit 1
469 fi
470 done
471 for type in btree recno; do
472 cat $TMP1 |
473 awk '{
474 if (i == 10)
475 exit;
476 printf("p\nk%d\nd%s\n", ++i, $0);
477 }
478 END {
479 printf("fR_CURSOR\np\nk1\ndsome data\n");
480 printf("eR_CURSOR SHOULD HAVE FAILED\n");
481 }' > $TMP2
482 $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
483 if [ -s $TMP3 ] ; then
484 echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
485 exit 1
486 fi
487 done
488}
489
490# Test insert in reverse order.
491test11()
492{
493 echo "Test 11: recno: reverse order insert"
494 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
495 awk '{
496 for (i = 1; i <= 779; ++i)
497 printf("%05d: input key %d: %s\n", i, i, $0);
498 exit;
499 }' > $TMP1
500 rm -f $TMP2 $TMP3
501
502 for type in recno; do
503 cat $TMP1 |
504 awk '{
505 if (i == 0) {
506 i = 1;
507 printf("p\nk1\nd%s\n", $0);
508 printf("%s\n", "fR_IBEFORE");
509 } else
510 printf("p\nk1\nd%s\n", $0);
511 }
512 END {
513 printf("or\n");
514 }' > $TMP2
515 $PROG -o $TMP3 $type $TMP2
516 if (cmp -s $TMP1 $TMP3) ; then :
517 else
518 echo "test11: type $type: failed"
519 exit 1
520 fi
521 done
522}
523
524# Take the first 20000 entries in the dictionary, reverse them, and give
525# them each a small size data entry. Use a small page size to make sure
526# the btree split code gets hammered.
527test12()
528{
529 echo "Test 12: btree: lots of keys, small page size"
530 mdata=abcdefghijklmnopqrstuvwxy
531 echo $mdata |
532 awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
533 for type in btree; do
534 rm -f $TMP2 $TMP3
535 for i in `sed 20000q $DICT | rev`; do
536 echo p
537 echo k$i
538 echo d$mdata
539 echo g
540 echo k$i
541 done > $TMP2
542 $PROG -i psize=512 -o $TMP3 $type $TMP2
543 if (cmp -s $TMP1 $TMP3) ; then :
544 else
545 echo "test12: type $type: failed"
546 exit 1
547 fi
548 done
549}
550
551# Test different byte orders.
552test13()
553{
554 echo "Test 13: btree, hash: differing byte orders"
555 sed 50q $DICT > $TMP1
556 for order in 1234 4321; do
557 for type in btree hash; do
558 rm -f byte.file $TMP2 $TMP3
559 for i in `sed 50q $DICT`; do
560 echo p
561 echo k$i
562 echo d$i
563 echo g
564 echo k$i
565 done > $TMP2
566 $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
567 if (cmp -s $TMP1 $TMP3) ; then :
568 else
569 echo "test13: $type/$order put failed"
570 exit 1
571 fi
572 for i in `sed 50q $DICT`; do
573 echo g
574 echo k$i
575 done > $TMP2
576 $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
577 if (cmp -s $TMP1 $TMP3) ; then :
578 else
579 echo "test13: $type/$order get failed"
580 exit 1
581 fi
582 done
583 done
584 rm -f byte.file
585}
586
587# Try a variety of bucketsizes and fill factors for hashing
588test20()
589{
590 echo\
591 "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536"
592 echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
593 awk '{
594 for (i = 1; i <= 10000; ++i) {
595 if (i % 34)
596 s = substr($0, 1, i % 34);
597 else
598 s = substr($0, 1);
599 printf("%s\n", s);
600 }
601 exit;
602 }' > $TMP1
603 sed 10000q $DICT |
604 awk 'BEGIN {
605 ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg"
606 }
607 {
608 if (++i % 34)
609 s = substr(ds, 1, i % 34);
610 else
611 s = substr(ds, 1);
612 printf("p\nk%s\nd%s\n", $0, s);
613 }' > $TMP2
614 sed 10000q $DICT |
615 awk '{
616 ++i;
617 printf("g\nk%s\n", $0);
618 }' >> $TMP2
619 bsize=256
620 for ffactor in 11 14 21; do
621 echo " bucketsize $bsize, fill factor $ffactor"
622 $PROG -o$TMP3 \
623 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
624 hash $TMP2
625 if (cmp -s $TMP1 $TMP3) ; then :
626 else
627 echo "test20: type hash:\
628bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
629 exit 1
630 fi
631 done
632 bsize=512
633 for ffactor in 21 28 43; do
634 echo " bucketsize $bsize, fill factor $ffactor"
635 $PROG -o$TMP3 \
636 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
637 hash $TMP2
638 if (cmp -s $TMP1 $TMP3) ; then :
639 else
640 echo "test20: type hash:\
641bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
642 exit 1
643 fi
644 done
645 bsize=1024
646 for ffactor in 43 57 85; do
647 echo " bucketsize $bsize, fill factor $ffactor"
648 $PROG -o$TMP3 \
649 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
650 hash $TMP2
651 if (cmp -s $TMP1 $TMP3) ; then :
652 else
653 echo "test20: type hash:\
654bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
655 exit 1
656 fi
657 done
658 bsize=2048
659 for ffactor in 85 114 171; do
660 echo " bucketsize $bsize, fill factor $ffactor"
661 $PROG -o$TMP3 \
662 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
663 hash $TMP2
664 if (cmp -s $TMP1 $TMP3) ; then :
665 else
666 echo "test20: type hash:\
667bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
668 exit 1
669 fi
670 done
671 bsize=4096
672 for ffactor in 171 228 341; do
673 echo " bucketsize $bsize, fill factor $ffactor"
674 $PROG -o$TMP3 \
675 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
676 hash $TMP2
677 if (cmp -s $TMP1 $TMP3) ; then :
678 else
679 echo "test20: type hash:\
680bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
681 exit 1
682 fi
683 done
684 bsize=8192
685 for ffactor in 341 455 683; do
686 echo " bucketsize $bsize, fill factor $ffactor"
687 $PROG -o$TMP3 \
688 -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
689 hash $TMP2
690 if (cmp -s $TMP1 $TMP3) ; then :
691 else
692 echo "test20: type hash:\
693bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
694 exit 1
695 fi
696 done
697}
698
699main $*