1 8 9 package com.sleepycat.je.log; 10 11 import java.io.File ; 12 import java.io.IOException ; 13 import java.io.RandomAccessFile ; 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.List ; 17 18 import junit.framework.TestCase; 19 20 import com.sleepycat.je.DatabaseException; 21 import com.sleepycat.je.DbInternal; 22 import com.sleepycat.je.EnvironmentConfig; 23 import com.sleepycat.je.config.EnvironmentParams; 24 import com.sleepycat.je.dbi.DbConfigManager; 25 import com.sleepycat.je.dbi.EnvironmentImpl; 26 import com.sleepycat.je.tree.LN; 27 import com.sleepycat.je.util.BadFileFilter; 28 import com.sleepycat.je.util.TestUtils; 29 import com.sleepycat.je.utilint.DbLsn; 30 import com.sleepycat.je.utilint.Tracer; 31 32 public class LastFileReaderTest extends TestCase { 33 34 private DbConfigManager configManager; 35 private FileManager fileManager; 36 private LogManager logManager; 37 private File envHome; 38 private EnvironmentImpl envImpl; 39 public LastFileReaderTest() { 40 super(); 41 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 42 } 43 44 public void setUp() 45 throws DatabaseException, IOException { 46 47 TestUtils.removeFiles("Setup", envHome, FileManager.JE_SUFFIX); 48 TestUtils.removeFiles(envHome, new BadFileFilter()); 49 } 50 51 public void tearDown() 52 throws DatabaseException, IOException { 53 54 59 try { 60 envImpl.close(false); 61 } catch (DatabaseException e) { 62 } 63 64 TestUtils.removeFiles("TearDown", envHome, FileManager.JE_SUFFIX); 65 TestUtils.removeFiles(envHome, new BadFileFilter()); 66 } 67 68 69 private void initEnv() 70 throws DatabaseException { 71 72 initEnv(null); 73 } 74 75 76 private void initEnv(String logFileSize) 77 throws DatabaseException { 78 79 EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 80 81 82 envConfig.setConfigParam 83 (EnvironmentParams.ENV_RUN_CLEANER.getName(), "false"); 84 envConfig.setConfigParam 85 (EnvironmentParams.ENV_RUN_CHECKPOINTER.getName(), "false"); 86 envConfig.setConfigParam 87 (EnvironmentParams.ENV_RUN_EVICTOR.getName(), "false"); 88 89 envConfig.setConfigParam 90 (EnvironmentParams.NODE_MAX.getName(), "6"); 91 envConfig.setConfigParam 92 (EnvironmentParams.JE_LOGGING_LEVEL.getName(), "CONFIG"); 93 if (logFileSize != null) { 94 DbInternal.disableParameterValidation(envConfig); 95 envConfig.setConfigParam 96 (EnvironmentParams.LOG_FILE_MAX.getName(), logFileSize); 97 } 98 99 100 DbInternal.setCreateUP(envConfig, false); 101 102 DbInternal.setCheckpointUP(envConfig, false); 103 104 envConfig.setAllowCreate(true); 105 envImpl = new EnvironmentImpl(envHome, envConfig); 106 configManager = envImpl.getConfigManager(); 107 fileManager = envImpl.getFileManager(); 108 logManager = envImpl.getLogManager(); 109 } 110 111 114 public void testEmptyAtEnd() 115 throws Throwable { 116 117 initEnv(); 118 119 122 FileManagerTestUtils.createLogFile(fileManager, envImpl, 100); 123 fileManager.clear(); 124 125 LastFileReader reader = new LastFileReader(envImpl, 1000); 126 assertTrue(reader.readNextEntry()); 127 assertEquals(0, DbLsn.getFileOffset(reader.getLastLsn())); 128 } 129 130 134 public void testLastFileEmpty() 135 throws Throwable { 136 137 initEnv("1000"); 138 int numIters = 10; 139 List testObjs = new ArrayList (); 140 List testLsns = new ArrayList (); 141 142 146 for (int i = 0; i < numIters; i++) { 147 148 LoggableObject loggableObj = 149 new Tracer("Hello there, rec " + (i+1)); 150 testObjs.add(loggableObj); 151 testLsns.add(new Long (logManager.log(loggableObj))); 152 } 153 154 logManager.flush(); 155 fileManager.clear(); 156 157 int lastFileNum = fileManager.getAllFileNumbers().length - 1; 158 159 162 fileManager.syncLogEnd(); 163 fileManager.clear(); 164 String emptyLastFile = fileManager.getFullFileName(lastFileNum+1, 165 FileManager.JE_SUFFIX); 166 167 RandomAccessFile file = 168 new RandomAccessFile (emptyLastFile, FileManager.FileMode. 169 READWRITE_MODE.getModeValue()); 170 file.close(); 171 172 assertTrue(fileManager.getAllFileNumbers().length >= 2); 173 174 178 LastFileReader reader = new LastFileReader(envImpl, 1000); 179 while (reader.readNextEntry()) { 180 } 181 182 186 assertEquals("lastValid=" + DbLsn.toString(reader.getLastValidLsn()), 187 lastFileNum, 188 DbLsn.getFileNumber(reader.getLastValidLsn())); 189 assertEquals(lastFileNum, DbLsn.getFileNumber(reader.getEndOfLog())); 190 } 191 192 195 public void testBadFileHeader() 196 throws Throwable { 197 198 initEnv(); 199 200 205 long lastFileNum = fileManager.getLastFileNum().longValue(); 206 String lastFile = 207 fileManager.getFullFileName(lastFileNum, 208 FileManager.JE_SUFFIX); 209 210 RandomAccessFile file = 211 new RandomAccessFile (lastFile, FileManager.FileMode. 212 READWRITE_MODE.getModeValue()); 213 214 file.seek(15); 215 file.writeBytes("putting more junk in, mess up header"); 216 file.close(); 217 218 222 try { 223 LastFileReader reader = new LastFileReader(envImpl, 1000); 224 fail("Should see exception when creating " + reader); 225 } catch (DbChecksumException e) { 226 227 } 228 229 233 file = new RandomAccessFile (lastFile, "rw"); 234 file.getChannel().truncate(0); 235 file.writeBytes("bad"); 236 file.close(); 237 238 LastFileReader reader = new LastFileReader(envImpl, 1000); 239 240 assertFalse(reader.readNextEntry()); 241 File movedFile = new File (envHome, "00000000.bad"); 242 assertTrue(movedFile.exists()); 243 244 245 file = new RandomAccessFile (lastFile, "rw"); 246 file.getChannel().truncate(0); 247 file.writeBytes("bad"); 248 file.close(); 249 250 reader = new LastFileReader(envImpl, 1000); 251 assertTrue(movedFile.exists()); 252 File movedFile1 = new File (envHome, "00000000.bad.1"); 253 assertTrue(movedFile1.exists()); 254 } 255 256 259 public void testBasic() 260 throws Throwable { 261 262 initEnv(); 263 int numIters = 50; 264 List testObjs = new ArrayList (); 265 List testLsns = new ArrayList (); 266 267 fillLogFile(numIters, testLsns, testObjs); 268 LastFileReader reader = 269 new LastFileReader(envImpl, 270 configManager.getInt 271 (EnvironmentParams.LOG_ITERATOR_READ_SIZE)); 272 273 checkLogEnd(reader, numIters, testLsns, testObjs); 274 } 275 276 279 public void testSmallBuffers() 280 throws Throwable { 281 282 initEnv(); 283 int numIters = 50; 284 List testObjs = new ArrayList (); 285 List testLsns = new ArrayList (); 286 287 fillLogFile(numIters, testLsns, testObjs); 288 LastFileReader reader = new LastFileReader(envImpl, 10); 289 checkLogEnd(reader, numIters, testLsns, testObjs); 290 } 291 292 295 public void testMedBuffers() 296 throws Throwable { 297 298 initEnv(); 299 int numIters = 50; 300 List testObjs = new ArrayList (); 301 List testLsns = new ArrayList (); 302 303 fillLogFile(numIters, testLsns, testObjs); 304 LastFileReader reader = new LastFileReader(envImpl, 100); 305 checkLogEnd(reader, numIters, testLsns, testObjs); 306 } 307 308 311 public void testJunk() 312 throws Throwable { 313 314 initEnv(); 315 int numIters = 50; 316 List testObjs = new ArrayList (); 317 List testLsns = new ArrayList (); 318 319 320 fillLogFile(numIters, testLsns, testObjs); 321 long lastFileNum = fileManager.getLastFileNum().longValue(); 322 String lastFile = 323 fileManager.getFullFileName(lastFileNum, 324 FileManager.JE_SUFFIX); 325 326 RandomAccessFile file = 327 new RandomAccessFile (lastFile, FileManager.FileMode. 328 READWRITE_MODE.getModeValue()); 329 file.seek(file.length()); 330 file.writeBytes("hello, some junk"); 331 file.close(); 332 333 334 335 LastFileReader reader = new LastFileReader(envImpl, 100); 336 checkLogEnd(reader, numIters, testLsns, testObjs); 337 } 338 339 343 public void testExtraEmpty() 344 throws Throwable { 345 346 initEnv(); 347 int numIters = 50; 348 List testObjs = new ArrayList (); 349 List testLsns = new ArrayList (); 350 int defaultBufferSize = 351 configManager.getInt(EnvironmentParams.LOG_ITERATOR_READ_SIZE); 352 353 358 359 fillLogFile(numIters, testLsns, testObjs); 360 361 362 fileManager.bumpLsn(100000000); 363 fileManager.bumpLsn(100000000); 364 FileManagerTestUtils.createLogFile(fileManager, envImpl, 10); 365 366 367 fileManager.bumpLsn(100000000); 368 fileManager.bumpLsn(100000000); 369 FileManagerTestUtils.createLogFile(fileManager, envImpl, 10); 370 371 assertEquals(3, fileManager.getAllFileNumbers().length); 372 373 377 long lastFileNum = fileManager.getLastFileNum().longValue(); 378 String lastFile = 379 fileManager.getFullFileName(lastFileNum, 380 FileManager.JE_SUFFIX); 381 RandomAccessFile file = 382 new RandomAccessFile (lastFile, FileManager.FileMode. 383 READWRITE_MODE.getModeValue()); 384 file.getChannel().truncate(10); 385 file.close(); 386 fileManager.clear(); 387 388 392 LastFileReader reader = new LastFileReader(envImpl, 393 defaultBufferSize); 394 checkLogEnd(reader, numIters, testLsns, testObjs); 395 assertEquals(2, fileManager.getAllFileNumbers().length); 396 397 401 lastFileNum = fileManager.getLastFileNum().longValue(); 402 lastFile = fileManager.getFullFileName(lastFileNum, 403 FileManager.JE_SUFFIX); 404 file = new RandomAccessFile (lastFile, FileManager.FileMode. 405 READWRITE_MODE.getModeValue()); 406 file.getChannel().truncate(10); 407 file.close(); 408 409 413 reader = new LastFileReader(envImpl, defaultBufferSize); 414 checkLogEnd(reader, numIters, testLsns, testObjs); 415 assertEquals(1, fileManager.getAllFileNumbers().length); 416 } 417 418 419 422 private void fillLogFile(int numIters, List testLsns, List testObjs) 423 throws Throwable { 424 425 428 for (int i = 0; i < numIters; i++) { 429 430 LoggableObject loggableObj = 431 new Tracer("Hello there, rec " + (i+1)); 432 testObjs.add(loggableObj); 433 testLsns.add(new Long (logManager.log(loggableObj))); 434 435 436 byte [] data = new byte[i+1]; 437 Arrays.fill(data, (byte)(i+1)); 438 loggableObj = new LN(data); 439 440 testObjs.add(loggableObj); 441 testLsns.add(new Long (logManager.log(loggableObj))); 442 } 443 444 445 logManager.flush(); 446 fileManager.clear(); 447 } 448 449 453 private void checkLogEnd(LastFileReader reader, 454 int numIters, 455 List testLsns, 456 List testObjs) 457 throws Throwable { 458 459 reader.setTargetType(LogEntryType.LOG_ROOT); 460 reader.setTargetType(LogEntryType.LOG_LN); 461 reader.setTargetType(LogEntryType.LOG_TRACE); 462 reader.setTargetType(LogEntryType.LOG_IN); 463 reader.setTargetType(LogEntryType.LOG_LN_TRANSACTIONAL); 464 465 466 while (reader.readNextEntry()) { 467 } 468 469 470 reader.setEndOfFile(); 471 472 478 assertEquals("should have seen this many entries", (numIters * 2) + 7, 479 reader.getNumRead()); 480 481 482 int numLsns = testLsns.size(); 483 long lastLsn = DbLsn.longToLsn((Long ) testLsns.get(numLsns - 1)); 484 assertEquals("last LSN", lastLsn, reader.getLastLsn()); 485 486 487 assertEquals("prev offset", DbLsn.getFileOffset(lastLsn), 488 reader.getPrevOffset()); 489 490 491 int lastSize = 492 ((LogWritable)testObjs.get(testObjs.size()-1)).getLogSize(); 493 assertEquals("next available", 494 DbLsn.makeLsn(DbLsn.getFileNumber(lastLsn), 495 DbLsn.getFileOffset(lastLsn) + 496 LogManager.HEADER_BYTES + lastSize), 497 reader.getEndOfLog()); 498 499 500 FileHandle handle = fileManager.getFileHandle(0L); 501 RandomAccessFile file = handle.getFile(); 502 assertEquals(DbLsn.getFileOffset(reader.getEndOfLog()), 503 file.getChannel().size()); 504 handle.release(); 505 fileManager.clear(); 506 507 508 assertTrue(reader.getLastSeen(LogEntryType.LOG_ROOT) != 509 DbLsn.NULL_LSN); 510 assertTrue(reader.getLastSeen(LogEntryType.LOG_IN) == DbLsn.NULL_LSN); 511 assertTrue(reader.getLastSeen(LogEntryType.LOG_LN_TRANSACTIONAL) == 512 DbLsn.NULL_LSN); 513 assertEquals(reader.getLastSeen(LogEntryType.LOG_TRACE), 514 DbLsn.longToLsn((Long ) testLsns.get(numLsns-2))); 515 assertEquals(reader.getLastSeen(LogEntryType.LOG_LN), 516 lastLsn); 517 } 518 } 519 | Popular Tags |