You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by vi...@apache.org on 2014/11/17 07:30:24 UTC
[22/45] hadoop git commit: HADOOP-8989. hadoop fs -find feature
(Jonathan Allen via aw)
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestFind.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestFind.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestFind.java
new file mode 100644
index 0000000..7d79420
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestFind.java
@@ -0,0 +1,900 @@
+/**
+ * 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.hadoop.fs.shell.find;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+import static org.mockito.Matchers.*;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.shell.PathData;
+import org.apache.hadoop.fs.shell.find.BaseExpression;
+import org.apache.hadoop.fs.shell.find.Expression;
+import org.apache.hadoop.fs.shell.find.Find;
+import org.apache.hadoop.fs.shell.find.FindOptions;
+import org.apache.hadoop.fs.shell.find.Result;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+public class TestFind {
+ private static FileSystem mockFs;
+ private static Configuration conf;
+
+ @Before
+ public void setup() throws IOException {
+ mockFs = MockFileSystem.setup();
+ conf = mockFs.getConf();
+ }
+
+ // check follow link option is recognized
+ @Test(timeout = 1000)
+ public void processOptionsFollowLink() throws IOException {
+ Find find = new Find();
+ String args = "-L path";
+ find.processOptions(getArgs(args));
+ assertTrue(find.getOptions().isFollowLink());
+ assertFalse(find.getOptions().isFollowArgLink());
+ }
+
+ // check follow arg link option is recognized
+ @Test(timeout = 1000)
+ public void processOptionsFollowArgLink() throws IOException {
+ Find find = new Find();
+ String args = "-H path";
+ find.processOptions(getArgs(args));
+ assertFalse(find.getOptions().isFollowLink());
+ assertTrue(find.getOptions().isFollowArgLink());
+ }
+
+ // check follow arg link option is recognized
+ @Test(timeout = 1000)
+ public void processOptionsFollowLinkFollowArgLink() throws IOException {
+ Find find = new Find();
+ String args = "-L -H path";
+ find.processOptions(getArgs(args));
+ assertTrue(find.getOptions().isFollowLink());
+
+ // follow link option takes precedence over follow arg link
+ assertFalse(find.getOptions().isFollowArgLink());
+ }
+
+ // check options and expressions are stripped from args leaving paths
+ @Test(timeout = 1000)
+ public void processOptionsExpression() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+
+ String paths = "path1 path2 path3";
+ String args = "-L -H " + paths + " -print -name test";
+ LinkedList<String> argsList = getArgs(args);
+ find.processOptions(argsList);
+ LinkedList<String> pathList = getArgs(paths);
+ assertEquals(pathList, argsList);
+ }
+
+ // check print is used as the default expression
+ @Test(timeout = 1000)
+ public void processOptionsNoExpression() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "path";
+ String expected = "Print(;)";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check unknown options are rejected
+ @Test(timeout = 1000)
+ public void processOptionsUnknown() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "path -unknown";
+ try {
+ find.processOptions(getArgs(args));
+ fail("Unknown expression not caught");
+ } catch (IOException e) {
+ }
+ }
+
+ // check unknown options are rejected when mixed with known options
+ @Test(timeout = 1000)
+ public void processOptionsKnownUnknown() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "path -print -unknown -print";
+ try {
+ find.processOptions(getArgs(args));
+ fail("Unknown expression not caught");
+ } catch (IOException e) {
+ }
+ }
+
+ // check no path defaults to current working directory
+ @Test(timeout = 1000)
+ public void processOptionsNoPath() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "-print";
+
+ LinkedList<String> argsList = getArgs(args);
+ find.processOptions(argsList);
+ assertEquals(Collections.singletonList(Path.CUR_DIR), argsList);
+ }
+
+ // check -name is handled correctly
+ @Test(timeout = 1000)
+ public void processOptionsName() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "path -name namemask";
+ String expected = "And(;Name(namemask;),Print(;))";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check -iname is handled correctly
+ @Test(timeout = 1000)
+ public void processOptionsIname() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "path -iname namemask";
+ String expected = "And(;Iname-Name(namemask;),Print(;))";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check -print is handled correctly
+ @Test(timeout = 1000)
+ public void processOptionsPrint() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "path -print";
+ String expected = "Print(;)";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check -print0 is handled correctly
+ @Test(timeout = 1000)
+ public void processOptionsPrint0() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+ String args = "path -print0";
+ String expected = "Print0-Print(;)";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check an implicit and is handled correctly
+ @Test(timeout = 1000)
+ public void processOptionsNoop() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+
+ String args = "path -name one -name two -print";
+ String expected = "And(;And(;Name(one;),Name(two;)),Print(;))";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check -a is handled correctly
+ @Test(timeout = 1000)
+ public void processOptionsA() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+
+ String args = "path -name one -a -name two -a -print";
+ String expected = "And(;And(;Name(one;),Name(two;)),Print(;))";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check -and is handled correctly
+ @Test(timeout = 1000)
+ public void processOptionsAnd() throws IOException {
+ Find find = new Find();
+ find.setConf(conf);
+
+ String args = "path -name one -and -name two -and -print";
+ String expected = "And(;And(;Name(one;),Name(two;)),Print(;))";
+ find.processOptions(getArgs(args));
+ Expression expression = find.getRootExpression();
+ assertEquals(expected, expression.toString());
+ }
+
+ // check expressions are called in the correct order
+ @Test(timeout = 1000)
+ public void processArguments() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1, 0);
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1aa, 2);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item2, 0);
+ inOrder.verify(expr).apply(item3, 0);
+ inOrder.verify(expr).apply(item4, 0);
+ inOrder.verify(expr).apply(item5, 0);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5ca, 2);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1aa.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item2.stat);
+ inOrderFsCheck.verify(fsCheck).check(item3.stat);
+ inOrderFsCheck.verify(fsCheck).check(item4.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5ca.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ // check that directories are descended correctly when -depth is specified
+ @Test(timeout = 1000)
+ public void processArgumentsDepthFirst() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.getOptions().setDepthFirst(true);
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1aa, 2);
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item1, 0);
+ inOrder.verify(expr).apply(item2, 0);
+ inOrder.verify(expr).apply(item3, 0);
+ inOrder.verify(expr).apply(item4, 0);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5ca, 2);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).apply(item5, 0);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1aa.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1.stat);
+ inOrderFsCheck.verify(fsCheck).check(item2.stat);
+ inOrderFsCheck.verify(fsCheck).check(item3.stat);
+ inOrderFsCheck.verify(fsCheck).check(item4.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5ca.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ // check symlinks given as path arguments are processed correctly with the
+ // follow arg option set
+ @Test(timeout = 1000)
+ public void processArgumentsOptionFollowArg() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.getOptions().setFollowArgLink(true);
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1, 0);
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1aa, 2);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item2, 0);
+ inOrder.verify(expr).apply(item3, 0);
+ inOrder.verify(expr).apply(item4, 0);
+ inOrder.verify(expr).apply(item5, 0);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5ca, 2);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1aa.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item2.stat);
+ inOrderFsCheck.verify(fsCheck, times(2)).check(item3.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5ca.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ // check symlinks given as path arguments are processed correctly with the
+ // follow option
+ @Test(timeout = 1000)
+ public void processArgumentsOptionFollow() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.getOptions().setFollowLink(true);
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1, 0);
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1aa, 2);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item2, 0);
+ inOrder.verify(expr).apply(item3, 0);
+ inOrder.verify(expr).apply(item4, 0);
+ inOrder.verify(expr).apply(item5, 0);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1); // triggers infinite loop message
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5ca, 2);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5ca, 2); // following item5d symlink
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1aa.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item2.stat);
+ inOrderFsCheck.verify(fsCheck, times(2)).check(item3.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5ca.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck, times(2)).check(item5ca.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verify(err).println(
+ "Infinite loop ignored: " + item5b.toString() + " -> "
+ + item5.toString());
+ verifyNoMoreInteractions(err);
+ }
+
+ // check minimum depth is handledfollowLink
+ @Test(timeout = 1000)
+ public void processArgumentsMinDepth() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.getOptions().setMinDepth(1);
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1aa, 2);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5ca, 2);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1aa.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5ca.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ // check maximum depth is handled
+ @Test(timeout = 1000)
+ public void processArgumentsMaxDepth() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.getOptions().setMaxDepth(1);
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1, 0);
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item2, 0);
+ inOrder.verify(expr).apply(item3, 0);
+ inOrder.verify(expr).apply(item4, 0);
+ inOrder.verify(expr).apply(item5, 0);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item2.stat);
+ inOrderFsCheck.verify(fsCheck).check(item3.stat);
+ inOrderFsCheck.verify(fsCheck).check(item4.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ // check min depth is handled when -depth is specified
+ @Test(timeout = 1000)
+ public void processArgumentsDepthFirstMinDepth() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.getOptions().setDepthFirst(true);
+ find.getOptions().setMinDepth(1);
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1aa, 2);
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5ca, 2);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1aa.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5ca.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ // check max depth is handled when -depth is specified
+ @Test(timeout = 1000)
+ public void processArgumentsDepthFirstMaxDepth() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.getOptions().setDepthFirst(true);
+ find.getOptions().setMaxDepth(1);
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item1, 0);
+ inOrder.verify(expr).apply(item2, 0);
+ inOrder.verify(expr).apply(item3, 0);
+ inOrder.verify(expr).apply(item4, 0);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).apply(item5, 0);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1.stat);
+ inOrderFsCheck.verify(fsCheck).check(item2.stat);
+ inOrderFsCheck.verify(fsCheck).check(item3.stat);
+ inOrderFsCheck.verify(fsCheck).check(item4.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ // check expressions are called in the correct order
+ @Test(timeout = 1000)
+ public void processArgumentsNoDescend() throws IOException {
+ LinkedList<PathData> items = createDirectories();
+
+ Find find = new Find();
+ find.setConf(conf);
+ PrintStream out = mock(PrintStream.class);
+ find.getOptions().setOut(out);
+ PrintStream err = mock(PrintStream.class);
+ find.getOptions().setErr(err);
+ Expression expr = mock(Expression.class);
+ when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS);
+ when(expr.apply(eq(item1a), anyInt())).thenReturn(Result.STOP);
+ FileStatusChecker fsCheck = mock(FileStatusChecker.class);
+ Expression test = new TestExpression(expr, fsCheck);
+ find.setRootExpression(test);
+ find.processArguments(items);
+
+ InOrder inOrder = inOrder(expr);
+ inOrder.verify(expr).setOptions(find.getOptions());
+ inOrder.verify(expr).prepare();
+ inOrder.verify(expr).apply(item1, 0);
+ inOrder.verify(expr).apply(item1a, 1);
+ inOrder.verify(expr).apply(item1b, 1);
+ inOrder.verify(expr).apply(item2, 0);
+ inOrder.verify(expr).apply(item3, 0);
+ inOrder.verify(expr).apply(item4, 0);
+ inOrder.verify(expr).apply(item5, 0);
+ inOrder.verify(expr).apply(item5a, 1);
+ inOrder.verify(expr).apply(item5b, 1);
+ inOrder.verify(expr).apply(item5c, 1);
+ inOrder.verify(expr).apply(item5ca, 2);
+ inOrder.verify(expr).apply(item5d, 1);
+ inOrder.verify(expr).apply(item5e, 1);
+ inOrder.verify(expr).finish();
+ verifyNoMoreInteractions(expr);
+
+ InOrder inOrderFsCheck = inOrder(fsCheck);
+ inOrderFsCheck.verify(fsCheck).check(item1.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item1b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item2.stat);
+ inOrderFsCheck.verify(fsCheck).check(item3.stat);
+ inOrderFsCheck.verify(fsCheck).check(item4.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5a.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5b.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5c.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5ca.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5d.stat);
+ inOrderFsCheck.verify(fsCheck).check(item5e.stat);
+ verifyNoMoreInteractions(fsCheck);
+
+ verifyNoMoreInteractions(out);
+ verifyNoMoreInteractions(err);
+ }
+
+ private interface FileStatusChecker {
+ public void check(FileStatus fileStatus);
+ }
+
+ private class TestExpression extends BaseExpression implements Expression {
+ private Expression expr;
+ private FileStatusChecker checker;
+ public TestExpression(Expression expr, FileStatusChecker checker) {
+ this.expr = expr;
+ this.checker = checker;
+ }
+ @Override
+ public Result apply(PathData item, int depth) throws IOException {
+ FileStatus fileStatus = getFileStatus(item, depth);
+ checker.check(fileStatus);
+ return expr.apply(item, depth);
+ }
+ @Override
+ public void setOptions(FindOptions options) throws IOException {
+ super.setOptions(options);
+ expr.setOptions(options);
+ }
+ @Override
+ public void prepare() throws IOException {
+ expr.prepare();
+ }
+ @Override
+ public void finish() throws IOException {
+ expr.finish();
+ }
+ }
+
+ // creates a directory structure for traversal
+ // item1 (directory)
+ // \- item1a (directory)
+ // \- item1aa (file)
+ // \- item1b (file)
+ // item2 (directory)
+ // item3 (file)
+ // item4 (link) -> item3
+ // item5 (directory)
+ // \- item5a (link) -> item1b
+ // \- item5b (link) -> item5 (infinite loop)
+ // \- item5c (directory)
+ // \- item5ca (file)
+ // \- item5d (link) -> item5c
+ // \- item5e (link) -> item5c/item5ca
+ private PathData item1 = null;
+ private PathData item1a = null;
+ private PathData item1aa = null;
+ private PathData item1b = null;
+ private PathData item2 = null;
+ private PathData item3 = null;
+ private PathData item4 = null;
+ private PathData item5 = null;
+ private PathData item5a = null;
+ private PathData item5b = null;
+ private PathData item5c = null;
+ private PathData item5ca = null;
+ private PathData item5d = null;
+ private PathData item5e = null;
+
+ private LinkedList<PathData> createDirectories() throws IOException {
+ item1 = createPathData("item1");
+ item1a = createPathData("item1/item1a");
+ item1aa = createPathData("item1/item1a/item1aa");
+ item1b = createPathData("item1/item1b");
+ item2 = createPathData("item2");
+ item3 = createPathData("item3");
+ item4 = createPathData("item4");
+ item5 = createPathData("item5");
+ item5a = createPathData("item5/item5a");
+ item5b = createPathData("item5/item5b");
+ item5c = createPathData("item5/item5c");
+ item5ca = createPathData("item5/item5c/item5ca");
+ item5d = createPathData("item5/item5d");
+ item5e = createPathData("item5/item5e");
+
+ LinkedList<PathData> args = new LinkedList<PathData>();
+
+ when(item1.stat.isDirectory()).thenReturn(true);
+ when(item1a.stat.isDirectory()).thenReturn(true);
+ when(item1aa.stat.isDirectory()).thenReturn(false);
+ when(item1b.stat.isDirectory()).thenReturn(false);
+ when(item2.stat.isDirectory()).thenReturn(true);
+ when(item3.stat.isDirectory()).thenReturn(false);
+ when(item4.stat.isDirectory()).thenReturn(false);
+ when(item5.stat.isDirectory()).thenReturn(true);
+ when(item5a.stat.isDirectory()).thenReturn(false);
+ when(item5b.stat.isDirectory()).thenReturn(false);
+ when(item5c.stat.isDirectory()).thenReturn(true);
+ when(item5ca.stat.isDirectory()).thenReturn(false);
+ when(item5d.stat.isDirectory()).thenReturn(false);
+ when(item5e.stat.isDirectory()).thenReturn(false);
+
+ when(mockFs.listStatus(eq(item1.path))).thenReturn(
+ new FileStatus[] { item1a.stat, item1b.stat });
+ when(mockFs.listStatus(eq(item1a.path))).thenReturn(
+ new FileStatus[] { item1aa.stat });
+ when(mockFs.listStatus(eq(item2.path))).thenReturn(new FileStatus[0]);
+ when(mockFs.listStatus(eq(item5.path))).thenReturn(
+ new FileStatus[] { item5a.stat, item5b.stat, item5c.stat, item5d.stat,
+ item5e.stat });
+ when(mockFs.listStatus(eq(item5c.path))).thenReturn(
+ new FileStatus[] { item5ca.stat });
+
+ when(item1.stat.isSymlink()).thenReturn(false);
+ when(item1a.stat.isSymlink()).thenReturn(false);
+ when(item1aa.stat.isSymlink()).thenReturn(false);
+ when(item1b.stat.isSymlink()).thenReturn(false);
+ when(item2.stat.isSymlink()).thenReturn(false);
+ when(item3.stat.isSymlink()).thenReturn(false);
+ when(item4.stat.isSymlink()).thenReturn(true);
+ when(item5.stat.isSymlink()).thenReturn(false);
+ when(item5a.stat.isSymlink()).thenReturn(true);
+ when(item5b.stat.isSymlink()).thenReturn(true);
+ when(item5d.stat.isSymlink()).thenReturn(true);
+ when(item5e.stat.isSymlink()).thenReturn(true);
+
+ when(item4.stat.getSymlink()).thenReturn(item3.path);
+ when(item5a.stat.getSymlink()).thenReturn(item1b.path);
+ when(item5b.stat.getSymlink()).thenReturn(item5.path);
+ when(item5d.stat.getSymlink()).thenReturn(item5c.path);
+ when(item5e.stat.getSymlink()).thenReturn(item5ca.path);
+
+ args.add(item1);
+ args.add(item2);
+ args.add(item3);
+ args.add(item4);
+ args.add(item5);
+
+ return args;
+ }
+
+ private PathData createPathData(String name) throws IOException {
+ Path path = new Path(name);
+ FileStatus fstat = mock(FileStatus.class);
+ when(fstat.getPath()).thenReturn(path);
+ when(fstat.toString()).thenReturn("fileStatus:" + name);
+
+ when(mockFs.getFileStatus(eq(path))).thenReturn(fstat);
+ PathData item = new PathData(path.toString(), conf);
+ return item;
+ }
+
+ private LinkedList<String> getArgs(String cmd) {
+ return new LinkedList<String>(Arrays.asList(cmd.split(" ")));
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestHelper.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestHelper.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestHelper.java
new file mode 100644
index 0000000..d4866b5
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestHelper.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.hadoop.fs.shell.find;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+
+/** Helper methods for the find expression unit tests. */
+class TestHelper {
+ /** Adds an argument string to an expression */
+ static void addArgument(Expression expr, String arg) {
+ expr.addArguments(new LinkedList<String>(Collections.singletonList(arg)));
+ }
+
+ /** Converts a command string into a list of arguments. */
+ static LinkedList<String> getArgs(String cmd) {
+ return new LinkedList<String>(Arrays.asList(cmd.split(" ")));
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestIname.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestIname.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestIname.java
new file mode 100644
index 0000000..6e42fce
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestIname.java
@@ -0,0 +1,93 @@
+/**
+ * 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.hadoop.fs.shell.find;
+
+import static org.junit.Assert.*;
+import static org.apache.hadoop.fs.shell.find.TestHelper.*;
+
+import java.io.IOException;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.shell.PathData;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestIname {
+ private FileSystem mockFs;
+ private Name.Iname name;
+
+ @Before
+ public void resetMock() throws IOException {
+ mockFs = MockFileSystem.setup();
+ }
+
+ private void setup(String arg) throws IOException {
+ name = new Name.Iname();
+ addArgument(name, arg);
+ name.setOptions(new FindOptions());
+ name.prepare();
+ }
+
+ // test a matching name (same case)
+ @Test(timeout = 1000)
+ public void applyMatch() throws IOException {
+ setup("name");
+ PathData item = new PathData("/directory/path/name", mockFs.getConf());
+ assertEquals(Result.PASS, name.apply(item, -1));
+ }
+
+ // test a non-matching name
+ @Test(timeout = 1000)
+ public void applyNotMatch() throws IOException {
+ setup("name");
+ PathData item = new PathData("/directory/path/notname", mockFs.getConf());
+ assertEquals(Result.FAIL, name.apply(item, -1));
+ }
+
+ // test a matching name (different case)
+ @Test(timeout = 1000)
+ public void applyMixedCase() throws IOException {
+ setup("name");
+ PathData item = new PathData("/directory/path/NaMe", mockFs.getConf());
+ assertEquals(Result.PASS, name.apply(item, -1));
+ }
+
+ // test a matching glob pattern (same case)
+ @Test(timeout = 1000)
+ public void applyGlob() throws IOException {
+ setup("n*e");
+ PathData item = new PathData("/directory/path/name", mockFs.getConf());
+ assertEquals(Result.PASS, name.apply(item, -1));
+ }
+
+ // test a matching glob pattern (different case)
+ @Test(timeout = 1000)
+ public void applyGlobMixedCase() throws IOException {
+ setup("n*e");
+ PathData item = new PathData("/directory/path/NaMe", mockFs.getConf());
+ assertEquals(Result.PASS, name.apply(item, -1));
+ }
+
+ // test a non-matching glob pattern
+ @Test(timeout = 1000)
+ public void applyGlobNotMatch() throws IOException {
+ setup("n*e");
+ PathData item = new PathData("/directory/path/notmatch", mockFs.getConf());
+ assertEquals(Result.FAIL, name.apply(item, -1));
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestName.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestName.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestName.java
new file mode 100644
index 0000000..2c77fe1
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestName.java
@@ -0,0 +1,93 @@
+/**
+ * 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.hadoop.fs.shell.find;
+
+import static org.junit.Assert.*;
+import static org.apache.hadoop.fs.shell.find.TestHelper.*;
+
+import java.io.IOException;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.shell.PathData;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestName {
+ private FileSystem mockFs;
+ private Name name;
+
+ @Before
+ public void resetMock() throws IOException {
+ mockFs = MockFileSystem.setup();
+ }
+
+ private void setup(String arg) throws IOException {
+ name = new Name();
+ addArgument(name, arg);
+ name.setOptions(new FindOptions());
+ name.prepare();
+ }
+
+ // test a matching name
+ @Test(timeout = 1000)
+ public void applyMatch() throws IOException {
+ setup("name");
+ PathData item = new PathData("/directory/path/name", mockFs.getConf());
+ assertEquals(Result.PASS, name.apply(item, -1));
+ }
+
+ // test a non-matching name
+ @Test(timeout = 1000)
+ public void applyNotMatch() throws IOException {
+ setup("name");
+ PathData item = new PathData("/directory/path/notname", mockFs.getConf());
+ assertEquals(Result.FAIL, name.apply(item, -1));
+ }
+
+ // test a different case name
+ @Test(timeout = 1000)
+ public void applyMixedCase() throws IOException {
+ setup("name");
+ PathData item = new PathData("/directory/path/NaMe", mockFs.getConf());
+ assertEquals(Result.FAIL, name.apply(item, -1));
+ }
+
+ // test a matching glob pattern
+ @Test(timeout = 1000)
+ public void applyGlob() throws IOException {
+ setup("n*e");
+ PathData item = new PathData("/directory/path/name", mockFs.getConf());
+ assertEquals(Result.PASS, name.apply(item, -1));
+ }
+
+ // test a glob pattern with different case
+ @Test(timeout = 1000)
+ public void applyGlobMixedCase() throws IOException {
+ setup("n*e");
+ PathData item = new PathData("/directory/path/NaMe", mockFs.getConf());
+ assertEquals(Result.FAIL, name.apply(item, -1));
+ }
+
+ // test a non-matching glob pattern
+ @Test(timeout = 1000)
+ public void applyGlobNotMatch() throws IOException {
+ setup("n*e");
+ PathData item = new PathData("/directory/path/notmatch", mockFs.getConf());
+ assertEquals(Result.FAIL, name.apply(item, -1));
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint.java
new file mode 100644
index 0000000..2d27665
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint.java
@@ -0,0 +1,56 @@
+/**
+ * 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.hadoop.fs.shell.find;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.io.IOException;
+
+import org.apache.hadoop.fs.shell.PathData;
+import org.junit.Test;
+
+import java.io.PrintStream;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.junit.Before;
+
+public class TestPrint {
+ private FileSystem mockFs;
+
+ @Before
+ public void resetMock() throws IOException {
+ mockFs = MockFileSystem.setup();
+ }
+
+ // test the full path is printed to stdout
+ @Test(timeout = 1000)
+ public void testPrint() throws IOException {
+ Print print = new Print();
+ PrintStream out = mock(PrintStream.class);
+ FindOptions options = new FindOptions();
+ options.setOut(out);
+ print.setOptions(options);
+
+ String filename = "/one/two/test";
+ PathData item = new PathData(filename, mockFs.getConf());
+ assertEquals(Result.PASS, print.apply(item, -1));
+ verify(out).print(filename + '\n');
+ verifyNoMoreInteractions(out);
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint0.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint0.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint0.java
new file mode 100644
index 0000000..3b89438
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint0.java
@@ -0,0 +1,56 @@
+/**
+ * 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.hadoop.fs.shell.find;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.io.IOException;
+
+import org.apache.hadoop.fs.shell.PathData;
+import org.junit.Test;
+
+import java.io.PrintStream;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.junit.Before;
+
+public class TestPrint0 {
+ private FileSystem mockFs;
+
+ @Before
+ public void resetMock() throws IOException {
+ mockFs = MockFileSystem.setup();
+ }
+
+ // test the full path is printed to stdout with a '\0'
+ @Test(timeout = 1000)
+ public void testPrint() throws IOException {
+ Print.Print0 print = new Print.Print0();
+ PrintStream out = mock(PrintStream.class);
+ FindOptions options = new FindOptions();
+ options.setOut(out);
+ print.setOptions(options);
+
+ String filename = "/one/two/test";
+ PathData item = new PathData(filename, mockFs.getConf());
+ assertEquals(Result.PASS, print.apply(item, -1));
+ verify(out).print(filename + '\0');
+ verifyNoMoreInteractions(out);
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestResult.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestResult.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestResult.java
new file mode 100644
index 0000000..1139220
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestResult.java
@@ -0,0 +1,172 @@
+/**
+ * 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.hadoop.fs.shell.find;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class TestResult {
+
+ // test the PASS value
+ @Test(timeout = 1000)
+ public void testPass() {
+ Result result = Result.PASS;
+ assertTrue(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the FAIL value
+ @Test(timeout = 1000)
+ public void testFail() {
+ Result result = Result.FAIL;
+ assertFalse(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the STOP value
+ @Test(timeout = 1000)
+ public void testStop() {
+ Result result = Result.STOP;
+ assertTrue(result.isPass());
+ assertFalse(result.isDescend());
+ }
+
+ // test combine method with two PASSes
+ @Test(timeout = 1000)
+ public void combinePassPass() {
+ Result result = Result.PASS.combine(Result.PASS);
+ assertTrue(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the combine method with a PASS and a FAIL
+ @Test(timeout = 1000)
+ public void combinePassFail() {
+ Result result = Result.PASS.combine(Result.FAIL);
+ assertFalse(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the combine method with a FAIL and a PASS
+ @Test(timeout = 1000)
+ public void combineFailPass() {
+ Result result = Result.FAIL.combine(Result.PASS);
+ assertFalse(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the combine method with two FAILs
+ @Test(timeout = 1000)
+ public void combineFailFail() {
+ Result result = Result.FAIL.combine(Result.FAIL);
+ assertFalse(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the combine method with a PASS and STOP
+ @Test(timeout = 1000)
+ public void combinePassStop() {
+ Result result = Result.PASS.combine(Result.STOP);
+ assertTrue(result.isPass());
+ assertFalse(result.isDescend());
+ }
+
+ // test the combine method with a STOP and FAIL
+ @Test(timeout = 1000)
+ public void combineStopFail() {
+ Result result = Result.STOP.combine(Result.FAIL);
+ assertFalse(result.isPass());
+ assertFalse(result.isDescend());
+ }
+
+ // test the combine method with a STOP and a PASS
+ @Test(timeout = 1000)
+ public void combineStopPass() {
+ Result result = Result.STOP.combine(Result.PASS);
+ assertTrue(result.isPass());
+ assertFalse(result.isDescend());
+ }
+
+ // test the combine method with a FAIL and a STOP
+ @Test(timeout = 1000)
+ public void combineFailStop() {
+ Result result = Result.FAIL.combine(Result.STOP);
+ assertFalse(result.isPass());
+ assertFalse(result.isDescend());
+ }
+
+ // test the negation of PASS
+ @Test(timeout = 1000)
+ public void negatePass() {
+ Result result = Result.PASS.negate();
+ assertFalse(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the negation of FAIL
+ @Test(timeout = 1000)
+ public void negateFail() {
+ Result result = Result.FAIL.negate();
+ assertTrue(result.isPass());
+ assertTrue(result.isDescend());
+ }
+
+ // test the negation of STOP
+ @Test(timeout = 1000)
+ public void negateStop() {
+ Result result = Result.STOP.negate();
+ assertFalse(result.isPass());
+ assertFalse(result.isDescend());
+ }
+
+ // test equals with two PASSes
+ @Test(timeout = 1000)
+ public void equalsPass() {
+ Result one = Result.PASS;
+ Result two = Result.PASS.combine(Result.PASS);
+ assertEquals(one, two);
+ }
+
+ // test equals with two FAILs
+ @Test(timeout = 1000)
+ public void equalsFail() {
+ Result one = Result.FAIL;
+ Result two = Result.FAIL.combine(Result.FAIL);
+ assertEquals(one, two);
+ }
+
+ // test equals with two STOPS
+ @Test(timeout = 1000)
+ public void equalsStop() {
+ Result one = Result.STOP;
+ Result two = Result.STOP.combine(Result.STOP);
+ assertEquals(one, two);
+ }
+
+ // test all combinations of not equals
+ @Test(timeout = 1000)
+ public void notEquals() {
+ assertFalse(Result.PASS.equals(Result.FAIL));
+ assertFalse(Result.PASS.equals(Result.STOP));
+ assertFalse(Result.FAIL.equals(Result.PASS));
+ assertFalse(Result.FAIL.equals(Result.STOP));
+ assertFalse(Result.STOP.equals(Result.PASS));
+ assertFalse(Result.STOP.equals(Result.FAIL));
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-common-project/hadoop-common/src/test/resources/testConf.xml
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/test/resources/testConf.xml b/hadoop-common-project/hadoop-common/src/test/resources/testConf.xml
index dcf8fb4..5196641 100644
--- a/hadoop-common-project/hadoop-common/src/test/resources/testConf.xml
+++ b/hadoop-common-project/hadoop-common/src/test/resources/testConf.xml
@@ -964,6 +964,50 @@
</test>
<test> <!-- TESTED -->
+ <description>help: help for find</description>
+ <test-commands>
+ <command>-help find</command>
+ </test-commands>
+ <cleanup-commands>
+ </cleanup-commands>
+ <comparators>
+ <comparator>
+ <type>RegexpAcrossOutputComparator</type>
+ <expected-output>-find <path> \.\.\. <expression> \.\.\. :
+ Finds all files that match the specified expression and
+ applies selected actions to them\. If no <path> is specified
+ then defaults to the current working directory\. If no
+ expression is specified then defaults to -print\.
+
+ The following primary expressions are recognised:
+ -name pattern
+ -iname pattern
+ Evaluates as true if the basename of the file matches the
+ pattern using standard file system globbing\.
+ If -iname is used then the match is case insensitive\.
+
+ -print
+ -print0
+ Always evaluates to true. Causes the current pathname to be
+ written to standard output followed by a newline. If the -print0
+ expression is used then an ASCII NULL character is appended rather
+ than a newline.
+
+ The following operators are recognised:
+ expression -a expression
+ expression -and expression
+ expression expression
+ Logical AND operator for joining two expressions\. Returns
+ true if both child expressions return true\. Implied by the
+ juxtaposition of two expressions and so does not need to be
+ explicitly specified\. The second expression will not be
+ applied if the first fails\.
+</expected-output>
+ </comparator>
+ </comparators>
+ </test>
+
+ <test> <!-- TESTED -->
<description>help: help for help</description>
<test-commands>
<command>-help help</command>
http://git-wip-us.apache.org/repos/asf/hadoop/blob/ba879a5d/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/testHDFSConf.xml
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/testHDFSConf.xml b/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/testHDFSConf.xml
index 8939f87..c86b06d 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/testHDFSConf.xml
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/testHDFSConf.xml
@@ -16841,5 +16841,228 @@
</comparator>
</comparators>
</test>
+
+ <!-- Tests for find -->
+ <test> <!-- TESTED -->
+ <description>find: default expression</description>
+ <test-commands>
+ <command>-fs NAMENODE -mkdir /donotfind</command>
+ <command>-fs NAMENODE -mkdir donotfind</command>
+ <command>-fs NAMENODE -mkdir /findtest</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1/item1a</command>
+ <command>-fs NAMENODE -touchz /findtest/item1/item1a/item1aa</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2</command>
+ <command>-fs NAMENODE -mkdir /findtest/item3</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4/item4a</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5</command>
+ <command>-fs NAMENODE -find /findtest</command>
+ </test-commands>
+ <cleanup-commands>
+ <command>-fs NAMENODE -rm -r /donotfind</command>
+ <command>-fs NAMENODE -rm -r donotfind</command>
+ <command>-fs NAMENODE -rm -r /findtest</command>
+ </cleanup-commands>
+ <comparators>
+ <comparator>
+ <type>RegexpAcrossOutputComparator</type>
+ <expected-output>^/findtest
+/findtest/item1
+/findtest/item1/item1a
+/findtest/item1/item1a/item1aa
+/findtest/item1/item1b
+/findtest/item2
+/findtest/item3
+/findtest/item4
+/findtest/item4/item4a
+/findtest/item4/item4b
+/findtest/item5
+$</expected-output>
+ </comparator>
+ </comparators>
+ </test>
+ <test> <!-- TESTED -->
+ <description>find: -print </description>
+ <test-commands>
+ <command>-fs NAMENODE -mkdir /donotfind</command>
+ <command>-fs NAMENODE -mkdir donotfind</command>
+ <command>-fs NAMENODE -mkdir /findtest</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1/item1a</command>
+ <command>-fs NAMENODE -touchz /findtest/item1/item1a/item1aa</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2</command>
+ <command>-fs NAMENODE -mkdir /findtest/item3</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4/item4a</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5</command>
+ <command>-fs NAMENODE -find /findtest -print</command>
+ </test-commands>
+ <cleanup-commands>
+ <command>-fs NAMENODE -rm -r /donotfind</command>
+ <command>-fs NAMENODE -rm -r donotfind</command>
+ <command>-fs NAMENODE -rm -r /findtest</command>
+ </cleanup-commands>
+ <comparators>
+ <comparator>
+ <type>RegexpAcrossOutputComparator</type>
+ <expected-output>^/findtest
+/findtest/item1
+/findtest/item1/item1a
+/findtest/item1/item1a/item1aa
+/findtest/item1/item1b
+/findtest/item2
+/findtest/item3
+/findtest/item4
+/findtest/item4/item4a
+/findtest/item4/item4b
+/findtest/item5
+$</expected-output>
+ </comparator>
+ </comparators>
+ </test>
+ <test> <!-- TESTED -->
+ <description>find: -print (relative path) </description>
+ <test-commands>
+ <command>-fs NAMENODE -mkdir /donotfind</command>
+ <command>-fs NAMENODE -mkdir -p donotfind</command>
+ <command>-fs NAMENODE -mkdir -p findtest</command>
+ <command>-fs NAMENODE -mkdir -p findtest/item1</command>
+ <command>-fs NAMENODE -mkdir -p findtest/item1/item1a</command>
+ <command>-fs NAMENODE -touchz findtest/item1/item1a/item1aa</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item1/item1b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item2</command>
+ <command>-fs NAMENODE -mkdir -p findtest/item3</command>
+ <command>-fs NAMENODE -mkdir -p findtest/item4</command>
+ <command>-fs NAMENODE -mkdir -p findtest/item4/item4a</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data120bytes findtest/item4/item4b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data1k findtest/item5</command>
+ <command>-fs NAMENODE -find findtest -print</command>
+ </test-commands>
+ <cleanup-commands>
+ <command>-fs NAMENODE -rm -r /donotfind</command>
+ <command>-fs NAMENODE -rm -r donotfind</command>
+ <command>-fs NAMENODE -rm -r findtest</command>
+ </cleanup-commands>
+ <comparators>
+ <comparator>
+ <type>RegexpAcrossOutputComparator</type>
+ <expected-output>^findtest
+findtest/item1
+findtest/item1/item1a
+findtest/item1/item1a/item1aa
+findtest/item1/item1b
+findtest/item2
+findtest/item3
+findtest/item4
+findtest/item4/item4a
+findtest/item4/item4b
+findtest/item5
+$</expected-output>
+ </comparator>
+ </comparators>
+ </test>
+ <test> <!-- TESTED -->
+ <description>find: -print (cwd) </description>
+ <test-commands>
+ <command>-fs NAMENODE -mkdir /donotfind</command>
+ <command>-fs NAMENODE -mkdir findtest</command>
+ <command>-fs NAMENODE -mkdir findtest/item1</command>
+ <command>-fs NAMENODE -mkdir findtest/item1/item1a</command>
+ <command>-fs NAMENODE -touchz findtest/item1/item1a/item1aa</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item1/item1b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item2</command>
+ <command>-fs NAMENODE -mkdir findtest/item3</command>
+ <command>-fs NAMENODE -mkdir findtest/item4</command>
+ <command>-fs NAMENODE -mkdir findtest/item4/item4a</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data120bytes findtest/item4/item4b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data1k findtest/item5</command>
+ <command>-fs NAMENODE -find -print</command>
+ </test-commands>
+ <cleanup-commands>
+ <command>-fs NAMENODE -rm -r findtest</command>
+ <command>-fs NAMENODE -rm -r /donotfind</command>
+ </cleanup-commands>
+ <comparators>
+ <comparator>
+ <type>RegexpAcrossOutputComparator</type>
+ <expected-output>^.
+findtest
+findtest/item1
+findtest/item1/item1a
+findtest/item1/item1a/item1aa
+findtest/item1/item1b
+findtest/item2
+findtest/item3
+findtest/item4
+findtest/item4/item4a
+findtest/item4/item4b
+findtest/item5
+$</expected-output>
+ </comparator>
+ </comparators>
+ </test>
+ <test> <!-- TESTED -->
+ <description>find: -name </description>
+ <test-commands>
+ <command>-fs NAMENODE -mkdir /findtest</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1/item1a</command>
+ <command>-fs NAMENODE -touchz /findtest/item1/item1a/item1aa</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2</command>
+ <command>-fs NAMENODE -mkdir /findtest/item3</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4/item4a</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5</command>
+ <command>-fs NAMENODE -find /findtest -name item*a</command>
+ </test-commands>
+ <cleanup-commands>
+ <command>-fs NAMENODE -rm -r /findtest</command>
+ </cleanup-commands>
+ <comparators>
+ <comparator>
+ <type>RegexpAcrossOutputComparator</type>
+ <expected-output>^/findtest/item1/item1a
+/findtest/item1/item1a/item1aa
+/findtest/item4/item4a
+$</expected-output>
+ </comparator>
+ </comparators>
+ </test>
+ <test> <!-- TESTED -->
+ <description>find: -iname </description>
+ <test-commands>
+ <command>-fs NAMENODE -mkdir /findtest</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1</command>
+ <command>-fs NAMENODE -mkdir /findtest/item1/item1a</command>
+ <command>-fs NAMENODE -touchz /findtest/item1/item1a/item1aa</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2</command>
+ <command>-fs NAMENODE -mkdir /findtest/item3</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4</command>
+ <command>-fs NAMENODE -mkdir /findtest/item4/item4a</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b</command>
+ <command>-fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5</command>
+ <command>-fs NAMENODE -find /findtest -iname ITEM*a</command>
+ </test-commands>
+ <cleanup-commands>
+ <command>-fs NAMENODE -rm -r /findtest</command>
+ </cleanup-commands>
+ <comparators>
+ <comparator>
+ <type>RegexpAcrossOutputComparator</type>
+ <expected-output>^/findtest/item1/item1a
+/findtest/item1/item1a/item1aa
+/findtest/item4/item4a
+$</expected-output>
+ </comparator>
+ </comparators>
+ </test>
</tests>
</configuration>