xref: /386bsd/usr/src/lib/libc/db/test/run.test (revision a2142627)
1#!/bin/sh -
2#
3# Copyright (c) 1992 The Regents of the University of California.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14# 3. All advertising materials mentioning features or use of this software
15#    must display the following acknowledgement:
16#	This product includes software developed by the University of
17#	California, Berkeley and its contributors.
18# 4. Neither the name of the University nor the names of its contributors
19#    may be used to endorse or promote products derived from this software
20#    without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32# SUCH DAMAGE.
33#
34#	@(#)run.test	5.17 (Berkeley) 5/22/93
35#
36
37# db regression tests
38
39main()
40{
41#	DICT=/usr/share/dict/words
42	DICT=/usr/share/dict/web2
43	PROG=obj/dbtest
44	TMP1=t1
45	TMP2=t2
46	TMP3=t3
47
48	test1
49	test2
50	test3
51	test4
52	test5
53	test6
54	test7
55	test8
56	test9
57	test10
58	test11
59	test12
60	test13
61	test20
62	rm -f $TMP1 $TMP2 $TMP3
63	exit 0
64}
65
66# Take the first hundred entries in the dictionary, and make them
67# be key/data pairs.
68test1()
69{
70	printf "Test 1: btree, hash: small key, small data pairs\n"
71	sed 200q $DICT > $TMP1
72	for type in btree hash; do
73		rm -f $TMP2 $TMP3
74		for i in `sed 200q $DICT`; do
75			printf "p\nk%s\nd%s\ng\nk%s\n" $i $i $i
76		done > $TMP2
77		$PROG -o $TMP3 $type $TMP2
78		if (cmp -s $TMP1 $TMP3) ; then :
79		else
80			printf "test1: type %s: failed\n" $type
81			exit 1
82		fi
83	done
84	printf "Test 1: recno: small key, small data pairs\n"
85	rm -f $TMP2 $TMP3
86	sed 200q $DICT |
87	awk '{
88		++i;
89		printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
90	}' > $TMP2
91	$PROG -o $TMP3 recno $TMP2
92	if (cmp -s $TMP1 $TMP3) ; then :
93	else
94		printf "test1: type recno: failed\n"
95		exit 1
96	fi
97}
98
99# Take the first 200 entries in the dictionary, and give them
100# each a medium size data entry.
101test2()
102{
103	printf "Test 2: btree, hash: small key, medium data pairs\n"
104	mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
105	echo $mdata |
106	awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1
107	for type in hash btree; do
108		rm -f $TMP2 $TMP3
109		for i in `sed 200q $DICT`; do
110			printf "p\nk%s\nd%s\ng\nk%s\n" $i $mdata $i
111		done > $TMP2
112		$PROG -o $TMP3 $type $TMP2
113		if (cmp -s $TMP1 $TMP3) ; then :
114		else
115			printf "test2: type %s: failed\n" $type
116			exit 1
117		fi
118	done
119	printf "Test 2: recno: small key, medium data pairs\n"
120	rm -f $TMP2 $TMP3
121	echo $mdata |
122	awk '{  for (i = 1; i < 201; ++i)
123		printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
124	}' > $TMP2
125	$PROG -o $TMP3 recno $TMP2
126	if (cmp -s $TMP1 $TMP3) ; then :
127	else
128		printf "test2: type recno: failed\n"
129		exit 1
130	fi
131}
132
133# Insert the programs in /bin with their paths as their keys.
134test3()
135{
136	printf "Test 3: hash: small key, big data pairs\n"
137	rm -f $TMP1
138	(find /bin -type f -print | xargs cat) > $TMP1
139	for type in hash; do
140		rm -f $TMP2 $TMP3
141		for i in `find /bin -type f -print`; do
142			printf "p\nk%s\nD%s\ng\nk%s\n" $i $i $i
143		done > $TMP2
144		$PROG -o $TMP3 $type $TMP2
145		if (cmp -s $TMP1 $TMP3) ; then :
146		else
147			printf "test3: %s: page size %d: failed\n" \
148			    $type $psize
149			exit 1
150		fi
151	done
152	printf "Test 3: btree: small key, big data pairs\n"
153	for psize in 512 16384 65536; do
154		printf "\tpage size %d\n" $psize
155		for type in btree; do
156			rm -f $TMP2 $TMP3
157			for i in `find /bin -type f -print`; do
158				printf "p\nk%s\nD%s\ng\nk%s\n" $i $i $i
159			done > $TMP2
160			$PROG -i psize=$psize -o $TMP3 $type $TMP2
161			if (cmp -s $TMP1 $TMP3) ; then :
162			else
163				printf "test3: %s: page size %d: failed\n" \
164				    $type $psize
165				exit 1
166			fi
167		done
168	done
169	printf "Test 3: recno: big data pairs\n"
170	rm -f $TMP2 $TMP3
171	find /bin -type f -print |
172	awk '{
173		++i;
174		printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
175	}' > $TMP2
176	for psize in 512 16384 65536; do
177		printf "\tpage size %d\n" $psize
178		$PROG -i psize=$psize -o $TMP3 recno $TMP2
179		if (cmp -s $TMP1 $TMP3) ; then :
180		else
181			printf "test3: recno: page size %d: failed\n" $psize
182			exit 1
183		fi
184	done
185}
186
187# Do random recno entries.
188test4()
189{
190	printf "Test 4: recno: random entries\n"
191	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
192	awk '{
193		for (i = 37; i <= 37 + 88 * 17; i += 17)
194			printf("input key %d: %.*s\n", i, i % 41, $0);
195		for (i = 1; i <= 15; ++i)
196			printf("input key %d: %.*s\n", i, i % 41, $0);
197		for (i = 19234; i <= 19234 + 61 * 27; i += 27)
198			printf("input key %d: %.*s\n", i, i % 41, $0);
199		exit
200	}' > $TMP1
201	rm -f TMP2 $TMP3
202	cat $TMP1 |
203	awk 'BEGIN {
204			i = 37;
205			incr = 17;
206		}
207		{
208			printf("p\nk%d\nd%s\n", i, $0);
209			if (i == 19234 + 61 * 27)
210				exit;
211			if (i == 37 + 88 * 17) {
212				i = 1;
213				incr = 1;
214			} else if (i == 15) {
215				i = 19234;
216				incr = 27;
217			} else
218				i += incr;
219		}
220		END {
221			for (i = 37; i <= 37 + 88 * 17; i += 17)
222				printf("g\nk%d\n", i);
223			for (i = 1; i <= 15; ++i)
224				printf("g\nk%d\n", i);
225			for (i = 19234; i <= 19234 + 61 * 27; i += 27)
226				printf("g\nk%d\n", i);
227		}' > $TMP2
228	$PROG -o $TMP3 recno $TMP2
229	if (cmp -s $TMP1 $TMP3) ; then :
230	else
231		printf "test4: type recno: failed\n"
232		exit 1
233	fi
234}
235
236# Do reverse order recno entries.
237test5()
238{
239	printf "Test 5: recno: reverse order entries\n"
240	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
241	awk ' {
242		for (i = 1500; i; --i)
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 = 1500;
250		}
251		{
252			printf("p\nk%d\nd%s\n", i, $0);
253			--i;
254		}
255		END {
256			for (i = 1500; i; --i)
257				printf("g\nk%d\n", i);
258		}' > $TMP2
259	$PROG -o $TMP3 recno $TMP2
260	if (cmp -s $TMP1 $TMP3) ; then :
261	else
262		printf "test5: type recno: failed\n"
263		exit 1
264	fi
265}
266
267# Do alternating order recno entries.
268test6()
269{
270	printf "Test 6: recno: alternating order entries\n"
271	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
272	awk ' {
273		for (i = 1; i < 1200; i += 2)
274			printf("input key %d: %.*s\n", i, i % 34, $0);
275		for (i = 2; i < 1200; i += 2)
276			printf("input key %d: %.*s\n", i, i % 34, $0);
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		printf "test6: type recno: failed\n"
305		exit 1
306	fi
307}
308
309# Delete cursor record
310test7()
311{
312	printf "Test 7: btree, recno: delete cursor record\n"
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			printf "test7: type $type: failed\n"
347			exit 1
348		fi
349	done
350}
351
352# Make sure that overflow pages are reused.
353test8()
354{
355	printf "Test 8: btree, hash: repeated small key, big data pairs\n"
356	rm -f $TMP1
357	awk 'BEGIN {
358		for (i = 1; i <= 10; ++i) {
359			printf("p\nkkey1\nD/bin/sh\n");
360			printf("p\nkkey2\nD/bin/csh\n");
361			if (i % 8 == 0) {
362				printf("c\nkkey2\nD/bin/csh\n");
363				printf("c\nkkey1\nD/bin/sh\n");
364				printf("e\t%d of 10 (comparison)\r\n", i);
365			} else
366				printf("e\t%d of 10             \r\n", i);
367			printf("r\nkkey1\nr\nkkey2\n");
368		}
369		printf("e\n");
370		printf("eend of test8 run\n");
371	}' > $TMP1
372	$PROG btree $TMP1
373	$PROG hash $TMP1
374	# No explicit test for success.
375}
376
377# Test btree duplicate keys
378test9()
379{
380	printf "Test 9: btree: duplicate keys\n"
381	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
382	awk '{
383		for (i = 1; i <= 543; ++i)
384			printf("%05d: input key %d: %s\n", i, i, $0);
385		exit;
386	}' > $TMP1
387	rm -f TMP2 $TMP3
388
389	for type in btree; do
390		cat $TMP1 |
391		awk '{
392			if (i++ % 2)
393				printf("p\nkduplicatekey\nd%s\n", $0);
394			else
395				printf("p\nkunique%dkey\nd%s\n", i, $0);
396		}
397		END {
398				printf("o\n");
399		}' > $TMP2
400		$PROG -iflags=1 -o $TMP3 $type $TMP2
401		sort -o $TMP3 $TMP3
402		if (cmp -s $TMP1 $TMP3) ; then :
403		else
404			printf "test9: type $type: failed\n"
405			exit 1
406		fi
407	done
408}
409
410# Test use of cursor flags without initialization
411test10()
412{
413	printf "Test 10: btree, recno: test cursor flag use\n"
414	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
415	awk '{
416		for (i = 1; i <= 20; ++i)
417			printf("%05d: input key %d: %s\n", i, i, $0);
418		exit;
419	}' > $TMP1
420	rm -f TMP2 $TMP3
421
422	# Test that R_CURSOR doesn't succeed before cursor initialized
423	for type in btree recno; do
424		cat $TMP1 |
425		awk '{
426			if (i == 10)
427				exit;
428			printf("p\nk%d\nd%s\n", ++i, $0);
429		}
430		END {
431			printf("fR_CURSOR\nr\nk1\n");
432			printf("eR_CURSOR SHOULD HAVE FAILED\n");
433		}' > $TMP2
434		$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
435		if [ -s $TMP3 ] ; then
436			printf "Test 10: delete: R_CURSOR SHOULD HAVE FAILED\n"
437			exit 1
438		fi
439	done
440	for type in btree recno; do
441		cat $TMP1 |
442		awk '{
443			if (i == 10)
444				exit;
445			printf("p\nk%d\nd%s\n", ++i, $0);
446		}
447		END {
448			printf("fR_CURSOR\np\nk1\ndsome data\n");
449			printf("eR_CURSOR SHOULD HAVE FAILED\n");
450		}' > $TMP2
451		$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
452		if [ -s $TMP3 ] ; then
453			printf "Test 10: put: R_CURSOR SHOULD HAVE FAILED\n"
454			exit 1
455		fi
456	done
457}
458
459# Test insert in reverse order.
460test11()
461{
462	printf "Test 11: recno: reverse order insert\n"
463	echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
464	awk '{
465		for (i = 1; i <= 779; ++i)
466			printf("%05d: input key %d: %s\n", i, i, $0);
467		exit;
468	}' > $TMP1
469	rm -f TMP2 $TMP3
470
471	for type in recno; do
472		cat $TMP1 |
473		awk '{
474			if (i == 0) {
475				i = 1;
476				printf("p\nk1\nd%s\n", $0);
477				printf("%s\n", "fR_IBEFORE");
478			} else
479				printf("p\nk1\nd%s\n", $0);
480		}
481		END {
482				printf("or\n");
483		}' > $TMP2
484		$PROG -o $TMP3 $type $TMP2
485		if (cmp -s $TMP1 $TMP3) ; then :
486		else
487			printf "test11: type $type: failed\n"
488			exit 1
489		fi
490	done
491}
492
493# Take the first 20000 entries in the dictionary, reverse them, and give
494# them each a small size data entry.  Use a small page size to make sure
495# the btree split code gets hammered.
496test12()
497{
498	printf "Test 12: btree: lots of keys, small page size\n"
499	mdata=abcdefghijklmnopqrstuvwxy
500	echo $mdata |
501	awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1
502	for type in btree; do
503		rm -f $TMP2 $TMP3
504		for i in `sed 20000q $DICT | rev`; do
505			printf "p\nk%s\nd%s\ng\nk%s\n" $i $mdata $i
506		done > $TMP2
507		$PROG -i psize=512 -o $TMP3 $type $TMP2
508		if (cmp -s $TMP1 $TMP3) ; then :
509		else
510			printf "test12: type %s: failed\n" $type
511			exit 1
512		fi
513	done
514}
515
516# Test different byte orders.
517test13()
518{
519	printf "Test 13: btree, hash: differing byte orders\n"
520	sed 50q $DICT > $TMP1
521	for order in 1234 4321; do
522		for type in btree hash; do
523			rm -f byte.file $TMP2 $TMP3
524			for i in `sed 50q $DICT`; do
525				printf "p\nk%s\nd%s\ng\nk%s\n" $i $i $i
526			done > $TMP2
527			$PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2
528			if (cmp -s $TMP1 $TMP3) ; then :
529			else
530				printf "test13: %s/%s put failed\n" $type $order
531				exit 1
532			fi
533			for i in `sed 50q $DICT`; do
534				printf "g\nk%s\n" $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				printf "test13: %s/%s get failed\n" $type $order
540				exit 1
541			fi
542		done
543	done
544	rm -f byte.file
545}
546
547# Try a variety of bucketsizes and fill factors for hashing
548test20()
549{
550	printf\
551    "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536\n"
552	awk 'BEGIN {
553		for (i = 1; i <= 10000; ++i)
554			printf("%.*s\n", i % 34,
555		    "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg");
556	}' > $TMP1
557	sed 10000q $DICT |
558	awk '{
559		++i;
560		printf("p\nk%s\nd%.*s\n", $0, i % 34,
561		    "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg");
562	}' > $TMP2
563	sed 10000q $DICT |
564	awk '{
565		++i;
566		printf("g\nk%s\n", $0);
567	}' >> $TMP2
568	bsize=256
569	for ffactor in 11 14 21; do
570		printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
571		$PROG -o$TMP3 \
572		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
573		    hash $TMP2
574		if (cmp -s $TMP1 $TMP3) ; then :
575		else
576			printf "test20: type hash:\
577bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
578			exit 1
579		fi
580	done
581	bsize=512
582	for ffactor in 21 28 43; do
583		printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
584		$PROG -o$TMP3 \
585		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
586		    hash $TMP2
587		if (cmp -s $TMP1 $TMP3) ; then :
588		else
589			printf "test20: type hash:\
590bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
591			exit 1
592		fi
593	done
594	bsize=1024
595	for ffactor in 43 57 85; do
596		printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
597		$PROG -o$TMP3 \
598		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
599		    hash $TMP2
600		if (cmp -s $TMP1 $TMP3) ; then :
601		else
602			printf "test20: type hash:\
603bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
604			exit 1
605		fi
606	done
607	bsize=2048
608	for ffactor in 85 114 171; do
609		printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
610		$PROG -o$TMP3 \
611		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
612		    hash $TMP2
613		if (cmp -s $TMP1 $TMP3) ; then :
614		else
615			printf "test20: type hash:\
616bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
617			exit 1
618		fi
619	done
620	bsize=4096
621	for ffactor in 171 228 341; do
622		printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
623		$PROG -o$TMP3 \
624		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
625		    hash $TMP2
626		if (cmp -s $TMP1 $TMP3) ; then :
627		else
628			printf "test20: type hash:\
629bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
630			exit 1
631		fi
632	done
633	bsize=8192
634	for ffactor in 341 455 683; do
635		printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
636		$PROG -o$TMP3 \
637		    -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\
638		    hash $TMP2
639		if (cmp -s $TMP1 $TMP3) ; then :
640		else
641			printf "test20: type hash:\
642bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
643			exit 1
644		fi
645	done
646}
647
648main
649