xref: /csrg-svn/lib/libc/db/test/run.test (revision 64451)
1#!/bin/sh -
2#
3#	@(#)run.test	8.5 (Berkeley) 09/06/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			s = substr($0, 1, i % 41);
184			printf("input key %d: %s\n", i, s);
185		}
186		for (i = 1; i <= 15; ++i) {
187			s = substr($0, 1, i % 41);
188			printf("input key %d: %s\n", i, s);
189		}
190		for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
191			s = substr($0, 1, i % 41);
192			printf("input key %d: %s\n", i, s);
193		}
194		exit
195	}' > $TMP1
196	rm -f $TMP2 $TMP3
197	cat $TMP1 |
198	awk 'BEGIN {
199			i = 37;
200			incr = 17;
201		}
202		{
203			printf("p\nk%d\nd%s\n", i, $0);
204			if (i == 19234 + 61 * 27)
205				exit;
206			if (i == 37 + 88 * 17) {
207				i = 1;
208				incr = 1;
209			} else if (i == 15) {
210				i = 19234;
211				incr = 27;
212			} else
213				i += incr;
214		}
215		END {
216			for (i = 37; i <= 37 + 88 * 17; i += 17)
217				printf("g\nk%d\n", i);
218			for (i = 1; i <= 15; ++i)
219				printf("g\nk%d\n", i);
220			for (i = 19234; i <= 19234 + 61 * 27; i += 27)
221				printf("g\nk%d\n", i);
222		}' > $TMP2
223	$PROG -o $TMP3 recno $TMP2
224	if (cmp -s $TMP1 $TMP3) ; then :
225	else
226		echo "test4: type recno: failed"
227		exit 1
228	fi
229}
230
231# Do reverse order recno entries.
232test5()
233{
234	echo "Test 5: recno: reverse order entries"
235	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
236	awk ' {
237		for (i = 1500; i; --i) {
238			s = substr($0, 1, i % 34);
239			printf("input key %d: %s\n", i, s);
240		}
241		exit;
242	}' > $TMP1
243	rm -f $TMP2 $TMP3
244	cat $TMP1 |
245	awk 'BEGIN {
246			i = 1500;
247		}
248		{
249			printf("p\nk%d\nd%s\n", i, $0);
250			--i;
251		}
252		END {
253			for (i = 1500; i; --i)
254				printf("g\nk%d\n", i);
255		}' > $TMP2
256	$PROG -o $TMP3 recno $TMP2
257	if (cmp -s $TMP1 $TMP3) ; then :
258	else
259		echo "test5: type recno: failed"
260		exit 1
261	fi
262}
263
264# Do alternating order recno entries.
265test6()
266{
267	echo "Test 6: recno: alternating order entries"
268	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
269	awk ' {
270		for (i = 1; i < 1200; i += 2) {
271			s = substr($0, 1, i % 34);
272			printf("input key %d: %s\n", i, s);
273		}
274		for (i = 2; i < 1200; i += 2) {
275			s = substr($0, 1, i % 34);
276			printf("input key %d: %s\n", i, s);
277		}
278		exit;
279	}' > $TMP1
280	rm -f $TMP2 $TMP3
281	cat $TMP1 |
282	awk 'BEGIN {
283			i = 1;
284			even = 0;
285		}
286		{
287			printf("p\nk%d\nd%s\n", i, $0);
288			i += 2;
289			if (i >= 1200) {
290				if (even == 1)
291					exit;
292				even = 1;
293				i = 2;
294			}
295		}
296		END {
297			for (i = 1; i < 1200; ++i)
298				printf("g\nk%d\n", i);
299		}' > $TMP2
300	$PROG -o $TMP3 recno $TMP2
301	sort -o $TMP1 $TMP1
302	sort -o $TMP3 $TMP3
303	if (cmp -s $TMP1 $TMP3) ; then :
304	else
305		echo "test6: type recno: failed"
306		exit 1
307	fi
308}
309
310# Delete cursor record
311test7()
312{
313	echo "Test 7: btree, recno: delete cursor record"
314	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
315	awk '{
316		for (i = 1; i <= 120; ++i)
317			printf("%05d: input key %d: %s\n", i, i, $0);
318		printf("%05d: input key %d: %s\n", 120, 120, $0);
319		printf("get failed, no such key\n");
320		printf("%05d: input key %d: %s\n", 1, 1, $0);
321		printf("%05d: input key %d: %s\n", 2, 2, $0);
322		exit;
323	}' > $TMP1
324	rm -f $TMP2 $TMP3
325
326	for type in btree recno; do
327		cat $TMP1 |
328		awk '{
329			if (i == 120)
330				exit;
331			printf("p\nk%d\nd%s\n", ++i, $0);
332		}
333		END {
334			printf("fR_NEXT\n");
335			for (i = 1; i <= 120; ++i)
336				printf("s\n");
337			printf("fR_CURSOR\ns\nk120\n");
338			printf("r\nk120\n");
339			printf("fR_NEXT\ns\n");
340			printf("fR_CURSOR\ns\nk1\n");
341			printf("r\nk1\n");
342			printf("fR_FIRST\ns\n");
343		}' > $TMP2
344		$PROG -o $TMP3 recno $TMP2
345		if (cmp -s $TMP1 $TMP3) ; then :
346		else
347			echo "test7: type $type: failed"
348			exit 1
349		fi
350	done
351}
352
353# Make sure that overflow pages are reused.
354test8()
355{
356	echo "Test 8: btree, hash: repeated small key, big data pairs"
357	rm -f $TMP1
358	echo "" |
359	awk 'BEGIN {
360		for (i = 1; i <= 10; ++i) {
361			printf("p\nkkey1\nD/bin/sh\n");
362			printf("p\nkkey2\nD/bin/csh\n");
363			if (i % 8 == 0) {
364				printf("c\nkkey2\nD/bin/csh\n");
365				printf("c\nkkey1\nD/bin/sh\n");
366				printf("e\t%d of 10 (comparison)\r\n", i);
367			} else
368				printf("e\t%d of 10             \r\n", i);
369			printf("r\nkkey1\nr\nkkey2\n");
370		}
371		printf("e\n");
372		printf("eend of test8 run\n");
373	}' > $TMP1
374	$PROG btree $TMP1
375#	$PROG hash $TMP1
376	# No explicit test for success.
377}
378
379# Test btree duplicate keys
380test9()
381{
382	echo "Test 9: btree: duplicate keys"
383	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
384	awk '{
385		for (i = 1; i <= 543; ++i)
386			printf("%05d: input key %d: %s\n", i, i, $0);
387		exit;
388	}' > $TMP1
389	rm -f $TMP2 $TMP3
390
391	for type in btree; do
392		cat $TMP1 |
393		awk '{
394			if (i++ % 2)
395				printf("p\nkduplicatekey\nd%s\n", $0);
396			else
397				printf("p\nkunique%dkey\nd%s\n", i, $0);
398		}
399		END {
400				printf("o\n");
401		}' > $TMP2
402		$PROG -iflags=1 -o $TMP3 $type $TMP2
403		sort -o $TMP3 $TMP3
404		if (cmp -s $TMP1 $TMP3) ; then :
405		else
406			echo "test9: type $type: failed"
407			exit 1
408		fi
409	done
410}
411
412# Test use of cursor flags without initialization
413test10()
414{
415	echo "Test 10: btree, recno: test cursor flag use"
416	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
417	awk '{
418		for (i = 1; i <= 20; ++i)
419			printf("%05d: input key %d: %s\n", i, i, $0);
420		exit;
421	}' > $TMP1
422	rm -f $TMP2 $TMP3
423
424	# Test that R_CURSOR doesn't succeed before cursor initialized
425	for type in btree recno; do
426		cat $TMP1 |
427		awk '{
428			if (i == 10)
429				exit;
430			printf("p\nk%d\nd%s\n", ++i, $0);
431		}
432		END {
433			printf("fR_CURSOR\nr\nk1\n");
434			printf("eR_CURSOR SHOULD HAVE FAILED\n");
435		}' > $TMP2
436		$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
437		if [ -s $TMP3 ] ; then
438			echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
439			exit 1
440		fi
441	done
442	for type in btree recno; do
443		cat $TMP1 |
444		awk '{
445			if (i == 10)
446				exit;
447			printf("p\nk%d\nd%s\n", ++i, $0);
448		}
449		END {
450			printf("fR_CURSOR\np\nk1\ndsome data\n");
451			printf("eR_CURSOR SHOULD HAVE FAILED\n");
452		}' > $TMP2
453		$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
454		if [ -s $TMP3 ] ; then
455			echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
456			exit 1
457		fi
458	done
459}
460
461# Test insert in reverse order.
462test11()
463{
464	echo "Test 11: recno: reverse order insert"
465	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
466	awk '{
467		for (i = 1; i <= 779; ++i)
468			printf("%05d: input key %d: %s\n", i, i, $0);
469		exit;
470	}' > $TMP1
471	rm -f $TMP2 $TMP3
472
473	for type in recno; do
474		cat $TMP1 |
475		awk '{
476			if (i == 0) {
477				i = 1;
478				printf("p\nk1\nd%s\n", $0);
479				printf("%s\n", "fR_IBEFORE");
480			} else
481				printf("p\nk1\nd%s\n", $0);
482		}
483		END {
484				printf("or\n");
485		}' > $TMP2
486		$PROG -o $TMP3 $type $TMP2
487		if (cmp -s $TMP1 $TMP3) ; then :
488		else
489			echo "test11: type $type: failed"
490			exit 1
491		fi
492	done
493}
494
495# Take the first 20000 entries in the dictionary, reverse them, and give
496# them each a small size data entry.  Use a small page size to make sure
497# the btree split code gets hammered.
498test12()
499{
500	echo "Test 12: btree: lots of keys, small page size"
501	mdata=abcdefghijklmnopqrstuvwxy
502	echo $mdata |
503	awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
504	for type in btree; do
505		rm -f $TMP2 $TMP3
506		for i in `sed 20000q $DICT | rev`; do
507			echo p
508			echo k$i
509			echo d$mdata
510			echo g
511			echo k$i
512		done > $TMP2
513		$PROG -i psize=512 -o $TMP3 $type $TMP2
514		if (cmp -s $TMP1 $TMP3) ; then :
515		else
516			echo "test12: type $type: failed"
517			exit 1
518		fi
519	done
520}
521
522# Test different byte orders.
523test13()
524{
525	echo "Test 13: btree, hash: differing byte orders"
526	sed 50q $DICT > $TMP1
527	for order in 1234 4321; do
528		for type in btree hash; do
529			rm -f byte.file $TMP2 $TMP3
530			for i in `sed 50q $DICT`; do
531				echo p
532				echo k$i
533				echo d$i
534				echo g
535				echo k$i
536			done > $TMP2
537			$PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
538			if (cmp -s $TMP1 $TMP3) ; then :
539			else
540				echo "test13: $type/$order put failed"
541				exit 1
542			fi
543			for i in `sed 50q $DICT`; do
544				echo g
545				echo k$i
546			done > $TMP2
547			$PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
548			if (cmp -s $TMP1 $TMP3) ; then :
549			else
550				echo "test13: $type/$order get failed"
551				exit 1
552			fi
553		done
554	done
555	rm -f byte.file
556}
557
558# Try a variety of bucketsizes and fill factors for hashing
559test20()
560{
561	echo\
562    "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536"
563	awk 'BEGIN {
564		for (i = 1; i <= 10000; ++i)
565			printf("%.*s\n", i % 34,
566		    "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg");
567	}' > $TMP1
568	sed 10000q $DICT |
569	awk '{
570		++i;
571		printf("p\nk%s\nd%.*s\n", $0, i % 34,
572		    "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg");
573	}' > $TMP2
574	sed 10000q $DICT |
575	awk '{
576		++i;
577		printf("g\nk%s\n", $0);
578	}' >> $TMP2
579	bsize=256
580	for ffactor in 11 14 21; do
581		echo "    bucketsize $bsize, fill factor $ffactor"
582		$PROG -o$TMP3 \
583		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
584		    hash $TMP2
585		if (cmp -s $TMP1 $TMP3) ; then :
586		else
587			echo "test20: type hash:\
588bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
589			exit 1
590		fi
591	done
592	bsize=512
593	for ffactor in 21 28 43; do
594		echo "    bucketsize $bsize, fill factor $ffactor"
595		$PROG -o$TMP3 \
596		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
597		    hash $TMP2
598		if (cmp -s $TMP1 $TMP3) ; then :
599		else
600			echo "test20: type hash:\
601bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
602			exit 1
603		fi
604	done
605	bsize=1024
606	for ffactor in 43 57 85; do
607		echo "    bucketsize $bsize, fill factor $ffactor"
608		$PROG -o$TMP3 \
609		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
610		    hash $TMP2
611		if (cmp -s $TMP1 $TMP3) ; then :
612		else
613			echo "test20: type hash:\
614bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
615			exit 1
616		fi
617	done
618	bsize=2048
619	for ffactor in 85 114 171; do
620		echo "    bucketsize $bsize, fill factor $ffactor"
621		$PROG -o$TMP3 \
622		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
623		    hash $TMP2
624		if (cmp -s $TMP1 $TMP3) ; then :
625		else
626			echo "test20: type hash:\
627bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
628			exit 1
629		fi
630	done
631	bsize=4096
632	for ffactor in 171 228 341; do
633		echo "    bucketsize $bsize, fill factor $ffactor"
634		$PROG -o$TMP3 \
635		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
636		    hash $TMP2
637		if (cmp -s $TMP1 $TMP3) ; then :
638		else
639			echo "test20: type hash:\
640bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
641			exit 1
642		fi
643	done
644	bsize=8192
645	for ffactor in 341 455 683; do
646		echo "    bucketsize $bsize, fill factor $ffactor"
647		$PROG -o$TMP3 \
648		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
649		    hash $TMP2
650		if (cmp -s $TMP1 $TMP3) ; then :
651		else
652			echo "test20: type hash:\
653bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
654			exit 1
655		fi
656	done
657}
658
659main $*
660