diff --git oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckInvalidRepositoryTest.java oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckInvalidRepositoryTest.java index c602223..0c3b0e8 100644 --- oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckInvalidRepositoryTest.java +++ oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckInvalidRepositoryTest.java @@ -68,11 +68,13 @@ public class CheckInvalidRepositoryTest extends CheckRepositoryTestBase { assertExpectedOutput(strOut.toString(), Lists.newArrayList("Checked 7 nodes and 21 properties", "Path / is consistent", "Searched through 2 revisions")); - assertExpectedOutput(strErr.toString(), Lists.newArrayList("Error while traversing /z")); + + // not sure whether first traversal will fail because of "/a" or "/z" + assertExpectedOutput(strErr.toString(), Lists.newArrayList("Error while traversing /")); } @Test - public void testBrokenPathWithoutValidRevision() { + public void testPartialBrokenPathWithoutValidRevision() { StringWriter strOut = new StringWriter(); StringWriter strErr = new StringWriter(); @@ -99,4 +101,34 @@ public class CheckInvalidRepositoryTest extends CheckRepositoryTestBase { assertExpectedOutput(strOut.toString(), Lists.newArrayList("No good revision found")); assertExpectedOutput(strErr.toString(), Lists.newArrayList("Error while traversing /z", "Path /z not found")); } + + @Test + public void testPartialBrokenPathWithValidRevision() { + StringWriter strOut = new StringWriter(); + StringWriter strErr = new StringWriter(); + + PrintWriter outWriter = new PrintWriter(strOut, true); + PrintWriter errWriter = new PrintWriter(strErr, true); + + Set filterPaths = new LinkedHashSet<>(); + filterPaths.add("/a"); + + Check.builder() + .withPath(new File(temporaryFolder.getRoot().getAbsolutePath())) + .withJournal("journal.log") + .withDebugInterval(Long.MAX_VALUE) + .withCheckBinaries(true) + .withFilterPaths(filterPaths) + .withOutWriter(outWriter) + .withErrWriter(errWriter) + .build() + .run(); + + outWriter.close(); + errWriter.close(); + + assertExpectedOutput(strOut.toString(), Lists.newArrayList("Checked 1 nodes and 1 properties", "Path /a is consistent", + "Searched through 2 revisions")); + assertExpectedOutput(strErr.toString(), Lists.newArrayList("Error while traversing /a")); + } } diff --git oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckRepositoryTestBase.java oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckRepositoryTestBase.java index 22284a5..8909371 100644 --- oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckRepositoryTestBase.java +++ oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tooling/CheckRepositoryTestBase.java @@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.segment.file.tooling; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; @@ -88,15 +89,29 @@ public class CheckRepositoryTestBase { SegmentNodeStore nodeStore = SegmentNodeStoreBuilders.builder(fileStore).build(); NodeBuilder builder = nodeStore.getRoot().builder(); + // add a new child "z" addChildWithBlobProperties(nodeStore, builder, "z", 5); + + // add a new property value to existing child "a" + addChildWithBlobProperties(nodeStore, builder, "a", 1); NodeState after = nodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); // get record number to corrupt (NODE record for "z") SegmentNodeState child = (SegmentNodeState) after.getChildNode("z"); - int recordNumber = child.getRecordId().getRecordNumber(); + int zRecordNumber = child.getRecordId().getRecordNumber(); + + // get record number to corrupt (NODE record for "a") + child = (SegmentNodeState) after.getChildNode("a"); + int aRecordNumber = child.getRecordId().getRecordNumber(); + fileStore.close(); + corruptRecord(zRecordNumber); + corruptRecord(aRecordNumber); + } + + private void corruptRecord(int recordNumber) throws FileNotFoundException, IOException { //since the filestore was closed after writing the first revision, we're always dealing with the 2nd tar file RandomAccessFile file = new RandomAccessFile(new File(temporaryFolder.getRoot(),"data00001a.tar"), "rw");