001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: RMWLockingTest.java,v 1.6.2.3 2008/01/07 15:14:25 cwl Exp $
007: */
008:
009: package com.sleepycat.je.cleaner;
010:
011: import java.io.File;
012: import java.io.IOException;
013:
014: import junit.framework.TestCase;
015:
016: import com.sleepycat.bind.tuple.IntegerBinding;
017: import com.sleepycat.je.CheckpointConfig;
018: import com.sleepycat.je.Database;
019: import com.sleepycat.je.DatabaseConfig;
020: import com.sleepycat.je.DatabaseEntry;
021: import com.sleepycat.je.DatabaseException;
022: import com.sleepycat.je.DbInternal;
023: import com.sleepycat.je.Environment;
024: import com.sleepycat.je.EnvironmentConfig;
025: import com.sleepycat.je.LockMode;
026: import com.sleepycat.je.OperationStatus;
027: import com.sleepycat.je.Transaction;
028: import com.sleepycat.je.log.FileManager;
029: import com.sleepycat.je.util.TestUtils;
030:
031: /**
032: * Use LockMode.RMW and verify that the FileSummaryLNs accurately reflect only
033: * those LNs that have been made obsolete.
034: */
035: public class RMWLockingTest extends TestCase {
036:
037: private static final int NUM_RECS = 5;
038:
039: private File envHome;
040: private Environment env;
041: private Database db;
042: private DatabaseEntry key;
043: private DatabaseEntry data;
044:
045: public RMWLockingTest() {
046: envHome = new File(System.getProperty(TestUtils.DEST_DIR));
047: }
048:
049: public void setUp() throws IOException, DatabaseException {
050:
051: TestUtils.removeLogFiles("Setup", envHome, false);
052: TestUtils.removeFiles("Setup", envHome, FileManager.DEL_SUFFIX);
053: }
054:
055: public void tearDown() throws IOException, DatabaseException {
056:
057: try {
058: if (db != null) {
059: db.close();
060: }
061: if (env != null) {
062: env.close();
063: }
064: } catch (Throwable e) {
065: System.out.println("tearDown: " + e);
066: }
067:
068: try {
069: TestUtils.removeLogFiles("tearDown", envHome, true);
070: TestUtils.removeFiles("tearDown", envHome,
071: FileManager.DEL_SUFFIX);
072: } catch (Throwable e) {
073: System.out.println("tearDown: " + e);
074: }
075:
076: db = null;
077: env = null;
078: envHome = null;
079: }
080:
081: public void testBasic() throws DatabaseException {
082:
083: init();
084: insertRecords();
085: rmwModify();
086:
087: UtilizationProfile up = DbInternal.envGetEnvironmentImpl(env)
088: .getUtilizationProfile();
089:
090: /*
091: * Checkpoint the environment to flush all utilization tracking
092: * information before verifying.
093: */
094: CheckpointConfig ckptConfig = new CheckpointConfig();
095: ckptConfig.setForce(true);
096: env.checkpoint(ckptConfig);
097:
098: assertTrue(up.verifyFileSummaryDatabase());
099: }
100:
101: /**
102: * Tests that we can load a log file containing offsets that correspond to
103: * non-obsolete LNs. The bad log file was created using testBasic run
104: * against JE 2.0.54. It contains version 1 FSLNs, one of which has an
105: * offset which is not obsolete.
106: */
107: public void testBadLog() throws DatabaseException, IOException {
108:
109: /* Copy a log file with bad offsets to log file zero. */
110: String resName = "rmw_bad_offsets.jdb";
111: TestUtils.loadLog(getClass(), resName, envHome);
112:
113: /* Open the log we just copied. */
114: EnvironmentConfig envConfig = TestUtils.initEnvConfig();
115: envConfig.setAllowCreate(false);
116: envConfig.setReadOnly(true);
117: env = new Environment(envHome, envConfig);
118:
119: /*
120: * Verify the UP of the bad log. Prior to adding the code in
121: * FileSummaryLN.postFetchInit that discards version 1 offsets, this
122: * assertion failed.
123: */
124: UtilizationProfile up = DbInternal.envGetEnvironmentImpl(env)
125: .getUtilizationProfile();
126: assertTrue(up.verifyFileSummaryDatabase());
127:
128: env.close();
129: env = null;
130: }
131:
132: private void init() throws DatabaseException {
133:
134: EnvironmentConfig envConfig = TestUtils.initEnvConfig();
135: envConfig.setAllowCreate(true);
136: envConfig.setTransactional(true);
137: env = new Environment(envHome, envConfig);
138:
139: DatabaseConfig dbConfig = new DatabaseConfig();
140: dbConfig.setAllowCreate(true);
141: dbConfig.setTransactional(true);
142: db = env.openDatabase(null, "foo", dbConfig);
143: }
144:
145: /* Insert records. */
146: private void insertRecords() throws DatabaseException {
147:
148: key = new DatabaseEntry();
149: data = new DatabaseEntry();
150:
151: IntegerBinding.intToEntry(100, data);
152:
153: for (int i = 0; i < NUM_RECS; i++) {
154: IntegerBinding.intToEntry(i, key);
155: assertEquals(OperationStatus.SUCCESS, db.put(null, key,
156: data));
157: }
158: }
159:
160: /* lock two records with RMW, only modify one. */
161: private void rmwModify() throws DatabaseException {
162:
163: Transaction txn = env.beginTransaction(null, null);
164: IntegerBinding.intToEntry(0, key);
165: assertEquals(OperationStatus.SUCCESS, db.get(txn, key, data,
166: LockMode.RMW));
167: IntegerBinding.intToEntry(1, key);
168: assertEquals(OperationStatus.SUCCESS, db.get(txn, key, data,
169: LockMode.RMW));
170:
171: IntegerBinding.intToEntry(200, data);
172: assertEquals(OperationStatus.SUCCESS, db.put(txn, key, data));
173: txn.commit();
174: }
175: }
|