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