| 1 8 9 package com.sleepycat.collections.test; 10 11 import java.util.ArrayList ; 12 import java.util.Collection ; 13 import java.util.Collections ; 14 import java.util.Enumeration ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.ListIterator ; 19 import java.util.Map ; 20 import java.util.NoSuchElementException ; 21 import java.util.Set ; 22 import java.util.SortedMap ; 23 import java.util.SortedSet ; 24 25 import junit.framework.Test; 26 import junit.framework.TestCase; 27 import junit.framework.TestSuite; 28 29 import com.sleepycat.bind.EntityBinding; 30 import com.sleepycat.bind.EntryBinding; 31 import com.sleepycat.collections.MapEntryParameter; 32 import com.sleepycat.collections.StoredCollection; 33 import com.sleepycat.collections.StoredCollections; 34 import com.sleepycat.collections.StoredContainer; 35 import com.sleepycat.collections.StoredEntrySet; 36 import com.sleepycat.collections.StoredIterator; 37 import com.sleepycat.collections.StoredKeySet; 38 import com.sleepycat.collections.StoredList; 39 import com.sleepycat.collections.StoredMap; 40 import com.sleepycat.collections.StoredSortedEntrySet; 41 import com.sleepycat.collections.StoredSortedKeySet; 42 import com.sleepycat.collections.StoredSortedMap; 43 import com.sleepycat.collections.StoredSortedValueSet; 44 import com.sleepycat.collections.StoredValueSet; 45 import com.sleepycat.collections.TransactionRunner; 46 import com.sleepycat.collections.TransactionWorker; 47 import com.sleepycat.compat.DbCompat; 48 import com.sleepycat.je.Database; 49 import com.sleepycat.je.DatabaseException; 50 import com.sleepycat.je.Environment; 51 import com.sleepycat.util.ExceptionUnwrapper; 52 53 56 public class CollectionTest extends TestCase { 57 58 private static final int NONE = 0; 59 private static final int SUB = 1; 60 private static final int HEAD = 2; 61 private static final int TAIL = 3; 62 63 70 private static final int DEFAULT_MAX_KEY = 6; 71 private static final int[] MAX_KEYS = {6, 10, 14, 22}; 72 73 private boolean testStoredIterator; 74 private int maxKey; 75 private int beginKey = 1; 76 private int endKey; 77 78 private Environment env; 79 private Database store; 80 private Database index; 81 private boolean isEntityBinding; 82 private boolean isAutoCommit; 83 private TestStore testStore; 84 private String testName; 85 private EntryBinding keyBinding; 86 private EntryBinding valueBinding; 87 private EntityBinding entityBinding; 88 private TransactionRunner readRunner; 89 private TransactionRunner writeRunner; 90 private TransactionRunner writeIterRunner; 91 private TestEnv testEnv; 92 93 private StoredMap map; 94 private StoredMap imap; private StoredSortedMap smap; private StoredMap saveMap; 97 private StoredSortedMap saveSMap; 98 private int rangeType; 99 private StoredList list; 100 private StoredList ilist; private StoredList saveList; 102 private StoredKeySet keySet; 103 private StoredValueSet valueSet; 104 105 109 public static void main(String [] args) 110 throws Exception { 111 112 if (args.length == 1 && 113 (args[0].equals("-h") || args[0].equals("-help"))) { 114 usage(); 115 } else { 116 junit.framework.TestResult tr = 117 junit.textui.TestRunner.run(suite(args)); 118 if (tr.errorCount() > 0 || 119 tr.failureCount() > 0) { 120 System.exit(1); 121 } else { 122 System.exit(0); 123 } 124 } 125 } 126 127 private static void usage() { 128 129 System.out.println( 130 "Usage: java com.sleepycat.collections.test.CollectionTest\n" + 131 " -h | -help\n" + 132 " [testName]...\n" + 133 " where testName has the format:\n" + 134 " <env>-<store>-{entity|value}\n" + 135 " <env> is:\n" + 136 " bdb | cdb | txn\n" + 137 " <store> is:\n" + 138 " btree-uniq | btree-dup | btree-dupsort | btree-recnum |\n" + 139 " hash-uniq | hash-dup | hash-dupsort |\n" + 140 " queue | recno | recno-renum\n" + 141 " For example: bdb-btree-uniq-entity\n" + 142 " If no arguments are given then all tests are run."); 143 System.exit(2); 144 } 145 146 public static Test suite() 147 throws Exception { 148 149 return suite(null); 150 } 151 152 static Test suite(String [] args) 153 throws Exception { 154 155 if ("true".equals(System.getProperty("longtest"))) { 156 TestSuite suite = new TestSuite(); 157 158 159 permuteTests(args, suite, true, DEFAULT_MAX_KEY); 160 161 162 for (int i = 0; i < MAX_KEYS.length; i += 1) { 163 permuteTests(args, suite, false, MAX_KEYS[i]); 164 } 165 166 return suite; 167 } else { 168 return baseSuite(args); 169 } 170 } 171 172 private static void permuteTests(String [] args, 173 TestSuite suite, 174 boolean storedIter, 175 int maxKey) 176 throws Exception { 177 178 TestSuite baseTests = baseSuite(args); 179 Enumeration e = baseTests.tests(); 180 while (e.hasMoreElements()) { 181 CollectionTest t = (CollectionTest) e.nextElement(); 182 t.setParams(storedIter, maxKey); 183 suite.addTest(t); 184 } 185 } 186 187 private static TestSuite baseSuite(String [] args) 188 throws Exception { 189 190 TestSuite suite = new TestSuite(); 191 for (int i = 0; i < TestEnv.ALL.length; i += 1) { 192 for (int j = 0; j < TestStore.ALL.length; j += 1) { 193 for (int k = 0; k < 2; k += 1) { 194 boolean entityBinding = (k != 0); 195 196 addTest(args, suite, new CollectionTest( 197 TestEnv.ALL[i], TestStore.ALL[j], 198 entityBinding, false)); 199 200 if (TestEnv.ALL[i].isTxnMode()) { 201 addTest(args, suite, new CollectionTest( 202 TestEnv.ALL[i], TestStore.ALL[j], 203 entityBinding, true)); 204 } 205 } 206 } 207 } 208 return suite; 209 } 210 211 private static void addTest(String [] args, TestSuite suite, 212 CollectionTest test) { 213 214 if (args == null || args.length == 0) { 215 suite.addTest(test); 216 } else { 217 for (int t = 0; t < args.length; t += 1) { 218 if (args[t].equals(test.testName)) { 219 suite.addTest(test); 220 break; 221 } 222 } 223 } 224 } 225 226 public CollectionTest(TestEnv testEnv, TestStore testStore, 227 boolean isEntityBinding, boolean isAutoCommit) { 228 229 super(null); 230 231 this.testEnv = testEnv; 232 this.testStore = testStore; 233 this.isEntityBinding = isEntityBinding; 234 this.isAutoCommit = isAutoCommit; 235 236 keyBinding = testStore.getKeyBinding(); 237 valueBinding = testStore.getValueBinding(); 238 entityBinding = testStore.getEntityBinding(); 239 240 setParams(false, DEFAULT_MAX_KEY); 241 } 242 243 private void setParams(boolean storedIter, int maxKey) { 244 245 this.testStoredIterator = storedIter; 246 this.maxKey = maxKey; 247 this.endKey = maxKey; 248 249 testName = testEnv.getName() + '-' + testStore.getName() + 250 (isEntityBinding ? "-entity" : "-value") + 251 (isAutoCommit ? "-autoCommit" : "") + 252 (testStoredIterator ? "-storedIter" : "") + 253 ((maxKey != DEFAULT_MAX_KEY) ? ("-maxKey-" + maxKey) : ""); 254 } 255 256 public void tearDown() 257 throws Exception { 258 259 setName(testName); 260 } 261 262 public void runTest() 263 throws Exception { 264 265 DbTestUtil.printTestName(DbTestUtil.qualifiedTestName(this)); 266 try { 267 env = testEnv.open(testName); 268 269 TransactionRunner normalRunner = newTransactionRunner(env); 275 normalRunner.setAllowNestedTransactions( 276 DbCompat.NESTED_TRANSACTIONS); 277 TransactionRunner nullRunner = new NullTransactionRunner(env); 278 readRunner = nullRunner; 279 writeIterRunner = normalRunner; 280 if (isAutoCommit) { 281 writeRunner = nullRunner; 282 } else { 283 writeRunner = normalRunner; 284 } 285 286 store = testStore.open(env, "unindexed.db"); 287 testUnindexed(); 288 store.close(); 289 store = null; 290 291 TestStore indexOf = testStore.getIndexOf(); 292 if (indexOf != null) { 293 store = indexOf.open(env, "indexed.db"); 294 index = testStore.openIndex(store, "index.db"); 295 testIndexed(); 296 index.close(); 297 index = null; 298 store.close(); 299 store = null; 300 } 301 env.close(); 302 env = null; 303 } catch (Exception e) { 304 throw ExceptionUnwrapper.unwrap(e); 305 } finally { 306 if (index != null) { 307 try { 308 index.close(); 309 } catch (Exception e) { 310 } 311 } 312 if (store != null) { 313 try { 314 store.close(); 315 } catch (Exception e) { 316 } 317 } 318 if (env != null) { 319 try { 320 env.close(); 321 } catch (Exception e) { 322 } 323 } 324 325 index = null; 326 store = null; 327 env = null; 328 readRunner = null; 329 writeRunner = null; 330 writeIterRunner = null; 331 map = null; 332 imap = null; 333 smap = null; 334 saveMap = null; 335 saveSMap = null; 336 list = null; 337 ilist = null; 338 saveList = null; 339 keySet = null; 340 valueSet = null; 341 testEnv = null; 342 testStore = null; 343 } 344 } 345 346 349 protected TransactionRunner newTransactionRunner(Environment env) 350 throws DatabaseException { 351 352 return new TransactionRunner(env); 353 } 354 355 void testCreation(StoredContainer cont, int expectSize) 356 throws Exception { 357 358 assertEquals(index != null, cont.isSecondary()); 359 assertEquals(testStore.isOrdered(), cont.isOrdered()); 360 assertEquals(testStore.areKeysRenumbered(), cont.areKeysRenumbered()); 361 assertEquals(testStore.areDuplicatesAllowed(), 362 cont.areDuplicatesAllowed()); 363 assertEquals(testEnv.isTxnMode(), cont.isTransactional()); 364 assertEquals(expectSize, cont.size()); 365 } 366 367 void testMapCreation(Map map) 368 throws Exception { 369 370 assertTrue(map.values() instanceof Set ); 371 assertEquals(testStore.isOrdered(), 372 map.keySet() instanceof SortedSet ); 373 assertEquals(testStore.isOrdered(), 374 map.entrySet() instanceof SortedSet ); 375 assertEquals(testStore.isOrdered() && isEntityBinding, 376 map.values() instanceof SortedSet ); 377 } 378 379 void testUnindexed() 380 throws Exception { 381 382 if (testStore.isOrdered()) { 384 if (isEntityBinding) { 385 smap = new StoredSortedMap(store, keyBinding, 386 entityBinding, 387 testStore.getKeyAssigner()); 388 valueSet = new StoredSortedValueSet(store, entityBinding, 389 true); 390 } else { 391 smap = new StoredSortedMap(store, keyBinding, 392 valueBinding, 393 testStore.getKeyAssigner()); 394 } 397 keySet = new StoredSortedKeySet(store, keyBinding, true); 398 map = smap; 399 } else { 400 if (isEntityBinding) { 401 map = new StoredMap(store, keyBinding, entityBinding, 402 testStore.getKeyAssigner()); 403 valueSet = new StoredValueSet(store, entityBinding, true); 404 } else { 405 map = new StoredMap(store, keyBinding, valueBinding, 406 testStore.getKeyAssigner()); 407 valueSet = new StoredValueSet(store, valueBinding, true); 408 } 409 smap = null; 410 keySet = new StoredKeySet(store, keyBinding, true); 411 } 412 imap = map; 413 414 if (testStore.hasRecNumAccess()) { 416 if (isEntityBinding) { 417 ilist = new StoredList(store, entityBinding, 418 testStore.getKeyAssigner()); 419 } else { 420 ilist = new StoredList(store, valueBinding, 421 testStore.getKeyAssigner()); 422 } 423 list = ilist; 424 } else { 425 try { 426 if (isEntityBinding) { 427 ilist = new StoredList(store, entityBinding, 428 testStore.getKeyAssigner()); 429 } else { 430 ilist = new StoredList(store, valueBinding, 431 testStore.getKeyAssigner()); 432 } 433 fail(); 434 } catch (IllegalArgumentException expected) {} 435 } 436 437 testCreation(map, 0); 438 if (list != null) { 439 testCreation(list, 0); 440 assertNotNull(smap); 441 } 442 testMapCreation(map); 443 addAll(); 444 testAll(); 445 } 446 447 void testIndexed() 448 throws Exception { 449 450 if (isEntityBinding) { 452 map = new StoredMap(store, keyBinding, entityBinding, 453 testStore.getKeyAssigner()); 454 } else { 455 map = new StoredMap(store, keyBinding, valueBinding, 456 testStore.getKeyAssigner()); 457 } 458 imap = map; 459 smap = null; 460 if (testStore.hasRecNumAccess()) { 462 if (isEntityBinding) { 463 list = new StoredList(store, entityBinding, 464 testStore.getKeyAssigner()); 465 } else { 466 list = new StoredList(store, valueBinding, 467 testStore.getKeyAssigner()); 468 } 469 ilist = list; 470 } 471 472 addAll(); 473 readAll(); 474 475 if (testStore.isOrdered()) { 477 if (isEntityBinding) { 478 map = smap = new StoredSortedMap(index, keyBinding, 479 entityBinding, true); 480 valueSet = new StoredSortedValueSet(index, entityBinding, 481 true); 482 } else { 483 map = smap = new StoredSortedMap(index, keyBinding, 484 valueBinding, true); 485 } 488 keySet = new StoredSortedKeySet(index, keyBinding, true); 489 } else { 490 if (isEntityBinding) { 491 map = new StoredMap(index, keyBinding, entityBinding, true); 492 valueSet = new StoredValueSet(index, entityBinding, true); 493 } else { 494 map = new StoredMap(index, keyBinding, valueBinding, true); 495 valueSet = new StoredValueSet(index, valueBinding, true); 496 } 497 smap = null; 498 keySet = new StoredKeySet(index, keyBinding, true); 499 } 500 501 if (testStore.hasRecNumAccess()) { 503 if (isEntityBinding) { 504 list = new StoredList(index, entityBinding, true); 505 } else { 506 list = new StoredList(index, valueBinding, true); 507 } 508 } else { 509 try { 510 if (isEntityBinding) { 511 list = new StoredList(index, entityBinding, true); 512 } else { 513 list = new StoredList(index, valueBinding, true); 514 } 515 fail(); 516 } 517 catch (IllegalArgumentException expected) {} 518 } 519 520 testCreation(map, maxKey); 521 testCreation((StoredContainer) map.values(), maxKey); 522 testCreation((StoredContainer) map.keySet(), maxKey); 523 testCreation((StoredContainer) map.entrySet(), maxKey); 524 if (list != null) { 525 testCreation(list, maxKey); 526 assertNotNull(smap); 527 } 528 testMapCreation(map); 529 testAll(); 530 } 531 532 void testAll() 533 throws Exception { 534 535 checkKeySetAndValueSet(); 536 readAll(); 537 updateAll(); 538 readAll(); 539 if (!map.areKeysRenumbered()) { 540 removeOdd(); 541 readEven(); 542 addOdd(); 543 readAll(); 544 removeOddIter(); 545 readEven(); 546 if (imap.areDuplicatesAllowed()) { 547 addOddDup(); 548 } else { 549 addOdd(); 550 } 551 readAll(); 552 removeOddEntry(); 553 readEven(); 554 addOdd(); 555 readAll(); 556 if (isEntityBinding) { 557 removeOddEntity(); 558 readEven(); 559 addOddEntity(); 560 readAll(); 561 } 562 bulkOperations(); 563 } 564 if (isListAddAllowed()) { 565 removeOddList(); 566 readEvenList(); 567 addOddList(); 568 readAll(); 569 if (!isEntityBinding) { 570 removeOddListValue(); 571 readEvenList(); 572 addOddList(); 573 readAll(); 574 } 575 } 576 if (list != null) { 577 bulkListOperations(); 578 } else { 579 listOperationsNotAllowed(); 580 } 581 if (smap != null) { 582 readWriteRange(SUB, 1, 1); 583 readWriteRange(HEAD, 1, 1); 584 readWriteRange(SUB, 1, maxKey); 585 readWriteRange(HEAD, 1, maxKey); 586 readWriteRange(TAIL, 1, maxKey); 587 readWriteRange(SUB, 1, 3); 588 readWriteRange(HEAD, 1, 3); 589 readWriteRange(SUB, 2, 2); 590 readWriteRange(SUB, 2, maxKey); 591 readWriteRange(TAIL, 2, maxKey); 592 readWriteRange(SUB, maxKey, maxKey); 593 readWriteRange(TAIL, maxKey, maxKey); 594 readWriteRange(SUB, maxKey + 1, maxKey + 1); 595 readWriteRange(TAIL, maxKey + 1, maxKey + 1); 596 readWriteRange(SUB, 0, 0); 597 readWriteRange(HEAD, 0, 0); 598 } 599 updateAll(); 600 readAll(); 601 if (map.areDuplicatesAllowed()) { 602 readWriteDuplicates(); 603 readAll(); 604 } else { 605 duplicatesNotAllowed(); 606 readAll(); 607 } 608 if (testEnv.isCdbMode()) { 609 testCdbLocking(); 610 } 611 removeAll(); 612 if (isListAddAllowed()) { 613 testIterAddList(); 614 clearAll(); 615 } 616 if (imap.areDuplicatesAllowed()) { 617 testIterAddDuplicates(); 618 clearAll(); 619 } 620 if (isListAddAllowed()) { 621 addAllList(); 622 readAll(); 623 removeAllList(); 624 } 625 appendAll(); 626 } 627 628 void checkKeySetAndValueSet() { 629 630 assertTrue(imap.keySet().equals(keySet)); 633 if (valueSet != null) { 634 assertTrue(imap.values().equals(valueSet)); 635 } 636 } 637 638 Iterator iterator(Collection storedCollection) { 639 640 if (testStoredIterator) { 641 return ((StoredCollection) storedCollection).storedIterator(); 642 } else { 643 return storedCollection.iterator(); 644 } 645 } 646 647 void addAll() 648 throws Exception { 649 650 writeRunner.run(new TransactionWorker() { 651 public void doWork() throws Exception { 652 assertTrue(imap.isEmpty()); 653 Iterator iter = iterator(imap.entrySet()); 654 try { 655 assertTrue(!iter.hasNext()); 656 } finally { 657 StoredIterator.close(iter); 658 } 659 assertEquals(0, imap.keySet().toArray().length); 660 assertEquals(0, imap.keySet().toArray(new Object [0]).length); 661 assertEquals(0, imap.entrySet().toArray().length); 662 assertEquals(0, imap.entrySet().toArray(new Object [0]).length); 663 assertEquals(0, imap.values().toArray().length); 664 assertEquals(0, imap.values().toArray(new Object [0]).length); 665 666 for (int i = beginKey; i <= endKey; i += 1) { 667 Long key = makeKey(i); 668 Object val = makeVal(i); 669 assertNull(imap.get(key)); 670 assertTrue(!imap.keySet().contains(key)); 671 assertTrue(!imap.values().contains(val)); 672 assertNull(imap.put(key, val)); 673 assertEquals(val, imap.get(key)); 674 assertTrue(imap.keySet().contains(key)); 675 assertTrue(imap.values().contains(val)); 676 assertTrue(imap.duplicates(key).contains(val)); 677 if (!imap.areDuplicatesAllowed()) { 678 assertEquals(val, imap.put(key, val)); 679 } 680 checkDupsSize(1, imap.duplicates(key)); 681 } 682 assertTrue(!imap.isEmpty()); 683 } 684 }); 685 } 686 687 void appendAll() 688 throws Exception { 689 690 writeRunner.run(new TransactionWorker() { 691 public void doWork() throws Exception { 692 assertTrue(imap.isEmpty()); 693 694 TestKeyAssigner keyAssigner = testStore.getKeyAssigner(); 695 if (keyAssigner != null) { 696 keyAssigner.reset(); 697 } 698 699 for (int i = beginKey; i <= endKey; i += 1) { 700 boolean useList = (i & 1) == 0; 701 Long key = makeKey(i); 702 Object val = makeVal(i); 703 assertNull(imap.get(key)); 704 if (keyAssigner != null) { 705 if (useList && ilist != null) { 706 assertEquals(i - 1, ilist.append(val)); 707 } else { 708 assertEquals(key, imap.append(val)); 709 } 710 assertEquals(val, imap.get(key)); 711 } else { 712 Long recnoKey; 713 if (useList && ilist != null) { 714 recnoKey = new Long (ilist.append(val) + 1); 715 } else { 716 recnoKey = (Long ) imap.append(val); 717 } 718 assertNotNull(recnoKey); 719 Object recnoVal; 720 if (isEntityBinding) { 721 recnoVal = makeEntity(recnoKey.intValue(), i); 722 } else { 723 recnoVal = val; 724 } 725 assertEquals(recnoVal, imap.get(recnoKey)); 726 } 727 } 728 } 729 }); 730 |