1 8 9 package com.sleepycat.je.txn; 10 11 import java.io.File ; 12 import java.io.IOException ; 13 import java.util.Arrays ; 14 15 import junit.framework.TestCase; 16 17 import com.sleepycat.je.Cursor; 18 import com.sleepycat.je.CursorConfig; 19 import com.sleepycat.je.Database; 20 import com.sleepycat.je.DatabaseConfig; 21 import com.sleepycat.je.DatabaseEntry; 22 import com.sleepycat.je.DatabaseException; 23 import com.sleepycat.je.DbInternal; 24 import com.sleepycat.je.Environment; 25 import com.sleepycat.je.EnvironmentConfig; 26 import com.sleepycat.je.EnvironmentStats; 27 import com.sleepycat.je.LockMode; 28 import com.sleepycat.je.OperationStatus; 29 import com.sleepycat.je.Transaction; 30 import com.sleepycat.je.TransactionStats; 31 import com.sleepycat.je.VerifyConfig; 32 import com.sleepycat.je.config.EnvironmentParams; 33 import com.sleepycat.je.dbi.DatabaseImpl; 34 import com.sleepycat.je.junit.JUnitThread; 35 import com.sleepycat.je.log.FileManager; 36 import com.sleepycat.je.util.TestUtils; 37 38 41 public class TxnEndTest extends TestCase { 42 private static final int NUM_DBS = 1; 43 private Environment env; 44 private File envHome; 45 private Database[] dbs; 46 private Cursor[] cursors; 47 48 public TxnEndTest() 49 throws DatabaseException { 50 51 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 52 } 53 54 public void setUp() 55 throws IOException , DatabaseException { 56 57 TestUtils.removeFiles("Setup", envHome, FileManager.JE_SUFFIX); 58 59 63 EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 64 envConfig.setTransactional(true); 65 envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6"); 66 envConfig.setConfigParam(EnvironmentParams. 67 ENV_RUN_INCOMPRESSOR.getName(), 68 "false"); 69 envConfig.setAllowCreate(true); 70 env = new Environment(envHome, envConfig); 71 } 72 73 public void tearDown() 74 throws IOException , DatabaseException { 75 76 if (env != null) { 77 try { 78 env.close(); 79 } catch (Exception e) { 80 System.out.println("tearDown: " + e); 81 } 82 } 83 env = null; 84 85 TestUtils.removeFiles("TearDown", envHome, FileManager.JE_SUFFIX); 86 } 87 88 private void createDbs() 89 throws DatabaseException { 90 91 dbs = new Database[NUM_DBS]; 93 cursors = new Cursor[NUM_DBS]; 94 95 DatabaseConfig dbConfig = new DatabaseConfig(); 96 dbConfig.setTransactional(true); 97 dbConfig.setAllowCreate(true); 98 for (int i = 0; i < NUM_DBS; i++) { 99 dbs[i] = env.openDatabase(null, "testDB" + i, dbConfig); 100 } 101 } 102 103 private void closeAll() 104 throws DatabaseException { 105 106 for (int i = 0; i < NUM_DBS; i++) { 107 dbs[i].close(); 108 } 109 dbs = null; 110 env.close(); 111 env = null; 112 } 113 114 117 private void createCursors(Transaction txn) 118 throws DatabaseException { 119 120 for (int i = 0; i < cursors.length; i++) { 121 cursors[i] = dbs[i].openCursor(txn, null); 122 } 123 } 124 125 128 private void closeCursors() 129 throws DatabaseException { 130 131 for (int i = 0; i < cursors.length; i++) { 132 cursors[i].close(); 133 } 134 } 135 136 139 private void cursorInsertData(int start, int end) 140 throws DatabaseException { 141 142 DatabaseEntry key = new DatabaseEntry(); 143 DatabaseEntry data = new DatabaseEntry(); 144 for (int i = 0; i < NUM_DBS; i++) { 145 for (int d = start; d < end; d++) { 146 key.setData(TestUtils.getTestArray(d)); 147 data.setData(TestUtils.getTestArray(d)); 148 cursors[i].put(key, data); 149 } 150 } 151 } 152 155 private void dbInsertData(int start, int end, Transaction txn) 156 throws DatabaseException { 157 158 DatabaseEntry key = new DatabaseEntry(); 159 DatabaseEntry data = new DatabaseEntry(); 160 for (int i = 0; i < NUM_DBS; i++) { 161 for (int d = start; d < end; d++) { 162 key.setData(TestUtils.getTestArray(d)); 163 data.setData(TestUtils.getTestArray(d)); 164 dbs[i].put(txn, key, data); 165 } 166 } 167 } 168 169 172 private void cursorModifyData(int start, int end, int valueOffset) 173 throws DatabaseException { 174 175 DatabaseEntry key = new DatabaseEntry(); 176 DatabaseEntry data = new DatabaseEntry(); 177 for (int i = 0; i < NUM_DBS; i++) { 178 OperationStatus status = 179 cursors[i].getFirst(key, data, LockMode.DEFAULT); 180 for (int d = start; d < end; d++) { 181 assertEquals(OperationStatus.SUCCESS, status); 182 byte[] changedVal = 183 TestUtils.getTestArray(d + valueOffset); 184 data.setData(changedVal); 185 cursors[i].putCurrent(data); 186 status = cursors[i].getNext(key, data, LockMode.DEFAULT); 187 } 188 } 189 } 190 191 194 private void cursorDeleteData(int start, int end) 195 throws DatabaseException { 196 197 DatabaseEntry key = new DatabaseEntry(); 198 DatabaseEntry foundData = new DatabaseEntry(); 199 for (int i = 0; i < NUM_DBS; i++) { 200 for (int d = start; d < end; d++) { 201 byte[] searchValue = 202 TestUtils.getTestArray(d); 203 key.setData(searchValue); 204 OperationStatus status = 205 cursors[i].getSearchKey(key, foundData, LockMode.DEFAULT); 206 assertEquals(OperationStatus.SUCCESS, status); 207 assertEquals(OperationStatus.SUCCESS, cursors[i].delete()); 208 } 209 } 210 } 211 212 215 private void dbDeleteData(int start, int end, Transaction txn) 216 throws DatabaseException { 217 218 DatabaseEntry key = new DatabaseEntry(); 219 for (int i = 0; i < NUM_DBS; i++) { 220 for (int d = start; d < end; d++) { 221 byte[] searchValue = 222 TestUtils.getTestArray(d); 223 key.setData(searchValue); 224 dbs[i].delete(txn, key); 225 } 226 } 227 } 228 229 233 private void verifyData(int numKeys, int valueOffset) 234 throws DatabaseException { 235 236 for (int i = 0; i < NUM_DBS; i++) { 237 238 DatabaseImpl dbImpl = DbInternal.dbGetDatabaseImpl(dbs[i]); 239 assertTrue(dbImpl.verify(new VerifyConfig(), 240 dbImpl.getEmptyStats())); 241 242 Cursor verifyCursor = 243 dbs[i].openCursor(null, CursorConfig.READ_UNCOMMITTED); 244 DatabaseEntry key = new DatabaseEntry(); 245 DatabaseEntry data = new DatabaseEntry(); 246 OperationStatus status = 247 verifyCursor.getFirst(key, data, LockMode.DEFAULT); 248 for (int d = 0; d < numKeys; d++) { 249 assertEquals("key=" + d, OperationStatus.SUCCESS, status); 250 byte[] expected = TestUtils.getTestArray(d + valueOffset); 251 assertTrue(Arrays.equals(expected, key.getData())); 252 assertTrue("Expected= " + TestUtils.dumpByteArray(expected) + 253 " saw=" + TestUtils.dumpByteArray(data.getData()), 254 Arrays.equals(expected, data.getData())); 255 status = verifyCursor.getNext(key, data, LockMode.DEFAULT); 256 } 257 assertTrue("More data than expected", 259 (status != OperationStatus.SUCCESS)); 260 verifyCursor.close(); 261 } 262 } 263 264 267 public void testBasicCursor() 268 throws Throwable { 269 270 try { 271 int numKeys = 7; 272 createDbs(); 273 274 Transaction txn = env.beginTransaction(null, null); 276 createCursors(txn); 277 cursorInsertData(0, numKeys*2); 278 closeCursors(); 279 txn.commit(); 280 verifyData(numKeys*2, 0); 281 282 txn = env.beginTransaction(null, null); 284 createCursors(txn); 285 cursorInsertData(numKeys*2, numKeys*3); 286 closeCursors(); 287 txn.abort(); 288 verifyData(numKeys*2, 0); 289 290 296 EnvironmentStats envStat = env.getStats(TestUtils.FAST_STATS); 297 int queueSize = envStat.getInCompQueueSize(); 298 assertTrue(queueSize > 0); 299 300 txn = env.beginTransaction(null, null); 302 createCursors(txn); 303 cursorModifyData(0, numKeys * 2, 1); 304 closeCursors(); 305 txn.abort(); 306 verifyData(numKeys*2, 0); 307 308 txn = env.beginTransaction(null, null); 310 createCursors(txn); 311 cursorDeleteData(numKeys+1, numKeys*2); 312 closeCursors(); 313 txn.abort(); 314 verifyData(numKeys*2, 0); 315 envStat = env.getStats(TestUtils.FAST_STATS); 317 assertEquals(queueSize, envStat.getInCompQueueSize()); 318 319 txn = env.beginTransaction(null, null); 321 createCursors(txn); 322 cursorDeleteData(numKeys, numKeys*2); 323 closeCursors(); 324 txn.commit(); 325 verifyData(numKeys, 0); 326 327 envStat = env.getStats(TestUtils.FAST_STATS); 329 assertTrue(envStat.getInCompQueueSize() > queueSize); 330 331 closeAll(); 332 333 } catch (Throwable t) { 334 t.printStackTrace(); 336 throw t; 337 } 338 } 339 340 343 public void testTxnClose() 344 throws DatabaseException { 345 346 createDbs(); 347 Transaction txn = env.beginTransaction(null, null); 348 createCursors(txn); 349 try { 350 txn.commit(); 351 fail("Commit should fail"); 352 } catch (DatabaseException e) { 353 } 354 closeCursors(); 355 closeAll(); 356 } 357 358 class CascadingAbortTestJUnitThread extends JUnitThread { 359 Transaction txn = null; 360 Database db = null; 361 362 CascadingAbortTestJUnitThread(Transaction txn, 363 Database db) { 364 super("testCascadingAborts"); 365 this.txn = txn; 366 this.db = db; 367 } 368 } 369 370 374 public void xtestCascadingAborts() 375 throws Throwable { 376 377 Database db = null; 378 379 try { 380 DatabaseConfig dbConfig = new DatabaseConfig(); 381 dbConfig.setAllowCreate(true); 382 dbConfig.setTransactional(true); 383 db = env.openDatabase(null, "testDB", dbConfig); 384 385 DatabaseEntry key = new DatabaseEntry(); 386 DatabaseEntry data = new DatabaseEntry(); 387 388 Transaction txn = env.beginTransaction(null, null); 389 key.setData("abb".getBytes()); 390 data.setData("def".getBytes()); 391 key.setData("abc".getBytes()); 393 data.setData("def".getBytes()); 394 db.put(txn, key, data); 395 txn.commit(); 396 397 399 Transaction txn1 = env.beginTransaction(null, null); 400 Transaction txn2 = env.beginTransaction(null, null); 401 402 CascadingAbortTestJUnitThread tester1 = 403 new CascadingAbortTestJUnitThread(txn2, db) { 404 public void testBody() 405 throws Throwable { 406 407 Cursor c = db.openCursor(txn, null); 408 DatabaseEntry data = new DatabaseEntry(); 409 try { 410 Thread.yield(); 411 DatabaseEntry key = new DatabaseEntry(); 412 key.setData("abc".getBytes()); 413 OperationStatus status; 414 status = 415 c.getSearchKeyRange(key, data, LockMode.DEFAULT); 416 status = c.delete(); 417 } catch (Throwable T) { 418 T.printStackTrace(); 419 } finally { 420 c.close(); 421 } 422 } 423 }; 424 425 tester1.start(); 426 Thread.yield(); 427 key.setData("abc".getBytes()); 428 OperationStatus status; 429 status = db.delete(txn1, key); 430 431 txn1.abort(); 432 Thread.yield(); 433 434 txn2.abort(); 435 tester1.finishTest(); 436 437 439 if (false) { 440 db.close(); 441 env.close(); 442 EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 443 envConfig.setTransactional(true); 444 envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), 445 "6"); 446 envConfig.setConfigParam(EnvironmentParams. 447 ENV_RUN_INCOMPRESSOR. 448 getName(), 449 "false"); 450 envConfig.setAllowCreate(true); 451 env = new Environment(envHome, envConfig); 452 db = env.openDatabase(null, "testDB", dbConfig); 453 } 454 455 txn = env.beginTransaction(null, null); 456 System.out.println(db.getSearchBoth(txn, key, data, 457 LockMode.DEFAULT)); 458 txn.commit(); 459 } catch (Throwable T) { 460 T.printStackTrace(); 461 } finally { 462 db.close(); 463 } 464 } 465 466 469 public void testBasicDb() 470 throws Throwable { 471 472 try { 473 TransactionStats stats = 474 env.getTransactionStats(TestUtils.FAST_STATS); 475 assertEquals(0, stats.getNAborts()); 476 int initialCommits = 1; assertEquals(initialCommits, stats.getNCommits()); 478 479 int numKeys = 7; 480 createDbs(); 481 482 dbInsertData(0, numKeys, null); 484 verifyData(numKeys, 0); 485 486 Transaction txn = env.beginTransaction(null, null); 488 dbInsertData(numKeys, numKeys*2, txn); 489 txn.commit(); 490 verifyData(numKeys*2, 0); 491 492 stats = env.getTransactionStats(TestUtils.FAST_STATS); 493 assertEquals(0, stats.getNAborts()); 494 assertEquals((initialCommits + 1 + (1 * NUM_DBS) + (numKeys*NUM_DBS)), stats.getNCommits()); 498 499 txn = env.beginTransaction(null, null); 501 dbDeleteData(numKeys, numKeys * 2, txn); 502 verifyData(numKeys, 0); txn.abort(); 504 505 closeAll(); 506 } catch (Throwable t) { 507 t.printStackTrace(); 508 throw t; 509 } 510 } 511 512 515 516 public void testDbCreation() 517 throws DatabaseException { 518 519 Transaction txnA = env.beginTransaction(null, null); 520 Transaction txnB = env.beginTransaction(null, null); 521 522 DatabaseConfig dbConfig = new DatabaseConfig(); 523 dbConfig.setAllowCreate(true); 524 dbConfig.setTransactional(true); 525 Database dbA = 526 env.openDatabase(txnA, "foo", dbConfig); 527 528 530 dbConfig.setAllowCreate(false); 531 532 try { 533 txnB.setLockTimeout(1000); 534 535 env.openDatabase(txnB, "foo", dbConfig); 536 fail("Shouldn't be able to open foo"); 537 } catch (DatabaseException e) { 538 } 539 540 txnB.abort(); 541 542 Database dbC = 544 env.openDatabase(txnA, "foo", dbConfig); 545 546 txnA.commit(); 548 txnB = env.beginTransaction(null, null); 549 Database dbB = 550 env.openDatabase(txnB, "foo", dbConfig); 551 txnB.commit(); 552 553 555 dbA.close(); 556 dbB.close(); 557 dbC.close(); 558 } 559 560 561 public void testClose() 562 throws DatabaseException { 563 564 Transaction txnA = env.beginTransaction(null, null); 565 txnA.commit(); 566 567 try { 568 env.openDatabase(txnA, "foo", null); 569 fail("Should not be able to use a closed exception"); 570 } catch (DatabaseException expected) { 571 } 572 } 573 574 } 575 | Popular Tags |