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