Return-Path: X-Original-To: apmail-hadoop-common-commits-archive@www.apache.org Delivered-To: apmail-hadoop-common-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 49C8510A69 for ; Mon, 17 Nov 2014 06:30:21 +0000 (UTC) Received: (qmail 12482 invoked by uid 500); 17 Nov 2014 06:30:04 -0000 Delivered-To: apmail-hadoop-common-commits-archive@hadoop.apache.org Received: (qmail 12066 invoked by uid 500); 17 Nov 2014 06:30:04 -0000 Mailing-List: contact common-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: common-dev@hadoop.apache.org Delivered-To: mailing list common-commits@hadoop.apache.org Received: (qmail 10801 invoked by uid 99); 17 Nov 2014 06:30:03 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 17 Nov 2014 06:30:03 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id B6A2C93D365; Mon, 17 Nov 2014 06:30:03 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: vinayakumarb@apache.org To: common-commits@hadoop.apache.org Date: Mon, 17 Nov 2014 06:30:24 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [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 argsList = getArgs(args); + find.processOptions(argsList); + LinkedList 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 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 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 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 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 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 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 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 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 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 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 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 args = new LinkedList(); + + 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 getArgs(String cmd) { + return new LinkedList(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(Collections.singletonList(arg))); + } + + /** Converts a command string into a list of arguments. */ + static LinkedList getArgs(String cmd) { + return new LinkedList(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 @@ + help: help for find + + -help find + + + + + + RegexpAcrossOutputComparator + -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\. + + + + + + help: help for help -help help 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 @@ + + + + find: default expression + + -fs NAMENODE -mkdir /donotfind + -fs NAMENODE -mkdir donotfind + -fs NAMENODE -mkdir /findtest + -fs NAMENODE -mkdir /findtest/item1 + -fs NAMENODE -mkdir /findtest/item1/item1a + -fs NAMENODE -touchz /findtest/item1/item1a/item1aa + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2 + -fs NAMENODE -mkdir /findtest/item3 + -fs NAMENODE -mkdir /findtest/item4 + -fs NAMENODE -mkdir /findtest/item4/item4a + -fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b + -fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5 + -fs NAMENODE -find /findtest + + + -fs NAMENODE -rm -r /donotfind + -fs NAMENODE -rm -r donotfind + -fs NAMENODE -rm -r /findtest + + + + RegexpAcrossOutputComparator + ^/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 +$ + + + + + find: -print + + -fs NAMENODE -mkdir /donotfind + -fs NAMENODE -mkdir donotfind + -fs NAMENODE -mkdir /findtest + -fs NAMENODE -mkdir /findtest/item1 + -fs NAMENODE -mkdir /findtest/item1/item1a + -fs NAMENODE -touchz /findtest/item1/item1a/item1aa + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2 + -fs NAMENODE -mkdir /findtest/item3 + -fs NAMENODE -mkdir /findtest/item4 + -fs NAMENODE -mkdir /findtest/item4/item4a + -fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b + -fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5 + -fs NAMENODE -find /findtest -print + + + -fs NAMENODE -rm -r /donotfind + -fs NAMENODE -rm -r donotfind + -fs NAMENODE -rm -r /findtest + + + + RegexpAcrossOutputComparator + ^/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 +$ + + + + + find: -print (relative path) + + -fs NAMENODE -mkdir /donotfind + -fs NAMENODE -mkdir -p donotfind + -fs NAMENODE -mkdir -p findtest + -fs NAMENODE -mkdir -p findtest/item1 + -fs NAMENODE -mkdir -p findtest/item1/item1a + -fs NAMENODE -touchz findtest/item1/item1a/item1aa + -fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item1/item1b + -fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item2 + -fs NAMENODE -mkdir -p findtest/item3 + -fs NAMENODE -mkdir -p findtest/item4 + -fs NAMENODE -mkdir -p findtest/item4/item4a + -fs NAMENODE -put CLITEST_DATA/data120bytes findtest/item4/item4b + -fs NAMENODE -put CLITEST_DATA/data1k findtest/item5 + -fs NAMENODE -find findtest -print + + + -fs NAMENODE -rm -r /donotfind + -fs NAMENODE -rm -r donotfind + -fs NAMENODE -rm -r findtest + + + + RegexpAcrossOutputComparator + ^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 +$ + + + + + find: -print (cwd) + + -fs NAMENODE -mkdir /donotfind + -fs NAMENODE -mkdir findtest + -fs NAMENODE -mkdir findtest/item1 + -fs NAMENODE -mkdir findtest/item1/item1a + -fs NAMENODE -touchz findtest/item1/item1a/item1aa + -fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item1/item1b + -fs NAMENODE -put CLITEST_DATA/data60bytes findtest/item2 + -fs NAMENODE -mkdir findtest/item3 + -fs NAMENODE -mkdir findtest/item4 + -fs NAMENODE -mkdir findtest/item4/item4a + -fs NAMENODE -put CLITEST_DATA/data120bytes findtest/item4/item4b + -fs NAMENODE -put CLITEST_DATA/data1k findtest/item5 + -fs NAMENODE -find -print + + + -fs NAMENODE -rm -r findtest + -fs NAMENODE -rm -r /donotfind + + + + RegexpAcrossOutputComparator + ^. +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 +$ + + + + + find: -name + + -fs NAMENODE -mkdir /findtest + -fs NAMENODE -mkdir /findtest/item1 + -fs NAMENODE -mkdir /findtest/item1/item1a + -fs NAMENODE -touchz /findtest/item1/item1a/item1aa + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2 + -fs NAMENODE -mkdir /findtest/item3 + -fs NAMENODE -mkdir /findtest/item4 + -fs NAMENODE -mkdir /findtest/item4/item4a + -fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b + -fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5 + -fs NAMENODE -find /findtest -name item*a + + + -fs NAMENODE -rm -r /findtest + + + + RegexpAcrossOutputComparator + ^/findtest/item1/item1a +/findtest/item1/item1a/item1aa +/findtest/item4/item4a +$ + + + + + find: -iname + + -fs NAMENODE -mkdir /findtest + -fs NAMENODE -mkdir /findtest/item1 + -fs NAMENODE -mkdir /findtest/item1/item1a + -fs NAMENODE -touchz /findtest/item1/item1a/item1aa + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item1/item1b + -fs NAMENODE -put CLITEST_DATA/data60bytes /findtest/item2 + -fs NAMENODE -mkdir /findtest/item3 + -fs NAMENODE -mkdir /findtest/item4 + -fs NAMENODE -mkdir /findtest/item4/item4a + -fs NAMENODE -put CLITEST_DATA/data120bytes /findtest/item4/item4b + -fs NAMENODE -put CLITEST_DATA/data1k /findtest/item5 + -fs NAMENODE -find /findtest -iname ITEM*a + + + -fs NAMENODE -rm -r /findtest + + + + RegexpAcrossOutputComparator + ^/findtest/item1/item1a +/findtest/item1/item1a/item1aa +/findtest/item4/item4a +$ + + +