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