diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index f6d5c472641..c44cc8ea27c 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -143,6 +143,9 @@ Trunk (Unreleased) HADOOP-9140 Cleanup rpc PB protos (sanjay Radia) + HADOOP-9147. Add missing fields to FIleStatus.toString. + (Jonathan Allen via suresh) + BUG FIXES HADOOP-9041. FsUrlStreamHandlerFactory could cause an infinite loop in diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java index 5445f6eb155..ea2f1dc6169 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java @@ -349,9 +349,15 @@ public class FileStatus implements Writable, Comparable { sb.append("; replication=" + block_replication); sb.append("; blocksize=" + blocksize); } + sb.append("; modification_time=" + modification_time); + sb.append("; access_time=" + access_time); sb.append("; owner=" + owner); sb.append("; group=" + group); sb.append("; permission=" + permission); + sb.append("; isSymlink=" + isSymlink()); + if(isSymlink()) { + sb.append("; symlink=" + symlink); + } sb.append("}"); return sb.toString(); } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java index c6622d25890..e5380484f97 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java @@ -25,18 +25,34 @@ import java.io.DataInput; import java.io.DataInputStream; import java.io.DataOutput; import java.io.DataOutputStream; +import java.io.IOException; import org.junit.Test; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.FsPermission; public class TestFileStatus { private static final Log LOG = LogFactory.getLog(TestFileStatus.class); + + /** Values for creating {@link FileStatus} in some tests */ + static final int LENGTH = 1; + static final int REPLICATION = 2; + static final long BLKSIZE = 3; + static final long MTIME = 4; + static final long ATIME = 5; + static final String OWNER = "owner"; + static final String GROUP = "group"; + static final FsPermission PERMISSION = FsPermission.valueOf("-rw-rw-rw-"); + static final Path PATH = new Path("path"); + /** + * Check that the write and readField methods work correctly. + */ @Test public void testFileStatusWritable() throws Exception { FileStatus[] tests = { @@ -68,4 +84,181 @@ public class TestFileStatus { iterator++; } } + + /** + * Check that the full parameter constructor works correctly. + */ + @Test + public void constructorFull() throws IOException { + boolean isdir = false; + Path symlink = new Path("symlink"); + FileStatus fileStatus = new FileStatus(LENGTH, isdir, REPLICATION, BLKSIZE, + MTIME, ATIME, PERMISSION, OWNER, GROUP, symlink, PATH); + + validateAccessors(fileStatus, LENGTH, isdir, REPLICATION, BLKSIZE, MTIME, + ATIME, PERMISSION, OWNER, GROUP, symlink, PATH); + } + + /** + * Check that the non-symlink constructor works correctly. + */ + @Test + public void constructorNoSymlink() throws IOException { + boolean isdir = true; + FileStatus fileStatus = new FileStatus(LENGTH, isdir, REPLICATION, BLKSIZE, + MTIME, ATIME, PERMISSION, OWNER, GROUP, PATH); + validateAccessors(fileStatus, LENGTH, isdir, REPLICATION, BLKSIZE, MTIME, + ATIME, PERMISSION, OWNER, GROUP, null, PATH); + } + + /** + * Check that the constructor without owner, group and permissions works + * correctly. + */ + @Test + public void constructorNoOwner() throws IOException { + boolean isdir = true; + FileStatus fileStatus = new FileStatus(LENGTH, isdir, + REPLICATION, BLKSIZE, MTIME, PATH); + validateAccessors(fileStatus, LENGTH, isdir, REPLICATION, BLKSIZE, MTIME, + 0, FsPermission.getDefault(), "", "", null, PATH); + } + + /** + * Check that the no parameter constructor works correctly. + */ + @Test + public void constructorBlank() throws IOException { + FileStatus fileStatus = new FileStatus(); + validateAccessors(fileStatus, 0, false, 0, 0, 0, + 0, FsPermission.getDefault(), "", "", null, null); + } + + /** + * Check that FileStatus are equal if their paths are equal. + */ + @Test + public void testEquals() { + Path path = new Path("path"); + FileStatus fileStatus1 = new FileStatus(1, true, 1, 1, 1, 1, + FsPermission.valueOf("-rw-rw-rw-"), "one", "one", null, path); + FileStatus fileStatus2 = new FileStatus(2, true, 2, 2, 2, 2, + FsPermission.valueOf("---x--x--x"), "two", "two", null, path); + assertEquals(fileStatus1, fileStatus2); + } + + /** + * Check that FileStatus are not equal if their paths are not equal. + */ + @Test + public void testNotEquals() { + Path path1 = new Path("path1"); + Path path2 = new Path("path2"); + FileStatus fileStatus1 = new FileStatus(1, true, 1, 1, 1, 1, + FsPermission.valueOf("-rw-rw-rw-"), "one", "one", null, path1); + FileStatus fileStatus2 = new FileStatus(1, true, 1, 1, 1, 1, + FsPermission.valueOf("-rw-rw-rw-"), "one", "one", null, path2); + assertFalse(fileStatus1.equals(fileStatus2)); + assertFalse(fileStatus2.equals(fileStatus1)); + } + + /** + * Check that toString produces the expected output for a file. + */ + @Test + public void toStringFile() throws IOException { + boolean isdir = false; + FileStatus fileStatus = new FileStatus(LENGTH, isdir, REPLICATION, BLKSIZE, + MTIME, ATIME, PERMISSION, OWNER, GROUP, null, PATH); + validateToString(fileStatus); + } + + /** + * Check that toString produces the expected output for a directory. + */ + @Test + public void toStringDir() throws IOException { + FileStatus fileStatus = new FileStatus(LENGTH, true, REPLICATION, BLKSIZE, + MTIME, ATIME, PERMISSION, OWNER, GROUP, null, PATH); + validateToString(fileStatus); + } + + /** + * Check that toString produces the expected output for a symlink. + */ + @Test + public void toStringSymlink() throws IOException { + boolean isdir = false; + Path symlink = new Path("symlink"); + FileStatus fileStatus = new FileStatus(LENGTH, isdir, REPLICATION, BLKSIZE, + MTIME, ATIME, PERMISSION, OWNER, GROUP, symlink, PATH); + validateToString(fileStatus); + } + + /** + * Validate the accessors for FileStatus. + * @param fileStatus FileStatus to checked + * @param length expected length + * @param isdir expected isDirectory + * @param replication expected replication + * @param blocksize expected blocksize + * @param mtime expected modification time + * @param atime expected access time + * @param permission expected permission + * @param owner expected owner + * @param group expected group + * @param symlink expected symlink + * @param path expected path + */ + private void validateAccessors(FileStatus fileStatus, + long length, boolean isdir, int replication, long blocksize, long mtime, + long atime, FsPermission permission, String owner, String group, + Path symlink, Path path) throws IOException { + + assertEquals(length, fileStatus.getLen()); + assertEquals(isdir, fileStatus.isDirectory()); + assertEquals(replication, fileStatus.getReplication()); + assertEquals(blocksize, fileStatus.getBlockSize()); + assertEquals(mtime, fileStatus.getModificationTime()); + assertEquals(atime, fileStatus.getAccessTime()); + assertEquals(permission, fileStatus.getPermission()); + assertEquals(owner, fileStatus.getOwner()); + assertEquals(group, fileStatus.getGroup()); + if(symlink == null) { + assertFalse(fileStatus.isSymlink()); + } else { + assertTrue(fileStatus.isSymlink()); + assertEquals(symlink, fileStatus.getSymlink()); + } + assertEquals(path, fileStatus.getPath()); + } + + /** + * Validates the toString method for FileStatus. + * @param fileStatus FileStatus to be validated + */ + private void validateToString(FileStatus fileStatus) throws IOException { + StringBuilder expected = new StringBuilder(); + expected.append("FileStatus{"); + expected.append("path=").append(fileStatus.getPath()).append("; "); + expected.append("isDirectory=").append(fileStatus.isDirectory()).append("; "); + if(!fileStatus.isDirectory()) { + expected.append("length=").append(fileStatus.getLen()).append("; "); + expected.append("replication=").append(fileStatus.getReplication()).append("; "); + expected.append("blocksize=").append(fileStatus.getBlockSize()).append("; "); + } + expected.append("modification_time=").append(fileStatus.getModificationTime()).append("; "); + expected.append("access_time=").append(fileStatus.getAccessTime()).append("; "); + expected.append("owner=").append(fileStatus.getOwner()).append("; "); + expected.append("group=").append(fileStatus.getGroup()).append("; "); + expected.append("permission=").append(fileStatus.getPermission()).append("; "); + if(fileStatus.isSymlink()) { + expected.append("isSymlink=").append(true).append("; "); + expected.append("symlink=").append(fileStatus.getSymlink()).append("}"); + } else { + expected.append("isSymlink=").append(false).append("}"); + } + + assertEquals(expected.toString(), fileStatus.toString()); + } }