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