diff --git a/CHANGES.txt b/CHANGES.txt index 428bb42680..a89bd515fb 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -150,6 +150,9 @@ Trunk (unreleased changes) HADOOP-7267. Refactor the rm/rmr/expunge commands to conform to new FsCommand class. (Daryn Sharp via szetszwo) + HADOOP-7285. Refactor the test command to conform to new FsCommand + class. (Daryn Sharp via todd) + OPTIMIZATIONS BUG FIXES diff --git a/src/java/org/apache/hadoop/fs/FsShell.java b/src/java/org/apache/hadoop/fs/FsShell.java index 19bd565c4c..f58a9604e0 100644 --- a/src/java/org/apache/hadoop/fs/FsShell.java +++ b/src/java/org/apache/hadoop/fs/FsShell.java @@ -432,32 +432,6 @@ private void printUsageSummary(List usages, } } - /** - * Check file types. - */ - int test(String argv[], int i) throws IOException { - if (!argv[i].startsWith("-") || argv[i].length() > 2) - throw new IOException("Not a flag: " + argv[i]); - char flag = argv[i].toCharArray()[1]; - PathData item = new PathData(argv[++i], getConf()); - - if ((flag != 'e') && !item.exists) { - // TODO: it's backwards compat, but why is this throwing an exception? - // it's not like the shell test cmd - throw new PathNotFoundException(item.toString()); - } - switch(flag) { - case 'e': - return item.exists ? 0 : 1; - case 'z': - return (item.stat.getLen() == 0) ? 0 : 1; - case 'd': - return item.stat.isDirectory() ? 0 : 1; - default: - throw new IOException("Unknown flag: " + flag); - } - } - /** * Move files that match the file pattern srcf * to a destination file. @@ -671,8 +645,7 @@ private void printHelp(String cmd) { "[-moveFromLocal ... ] [" + GET_SHORT_USAGE + "\n\t" + "[" + COPYTOLOCAL_SHORT_USAGE + "] [-moveToLocal ]\n\t" + - "[-report]\n\t" + - "[-test -[ezd] ]"; + "[-report]"; String conf ="-conf : Specify an application configuration file."; @@ -735,9 +708,6 @@ private void printHelp(String cmd) { String moveToLocal = "-moveToLocal : Not implemented yet \n"; - String test = "-test -[ezd] : If file { exists, has zero length, is a directory\n" + - "\t\tthen return 0, else return 1.\n"; - String help = "-help [cmd]: \tDisplays help for given command or all commands if none\n" + "\t\tis specified.\n"; @@ -774,8 +744,6 @@ private void printHelp(String cmd) { System.out.println(moveToLocal); } else if ("get".equals(cmd)) { System.out.println(get); - } else if ("test".equals(cmd)) { - System.out.println(test); } else if ("help".equals(cmd)) { System.out.println(help); } else { @@ -798,7 +766,6 @@ private void printHelp(String cmd) { System.out.println(get); System.out.println(copyToLocal); System.out.println(moveToLocal); - System.out.println(test); for (String thisCmdName : commandFactory.getNames()) { printHelp(commandFactory.getInstance(thisCmdName)); @@ -891,9 +858,6 @@ private void printUsage(String cmd) { } else if ("-moveToLocal".equals(cmd)) { System.err.println("Usage: java FsShell" + " [" + cmd + " [-crc] ]"); - } else if ("-test".equals(cmd)) { - System.err.println("Usage: java FsShell" + - " [-test -[ezd] ]"); } else { System.err.println("Usage: java FsShell"); System.err.println(" [-df []]"); @@ -907,7 +871,6 @@ private void printUsage(String cmd) { System.err.println(" [" + GET_SHORT_USAGE + "]"); System.err.println(" [" + COPYTOLOCAL_SHORT_USAGE + "]"); System.err.println(" [-moveToLocal [-crc] ]"); - System.err.println(" [-test -[ezd] ]"); for (String name : commandFactory.getNames()) { instance = commandFactory.getInstance(name); System.err.println(" [" + instance.getUsage() + "]"); @@ -939,7 +902,7 @@ public int run(String argv[]) throws Exception { // // verify that we have enough command line parameters // - if ("-put".equals(cmd) || "-test".equals(cmd) || + if ("-put".equals(cmd) || "-copyFromLocal".equals(cmd) || "-moveFromLocal".equals(cmd)) { if (argv.length < 3) { printUsage(cmd); @@ -1014,8 +977,6 @@ public int run(String argv[]) throws Exception { du(argv, i); } else if ("-dus".equals(cmd)) { dus(argv, i); - } else if ("-test".equals(cmd)) { - exitCode = test(argv, i); } else if ("-help".equals(cmd)) { if (i < argv.length) { printHelp(argv[i]); @@ -1082,30 +1043,7 @@ public static void main(String argv[]) throws Exception { } System.exit(res); } - - /** - * Accumulate exceptions if there is any. Throw them at last. - */ - private abstract class DelayedExceptionThrowing { - abstract void process(Path p, FileSystem srcFs) throws IOException; - - final void globAndProcess(Path srcPattern, FileSystem srcFs - ) throws IOException { - List exceptions = new ArrayList(); - for(Path p : FileUtil.stat2Paths(srcFs.globStatus(srcPattern), - srcPattern)) - try { process(p, srcFs); } - catch(IOException ioe) { exceptions.add(ioe); } - - if (!exceptions.isEmpty()) - if (exceptions.size() == 1) - throw exceptions.get(0); - else - throw new IOException("Multiple IOExceptions: " + exceptions); - } - } - - + /** * Utility class for a line of du output */ diff --git a/src/java/org/apache/hadoop/fs/shell/FsCommand.java b/src/java/org/apache/hadoop/fs/shell/FsCommand.java index 7e2045da0f..29628ea4a9 100644 --- a/src/java/org/apache/hadoop/fs/shell/FsCommand.java +++ b/src/java/org/apache/hadoop/fs/shell/FsCommand.java @@ -53,6 +53,7 @@ public static void registerCommands(CommandFactory factory) { factory.registerCommands(SetReplication.class); factory.registerCommands(Stat.class); factory.registerCommands(Tail.class); + factory.registerCommands(Test.class); factory.registerCommands(Touch.class); } diff --git a/src/java/org/apache/hadoop/fs/shell/Test.java b/src/java/org/apache/hadoop/fs/shell/Test.java new file mode 100644 index 0000000000..309ad053aa --- /dev/null +++ b/src/java/org/apache/hadoop/fs/shell/Test.java @@ -0,0 +1,87 @@ +/** + * 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; + +import java.io.IOException; +import java.util.LinkedList; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.fs.shell.PathExceptions.PathNotFoundException; + +/** + * Perform shell-like file tests + */ +@InterfaceAudience.Private +@InterfaceStability.Unstable + +class Test extends FsCommand { + public static void registerCommands(CommandFactory factory) { + factory.addClass(Test.class, "-test"); + } + + public static final String NAME = "test"; + public static final String USAGE = "-[ezd] "; + public static final String DESCRIPTION = + "If file exists, has zero length, is a directory\n" + + "then return 0, else return 1."; + + private char flag; + + @Override + protected void processOptions(LinkedList args) { + CommandFormat cf = new CommandFormat(null, 1, 1, "e", "d", "z"); + cf.parse(args); + + String[] opts = cf.getOpts().toArray(new String[0]); + switch (opts.length) { + case 0: + throw new IllegalArgumentException("No test flag given"); + case 1: + flag = opts[0].charAt(0); + break; + default: + throw new IllegalArgumentException("Only one test flag is allowed"); + } + } + + @Override + protected void processPath(PathData item) throws IOException { + boolean test = false; + switch (flag) { + case 'e': + test = true; + break; + case 'd': + test = item.stat.isDirectory(); + break; + case 'z': + test = (item.stat.getLen() == 0); + break; + } + if (!test) exitCode = 1; + } + + @Override + protected void processNonexistentPath(PathData item) throws IOException { + // NOTE: errors for FNF is not how the shell works! + if (flag != 'e') displayError(new PathNotFoundException(item.toString())); + exitCode = 1; + } +} diff --git a/src/test/core/org/apache/hadoop/cli/testConf.xml b/src/test/core/org/apache/hadoop/cli/testConf.xml index 3dfa85f0a3..4351f4b3b9 100644 --- a/src/test/core/org/apache/hadoop/cli/testConf.xml +++ b/src/test/core/org/apache/hadoop/cli/testConf.xml @@ -564,7 +564,7 @@ RegexpComparator - ^-test -\[ezd\] <path>: If file \{ exists, has zero length, is a directory( )* + ^-test -\[ezd\] <path>:\s+If file exists, has zero length, is a directory( )* RegexpComparator