xref: /freebsd/lib/libc/db/test/run.test (revision afe61c15161c324a7af299a9b8457aba5afc92db)
1#!/bin/sh -
2#
3#	@(#)run.test	8.7 (Berkeley) 9/16/93
4#
5
6# db regression tests
7main()
8{
9
10DICT=/usr/share/dict/words
11#DICT=/usr/dict/words
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)\r\n", i);
396			} else
397				printf("e\t%d of 10             \r\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 $*
700