1 8 9 package com.sleepycat.je; 10 11 import java.io.File ; 12 13 import junit.framework.TestCase; 14 15 import com.sleepycat.je.LockNotGrantedException; 16 import com.sleepycat.je.config.EnvironmentParams; 17 import com.sleepycat.je.junit.JUnitThread; 18 import com.sleepycat.je.latch.LatchSupport; 19 import com.sleepycat.je.util.TestUtils; 20 21 25 public class CursorEdgeTest extends TestCase { 26 27 private static final boolean DEBUG = false; 28 private Environment env; 29 private File envHome; 30 private boolean operationStarted; 31 32 public CursorEdgeTest() { 33 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 34 } 35 36 public void setUp() 37 throws Exception { 38 39 TestUtils.removeLogFiles("Setup", envHome, false); 40 41 46 EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 47 envConfig.setTransactional(true); 48 envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6"); 49 envConfig.setConfigParam(EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName(), 50 "false"); 51 envConfig.setAllowCreate(true); 52 env = new Environment(envHome, envConfig); 53 } 54 55 public void tearDown() 56 throws Exception { 57 58 try { 59 env.close(); 60 } catch (Throwable e) { 61 System.out.println("Exception during tearDown"); 62 e.printStackTrace(); 63 } 64 env = null; 65 TestUtils.removeLogFiles("TearDown", envHome, false); 66 } 67 68 73 public void testSearchOnDuplicatesWithDeletions() 74 throws Throwable { 75 76 Database myDb = null; 77 Cursor cursor = null; 78 try { 79 80 DatabaseConfig dbConfig = new DatabaseConfig(); 81 dbConfig.setTransactional(true); 82 dbConfig.setSortedDuplicates(true); 83 dbConfig.setAllowCreate(true); 84 myDb = env.openDatabase(null, "foo", dbConfig); 85 86 96 DatabaseEntry key = new DatabaseEntry(); 97 DatabaseEntry data = new DatabaseEntry(); 98 key.setData(TestUtils.getTestArray(1)); 99 data.setData(TestUtils.getTestArray(1)); 100 myDb.put(null, key, data); key.setData(TestUtils.getTestArray(3)); 102 myDb.put(null, key, data); 104 105 key.setData(TestUtils.getTestArray(2)); 106 for (int i = 1; i <= 15; i++) { 107 data.setData(TestUtils.getTestArray(i)); 108 myDb.put(null, key, data); 109 } 110 111 112 Transaction txn = 113 env.beginTransaction(null, TransactionConfig.DEFAULT); 114 cursor = myDb.openCursor(txn, CursorConfig.DEFAULT); 115 assertEquals(OperationStatus.SUCCESS, 116 cursor.getSearchKey(key, data, LockMode.DEFAULT)); 117 for (int i = 0; i < 7; i ++) { 118 assertEquals(OperationStatus.SUCCESS, cursor.delete()); 119 assertEquals(OperationStatus.SUCCESS, 120 cursor.getNext(key, data, LockMode.DEFAULT)); 121 } 122 123 124 data.setData(TestUtils.getTestArray(10)); 125 assertEquals(OperationStatus.SUCCESS, 126 cursor.getSearchBoth(key, data, LockMode.DEFAULT)); 127 for (int i = 0; i < 3; i ++) { 128 assertEquals(OperationStatus.SUCCESS, cursor.delete()); 129 assertEquals(OperationStatus.SUCCESS, 130 cursor.getNext(key, data, LockMode.DEFAULT)); 131 } 132 133 134 if (DEBUG) { 135 Cursor checkCursor = myDb.openCursor(txn, 136 CursorConfig.DEFAULT); 137 while (checkCursor.getNext(key, data, LockMode.DEFAULT) == 138 OperationStatus.SUCCESS) { 139 System.out.println("key=" + 140 TestUtils.getTestVal(key.getData()) + 141 " data=" + 142 TestUtils.getTestVal(data.getData())); 143 } 144 checkCursor.close(); 145 } 146 cursor.close(); 147 cursor = null; 148 txn.commit(); 149 150 153 Cursor readCursor = myDb.openCursor(null, CursorConfig.DEFAULT); 154 key.setData(TestUtils.getTestArray(2)); 155 156 157 assertEquals(OperationStatus.SUCCESS, 158 readCursor.getSearchKey(key, data, LockMode.DEFAULT)); 159 assertEquals(2, TestUtils.getTestVal(key.getData())); 160 assertEquals(8, TestUtils.getTestVal(data.getData())); 161 162 163 assertEquals(OperationStatus.SUCCESS, 164 readCursor.getSearchKeyRange(key, data, 165 LockMode.DEFAULT)); 166 assertEquals(2, TestUtils.getTestVal(key.getData())); 167 assertEquals(8, TestUtils.getTestVal(data.getData())); 168 169 170 data.setData(TestUtils.getTestArray(8)); 171 assertEquals(OperationStatus.SUCCESS, 172 readCursor.getSearchBoth(key, data, 173 LockMode.DEFAULT)); 174 assertEquals(2, TestUtils.getTestVal(key.getData())); 175 assertEquals(8, TestUtils.getTestVal(data.getData())); 176 177 178 data.setData(TestUtils.getTestArray(8)); 179 assertEquals(OperationStatus.SUCCESS, 180 readCursor.getSearchBothRange(key, data, 181 LockMode.DEFAULT)); 182 assertEquals(2, TestUtils.getTestVal(key.getData())); 183 assertEquals(8, TestUtils.getTestVal(data.getData())); 184 185 186 data.setData(TestUtils.getTestArray(1)); 187 assertEquals(OperationStatus.SUCCESS, 188 readCursor.getSearchBothRange(key, data, 189 LockMode.DEFAULT)); 190 assertEquals(2, TestUtils.getTestVal(key.getData())); 191 assertEquals(8, TestUtils.getTestVal(data.getData())); 192 193 196 197 202 key.setData(TestUtils.getTestArray(5)); 203 for (int i = 0; i < 10; i++) { 204 data.setData(TestUtils.getTestArray(i)); 205 myDb.put(null, key, data); 206 } 207 myDb.delete(null, key); 209 210 assertFalse(readCursor.getSearchKey(key, data, LockMode.DEFAULT) == 211 OperationStatus.SUCCESS); 212 assertFalse(readCursor.getSearchKeyRange(key, data, 213 LockMode.DEFAULT) == 214 OperationStatus.SUCCESS); 215 data.setData(TestUtils.getTestArray(0)); 216 assertFalse(readCursor.getSearchBoth(key, data, 217 LockMode.DEFAULT) == 218 OperationStatus.SUCCESS); 219 assertFalse(readCursor.getSearchBothRange(key, data, 220 LockMode.DEFAULT) == 221 OperationStatus.SUCCESS); 222 223 224 key.setData(TestUtils.getTestArray(4)); 225 assertFalse(readCursor.getSearchKeyRange(key, data, 226 LockMode.DEFAULT) == 227 OperationStatus.SUCCESS); 228 assertFalse(readCursor.getSearchBothRange(key, data, 229 LockMode.DEFAULT) == 230 OperationStatus.SUCCESS); 231 232 readCursor.close(); 233 } catch (Throwable t) { 234 235 t.printStackTrace(); 236 throw t; 237 } finally { 238 if (cursor != null) { 239 cursor.close(); 240 } 241 myDb.close(); 242 } 243 } 244 245 253 public void testSearchBothWithOneDuplicate() 254 throws Throwable { 255 256 Database myDb = null; 257 Cursor cursor = null; 258 try { 259 260 DatabaseConfig dbConfig = new DatabaseConfig(); 261 dbConfig.setTransactional(true); 262 dbConfig.setSortedDuplicates(true); 263 dbConfig.setAllowCreate(true); 264 myDb = env.openDatabase(null, "foo", dbConfig); 265 266 267 DatabaseEntry key = new DatabaseEntry(); 268 DatabaseEntry data = new DatabaseEntry(); 269 key.setData(TestUtils.getTestArray(1)); 270 data.setData(TestUtils.getTestArray(1)); 271 myDb.put(null, key, data); 272 273 key.setData(TestUtils.getTestArray(1)); 274 data.setData(TestUtils.getTestArray(0)); 275 cursor = myDb.openCursor(null, CursorConfig.DEFAULT); 276 OperationStatus status = 277 cursor.getSearchBothRange(key, data, LockMode.DEFAULT); 278 assertSame(status, OperationStatus.SUCCESS); 279 assertEquals(1, TestUtils.getTestVal(key.getData())); 280 assertEquals(1, TestUtils.getTestVal(data.getData())); 281 } finally { 282 if (cursor != null) { 283 cursor.close(); 284 } 285 if (myDb != null) { 286 myDb.close(); 287 } 288 } 289 } 290 291 303 public void testGetCurrentDuringDupTreeCreation() 304 throws Throwable { 305 306 307 DatabaseConfig dbConfig = new DatabaseConfig(); 308 dbConfig.setTransactional(true); 309 dbConfig.setSortedDuplicates(true); 310 dbConfig.setAllowCreate(true); 311 final Database myDb = env.openDatabase(null, "foo", dbConfig); 312 313 314 Transaction t1 = env.beginTransaction(null, null); 315 DatabaseEntry key = new DatabaseEntry(); 316 DatabaseEntry data = new DatabaseEntry(); 317 key.setData(TestUtils.getTestArray(1)); 318 data.setData(TestUtils.getTestArray(1)); 319 myDb.put(t1, key, data); 320 321 322 JUnitThread thread = new JUnitThread("getFirst") { 323 public void testBody() 324 throws DatabaseException { 325 DatabaseEntry key = new DatabaseEntry(); 326 DatabaseEntry data = new DatabaseEntry(); 327 Transaction t2 = env.beginTransaction(null, null); 328 operationStarted = true; 329 Cursor cursor = myDb.openCursor(t2, null); 330 OperationStatus status = cursor.getFirst(key, data, null); 331 assertEquals(1, TestUtils.getTestVal(key.getData())); 332 assertEquals(1, TestUtils.getTestVal(data.getData())); 333 assertEquals(OperationStatus.SUCCESS, status); 334 cursor.close(); 335 t2.commitNoSync(); 336 } 337 }; 338 thread.start(); 339 while (!operationStarted) { 340 Thread.yield(); 341 } 342 Thread.sleep(10); 343 344 345 key.setData(TestUtils.getTestArray(1)); 346 data.setData(TestUtils.getTestArray(2)); 347 myDb.put(t1, key, data); 348 t1.commitNoSync(); 349 350 try { 351 thread.finishTest(); 352 } catch (Throwable e) { 353 e.printStackTrace(); 354 fail(e.toString()); 355 } 356 myDb.close(); 357 } 358 359 363 public void testGetPrevNoDupWithEmptyTree() 364 throws Throwable { 365 366 OperationStatus status; 367 368 371 DatabaseConfig dbConfig = new DatabaseConfig(); 372 dbConfig.setSortedDuplicates(true); 373 dbConfig.setAllowCreate(true); 374 Database myDb = env.openDatabase(null, "foo", dbConfig); 375 376 379 DatabaseEntry key = new DatabaseEntry(); 380 DatabaseEntry data = new DatabaseEntry(); 381 382 key.setData(TestUtils.getTestArray(1)); 383 data.setData(TestUtils.getTestArray(1)); 384 myDb.put(null, key, data); 385 data.setData(TestUtils.getTestArray(2)); 386 myDb.put(null, key, data); 387 388 key.setData(TestUtils.getTestArray(2)); 389 data.setData(TestUtils.getTestArray(1)); 390 myDb.put(null, key, data); 391 data.setData(TestUtils.getTestArray(2)); 392 myDb.put(null, key, data); 393 394 397 Cursor cursor = myDb.openCursor(null, null); 398 while ((status = cursor.getNext(key, data, null)) == 399 OperationStatus.SUCCESS) { 400 cursor.delete(); 401 } 402 403 408 env.compress(); 409 410 414 status = cursor.getPrevNoDup(key, data, null); 415 assertEquals(OperationStatus.NOTFOUND, status); 416 417 cursor.close(); 418 myDb.close(); 419 } 420 421 425 public void testNonTxnalCursorNoUpdates() 426 throws Throwable { 427 428 Database myDb = null; 429 SecondaryDatabase mySecDb = null; 430 Cursor cursor = null; 431 SecondaryCursor secCursor = null; 432 try { 433 434 DatabaseConfig dbConfig = new DatabaseConfig(); 435 dbConfig.setTransactional(true); 436 dbConfig.setAllowCreate(true); 437 myDb = env.openDatabase(null, "foo", dbConfig); 438 439 SecondaryConfig secConfig = new SecondaryConfig(); 440 secConfig.setTransactional(true); 441 secConfig.setAllowCreate(true); 442 secConfig.setKeyCreator(new KeyCreator()); 443 mySecDb = env.openSecondaryDatabase(null, "fooSecDb", myDb, 444 secConfig); 445 446 447 DatabaseEntry key = new DatabaseEntry(new byte[1]); 448 assertEquals(myDb.put(null, key, key), OperationStatus.SUCCESS); 449 450 451 cursor = myDb.openCursor(null, null); 452 DatabaseEntry data = new DatabaseEntry(); 453 assertEquals(OperationStatus.SUCCESS, 454 cursor.getNext(key, data, LockMode.DEFAULT)); 455 456 457 updatesShouldBeProhibited(cursor); 458 459 460 secCursor = mySecDb.openSecondaryCursor(null, null); 461 assertEquals(OperationStatus.SUCCESS, 462 secCursor.getNext(key, data, LockMode.DEFAULT)); 463 464 465 updatesShouldBeProhibited(secCursor); 466 467 } catch (Throwable t) { 468 t.printStackTrace(); 469 throw t; 470 } finally { 471 if (secCursor != null) { 472 secCursor.close(); 473 } 474 475 if (cursor != null) { 476 cursor.close(); 477 } 478 479 if (mySecDb != null) { 480 mySecDb.close(); 481 } 482 483 myDb.close(); 484 } 485 } 486 487 488 private void updatesShouldBeProhibited(Cursor cursor) 489 throws Exception { 490 491 try { 492 cursor.delete(); 493 fail("Should not be able to do a delete"); 494 } catch (DatabaseException e) { 495 checkForTransactionException(e); 496 } 497 498 DatabaseEntry key = new DatabaseEntry(new byte[0]); 499 DatabaseEntry data = new DatabaseEntry(new byte[0]); 500 501 try { 502 cursor.put(key, data); 503 fail("Should not be able to do a put"); 504 } catch (UnsupportedOperationException e) { 505 506 } catch (DatabaseException e) { 507 checkForTransactionException(e); 508 } 509 510 511 try { 512 cursor.putCurrent(data); 513 fail("Should not be able to do a putCurrent"); 514 } catch (UnsupportedOperationException e) { 515 516 } catch (DatabaseException e) { 517 checkForTransactionException(e); 518 } 519 520 try { 521 cursor.putNoDupData(key, data); 522 fail("Should not be able to do a putNoDupData"); 523 } catch (UnsupportedOperationException e) { 524 525 } catch (DatabaseException e) { 526 checkForTransactionException(e); 527 } 528 529 try { 530 cursor.putNoOverwrite(key, data); 531 fail("Should not be able to do a putNoOverwrite"); 532 } catch (UnsupportedOperationException e) { 533 534 } catch (DatabaseException e) { 535 checkForTransactionException(e); 536 } 537 } 538 539 private void checkForTransactionException(DatabaseException e) { 540 544 String eMsg = e.getMessage(); 545 assertTrue(TestUtils.skipVersion(e).startsWith("A transaction was not supplied")); 546 } 547 548 private static class KeyCreator implements SecondaryKeyCreator { 549 public boolean createSecondaryKey(SecondaryDatabase secondaryDb, 550 DatabaseEntry keyEntry, 551 DatabaseEntry dataEntry, 552 DatabaseEntry resultEntry) { 553 resultEntry.setData(dataEntry.getData()); 554 return true; 555 } 556 } 557 558 569 public void testNoWaitLatchRelease() 570 throws Throwable { 571 572 DatabaseEntry key = new DatabaseEntry(); 573 DatabaseEntry data = new DatabaseEntry(); 574 575 576 DatabaseConfig dbConfig = new DatabaseConfig(); 577 dbConfig.setTransactional(true); 578 dbConfig.setAllowCreate(true); 579 dbConfig.setSortedDuplicates(true); 580 Database db = env.openDatabase(null, "foo", dbConfig); 581 582 583 key.setData(TestUtils.getTestArray(1)); 584 data.setData(TestUtils.getTestArray(1)); 585 db.put(null, key, data); 586 587 588 Transaction txn1 = env.beginTransaction(null, null); 589 Cursor cursor1 = db.openCursor(txn1, null); 590 key.setData(TestUtils.getTestArray(1)); 591 data.setData(TestUtils.getTestArray(1)); 592 OperationStatus status = cursor1.getSearchBoth(key, data, null); 593 assertSame(status, OperationStatus.SUCCESS); 594 assertEquals(1, TestUtils.getTestVal(key.getData())); 595 assertEquals(1, TestUtils.getTestVal(data.getData())); 596 597 598 TransactionConfig noWaitConfig = new TransactionConfig(); 599 noWaitConfig.setNoWait(true); 600 Transaction txn2 = env.beginTransaction(null, noWaitConfig); 601 Cursor cursor2 = db.openCursor(txn2, null); 602 key.setData(TestUtils.getTestArray(1)); 603 data.setData(TestUtils.getTestArray(1)); 604 status = cursor2.getSearchBoth(key, data, null); 605 assertSame(status, OperationStatus.SUCCESS); 606 assertEquals(1, TestUtils.getTestVal(key.getData())); 607 assertEquals(1, TestUtils.getTestVal(data.getData())); 608 try { 609 cursor2.delete(); 610 fail("Expected LockNotGrantedException"); 611 } catch (LockNotGrantedException expected) { 612 } 613 614 620 assertEquals(0, LatchSupport.countLatchesHeld()); 621 622 623 cursor1.close(); 624 cursor2.close(); 625 txn1.commit(); 626 txn2.commit(); 627 628 629 key.setData(TestUtils.getTestArray(1)); 630 data.setData(TestUtils.getTestArray(2)); 631 db.put(null, key, data); 632 633 634 txn1 = env.beginTransaction(null, null); 635 cursor1 = db.openCursor(txn1, null); 636 key.setData(TestUtils.getTestArray(1)); 637 status = cursor1.getSearchKey(key, data, null); 638 assertSame(status, OperationStatus.SUCCESS); 639 assertEquals(1, TestUtils.getTestVal(key.getData())); 640 assertEquals(1, TestUtils.getTestVal(data.getData())); 641 assertEquals(2, cursor1.count()); 642 643 644 txn2 = env.beginTransaction(null, noWaitConfig); 645 cursor2 = db.openCursor(txn2, null); 646 key.setData(TestUtils.getTestArray(1)); 647 data.setData(TestUtils.getTestArray(2)); 648 status = cursor2.getSearchBoth(key, data, null); 649 assertSame(status, OperationStatus.SUCCESS); 650 assertEquals(1, TestUtils.getTestVal(key.getData())); 651 assertEquals(2, TestUtils.getTestVal(data.getData())); 652 try { 653 cursor2.delete(); 654 fail("Expected LockNotGrantedException"); 655 } catch (LockNotGrantedException expected) { 656 } 657 658 659 assertEquals(0, LatchSupport.countLatchesHeld()); 660 661 662 cursor1.close(); 663 cursor2.close(); 664 txn1.commit(); 665 txn2.commit(); 666 db.close(); 667 } 668 } 669 | Popular Tags |