xref: /freebsd/lib/libc/db/test/run.test (revision d4eeb02986980bf33dd56c41ceb9fc5f180c0d47)
1#!/bin/sh -
2#
3#	@(#)run.test	8.10 (Berkeley) 7/26/94
4#
5
6# db regression tests
7main()
8{
9
10	PROG=./dbtest
11	TMP1=t1
12	TMP2=t2
13	TMP3=t3
14
15	if [ -f /usr/share/dict/words ]; then
16		DICT=/usr/share/dict/words
17	elif [ -f /usr/dict/words ]; then
18		DICT=/usr/dict/words
19	else
20		echo 'run.test: no dictionary'
21		exit 1
22	fi
23
24	if [ $# -eq 0 ]; then
25		for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do
26			test$t
27		done
28	else
29		while [ $# -gt 0 ]
30			do case "$1" in
31			test*)
32				$1;;
33			[0-9]*)
34				test$1;;
35			btree)
36				for t in 1 2 3 7 8 9 10 12 13; do
37					test$t
38				done;;
39			hash)
40				for t in 1 2 3 8 13 20; do
41					test$t
42				done;;
43			recno)
44				for t in 1 2 3 4 5 6 7 10 11; do
45					test$t
46				done;;
47			*)
48				echo "run.test: unknown test $1"
49				echo "usage: run.test test# | type"
50				exit 1
51			esac
52			shift
53		done
54	fi
55	rm -f $TMP1 $TMP2 $TMP3
56	exit 0
57}
58
59# Take the first hundred entries in the dictionary, and make them
60# be key/data pairs.
61test1()
62{
63	echo "Test 1: btree, hash: small key, small data pairs"
64	sed 200q $DICT > $TMP1
65	for type in btree hash; do
66		rm -f $TMP2 $TMP3
67		for i in `sed 200q $DICT`; do
68			echo p
69			echo k$i
70			echo d$i
71			echo g
72			echo k$i
73		done > $TMP2
74		$PROG -o $TMP3 $type $TMP2
75		if (cmp -s $TMP1 $TMP3) ; then :
76		else
77			echo "test1: type $type: failed"
78			exit 1
79		fi
80	done
81	echo "Test 1: recno: small key, small data pairs"
82	rm -f $TMP2 $TMP3
83	sed 200q $DICT |
84	awk '{
85		++i;
86		printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
87	}' > $TMP2
88	$PROG -o $TMP3 recno $TMP2
89	if (cmp -s $TMP1 $TMP3) ; then :
90	else
91		echo "test1: type recno: failed"
92		exit 1
93	fi
94}
95
96# Take the first 200 entries in the dictionary, and give them
97# each a medium size data entry.
98test2()
99{
100	echo "Test 2: btree, hash: small key, medium data pairs"
101	mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
102	echo $mdata |
103	awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1
104	for type in hash btree; do
105		rm -f $TMP2 $TMP3
106		for i in `sed 200q $DICT`; do
107			echo p
108			echo k$i
109			echo d$mdata
110			echo g
111			echo k$i
112		done > $TMP2
113		$PROG -o $TMP3 $type $TMP2
114		if (cmp -s $TMP1 $TMP3) ; then :
115		else
116			echo "test2: type $type: failed"
117			exit 1
118		fi
119	done
120	echo "Test 2: recno: small key, medium data pairs"
121	rm -f $TMP2 $TMP3
122	echo $mdata |
123	awk '{  for (i = 1; i < 201; ++i)
124		printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
125	}' > $TMP2
126	$PROG -o $TMP3 recno $TMP2
127	if (cmp -s $TMP1 $TMP3) ; then :
128	else
129		echo "test2: type recno: failed"
130		exit 1
131	fi
132}
133
134# Insert the programs in /bin with their paths as their keys.
135test3()
136{
137	echo "Test 3: hash: small key, big data pairs"
138	rm -f $TMP1
139	(find /bin -type f -print | xargs cat) > $TMP1
140	for type in hash; do
141		rm -f $TMP2 $TMP3
142		for i in `find /bin -type f -print`; do
143			echo p
144			echo k$i
145			echo D$i
146			echo g
147			echo k$i
148		done > $TMP2
149		$PROG -o $TMP3 $type $TMP2
150		if (cmp -s $TMP1 $TMP3) ; then :
151		else
152			echo "test3: $type: failed"
153			exit 1
154		fi
155	done
156	echo "Test 3: btree: small key, big data pairs"
157	for psize in 512 16384 65536; do
158		echo "    page size $psize"
159		for type in btree; do
160			rm -f $TMP2 $TMP3
161			for i in `find /bin -type f -print`; do
162				echo p
163				echo k$i
164				echo D$i
165				echo g
166				echo k$i
167			done > $TMP2
168			$PROG -i psize=$psize -o $TMP3 $type $TMP2
169			if (cmp -s $TMP1 $TMP3) ; then :
170			else
171				echo "test3: $type: page size $psize: failed"
172				exit 1
173			fi
174		done
175	done
176	echo "Test 3: recno: big data pairs"
177	rm -f $TMP2 $TMP3
178	find /bin -type f -print |
179	awk '{
180		++i;
181		printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
182	}' > $TMP2
183	for psize in 512 16384 65536; do
184		echo "    page size $psize"
185		$PROG -i psize=$psize -o $TMP3 recno $TMP2
186		if (cmp -s $TMP1 $TMP3) ; then :
187		else
188			echo "test3: recno: page size $psize: failed"
189			exit 1
190		fi
191	done
192}
193
194# Do random recno entries.
195test4()
196{
197	echo "Test 4: recno: random entries"
198	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
199	awk '{
200		for (i = 37; i <= 37 + 88 * 17; i += 17) {
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 = 1; i <= 15; ++i) {
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		for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
215			if (i % 41)
216				s = substr($0, 1, i % 41);
217			else
218				s = substr($0, 1);
219			printf("input key %d: %s\n", i, s);
220		}
221		exit
222	}' > $TMP1
223	rm -f $TMP2 $TMP3
224	cat $TMP1 |
225	awk 'BEGIN {
226			i = 37;
227			incr = 17;
228		}
229		{
230			printf("p\nk%d\nd%s\n", i, $0);
231			if (i == 19234 + 61 * 27)
232				exit;
233			if (i == 37 + 88 * 17) {
234				i = 1;
235				incr = 1;
236			} else if (i == 15) {
237				i = 19234;
238				incr = 27;
239			} else
240				i += incr;
241		}
242		END {
243			for (i = 37; i <= 37 + 88 * 17; i += 17)
244				printf("g\nk%d\n", i);
245			for (i = 1; i <= 15; ++i)
246				printf("g\nk%d\n", i);
247			for (i = 19234; i <= 19234 + 61 * 27; i += 27)
248				printf("g\nk%d\n", i);
249		}' > $TMP2
250	$PROG -o $TMP3 recno $TMP2
251	if (cmp -s $TMP1 $TMP3) ; then :
252	else
253		echo "test4: type recno: failed"
254		exit 1
255	fi
256}
257
258# Do reverse order recno entries.
259test5()
260{
261	echo "Test 5: recno: reverse order entries"
262	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
263	awk ' {
264		for (i = 1500; i; --i) {
265			if (i % 34)
266				s = substr($0, 1, i % 34);
267			else
268				s = substr($0, 1);
269			printf("input key %d: %s\n", i, s);
270		}
271		exit;
272	}' > $TMP1
273	rm -f $TMP2 $TMP3
274	cat $TMP1 |
275	awk 'BEGIN {
276			i = 1500;
277		}
278		{
279			printf("p\nk%d\nd%s\n", i, $0);
280			--i;
281		}
282		END {
283			for (i = 1500; i; --i)
284				printf("g\nk%d\n", i);
285		}' > $TMP2
286	$PROG -o $TMP3 recno $TMP2
287	if (cmp -s $TMP1 $TMP3) ; then :
288	else
289		echo "test5: type recno: failed"
290		exit 1
291	fi
292}
293
294# Do alternating order recno entries.
295test6()
296{
297	echo "Test 6: recno: alternating order entries"
298	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
299	awk ' {
300		for (i = 1; 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		for (i = 2; i < 1200; i += 2) {
308			if (i % 34)
309				s = substr($0, 1, i % 34);
310			else
311				s = substr($0, 1);
312			printf("input key %d: %s\n", i, s);
313		}
314		exit;
315	}' > $TMP1
316	rm -f $TMP2 $TMP3
317	cat $TMP1 |
318	awk 'BEGIN {
319			i = 1;
320			even = 0;
321		}
322		{
323			printf("p\nk%d\nd%s\n", i, $0);
324			i += 2;
325			if (i >= 1200) {
326				if (even == 1)
327					exit;
328				even = 1;
329				i = 2;
330			}
331		}
332		END {
333			for (i = 1; i < 1200; ++i)
334				printf("g\nk%d\n", i);
335		}' > $TMP2
336	$PROG -o $TMP3 recno $TMP2
337	sort -o $TMP1 $TMP1
338	sort -o $TMP3 $TMP3
339	if (cmp -s $TMP1 $TMP3) ; then :
340	else
341		echo "test6: type recno: failed"
342		exit 1
343	fi
344}
345
346# Delete cursor record
347test7()
348{
349	echo "Test 7: btree, recno: delete cursor record"
350	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
351	awk '{
352		for (i = 1; i <= 120; ++i)
353			printf("%05d: input key %d: %s\n", i, i, $0);
354		printf("%05d: input key %d: %s\n", 120, 120, $0);
355		printf("seq failed, no such key\n");
356		printf("%05d: input key %d: %s\n", 1, 1, $0);
357		printf("%05d: input key %d: %s\n", 2, 2, $0);
358		exit;
359	}' > $TMP1
360	rm -f $TMP2 $TMP3
361
362	for type in btree recno; do
363		cat $TMP1 |
364		awk '{
365			if (i == 120)
366				exit;
367			printf("p\nk%d\nd%s\n", ++i, $0);
368		}
369		END {
370			printf("fR_NEXT\n");
371			for (i = 1; i <= 120; ++i)
372				printf("s\n");
373			printf("fR_CURSOR\ns\nk120\n");
374			printf("r\n");
375			printf("fR_NEXT\ns\n");
376			printf("fR_CURSOR\ns\nk1\n");
377			printf("r\n");
378			printf("fR_FIRST\ns\n");
379		}' > $TMP2
380		$PROG -o $TMP3 recno $TMP2
381		if (cmp -s $TMP1 $TMP3) ; then :
382		else
383			echo "test7: type $type: failed"
384			exit 1
385		fi
386	done
387}
388
389# Make sure that overflow pages are reused.
390test8()
391{
392	echo "Test 8: btree, hash: repeated small key, big data pairs"
393	rm -f $TMP1
394	echo "" |
395	awk 'BEGIN {
396		for (i = 1; i <= 10; ++i) {
397			printf("p\nkkey1\nD/bin/sh\n");
398			printf("p\nkkey2\nD/bin/csh\n");
399			if (i % 8 == 0) {
400				printf("c\nkkey2\nD/bin/csh\n");
401				printf("c\nkkey1\nD/bin/sh\n");
402				printf("e\t%d of 10 (comparison)\n", i);
403			} else
404				printf("e\t%d of 10             \n", i);
405			printf("r\nkkey1\nr\nkkey2\n");
406		}
407	}' > $TMP1
408	$PROG btree $TMP1
409#	$PROG hash $TMP1
410	# No explicit test for success.
411}
412
413# Test btree duplicate keys
414test9()
415{
416	echo "Test 9: btree: duplicate keys"
417	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
418	awk '{
419		for (i = 1; i <= 543; ++i)
420			printf("%05d: input key %d: %s\n", i, i, $0);
421		exit;
422	}' > $TMP1
423	rm -f $TMP2 $TMP3
424
425	for type in btree; do
426		cat $TMP1 |
427		awk '{
428			if (i++ % 2)
429				printf("p\nkduplicatekey\nd%s\n", $0);
430			else
431				printf("p\nkunique%dkey\nd%s\n", i, $0);
432		}
433		END {
434				printf("o\n");
435		}' > $TMP2
436		$PROG -iflags=1 -o $TMP3 $type $TMP2
437		sort -o $TMP3 $TMP3
438		if (cmp -s $TMP1 $TMP3) ; then :
439		else
440			echo "test9: type $type: failed"
441			exit 1
442		fi
443	done
444}
445
446# Test use of cursor flags without initialization
447test10()
448{
449	echo "Test 10: btree, recno: test cursor flag use"
450	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
451	awk '{
452		for (i = 1; i <= 20; ++i)
453			printf("%05d: input key %d: %s\n", i, i, $0);
454		exit;
455	}' > $TMP1
456	rm -f $TMP2 $TMP3
457
458	# Test that R_CURSOR doesn't succeed before cursor initialized
459	for type in btree recno; do
460		cat $TMP1 |
461		awk '{
462			if (i == 10)
463				exit;
464			printf("p\nk%d\nd%s\n", ++i, $0);
465		}
466		END {
467			printf("fR_CURSOR\nr\n");
468			printf("eR_CURSOR SHOULD HAVE FAILED\n");
469		}' > $TMP2
470		$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
471		if [ -s $TMP3 ] ; then
472			echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
473			exit 1
474		fi
475	done
476	for type in btree recno; do
477		cat $TMP1 |
478		awk '{
479			if (i == 10)
480				exit;
481			printf("p\nk%d\nd%s\n", ++i, $0);
482		}
483		END {
484			printf("fR_CURSOR\np\nk1\ndsome data\n");
485			printf("eR_CURSOR SHOULD HAVE FAILED\n");
486		}' > $TMP2
487		$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
488		if [ -s $TMP3 ] ; then
489			echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
490			exit 1
491		fi
492	done
493}
494
495# Test insert in reverse order.
496test11()
497{
498	echo "Test 11: recno: reverse order insert"
499	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
500	awk '{
501		for (i = 1; i <= 779; ++i)
502			printf("%05d: input key %d: %s\n", i, i, $0);
503		exit;
504	}' > $TMP1
505	rm -f $TMP2 $TMP3
506
507	for type in recno; do
508		cat $TMP1 |
509		awk '{
510			if (i == 0) {
511				i = 1;
512				printf("p\nk1\nd%s\n", $0);
513				printf("%s\n", "fR_IBEFORE");
514			} else
515				printf("p\nk1\nd%s\n", $0);
516		}
517		END {
518				printf("or\n");
519		}' > $TMP2
520		$PROG -o $TMP3 $type $TMP2
521		if (cmp -s $TMP1 $TMP3) ; then :
522		else
523			echo "test11: type $type: failed"
524			exit 1
525		fi
526	done
527}
528
529# Take the first 20000 entries in the dictionary, reverse them, and give
530# them each a small size data entry.  Use a small page size to make sure
531# the btree split code gets hammered.
532test12()
533{
534	echo "Test 12: btree: lots of keys, small page size"
535	mdata=abcdefghijklmnopqrstuvwxy
536	echo $mdata |
537	awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
538	for type in btree; do
539		rm -f $TMP2 $TMP3
540		for i in `sed 20000q $DICT | rev`; do
541			echo p
542			echo k$i
543			echo d$mdata
544			echo g
545			echo k$i
546		done > $TMP2
547		$PROG -i psize=512 -o $TMP3 $type $TMP2
548		if (cmp -s $TMP1 $TMP3) ; then :
549		else
550			echo "test12: type $type: failed"
551			exit 1
552		fi
553	done
554}
555
556# Test different byte orders.
557test13()
558{
559	echo "Test 13: btree, hash: differing byte orders"
560	sed 50q $DICT > $TMP1
561	for order in 1234 4321; do
562		for type in btree hash; do
563			rm -f byte.file $TMP2 $TMP3
564			for i in `sed 50q $DICT`; do
565				echo p
566				echo k$i
567				echo d$i
568				echo g
569				echo k$i
570			done > $TMP2
571			$PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
572			if (cmp -s $TMP1 $TMP3) ; then :
573			else
574				echo "test13: $type/$order put failed"
575				exit 1
576			fi
577			for i in `sed 50q $DICT`; do
578				echo g
579				echo k$i
580			done > $TMP2
581			$PROG -s \
582			    -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
583			if (cmp -s $TMP1 $TMP3) ; then :
584			else
585				echo "test13: $type/$order get failed"
586				exit 1
587			fi
588		done
589	done
590	rm -f byte.file
591}
592
593# Try a variety of bucketsizes and fill factors for hashing
594test20()
595{
596	echo\
597    "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536"
598	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
599	awk '{
600		for (i = 1; i <= 10000; ++i) {
601			if (i % 34)
602				s = substr($0, 1, i % 34);
603			else
604				s = substr($0, 1);
605			printf("%s\n", s);
606		}
607		exit;
608	}' > $TMP1
609	sed 10000q $DICT |
610	awk 'BEGIN {
611		ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg"
612	}
613	{
614		if (++i % 34)
615			s = substr(ds, 1, i % 34);
616		else
617			s = substr(ds, 1);
618		printf("p\nk%s\nd%s\n", $0, s);
619	}' > $TMP2
620	sed 10000q $DICT |
621	awk '{
622		++i;
623		printf("g\nk%s\n", $0);
624	}' >> $TMP2
625	bsize=256
626	for ffactor in 11 14 21; do
627		echo "    bucketsize $bsize, fill factor $ffactor"
628		$PROG -o$TMP3 \
629		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
630		    hash $TMP2
631		if (cmp -s $TMP1 $TMP3) ; then :
632		else
633			echo "test20: type hash:\
634bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
635			exit 1
636		fi
637	done
638	bsize=512
639	for ffactor in 21 28 43; do
640		echo "    bucketsize $bsize, fill factor $ffactor"
641		$PROG -o$TMP3 \
642		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
643		    hash $TMP2
644		if (cmp -s $TMP1 $TMP3) ; then :
645		else
646			echo "test20: type hash:\
647bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
648			exit 1
649		fi
650	done
651	bsize=1024
652	for ffactor in 43 57 85; do
653		echo "    bucketsize $bsize, fill factor $ffactor"
654		$PROG -o$TMP3 \
655		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
656		    hash $TMP2
657		if (cmp -s $TMP1 $TMP3) ; then :
658		else
659			echo "test20: type hash:\
660bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
661			exit 1
662		fi
663	done
664	bsize=2048
665	for ffactor in 85 114 171; do
666		echo "    bucketsize $bsize, fill factor $ffactor"
667		$PROG -o$TMP3 \
668		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
669		    hash $TMP2
670		if (cmp -s $TMP1 $TMP3) ; then :
671		else
672			echo "test20: type hash:\
673bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
674			exit 1
675		fi
676	done
677	bsize=4096
678	for ffactor in 171 228 341; do
679		echo "    bucketsize $bsize, fill factor $ffactor"
680		$PROG -o$TMP3 \
681		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
682		    hash $TMP2
683		if (cmp -s $TMP1 $TMP3) ; then :
684		else
685			echo "test20: type hash:\
686bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
687			exit 1
688		fi
689	done
690	bsize=8192
691	for ffactor in 341 455 683; do
692		echo "    bucketsize $bsize, fill factor $ffactor"
693		$PROG -o$TMP3 \
694		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
695		    hash $TMP2
696		if (cmp -s $TMP1 $TMP3) ; then :
697		else
698			echo "test20: type hash:\
699bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
700			exit 1
701		fi
702	done
703}
704
705main $*
706