HDFS-13661. Ls command with e option fails when the filesystem is not HDFS.
(cherry picked from commit d963575918
)
This commit is contained in:
parent
956e6cfee6
commit
9f30916a1b
|
@ -25,6 +25,7 @@ import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.util.StringUtils;
|
import org.apache.hadoop.util.StringUtils;
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ class Ls extends FsCommand {
|
||||||
* Should display only paths of files and directories.
|
* Should display only paths of files and directories.
|
||||||
* @return true display paths only, false display all fields
|
* @return true display paths only, false display all fields
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
boolean isPathOnly() {
|
boolean isPathOnly() {
|
||||||
return this.pathOnly;
|
return this.pathOnly;
|
||||||
}
|
}
|
||||||
|
@ -164,7 +165,7 @@ class Ls extends FsCommand {
|
||||||
* Should the contents of the directory be shown or just the directory?
|
* Should the contents of the directory be shown or just the directory?
|
||||||
* @return true if directory contents, false if just directory
|
* @return true if directory contents, false if just directory
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
boolean isDirRecurse() {
|
boolean isDirRecurse() {
|
||||||
return this.dirRecurse;
|
return this.dirRecurse;
|
||||||
}
|
}
|
||||||
|
@ -173,12 +174,12 @@ class Ls extends FsCommand {
|
||||||
* Should file sizes be returned in human readable format rather than bytes?
|
* Should file sizes be returned in human readable format rather than bytes?
|
||||||
* @return true is human readable, false if bytes
|
* @return true is human readable, false if bytes
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
boolean isHumanReadable() {
|
boolean isHumanReadable() {
|
||||||
return this.humanReadable;
|
return this.humanReadable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
private boolean isHideNonPrintable() {
|
private boolean isHideNonPrintable() {
|
||||||
return hideNonPrintable;
|
return hideNonPrintable;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +188,7 @@ class Ls extends FsCommand {
|
||||||
* Should directory contents be displayed in reverse order
|
* Should directory contents be displayed in reverse order
|
||||||
* @return true reverse order, false default order
|
* @return true reverse order, false default order
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
boolean isOrderReverse() {
|
boolean isOrderReverse() {
|
||||||
return this.orderReverse;
|
return this.orderReverse;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,7 @@ class Ls extends FsCommand {
|
||||||
* Should directory contents be displayed in mtime order.
|
* Should directory contents be displayed in mtime order.
|
||||||
* @return true mtime order, false default order
|
* @return true mtime order, false default order
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
boolean isOrderTime() {
|
boolean isOrderTime() {
|
||||||
return this.orderTime;
|
return this.orderTime;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,7 @@ class Ls extends FsCommand {
|
||||||
* Should directory contents be displayed in size order.
|
* Should directory contents be displayed in size order.
|
||||||
* @return true size order, false default order
|
* @return true size order, false default order
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
boolean isOrderSize() {
|
boolean isOrderSize() {
|
||||||
return this.orderSize;
|
return this.orderSize;
|
||||||
}
|
}
|
||||||
|
@ -214,13 +215,28 @@ class Ls extends FsCommand {
|
||||||
* Should access time be used rather than modification time.
|
* Should access time be used rather than modification time.
|
||||||
* @return true use access time, false use modification time
|
* @return true use access time, false use modification time
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@VisibleForTesting
|
||||||
boolean isUseAtime() {
|
boolean isUseAtime() {
|
||||||
return this.useAtime;
|
return this.useAtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should EC policies be displayed.
|
||||||
|
* @return true display EC policies, false doesn't display EC policies
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isDisplayECPolicy() {
|
||||||
|
return this.displayECPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processPathArgument(PathData item) throws IOException {
|
protected void processPathArgument(PathData item) throws IOException {
|
||||||
|
if (isDisplayECPolicy() && item.fs.getContentSummary(item.path)
|
||||||
|
.getErasureCodingPolicy() == null) {
|
||||||
|
throw new UnsupportedOperationException("FileSystem "
|
||||||
|
+ item.fs.getUri() + " does not support Erasure Coding");
|
||||||
|
}
|
||||||
|
|
||||||
// implicitly recurse once for cmdline directories
|
// implicitly recurse once for cmdline directories
|
||||||
if (dirRecurse && item.stat.isDirectory()) {
|
if (dirRecurse && item.stat.isDirectory()) {
|
||||||
recursePath(item);
|
recursePath(item);
|
||||||
|
@ -298,19 +314,19 @@ class Ls extends FsCommand {
|
||||||
StringBuilder fmt = new StringBuilder();
|
StringBuilder fmt = new StringBuilder();
|
||||||
fmt.append("%s%s"); // permission string
|
fmt.append("%s%s"); // permission string
|
||||||
fmt.append("%" + maxRepl + "s ");
|
fmt.append("%" + maxRepl + "s ");
|
||||||
|
fmt.append((maxOwner > 0) ? "%-" + maxOwner + "s " : "%s");
|
||||||
|
fmt.append((maxGroup > 0) ? "%-" + maxGroup + "s " : "%s");
|
||||||
// Do not use '%-0s' as a formatting conversion, since it will throw a
|
// Do not use '%-0s' as a formatting conversion, since it will throw a
|
||||||
// a MissingFormatWidthException if it is used in String.format().
|
// a MissingFormatWidthException if it is used in String.format().
|
||||||
// http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#intFlags
|
// http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#intFlags
|
||||||
if(displayECPolicy){
|
if(displayECPolicy){
|
||||||
int maxEC=0;
|
int maxEC = 0;
|
||||||
for (PathData item : items) {
|
for (PathData item : items) {
|
||||||
ContentSummary contentSummary = item.fs.getContentSummary(item.path);
|
ContentSummary contentSummary = item.fs.getContentSummary(item.path);
|
||||||
maxEC=maxLength(maxEC,contentSummary.getErasureCodingPolicy().length());
|
maxEC=maxLength(maxEC,contentSummary.getErasureCodingPolicy().length());
|
||||||
}
|
}
|
||||||
fmt.append(" %"+maxEC+"s ");
|
fmt.append((maxEC > 0) ? "%-" + maxEC + "s " : "%s");
|
||||||
}
|
}
|
||||||
fmt.append((maxOwner > 0) ? "%-" + maxOwner + "s " : "%s");
|
|
||||||
fmt.append((maxGroup > 0) ? "%-" + maxGroup + "s " : "%s");
|
|
||||||
fmt.append("%" + maxLen + "s ");
|
fmt.append("%" + maxLen + "s ");
|
||||||
fmt.append("%s %s"); // mod time & path
|
fmt.append("%s %s"); // mod time & path
|
||||||
lineFormat = fmt.toString();
|
lineFormat = fmt.toString();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.fs.shell;
|
package org.apache.hadoop.fs.shell;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY;
|
||||||
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SHELL_MISSING_DEFAULT_FS_WARNING_KEY;
|
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SHELL_MISSING_DEFAULT_FS_WARNING_KEY;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
|
@ -26,6 +27,7 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -57,17 +59,18 @@ public class TestLs {
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setup() throws IOException {
|
public static void setup() throws IOException {
|
||||||
conf = new Configuration();
|
conf = new Configuration();
|
||||||
conf.set("fs.defaultFS", "mockfs:///");
|
conf.set(FS_DEFAULT_NAME_KEY, "mockfs:///");
|
||||||
conf.setClass("fs.mockfs.impl", MockFileSystem.class, FileSystem.class);
|
conf.setClass("fs.mockfs.impl", MockFileSystem.class, FileSystem.class);
|
||||||
mockFs = mock(FileSystem.class);
|
mockFs = mock(FileSystem.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void resetMock() throws IOException {
|
public void resetMock() throws IOException, URISyntaxException {
|
||||||
reset(mockFs);
|
reset(mockFs);
|
||||||
AclStatus mockAclStatus = mock(AclStatus.class);
|
AclStatus mockAclStatus = mock(AclStatus.class);
|
||||||
when(mockAclStatus.getEntries()).thenReturn(new ArrayList<AclEntry>());
|
when(mockAclStatus.getEntries()).thenReturn(new ArrayList<AclEntry>());
|
||||||
when(mockFs.getAclStatus(any(Path.class))).thenReturn(mockAclStatus);
|
when(mockFs.getAclStatus(any(Path.class))).thenReturn(mockAclStatus);
|
||||||
|
when(mockFs.getUri()).thenReturn(new URI(conf.get(FS_DEFAULT_NAME_KEY)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that default options are correct
|
// check that default options are correct
|
||||||
|
@ -84,6 +87,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the -C option is recognised
|
// check the -C option is recognised
|
||||||
|
@ -101,6 +105,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the -d option is recognised
|
// check the -d option is recognised
|
||||||
|
@ -118,6 +123,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the -h option is recognised
|
// check the -h option is recognised
|
||||||
|
@ -135,6 +141,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the -R option is recognised
|
// check the -R option is recognised
|
||||||
|
@ -152,6 +159,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the -r option is recognised
|
// check the -r option is recognised
|
||||||
|
@ -169,6 +177,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the -S option is recognised
|
// check the -S option is recognised
|
||||||
|
@ -186,6 +195,7 @@ public class TestLs {
|
||||||
assertTrue(ls.isOrderSize());
|
assertTrue(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the -t option is recognised
|
// check the -t option is recognised
|
||||||
|
@ -203,6 +213,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertTrue(ls.isOrderTime());
|
assertTrue(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the precedence of the -t and -S options
|
// check the precedence of the -t and -S options
|
||||||
|
@ -221,6 +232,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertTrue(ls.isOrderTime());
|
assertTrue(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the precedence of the -t, -S and -r options
|
// check the precedence of the -t, -S and -r options
|
||||||
|
@ -240,6 +252,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertTrue(ls.isOrderTime());
|
assertTrue(ls.isOrderTime());
|
||||||
assertFalse(ls.isUseAtime());
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// chheck the -u option is recognised
|
// chheck the -u option is recognised
|
||||||
|
@ -257,6 +270,25 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize());
|
assertFalse(ls.isOrderSize());
|
||||||
assertFalse(ls.isOrderTime());
|
assertFalse(ls.isOrderTime());
|
||||||
assertTrue(ls.isUseAtime());
|
assertTrue(ls.isUseAtime());
|
||||||
|
assertFalse(ls.isDisplayECPolicy());
|
||||||
|
}
|
||||||
|
|
||||||
|
// chheck the -e option is recognised
|
||||||
|
@Test
|
||||||
|
public void processOptionsDisplayECPolicy() throws IOException {
|
||||||
|
LinkedList<String> options = new LinkedList<String>();
|
||||||
|
options.add("-e");
|
||||||
|
Ls ls = new Ls();
|
||||||
|
ls.processOptions(options);
|
||||||
|
assertFalse(ls.isPathOnly());
|
||||||
|
assertTrue(ls.isDirRecurse());
|
||||||
|
assertFalse(ls.isHumanReadable());
|
||||||
|
assertFalse(ls.isRecursive());
|
||||||
|
assertFalse(ls.isOrderReverse());
|
||||||
|
assertFalse(ls.isOrderSize());
|
||||||
|
assertFalse(ls.isOrderTime());
|
||||||
|
assertFalse(ls.isUseAtime());
|
||||||
|
assertTrue(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check all options is handled correctly
|
// check all options is handled correctly
|
||||||
|
@ -271,6 +303,7 @@ public class TestLs {
|
||||||
options.add("-t"); // time order
|
options.add("-t"); // time order
|
||||||
options.add("-S"); // size order
|
options.add("-S"); // size order
|
||||||
options.add("-u"); // show atime
|
options.add("-u"); // show atime
|
||||||
|
options.add("-e"); // show EC policies
|
||||||
Ls ls = new Ls();
|
Ls ls = new Ls();
|
||||||
ls.processOptions(options);
|
ls.processOptions(options);
|
||||||
assertTrue(ls.isPathOnly());
|
assertTrue(ls.isPathOnly());
|
||||||
|
@ -281,6 +314,7 @@ public class TestLs {
|
||||||
assertFalse(ls.isOrderSize()); // -t overrules -S
|
assertFalse(ls.isOrderSize()); // -t overrules -S
|
||||||
assertTrue(ls.isOrderTime());
|
assertTrue(ls.isOrderTime());
|
||||||
assertTrue(ls.isUseAtime());
|
assertTrue(ls.isUseAtime());
|
||||||
|
assertTrue(ls.isDisplayECPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check listing of a single file
|
// check listing of a single file
|
||||||
|
@ -1100,6 +1134,35 @@ public class TestLs {
|
||||||
assertEquals("Ls.getName", expected, actual);
|
assertEquals("Ls.getName", expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void processPathFileDisplayECPolicyWhenUnsupported()
|
||||||
|
throws IOException {
|
||||||
|
TestFile testFile = new TestFile("testDirectory", "testFile");
|
||||||
|
LinkedList<PathData> pathData = new LinkedList<PathData>();
|
||||||
|
pathData.add(testFile.getPathData());
|
||||||
|
Ls ls = new Ls();
|
||||||
|
LinkedList<String> options = new LinkedList<String>();
|
||||||
|
options.add("-e");
|
||||||
|
ls.processOptions(options);
|
||||||
|
ls.processArguments(pathData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void processPathDirDisplayECPolicyWhenUnsupported()
|
||||||
|
throws IOException {
|
||||||
|
TestFile testFile = new TestFile("testDirectory", "testFile");
|
||||||
|
TestFile testDir = new TestFile("", "testDirectory");
|
||||||
|
testDir.setIsDir(true);
|
||||||
|
testDir.addContents(testFile);
|
||||||
|
LinkedList<PathData> pathData = new LinkedList<PathData>();
|
||||||
|
pathData.add(testDir.getPathData());
|
||||||
|
Ls ls = new Ls();
|
||||||
|
LinkedList<String> options = new LinkedList<String>();
|
||||||
|
options.add("-e");
|
||||||
|
ls.processOptions(options);
|
||||||
|
ls.processArguments(pathData);
|
||||||
|
}
|
||||||
|
|
||||||
// test class representing a file to be listed
|
// test class representing a file to be listed
|
||||||
static class TestFile {
|
static class TestFile {
|
||||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
|
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
|
||||||
|
|
Loading…
Reference in New Issue