001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: SR10553Test.java,v 1.10.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.je.CheckpointConfig;
017: import com.sleepycat.je.Cursor;
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.OperationStatus;
026: import com.sleepycat.je.config.EnvironmentParams;
027: import com.sleepycat.je.log.FileManager;
028: import com.sleepycat.je.util.TestUtils;
029:
030: public class SR10553Test extends TestCase {
031:
032: private static final String DB_NAME = "foo";
033:
034: private static final CheckpointConfig forceConfig = new CheckpointConfig();
035: static {
036: forceConfig.setForce(true);
037: }
038:
039: private File envHome;
040: private Environment env;
041: private Database db;
042:
043: public SR10553Test() {
044: envHome = new File(System.getProperty(TestUtils.DEST_DIR));
045: }
046:
047: public void setUp() throws IOException, DatabaseException {
048:
049: TestUtils.removeLogFiles("Setup", envHome, false);
050: TestUtils.removeFiles("Setup", envHome, FileManager.DEL_SUFFIX);
051: }
052:
053: public void tearDown() throws IOException, DatabaseException {
054:
055: try {
056: if (env != null) {
057: env.close();
058: }
059: } catch (Throwable e) {
060: System.out.println("tearDown: " + e);
061: }
062:
063: try {
064: TestUtils.removeLogFiles("tearDown", envHome, true);
065: TestUtils.removeFiles("tearDown", envHome,
066: FileManager.DEL_SUFFIX);
067: } catch (Throwable e) {
068: System.out.println("tearDown: " + e);
069: }
070:
071: db = null;
072: env = null;
073: envHome = null;
074: }
075:
076: /**
077: * Opens the environment and database.
078: */
079: private void openEnv() throws DatabaseException {
080:
081: EnvironmentConfig config = TestUtils.initEnvConfig();
082: DbInternal.disableParameterValidation(config);
083: config.setAllowCreate(true);
084: /* Do not run the daemons. */
085: config.setConfigParam(EnvironmentParams.ENV_RUN_CLEANER
086: .getName(), "false");
087: config.setConfigParam(EnvironmentParams.ENV_RUN_EVICTOR
088: .getName(), "false");
089: config.setConfigParam(EnvironmentParams.ENV_RUN_CHECKPOINTER
090: .getName(), "false");
091: config.setConfigParam(EnvironmentParams.ENV_RUN_INCOMPRESSOR
092: .getName(), "false");
093: /* Use a small log file size to make cleaning more frequent. */
094: config.setConfigParam(EnvironmentParams.LOG_FILE_MAX.getName(),
095: Integer.toString(1024));
096: /* Use a small memory size to force eviction. */
097: config.setConfigParam(EnvironmentParams.MAX_MEMORY.getName(),
098: Integer.toString(1024 * 96));
099: /* Don't track detail with a tiny cache size. */
100: config.setConfigParam(EnvironmentParams.CLEANER_TRACK_DETAIL
101: .getName(), "false");
102: config.setConfigParam(EnvironmentParams.NUM_LOG_BUFFERS
103: .getName(), Integer.toString(2));
104: /* Set log buffers large enough for trace messages. */
105: config.setConfigParam(EnvironmentParams.LOG_MEM_SIZE.getName(),
106: Integer.toString(7000));
107:
108: env = new Environment(envHome, config);
109:
110: openDb();
111: }
112:
113: /**
114: * Opens that database.
115: */
116: private void openDb() throws DatabaseException {
117:
118: DatabaseConfig dbConfig = new DatabaseConfig();
119: dbConfig.setAllowCreate(true);
120: dbConfig.setSortedDuplicates(true);
121: db = env.openDatabase(null, DB_NAME, dbConfig);
122: }
123:
124: /**
125: * Closes the environment and database.
126: */
127: private void closeEnv() throws DatabaseException {
128:
129: if (db != null) {
130: db.close();
131: db = null;
132: }
133: if (env != null) {
134: env.close();
135: env = null;
136: }
137: }
138:
139: /**
140: */
141: public void testSR10553() throws DatabaseException {
142:
143: openEnv();
144:
145: /* Put some duplicates, enough to fill a log file. */
146: final int COUNT = 10;
147: DatabaseEntry key = new DatabaseEntry(TestUtils.getTestArray(0));
148: DatabaseEntry data = new DatabaseEntry();
149: for (int i = 0; i < COUNT; i += 1) {
150: data.setData(TestUtils.getTestArray(i));
151: db.put(null, key, data);
152: }
153: Cursor cursor = db.openCursor(null, null);
154: assertEquals(OperationStatus.SUCCESS, cursor.getSearchKey(key,
155: data, null));
156: assertEquals(COUNT, cursor.count());
157: cursor.close();
158:
159: /* Delete everything. Do not compress. */
160: db.delete(null, key);
161:
162: /* Checkpoint and clean. */
163: env.checkpoint(forceConfig);
164: int cleaned = env.cleanLog();
165: assertTrue("cleaned=" + cleaned, cleaned > 0);
166:
167: /* Force eviction. */
168: env.evictMemory();
169:
170: /* Scan all values. */
171: cursor = db.openCursor(null, null);
172: for (OperationStatus status = cursor.getFirst(key, data, null); status == OperationStatus.SUCCESS; status = cursor
173: .getNext(key, data, null)) {
174: }
175: cursor.close();
176:
177: /*
178: * Before the fix to 10553, while scanning over deleted records, a
179: * LogFileNotFoundException would occur when faulting in a deleted
180: * record, if the log file had been cleaned. This was because the
181: * cleaner was not setting knownDeleted for deleted records.
182: */
183: closeEnv();
184: }
185: }
|