/** * Test that we can read from a stream created by FileJournalManager. Create a single edits * directory, failing it on the final roll. Then try loading from the point of the 3rd roll. * Verify that we read the correct number of transactions from this point. */ @Test public void testReadFromStream() throws IOException { File f = new File(TestEditLog.TEST_DIR + "/filejournaltest1"); // abort after 10th roll NNStorage storage = setupEdits(Collections.<URI>singletonList(f.toURI()), 10, new AbortSpec(10, 0)); StorageDirectory sd = storage.dirIterator(NameNodeDirType.EDITS).next(); FileJournalManager jm = new FileJournalManager(sd); long expectedTotalTxnCount = TXNS_PER_ROLL * 10 + TXNS_PER_FAIL; assertEquals(expectedTotalTxnCount, jm.getNumberOfTransactions(1)); long skippedTxns = (3 * TXNS_PER_ROLL); // skip first 3 files long startingTxId = skippedTxns + 1; long numTransactionsToLoad = jm.getNumberOfTransactions(startingTxId); long numLoaded = 0; while (numLoaded < numTransactionsToLoad) { EditLogInputStream editIn = jm.getInputStream(startingTxId); FSEditLogLoader.EditLogValidation val = FSEditLogLoader.validateEditLog(editIn); long count = val.getNumTransactions(); editIn.close(); startingTxId += count; numLoaded += count; } assertEquals(expectedTotalTxnCount - skippedTxns, numLoaded); }
static FSEditLogLoader.EditLogValidation validateEditLog(File file) throws IOException { EditLogFileInputStream in; try { in = new EditLogFileInputStream(file); in.getVersion(); // causes us to read the header } catch (LogHeaderCorruptException e) { // If the header is malformed or the wrong value, this indicates a corruption LOG.warn("Log file " + file + " has no valid header", e); return new FSEditLogLoader.EditLogValidation(0, HdfsConstants.INVALID_TXID, true); } try { return FSEditLogLoader.validateEditLog(in); } finally { IOUtils.closeStream(in); } }