HADOOP-9774. RawLocalFileSystem.listStatus() return absolute paths when input path is relative on Windows. Contributed by Shanyu Zhao.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1518865 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ivan Mitic 2013-08-30 01:04:35 +00:00
parent 87e449fd23
commit 2088309d66
5 changed files with 71 additions and 3 deletions

View File

@ -438,6 +438,9 @@ Release 2.1.1-beta - UNRELEASED
HADOOP-9894. Race condition in Shell leads to logged error stream handling
exceptions (Arpit Agarwal)
HADOOP-9774. RawLocalFileSystem.listStatus() return absolute paths when
input path is relative on Windows. (Shanyu Zhao via ivanmi)
Release 2.1.0-beta - 2013-08-22
INCOMPATIBLE CHANGES

View File

@ -182,6 +182,18 @@ public class Path implements Comparable {
/** Construct a Path from components. */
public Path(String scheme, String authority, String path) {
checkPathArg( path );
// add a slash in front of paths with Windows drive letters
if (hasWindowsDrive(path) && path.charAt(0) != '/') {
path = "/" + path;
}
// add "./" in front of Linux relative paths so that a path containing
// a colon e.q. "a:b" will not be interpreted as scheme "a".
if (!WINDOWS && path.charAt(0) != '/') {
path = "./" + path;
}
initialize(scheme, authority, path, null);
}

View File

@ -393,7 +393,7 @@ public class RawLocalFileSystem extends FileSystem {
new DeprecatedRawLocalFileStatus(localf, getDefaultBlockSize(f), this)};
}
File[] names = localf.listFiles();
String[] names = localf.list();
if (names == null) {
return null;
}
@ -401,7 +401,9 @@ public class RawLocalFileSystem extends FileSystem {
int j = 0;
for (int i = 0; i < names.length; i++) {
try {
results[j] = getFileStatus(new Path(names[i].getAbsolutePath()));
// Assemble the path using the Path 3 arg constructor to make sure
// paths with colon are properly resolved on Linux
results[j] = getFileStatus(new Path(f, new Path(null, null, names[i])));
j++;
} catch (FileNotFoundException e) {
// ignore the files not found since the dir list may have have changed

View File

@ -280,6 +280,21 @@ public class TestLocalFileSystem {
stats[0].getPath().toUri().getPath());
}
@Test
public void testListStatusReturnConsistentPathOnWindows() throws IOException {
assumeTrue(Shell.WINDOWS);
String dirNoDriveSpec = TEST_ROOT_DIR;
if (dirNoDriveSpec.charAt(1) == ':')
dirNoDriveSpec = dirNoDriveSpec.substring(2);
File file = new File(dirNoDriveSpec, "foo");
file.mkdirs();
FileStatus[] stats = fileSys.listStatus(new Path(dirNoDriveSpec));
assertEquals("Unexpected number of stats", 1, stats.length);
assertEquals("Bad path from stat", new Path(file.getPath()).toUri().getPath(),
stats[0].getPath().toUri().getPath());
}
@Test(timeout = 10000)
public void testReportChecksumFailure() throws IOException {
base.mkdirs();

View File

@ -158,7 +158,43 @@ public class TestPath extends TestCase {
assertEquals(new Path("c:/foo"), new Path("d:/bar", "c:/foo"));
}
}
@Test (timeout = 30000)
public void testPathThreeArgContructor() {
assertEquals(new Path("foo"), new Path(null, null, "foo"));
assertEquals(new Path("scheme:///foo"), new Path("scheme", null, "/foo"));
assertEquals(
new Path("scheme://authority/foo"),
new Path("scheme", "authority", "/foo"));
if (Path.WINDOWS) {
assertEquals(new Path("c:/foo/bar"), new Path(null, null, "c:/foo/bar"));
assertEquals(new Path("c:/foo/bar"), new Path(null, null, "/c:/foo/bar"));
} else {
assertEquals(new Path("./a:b"), new Path(null, null, "a:b"));
}
// Resolution tests
if (Path.WINDOWS) {
assertEquals(
new Path("c:/foo/bar"),
new Path("/fou", new Path(null, null, "c:/foo/bar")));
assertEquals(
new Path("c:/foo/bar"),
new Path("/fou", new Path(null, null, "/c:/foo/bar")));
assertEquals(
new Path("/foo/bar"),
new Path("/foo", new Path(null, null, "bar")));
} else {
assertEquals(
new Path("/foo/bar/a:b"),
new Path("/foo/bar", new Path(null, null, "a:b")));
assertEquals(
new Path("/a:b"),
new Path("/foo/bar", new Path(null, null, "/a:b")));
}
}
@Test (timeout = 30000)
public void testEquals() {
assertFalse(new Path("/").equals(new Path("/foo")));