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