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