diff --git oak-run/src/main/java/org/apache/jackrabbit/oak/run/CheckCommand.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/CheckCommand.java index 3a09afc..41fe337 100644 --- oak-run/src/main/java/org/apache/jackrabbit/oak/run/CheckCommand.java +++ oak-run/src/main/java/org/apache/jackrabbit/oak/run/CheckCommand.java @@ -48,6 +48,7 @@ class CheckCommand implements Command { if (options.nonOptionArguments().size() != 1) { printUsage(parser); + return; } File dir = isValidFileStoreOrFail(new File(options.nonOptionArguments().get(0).toString())); @@ -79,7 +80,6 @@ class CheckCommand implements Command { System.err.println("usage: check path/to/segmentstore "); parser.printHelpOn(System.err); - System.exit(1); } } diff --git oak-run/src/test/java/org/apache/jackrabbit/oak/run/CheckValidRepositoryTest.java oak-run/src/test/java/org/apache/jackrabbit/oak/run/CheckValidRepositoryTest.java new file mode 100644 index 0000000..a9667b4 --- /dev/null +++ oak-run/src/test/java/org/apache/jackrabbit/oak/run/CheckValidRepositoryTest.java @@ -0,0 +1,181 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.jackrabbit.oak.run; + +import static com.google.common.base.Charsets.UTF_8; +import static org.apache.jackrabbit.oak.run.TestUtils.randomStream; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.jackrabbit.oak.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders; +import org.apache.jackrabbit.oak.segment.file.FileStore; +import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder; +import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.EmptyHook; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; + +/** + * Tests for {@link CheckCommand} + */ +public class CheckValidRepositoryTest { + private static final Logger log = LoggerFactory.getLogger(CheckValidRepositoryTest.class); + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(new File("target")); + + @Before + public void setup() throws Exception { + FileStore fileStore = FileStoreBuilder.fileStoreBuilder(temporaryFolder.getRoot()) + .withMaxFileSize(256) + .withSegmentCacheSize(64) + .build(); + + SegmentNodeStore nodeStore = SegmentNodeStoreBuilders.builder(fileStore).build(); + NodeBuilder builder = nodeStore.getRoot().builder(); + + addChildWithBlobProperties(nodeStore, builder, "a", 5); + addChildWithBlobProperties(nodeStore, builder, "b", 10); + addChildWithBlobProperties(nodeStore, builder, "c", 15); + + addChildWithProperties(nodeStore, builder, "d", 5); + addChildWithProperties(nodeStore, builder, "e", 5); + addChildWithProperties(nodeStore, builder, "f", 5); + + nodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + fileStore.close(); + } + + @After + public void tearDown() { + System.setErr(new PrintStream(new FileOutputStream(FileDescriptor.err))); + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + } + + @Test + public void testMissingPath() throws Exception { + List argsList = Lists + .newArrayList("--journal", "journal.log","--bin", "--notify", "0", "--io-stats"); + log.info("Running testMissingPath: {}", argsList); + testIncorrectParams(argsList, Lists.newArrayList("usage: check path/to/segmentstore ")); + } + + @Test + public void testDeprecatedDeep() throws Exception { + List argsList = Lists + .newArrayList(temporaryFolder.getRoot().getAbsolutePath(), "--deep"); + log.info("Running testDeprecatedDeep: {}", argsList); + testIncorrectParams(argsList, + Lists.newArrayList("The --deep option was deprecated! Please do not use it in the future!", + "A deep scan of the content tree, traversing every node, will be performed by default.")); + } + + @Test + public void testDeprecatedBin() throws Exception { + List argsList = Lists + .newArrayList(temporaryFolder.getRoot().getAbsolutePath(), "--bin", "10"); + log.info("Running testDeprecatedBin: {}", argsList); + testIncorrectParams(argsList, Lists.newArrayList("usage: check path/to/segmentstore ")); + } + + @Test + public void testAllCorrectParams() throws Exception { + List argsList = Lists + .newArrayList(temporaryFolder.getRoot().getAbsolutePath(), "--journal", "journal.log", + "--bin", "--notify", "0", "--io-stats"); + + log.info("Running testAllCorrectParams: {}", argsList); + testCorrectParams(argsList, + Lists.newArrayList("Searched through 1 revisions", "Checked 7 nodes and 45 properties")); + } + + @Test + public void testCheckWithoutBin() throws Exception { + List argsList = Lists + .newArrayList(temporaryFolder.getRoot().getAbsolutePath()); + + log.info("Running testCheckWithoutBin: {}", argsList); + testCorrectParams(argsList, + Lists.newArrayList("Searched through 1 revisions", "Checked 7 nodes and 15 properties")); + } + + private static void testCorrectParams(List argList, ArrayList assertMsg) throws Exception { + InMemoryAppender.clearMessages(); + CheckCommand checkCommand = new CheckCommand(); + + checkCommand.execute(argList.toArray(new String[0])); + log.info("Assert message: {}", assertMsg); + log.info("Message logged in System.out: {}", InMemoryAppender.messages); + + for (String msg : assertMsg) { + Assert.assertTrue(InMemoryAppender.messages.toString().contains(msg)); + } + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + } + + private static void testIncorrectParams(List argList, ArrayList assertMsg) throws Exception { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + System.setErr(new PrintStream(buffer, true, UTF_8.toString())); + + CheckCommand checkCommand = new CheckCommand(); + + checkCommand.execute(argList.toArray(new String[0])); + String message = buffer.toString(UTF_8.toString()); + log.info("Assert message: {}", assertMsg); + log.info("Message logged in System.err: {}", message); + + for (String msg : assertMsg) { + Assert.assertTrue(message.contains(msg)); + } + System.setErr(new PrintStream(new FileOutputStream(FileDescriptor.err))); + } + + private static void addChildWithBlobProperties(SegmentNodeStore nodeStore, NodeBuilder builder, String childName, + int propCount) throws IOException { + NodeBuilder child = builder.child(childName); + for (int i = 0; i < propCount; i++) { + child.setProperty(childName + i, nodeStore.createBlob(randomStream(i, 2000))); + } + } + + private static void addChildWithProperties(SegmentNodeStore nodeStore, NodeBuilder builder, String childName, + int propCount) throws IOException { + NodeBuilder child = builder.child(childName); + for (int i = 0; i < propCount; i++) { + child.setProperty(childName + i, childName + i); + } + } +} diff --git oak-run/src/test/java/org/apache/jackrabbit/oak/run/DataStoreCheckTest.java oak-run/src/test/java/org/apache/jackrabbit/oak/run/DataStoreCheckTest.java index 8d21cbd..1369684 100644 --- oak-run/src/test/java/org/apache/jackrabbit/oak/run/DataStoreCheckTest.java +++ oak-run/src/test/java/org/apache/jackrabbit/oak/run/DataStoreCheckTest.java @@ -18,18 +18,17 @@ */ package org.apache.jackrabbit.oak.run; +import static org.apache.jackrabbit.oak.run.TestUtils.randomStream; import static com.google.common.base.Charsets.UTF_8; import static org.junit.Assert.assertEquals; import java.io.BufferedWriter; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Iterator; @@ -229,11 +228,4 @@ public class DataStoreCheckTest { assertEquals(blobsAdded, FileIOUtils.readStringsAsSet(new FileInputStream(files[0]), false)); } - - static InputStream randomStream(int seed, int size) { - Random r = new Random(seed); - byte[] data = new byte[size]; - r.nextBytes(data); - return new ByteArrayInputStream(data); - } } diff --git oak-run/src/test/java/org/apache/jackrabbit/oak/run/InMemoryAppender.java oak-run/src/test/java/org/apache/jackrabbit/oak/run/InMemoryAppender.java new file mode 100644 index 0000000..c40ca12 --- /dev/null +++ oak-run/src/test/java/org/apache/jackrabbit/oak/run/InMemoryAppender.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.jackrabbit.oak.run; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; + +public class InMemoryAppender extends AppenderBase { + public static StringBuilder messages = new StringBuilder(); + + @Override + protected void append(ILoggingEvent e) { + messages.append(e.getFormattedMessage()); + } + + public static void clearMessages() { + messages = new StringBuilder(); + } +} diff --git oak-run/src/test/java/org/apache/jackrabbit/oak/run/TestUtils.java oak-run/src/test/java/org/apache/jackrabbit/oak/run/TestUtils.java new file mode 100644 index 0000000..b913fca --- /dev/null +++ oak-run/src/test/java/org/apache/jackrabbit/oak/run/TestUtils.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.jackrabbit.oak.run; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Random; + +/** Utility class */ +class TestUtils { + + private TestUtils() { + //prevent instantiation + } + + public static InputStream randomStream(int seed, int size) { + Random r = new Random(seed); + byte[] data = new byte[size]; + r.nextBytes(data); + return new ByteArrayInputStream(data); + } +} diff --git oak-run/src/test/resources/logback-test.xml oak-run/src/test/resources/logback-test.xml index 7a9abc4..2c6f3a0 100644 --- oak-run/src/test/resources/logback-test.xml +++ oak-run/src/test/resources/logback-test.xml @@ -29,11 +29,20 @@ + + + %date{HH:mm:ss.SSS} %-5level %-40([%thread] %F:%L) %msg%n + + + - + + +