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