diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 4c7d30c75dc..7a88266cade 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -25,6 +25,12 @@ Release 2.2.0 - UNRELEASED HADOOP-9661. Allow metrics sources to be extended. (sandyr via tucu) + HADOOP-9370. Write FSWrapper class to wrap FileSystem and FileContext for + better test coverage. (Andrew Wang via Colin Patrick McCabe) + + HADOOP-9355. Abstract symlink tests to use either FileContext or + FileSystem. (Andrew Wang via Colin Patrick McCabe) + OPTIMIZATIONS BUG FIXES @@ -147,9 +153,6 @@ Release 2.1.0-beta - UNRELEASED HADOOP-9619 Mark stability of .proto files (sanjay Radia) - HADOOP-9370. Write FSWrapper class to wrap FileSystem and FileContext for - better test coverage. (Andrew Wang via Colin Patrick McCabe) - OPTIMIZATIONS HADOOP-9150. Avoid unnecessary DNS resolution attempts for logical URIs diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/FileContextSymlinkBaseTest.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/SymlinkBaseTest.java similarity index 61% rename from hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/FileContextSymlinkBaseTest.java rename to hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/SymlinkBaseTest.java index fd7555690e4..c937646c2b9 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/FileContextSymlinkBaseTest.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/SymlinkBaseTest.java @@ -27,7 +27,7 @@ import org.apache.hadoop.fs.CreateFlag; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.FSDataOutputStream; -import static org.apache.hadoop.fs.FileContextTestHelper.*; +import org.apache.hadoop.test.GenericTestUtils; import static org.junit.Assert.*; import static org.junit.Assume.assumeTrue; @@ -36,15 +36,15 @@ import org.junit.After; /** - * Test symbolic links using FileContext. + * Base test for symbolic links */ -public abstract class FileContextSymlinkBaseTest { +public abstract class SymlinkBaseTest { static final long seed = 0xDEADBEEFL; static final int blockSize = 8192; static final int fileSize = 16384; - - protected final FileContextTestHelper fileContextTestHelper = new FileContextTestHelper(); - protected static FileContext fc; + static final int numBlocks = fileSize / blockSize; + + protected static FSTestWrapper wrapper; abstract protected String getScheme(); abstract protected String testBaseDir1() throws IOException; @@ -55,117 +55,111 @@ protected IOException unwrapException(IOException e) { return e; } - protected static void createAndWriteFile(FileContext fc, Path p) - throws IOException { - createFile(fc, p, fileSize / blockSize, - CreateOpts.createParent(), - CreateOpts.repFac((short) 1), - CreateOpts.blockSize(blockSize)); + protected static void createAndWriteFile(Path p) throws IOException { + createAndWriteFile(wrapper, p); } - protected static void createAndWriteFile(Path p) throws IOException { - createAndWriteFile(fc, p); + protected static void createAndWriteFile(FSTestWrapper wrapper, Path p) + throws IOException { + wrapper.createFile(p, numBlocks, CreateOpts.createParent(), + CreateOpts.repFac((short) 1), CreateOpts.blockSize(blockSize)); } protected static void readFile(Path p) throws IOException { - FileContextTestHelper.readFile(fc, p, fileSize); - } - - protected static void readFile(FileContext fc, Path p) throws IOException { - FileContextTestHelper.readFile(fc, p, fileSize); + wrapper.readFile(p, fileSize); } protected static void appendToFile(Path p) throws IOException { - FileContextTestHelper.appendToFile(fc, p, fileSize / blockSize, + wrapper.appendToFile(p, numBlocks, CreateOpts.blockSize(blockSize)); } @Before public void setUp() throws Exception { - fc.mkdir(new Path(testBaseDir1()), FileContext.DEFAULT_PERM, true); - fc.mkdir(new Path(testBaseDir2()), FileContext.DEFAULT_PERM, true); + wrapper.mkdir(new Path(testBaseDir1()), FileContext.DEFAULT_PERM, true); + wrapper.mkdir(new Path(testBaseDir2()), FileContext.DEFAULT_PERM, true); } @After - public void tearDown() throws Exception { - fc.delete(new Path(testBaseDir1()), true); - fc.delete(new Path(testBaseDir2()), true); - } - - @Test - /** The root is not a symlink */ - public void testStatRoot() throws IOException { - assertFalse(fc.getFileLinkStatus(new Path("/")).isSymlink()); + public void tearDown() throws Exception { + wrapper.delete(new Path(testBaseDir1()), true); + wrapper.delete(new Path(testBaseDir2()), true); } - @Test + @Test(timeout=10000) + /** The root is not a symlink */ + public void testStatRoot() throws IOException { + assertFalse(wrapper.getFileLinkStatus(new Path("/")).isSymlink()); + } + + @Test(timeout=10000) /** Test setWorkingDirectory not resolves symlinks */ public void testSetWDNotResolvesLinks() throws IOException { Path dir = new Path(testBaseDir1()); Path linkToDir = new Path(testBaseDir1()+"/link"); - fc.createSymlink(dir, linkToDir, false); - fc.setWorkingDirectory(linkToDir); - assertEquals(linkToDir.getName(), fc.getWorkingDirectory().getName()); + wrapper.createSymlink(dir, linkToDir, false); + wrapper.setWorkingDirectory(linkToDir); + assertEquals(linkToDir.getName(), wrapper.getWorkingDirectory().getName()); } - @Test + @Test(timeout=10000) /** Test create a dangling link */ public void testCreateDanglingLink() throws IOException { Path file = new Path("/noSuchFile"); - Path link = new Path(testBaseDir1()+"/link"); - fc.createSymlink(file, link, false); + Path link = new Path(testBaseDir1()+"/link"); + wrapper.createSymlink(file, link, false); try { - fc.getFileStatus(link); + wrapper.getFileStatus(link); fail("Got file status of non-existant file"); } catch (FileNotFoundException f) { // Expected } - fc.delete(link, false); - } + wrapper.delete(link, false); + } - @Test + @Test(timeout=10000) /** Test create a link to null and empty path */ public void testCreateLinkToNullEmpty() throws IOException { Path link = new Path(testBaseDir1()+"/link"); try { - fc.createSymlink(null, link, false); + wrapper.createSymlink(null, link, false); fail("Can't create symlink to null"); } catch (java.lang.NullPointerException e) { // Expected, create* with null yields NPEs } try { - fc.createSymlink(new Path(""), link, false); + wrapper.createSymlink(new Path(""), link, false); fail("Can't create symlink to empty string"); } catch (java.lang.IllegalArgumentException e) { // Expected, Path("") is invalid } - } - - @Test + } + + @Test(timeout=10000) /** Create a link with createParent set */ public void testCreateLinkCanCreateParent() throws IOException { Path file = new Path(testBaseDir1()+"/file"); Path link = new Path(testBaseDir2()+"/linkToFile"); createAndWriteFile(file); - fc.delete(new Path(testBaseDir2()), true); + wrapper.delete(new Path(testBaseDir2()), true); try { - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); fail("Created link without first creating parent dir"); } catch (IOException x) { // Expected. Need to create testBaseDir2() first. } - assertFalse(exists(fc, new Path(testBaseDir2()))); - fc.createSymlink(file, link, true); + assertFalse(wrapper.exists(new Path(testBaseDir2()))); + wrapper.createSymlink(file, link, true); readFile(link); } - @Test + @Test(timeout=10000) /** Try to create a directory given a path that refers to a symlink */ public void testMkdirExistingLink() throws IOException { Path dir = new Path(testBaseDir1()+"/link"); - fc.createSymlink(new Path("/doesNotExist"), dir, false); + wrapper.createSymlink(new Path("/doesNotExist"), dir, false); try { - fc.mkdir(dir, FileContext.DEFAULT_PERM, false); + wrapper.mkdir(dir, FileContext.DEFAULT_PERM, false); fail("Created a dir where a symlink exists"); } catch (FileAlreadyExistsException e) { // Expected. The symlink already exists. @@ -175,15 +169,15 @@ public void testMkdirExistingLink() throws IOException { } } - @Test + @Test(timeout=10000) /** Try to create a file with parent that is a dangling link */ public void testCreateFileViaDanglingLinkParent() throws IOException { Path dir = new Path(testBaseDir1()+"/dangling"); Path file = new Path(testBaseDir1()+"/dangling/file"); - fc.createSymlink(new Path("/doesNotExist"), dir, false); + wrapper.createSymlink(new Path("/doesNotExist"), dir, false); FSDataOutputStream out; try { - out = fc.create(file, EnumSet.of(CreateFlag.CREATE), + out = wrapper.create(file, EnumSet.of(CreateFlag.CREATE), CreateOpts.repFac((short) 1), CreateOpts.blockSize(blockSize)); out.close(); @@ -193,15 +187,15 @@ public void testCreateFileViaDanglingLinkParent() throws IOException { } } - @Test + @Test(timeout=10000) /** Delete a link */ public void testDeleteLink() throws IOException { Path file = new Path(testBaseDir1()+"/file"); - Path link = new Path(testBaseDir1()+"/linkToFile"); - createAndWriteFile(file); - fc.createSymlink(file, link, false); + Path link = new Path(testBaseDir1()+"/linkToFile"); + createAndWriteFile(file); + wrapper.createSymlink(file, link, false); readFile(link); - fc.delete(link, false); + wrapper.delete(link, false); try { readFile(link); fail("Symlink should have been deleted"); @@ -209,241 +203,256 @@ public void testDeleteLink() throws IOException { // Expected } // If we deleted the link we can put it back - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); } - - @Test + + @Test(timeout=10000) /** Ensure open resolves symlinks */ public void testOpenResolvesLinks() throws IOException { Path file = new Path(testBaseDir1()+"/noSuchFile"); Path link = new Path(testBaseDir1()+"/link"); - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); try { - fc.open(link); + wrapper.open(link); fail("link target does not exist"); } catch (FileNotFoundException x) { // Expected } - fc.delete(link, false); + wrapper.delete(link, false); } - @Test + @Test(timeout=10000) /** Stat a link to a file */ public void testStatLinkToFile() throws IOException { Path file = new Path(testBaseDir1()+"/file"); - Path linkToFile = new Path(testBaseDir1()+"/linkToFile"); + Path linkToFile = new Path(testBaseDir1()+"/linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, linkToFile, false); - assertFalse(fc.getFileLinkStatus(linkToFile).isDirectory()); - assertTrue(isSymlink(fc, linkToFile)); - assertTrue(isFile(fc, linkToFile)); - assertFalse(isDir(fc, linkToFile)); - assertEquals(file.toUri().getPath(), - fc.getLinkTarget(linkToFile).toString()); + wrapper.createSymlink(file, linkToFile, false); + assertFalse(wrapper.getFileLinkStatus(linkToFile).isDirectory()); + assertTrue(wrapper.isSymlink(linkToFile)); + assertTrue(wrapper.isFile(linkToFile)); + assertFalse(wrapper.isDir(linkToFile)); + assertEquals(file.toUri().getPath(), + wrapper.getLinkTarget(linkToFile).toString()); // The local file system does not fully resolve the link // when obtaining the file status if (!"file".equals(getScheme())) { - assertEquals(fc.getFileStatus(file), fc.getFileStatus(linkToFile)); - assertEquals(fc.makeQualified(file), - fc.getFileStatus(linkToFile).getPath()); - assertEquals(fc.makeQualified(linkToFile), - fc.getFileLinkStatus(linkToFile).getPath()); + assertEquals(wrapper.getFileStatus(file), + wrapper.getFileStatus(linkToFile)); + assertEquals(wrapper.makeQualified(file), + wrapper.getFileStatus(linkToFile).getPath()); + assertEquals(wrapper.makeQualified(linkToFile), + wrapper.getFileLinkStatus(linkToFile).getPath()); } } - @Test + @Test(timeout=10000) /** Stat a relative link to a file */ public void testStatRelLinkToFile() throws IOException { assumeTrue(!"file".equals(getScheme())); - Path baseDir = new Path(testBaseDir1()); Path file = new Path(testBaseDir1(), "file"); Path linkToFile = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(new Path("file"), linkToFile, false); - assertEquals(fc.getFileStatus(file), fc.getFileStatus(linkToFile)); - assertEquals(fc.makeQualified(file), - fc.getFileStatus(linkToFile).getPath()); - assertEquals(fc.makeQualified(linkToFile), - fc.getFileLinkStatus(linkToFile).getPath()); + wrapper.createSymlink(new Path("file"), linkToFile, false); + assertEquals(wrapper.getFileStatus(file), + wrapper.getFileStatus(linkToFile)); + assertEquals(wrapper.makeQualified(file), + wrapper.getFileStatus(linkToFile).getPath()); + assertEquals(wrapper.makeQualified(linkToFile), + wrapper.getFileLinkStatus(linkToFile).getPath()); } - @Test + @Test(timeout=10000) /** Stat a link to a directory */ public void testStatLinkToDir() throws IOException { Path dir = new Path(testBaseDir1()); Path linkToDir = new Path(testBaseDir1()+"/linkToDir"); - fc.createSymlink(dir, linkToDir, false); + wrapper.createSymlink(dir, linkToDir, false); - assertFalse(fc.getFileStatus(linkToDir).isSymlink()); - assertTrue(isDir(fc, linkToDir)); - assertFalse(fc.getFileLinkStatus(linkToDir).isDirectory()); - assertTrue(fc.getFileLinkStatus(linkToDir).isSymlink()); + assertFalse(wrapper.getFileStatus(linkToDir).isSymlink()); + assertTrue(wrapper.isDir(linkToDir)); + assertFalse(wrapper.getFileLinkStatus(linkToDir).isDirectory()); + assertTrue(wrapper.getFileLinkStatus(linkToDir).isSymlink()); - assertFalse(isFile(fc, linkToDir)); - assertTrue(isDir(fc, linkToDir)); + assertFalse(wrapper.isFile(linkToDir)); + assertTrue(wrapper.isDir(linkToDir)); - assertEquals(dir.toUri().getPath(), - fc.getLinkTarget(linkToDir).toString()); + assertEquals(dir.toUri().getPath(), + wrapper.getLinkTarget(linkToDir).toString()); } - @Test + @Test(timeout=10000) /** Stat a dangling link */ public void testStatDanglingLink() throws IOException { Path file = new Path("/noSuchFile"); - Path link = new Path(testBaseDir1()+"/link"); - fc.createSymlink(file, link, false); - assertFalse(fc.getFileLinkStatus(link).isDirectory()); - assertTrue(fc.getFileLinkStatus(link).isSymlink()); + Path link = new Path(testBaseDir1()+"/link"); + wrapper.createSymlink(file, link, false); + assertFalse(wrapper.getFileLinkStatus(link).isDirectory()); + assertTrue(wrapper.getFileLinkStatus(link).isSymlink()); } - - @Test + + @Test(timeout=10000) /** Stat a non-existant file */ - public void testStatNonExistantFiles() throws IOException { + public void testStatNonExistentFiles() throws IOException { Path fileAbs = new Path("/doesNotExist"); try { - fc.getFileLinkStatus(fileAbs); + wrapper.getFileLinkStatus(fileAbs); fail("Got FileStatus for non-existant file"); } catch (FileNotFoundException f) { // Expected } try { - fc.getLinkTarget(fileAbs); + wrapper.getLinkTarget(fileAbs); fail("Got link target for non-existant file"); } catch (FileNotFoundException f) { // Expected } } - @Test + @Test(timeout=10000) /** Test stat'ing a regular file and directory */ public void testStatNonLinks() throws IOException { Path dir = new Path(testBaseDir1()); Path file = new Path(testBaseDir1()+"/file"); createAndWriteFile(file); try { - fc.getLinkTarget(dir); + wrapper.getLinkTarget(dir); fail("Lstat'd a non-symlink"); } catch (IOException e) { // Expected. } try { - fc.getLinkTarget(file); + wrapper.getLinkTarget(file); fail("Lstat'd a non-symlink"); } catch (IOException e) { // Expected. } } - - @Test + + @Test(timeout=10000) /** Test links that link to each other */ public void testRecursiveLinks() throws IOException { Path link1 = new Path(testBaseDir1()+"/link1"); Path link2 = new Path(testBaseDir1()+"/link2"); - fc.createSymlink(link1, link2, false); - fc.createSymlink(link2, link1, false); + wrapper.createSymlink(link1, link2, false); + wrapper.createSymlink(link2, link1, false); try { readFile(link1); fail("Read recursive link"); } catch (FileNotFoundException f) { - // LocalFs throws sub class of IOException, since File.exists - // returns false for a link to link. + // LocalFs throws sub class of IOException, since File.exists + // returns false for a link to link. } catch (IOException x) { assertEquals("Possible cyclic loop while following symbolic link "+ link1.toString(), x.getMessage()); - } + } } /* Assert that the given link to a file behaves as expected. */ - private void checkLink(Path linkAbs, Path expectedTarget, Path targetQual) - throws IOException { + private void checkLink(Path linkAbs, Path expectedTarget, Path targetQual) + throws IOException { Path dir = new Path(testBaseDir1()); // isFile/Directory - assertTrue(isFile(fc, linkAbs)); - assertFalse(isDir(fc, linkAbs)); + assertTrue(wrapper.isFile(linkAbs)); + assertFalse(wrapper.isDir(linkAbs)); - // Check getFileStatus - assertFalse(fc.getFileStatus(linkAbs).isSymlink()); - assertFalse(fc.getFileStatus(linkAbs).isDirectory()); - assertEquals(fileSize, fc.getFileStatus(linkAbs).getLen()); + // Check getFileStatus + assertFalse(wrapper.getFileStatus(linkAbs).isSymlink()); + assertFalse(wrapper.getFileStatus(linkAbs).isDirectory()); + assertEquals(fileSize, wrapper.getFileStatus(linkAbs).getLen()); // Check getFileLinkStatus - assertTrue(isSymlink(fc, linkAbs)); - assertFalse(fc.getFileLinkStatus(linkAbs).isDirectory()); + assertTrue(wrapper.isSymlink(linkAbs)); + assertFalse(wrapper.getFileLinkStatus(linkAbs).isDirectory()); // Check getSymlink always returns a qualified target, except // when partially qualified paths are used (see tests below). - assertEquals(targetQual.toString(), - fc.getFileLinkStatus(linkAbs).getSymlink().toString()); - assertEquals(targetQual, fc.getFileLinkStatus(linkAbs).getSymlink()); - // Check that the target is qualified using the file system of the - // path used to access the link (if the link target was not specified + assertEquals(targetQual.toString(), + wrapper.getFileLinkStatus(linkAbs).getSymlink().toString()); + assertEquals(targetQual, wrapper.getFileLinkStatus(linkAbs).getSymlink()); + // Check that the target is qualified using the file system of the + // path used to access the link (if the link target was not specified // fully qualified, in that case we use the link target verbatim). if (!"file".equals(getScheme())) { FileContext localFc = FileContext.getLocalFSFileContext(); Path linkQual = new Path(testURI().toString(), linkAbs); - assertEquals(targetQual, + assertEquals(targetQual, localFc.getFileLinkStatus(linkQual).getSymlink()); } - + // Check getLinkTarget - assertEquals(expectedTarget, fc.getLinkTarget(linkAbs)); - + assertEquals(expectedTarget, wrapper.getLinkTarget(linkAbs)); + // Now read using all path types.. - fc.setWorkingDirectory(dir); + wrapper.setWorkingDirectory(dir); readFile(new Path("linkToFile")); readFile(linkAbs); // And fully qualified.. (NB: for local fs this is partially qualified) readFile(new Path(testURI().toString(), linkAbs)); // And partially qualified.. - boolean failureExpected = "file".equals(getScheme()) ? false : true; + boolean failureExpected = true; + // local files are special cased, no authority + if ("file".equals(getScheme())) { + failureExpected = false; + } + // FileSystem automatically adds missing authority if scheme matches default + else if (wrapper instanceof FileSystemTestWrapper) { + failureExpected = false; + } try { readFile(new Path(getScheme()+"://"+testBaseDir1()+"/linkToFile")); assertFalse(failureExpected); } catch (Exception e) { - assertTrue(failureExpected); + if (!failureExpected) { + throw new IOException(e); + } + //assertTrue(failureExpected); } - + // Now read using a different file context (for HDFS at least) - if (!"file".equals(getScheme())) { - FileContext localFc = FileContext.getLocalFSFileContext(); - readFile(localFc, new Path(testURI().toString(), linkAbs)); + if (wrapper instanceof FileContextTestWrapper + && !"file".equals(getScheme())) { + FSTestWrapper localWrapper = wrapper.getLocalFSWrapper(); + localWrapper.readFile(new Path(testURI().toString(), linkAbs), fileSize); } } - - @Test + + @Test(timeout=10000) /** Test creating a symlink using relative paths */ public void testCreateLinkUsingRelPaths() throws IOException { Path fileAbs = new Path(testBaseDir1(), "file"); Path linkAbs = new Path(testBaseDir1(), "linkToFile"); - Path schemeAuth = new Path(testURI().toString()); + Path schemeAuth = new Path(testURI().toString()); Path fileQual = new Path(schemeAuth, testBaseDir1()+"/file"); createAndWriteFile(fileAbs); - - fc.setWorkingDirectory(new Path(testBaseDir1())); - fc.createSymlink(new Path("file"), new Path("linkToFile"), false); + + wrapper.setWorkingDirectory(new Path(testBaseDir1())); + wrapper.createSymlink(new Path("file"), new Path("linkToFile"), false); checkLink(linkAbs, new Path("file"), fileQual); - - // Now rename the link's parent. Because the target was specified + + // Now rename the link's parent. Because the target was specified // with a relative path the link should still resolve. Path dir1 = new Path(testBaseDir1()); Path dir2 = new Path(testBaseDir2()); Path linkViaDir2 = new Path(testBaseDir2(), "linkToFile"); Path fileViaDir2 = new Path(schemeAuth, testBaseDir2()+"/file"); - fc.rename(dir1, dir2, Rename.OVERWRITE); - assertEquals(fileViaDir2, fc.getFileLinkStatus(linkViaDir2).getSymlink()); + wrapper.rename(dir1, dir2, Rename.OVERWRITE); + FileStatus[] stats = wrapper.listStatus(dir2); + assertEquals(fileViaDir2, + wrapper.getFileLinkStatus(linkViaDir2).getSymlink()); readFile(linkViaDir2); } - @Test + @Test(timeout=10000) /** Test creating a symlink using absolute paths */ public void testCreateLinkUsingAbsPaths() throws IOException { Path fileAbs = new Path(testBaseDir1()+"/file"); Path linkAbs = new Path(testBaseDir1()+"/linkToFile"); - Path schemeAuth = new Path(testURI().toString()); + Path schemeAuth = new Path(testURI().toString()); Path fileQual = new Path(schemeAuth, testBaseDir1()+"/file"); createAndWriteFile(fileAbs); - fc.createSymlink(fileAbs, linkAbs, false); + wrapper.createSymlink(fileAbs, linkAbs, false); checkLink(linkAbs, fileAbs, fileQual); // Now rename the link's parent. The target doesn't change and @@ -451,18 +460,18 @@ public void testCreateLinkUsingAbsPaths() throws IOException { Path dir1 = new Path(testBaseDir1()); Path dir2 = new Path(testBaseDir2()); Path linkViaDir2 = new Path(testBaseDir2(), "linkToFile"); - fc.rename(dir1, dir2, Rename.OVERWRITE); - assertEquals(fileQual, fc.getFileLinkStatus(linkViaDir2).getSymlink()); + wrapper.rename(dir1, dir2, Rename.OVERWRITE); + assertEquals(fileQual, wrapper.getFileLinkStatus(linkViaDir2).getSymlink()); try { readFile(linkViaDir2); fail("The target should not exist"); } catch (FileNotFoundException x) { // Expected } - } - - @Test - /** + } + + @Test(timeout=10000) + /** * Test creating a symlink using fully and partially qualified paths. * NB: For local fs this actually tests partially qualified paths, * as they don't support fully qualified paths. @@ -473,30 +482,30 @@ public void testCreateLinkUsingFullyQualPaths() throws IOException { Path fileQual = new Path(testURI().toString(), fileAbs); Path linkQual = new Path(testURI().toString(), linkAbs); createAndWriteFile(fileAbs); - - fc.createSymlink(fileQual, linkQual, false); - checkLink(linkAbs, - "file".equals(getScheme()) ? fileAbs : fileQual, + + wrapper.createSymlink(fileQual, linkQual, false); + checkLink(linkAbs, + "file".equals(getScheme()) ? fileAbs : fileQual, fileQual); - + // Now rename the link's parent. The target doesn't change and // now no longer exists so accessing the link should fail. Path dir1 = new Path(testBaseDir1()); Path dir2 = new Path(testBaseDir2()); Path linkViaDir2 = new Path(testBaseDir2(), "linkToFile"); - fc.rename(dir1, dir2, Rename.OVERWRITE); - assertEquals(fileQual, fc.getFileLinkStatus(linkViaDir2).getSymlink()); + wrapper.rename(dir1, dir2, Rename.OVERWRITE); + assertEquals(fileQual, wrapper.getFileLinkStatus(linkViaDir2).getSymlink()); try { readFile(linkViaDir2); fail("The target should not exist"); } catch (FileNotFoundException x) { // Expected } - } - - @Test - /** - * Test creating a symlink using partially qualified paths, ie a scheme + } + + @Test(timeout=10000) + /** + * Test creating a symlink using partially qualified paths, ie a scheme * but no authority and vice versa. We just test link targets here since * creating using a partially qualified path is file system specific. */ @@ -508,51 +517,62 @@ public void testCreateLinkUsingPartQualPath1() throws IOException { Path fileWoHost = new Path(getScheme()+"://"+testBaseDir1()+"/file"); Path link = new Path(testBaseDir1()+"/linkToFile"); Path linkQual = new Path(schemeAuth, testBaseDir1()+"/linkToFile"); - FileContext localFc = FileContext.getLocalFSFileContext(); + FSTestWrapper localWrapper = wrapper.getLocalFSWrapper(); - fc.createSymlink(fileWoHost, link, false); + wrapper.createSymlink(fileWoHost, link, false); // Partially qualified path is stored - assertEquals(fileWoHost, fc.getLinkTarget(linkQual)); + assertEquals(fileWoHost, wrapper.getLinkTarget(linkQual)); // NB: We do not add an authority assertEquals(fileWoHost.toString(), - fc.getFileLinkStatus(link).getSymlink().toString()); + wrapper.getFileLinkStatus(link).getSymlink().toString()); assertEquals(fileWoHost.toString(), - fc.getFileLinkStatus(linkQual).getSymlink().toString()); + wrapper.getFileLinkStatus(linkQual).getSymlink().toString()); // Ditto even from another file system - assertEquals(fileWoHost.toString(), - localFc.getFileLinkStatus(linkQual).getSymlink().toString()); + if (wrapper instanceof FileContextTestWrapper) { + assertEquals(fileWoHost.toString(), + localWrapper.getFileLinkStatus(linkQual).getSymlink().toString()); + } // Same as if we accessed a partially qualified path directly - try { + try { readFile(link); fail("DFS requires URIs with schemes have an authority"); } catch (java.lang.RuntimeException e) { + assertTrue(wrapper instanceof FileContextTestWrapper); // Expected + } catch (FileNotFoundException e) { + assertTrue(wrapper instanceof FileSystemTestWrapper); + GenericTestUtils.assertExceptionContains( + "File does not exist: /test1/file", e); } } - @Test + @Test(timeout=10000) /** Same as above but vice versa (authority but no scheme) */ public void testCreateLinkUsingPartQualPath2() throws IOException { Path link = new Path(testBaseDir1(), "linkToFile"); - Path fileWoScheme = new Path("//"+testURI().getAuthority()+ + Path fileWoScheme = new Path("//"+testURI().getAuthority()+ testBaseDir1()+"/file"); if ("file".equals(getScheme())) { return; } - fc.createSymlink(fileWoScheme, link, false); - assertEquals(fileWoScheme, fc.getLinkTarget(link)); + wrapper.createSymlink(fileWoScheme, link, false); + assertEquals(fileWoScheme, wrapper.getLinkTarget(link)); assertEquals(fileWoScheme.toString(), - fc.getFileLinkStatus(link).getSymlink().toString()); + wrapper.getFileLinkStatus(link).getSymlink().toString()); try { readFile(link); fail("Accessed a file with w/o scheme"); } catch (IOException e) { - // Expected - assertEquals("No AbstractFileSystem for scheme: null", e.getMessage()); + // Expected + if (wrapper instanceof FileContextTestWrapper) { + assertEquals("No AbstractFileSystem for scheme: null", e.getMessage()); + } else if (wrapper instanceof FileSystemTestWrapper) { + assertEquals("No FileSystem for scheme: null", e.getMessage()); + } } } - @Test + @Test(timeout=10000) /** Lstat and readlink on a normal file and directory */ public void testLinkStatusAndTargetWithNonLink() throws IOException { Path schemeAuth = new Path(testURI().toString()); @@ -561,69 +581,69 @@ public void testLinkStatusAndTargetWithNonLink() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path fileQual = new Path(schemeAuth, file.toString()); createAndWriteFile(file); - assertEquals(fc.getFileStatus(file), fc.getFileLinkStatus(file)); - assertEquals(fc.getFileStatus(dir), fc.getFileLinkStatus(dir)); + assertEquals(wrapper.getFileStatus(file), wrapper.getFileLinkStatus(file)); + assertEquals(wrapper.getFileStatus(dir), wrapper.getFileLinkStatus(dir)); try { - fc.getLinkTarget(file); + wrapper.getLinkTarget(file); fail("Get link target on non-link should throw an IOException"); } catch (IOException x) { assertEquals("Path "+fileQual+" is not a symbolic link", x.getMessage()); } try { - fc.getLinkTarget(dir); + wrapper.getLinkTarget(dir); fail("Get link target on non-link should throw an IOException"); } catch (IOException x) { assertEquals("Path "+dirQual+" is not a symbolic link", x.getMessage()); - } + } } - @Test + @Test(timeout=10000) /** Test create symlink to a directory */ public void testCreateLinkToDirectory() throws IOException { Path dir1 = new Path(testBaseDir1()); Path file = new Path(testBaseDir1(), "file"); Path linkToDir = new Path(testBaseDir2(), "linkToDir"); createAndWriteFile(file); - fc.createSymlink(dir1, linkToDir, false); - assertFalse(isFile(fc, linkToDir)); - assertTrue(isDir(fc, linkToDir)); - assertTrue(fc.getFileStatus(linkToDir).isDirectory()); - assertTrue(fc.getFileLinkStatus(linkToDir).isSymlink()); + wrapper.createSymlink(dir1, linkToDir, false); + assertFalse(wrapper.isFile(linkToDir)); + assertTrue(wrapper.isDir(linkToDir)); + assertTrue(wrapper.getFileStatus(linkToDir).isDirectory()); + assertTrue(wrapper.getFileLinkStatus(linkToDir).isSymlink()); } - - @Test + + @Test(timeout=10000) /** Test create and remove a file through a symlink */ public void testCreateFileViaSymlink() throws IOException { Path dir = new Path(testBaseDir1()); Path linkToDir = new Path(testBaseDir2(), "linkToDir"); Path fileViaLink = new Path(linkToDir, "file"); - fc.createSymlink(dir, linkToDir, false); + wrapper.createSymlink(dir, linkToDir, false); createAndWriteFile(fileViaLink); - assertTrue(isFile(fc, fileViaLink)); - assertFalse(isDir(fc, fileViaLink)); - assertFalse(fc.getFileLinkStatus(fileViaLink).isSymlink()); - assertFalse(fc.getFileStatus(fileViaLink).isDirectory()); + assertTrue(wrapper.isFile(fileViaLink)); + assertFalse(wrapper.isDir(fileViaLink)); + assertFalse(wrapper.getFileLinkStatus(fileViaLink).isSymlink()); + assertFalse(wrapper.getFileStatus(fileViaLink).isDirectory()); readFile(fileViaLink); - fc.delete(fileViaLink, true); - assertFalse(exists(fc, fileViaLink)); + wrapper.delete(fileViaLink, true); + assertFalse(wrapper.exists(fileViaLink)); } - - @Test + + @Test(timeout=10000) /** Test make and delete directory through a symlink */ public void testCreateDirViaSymlink() throws IOException { Path dir1 = new Path(testBaseDir1()); Path subDir = new Path(testBaseDir1(), "subDir"); Path linkToDir = new Path(testBaseDir2(), "linkToDir"); Path subDirViaLink = new Path(linkToDir, "subDir"); - fc.createSymlink(dir1, linkToDir, false); - fc.mkdir(subDirViaLink, FileContext.DEFAULT_PERM, true); - assertTrue(isDir(fc, subDirViaLink)); - fc.delete(subDirViaLink, false); - assertFalse(exists(fc, subDirViaLink)); - assertFalse(exists(fc, subDir)); + wrapper.createSymlink(dir1, linkToDir, false); + wrapper.mkdir(subDirViaLink, FileContext.DEFAULT_PERM, true); + assertTrue(wrapper.isDir(subDirViaLink)); + wrapper.delete(subDirViaLink, false); + assertFalse(wrapper.exists(subDirViaLink)); + assertFalse(wrapper.exists(subDir)); } - @Test + @Test(timeout=10000) /** Create symlink through a symlink */ public void testCreateLinkViaLink() throws IOException { Path dir1 = new Path(testBaseDir1()); @@ -636,27 +656,27 @@ public void testCreateLinkViaLink() throws IOException { * /b2/linkToDir/linkToFile -> /b2/linkToDir/file */ createAndWriteFile(file); - fc.createSymlink(dir1, linkToDir, false); - fc.createSymlink(fileViaLink, linkToFile, false); - assertTrue(isFile(fc, linkToFile)); - assertTrue(fc.getFileLinkStatus(linkToFile).isSymlink()); + wrapper.createSymlink(dir1, linkToDir, false); + wrapper.createSymlink(fileViaLink, linkToFile, false); + assertTrue(wrapper.isFile(linkToFile)); + assertTrue(wrapper.getFileLinkStatus(linkToFile).isSymlink()); readFile(linkToFile); - assertEquals(fileSize, fc.getFileStatus(linkToFile).getLen()); - assertEquals(fileViaLink, fc.getLinkTarget(linkToFile)); + assertEquals(fileSize, wrapper.getFileStatus(linkToFile).getLen()); + assertEquals(fileViaLink, wrapper.getLinkTarget(linkToFile)); } - @Test + @Test(timeout=10000) /** Test create symlink to a directory */ public void testListStatusUsingLink() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "link"); createAndWriteFile(file); - fc.createSymlink(new Path(testBaseDir1()), link, false); - // The size of the result is file system dependent, Hdfs is 2 (file + wrapper.createSymlink(new Path(testBaseDir1()), link, false); + // The size of the result is file system dependent, Hdfs is 2 (file // and link) and LocalFs is 3 (file, link, file crc). - FileStatus[] stats = fc.util().listStatus(link); + FileStatus[] stats = wrapper.listStatus(link); assertTrue(stats.length == 2 || stats.length == 3); - RemoteIterator statsItor = fc.listStatus(link); + RemoteIterator statsItor = wrapper.listStatusIterator(link); int dirLen = 0; while(statsItor.hasNext()) { statsItor.next(); @@ -664,23 +684,23 @@ public void testListStatusUsingLink() throws IOException { } assertTrue(dirLen == 2 || dirLen == 3); } - - @Test + + @Test(timeout=10000) /** Test create symlink using the same path */ public void testCreateLinkTwice() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); try { - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); fail("link already exists"); } catch (IOException x) { // Expected } - } - - @Test + } + + @Test(timeout=10000) /** Test access via a symlink to a symlink */ public void testCreateLinkToLink() throws IOException { Path dir1 = new Path(testBaseDir1()); @@ -689,22 +709,22 @@ public void testCreateLinkToLink() throws IOException { Path linkToLink = new Path(testBaseDir2(), "linkToLink"); Path fileViaLink = new Path(testBaseDir2(), "linkToLink/file"); createAndWriteFile(file); - fc.createSymlink(dir1, linkToDir, false); - fc.createSymlink(linkToDir, linkToLink, false); - assertTrue(isFile(fc, fileViaLink)); - assertFalse(isDir(fc, fileViaLink)); - assertFalse(fc.getFileLinkStatus(fileViaLink).isSymlink()); - assertFalse(fc.getFileStatus(fileViaLink).isDirectory()); + wrapper.createSymlink(dir1, linkToDir, false); + wrapper.createSymlink(linkToDir, linkToLink, false); + assertTrue(wrapper.isFile(fileViaLink)); + assertFalse(wrapper.isDir(fileViaLink)); + assertFalse(wrapper.getFileLinkStatus(fileViaLink).isSymlink()); + assertFalse(wrapper.getFileStatus(fileViaLink).isDirectory()); readFile(fileViaLink); } - @Test + @Test(timeout=10000) /** Can not create a file with path that refers to a symlink */ public void testCreateFileDirExistingLink() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); try { createAndWriteFile(link); fail("link already exists"); @@ -712,51 +732,50 @@ public void testCreateFileDirExistingLink() throws IOException { // Expected } try { - fc.mkdir(link, FsPermission.getDefault(), false); + wrapper.mkdir(link, FsPermission.getDefault(), false); fail("link already exists"); } catch (IOException x) { // Expected - } - } + } + } - @Test + @Test(timeout=10000) /** Test deleting and recreating a symlink */ public void testUseLinkAferDeleteLink() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); - fc.delete(link, false); + wrapper.createSymlink(file, link, false); + wrapper.delete(link, false); try { - readFile(link); + readFile(link); fail("link was deleted"); } catch (IOException x) { // Expected } readFile(file); - fc.createSymlink(file, link, false); - readFile(link); - } - - - @Test + wrapper.createSymlink(file, link, false); + readFile(link); + } + + @Test(timeout=10000) /** Test create symlink to . */ public void testCreateLinkToDot() throws IOException { Path dir = new Path(testBaseDir1()); - Path file = new Path(testBaseDir1(), "file"); + Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToDot"); - createAndWriteFile(file); - fc.setWorkingDirectory(dir); + createAndWriteFile(file); + wrapper.setWorkingDirectory(dir); try { - fc.createSymlink(new Path("."), link, false); + wrapper.createSymlink(new Path("."), link, false); fail("Created symlink to dot"); } catch (IOException x) { // Expected. Path(".") resolves to "" because URI normalizes - // the dot away and AbstractFileSystem considers "" invalid. + // the dot away and AbstractFileSystem considers "" invalid. } } - @Test + @Test(timeout=10000) /** Test create symlink to .. */ public void testCreateLinkToDotDot() throws IOException { Path file = new Path(testBaseDir1(), "test/file"); @@ -766,27 +785,27 @@ public void testCreateLinkToDotDot() throws IOException { // Symlink to .. is not a problem since the .. is squashed early assertEquals(testBaseDir1(), dotDot.toString()); createAndWriteFile(file); - fc.createSymlink(dotDot, linkToDir, false); + wrapper.createSymlink(dotDot, linkToDir, false); readFile(fileViaLink); - assertEquals(fileSize, fc.getFileStatus(fileViaLink).getLen()); + assertEquals(fileSize, wrapper.getFileStatus(fileViaLink).getLen()); } - @Test + @Test(timeout=10000) /** Test create symlink to ../file */ public void testCreateLinkToDotDotPrefix() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path dir = new Path(testBaseDir1(), "test"); Path link = new Path(testBaseDir1(), "test/link"); createAndWriteFile(file); - fc.mkdir(dir, FsPermission.getDefault(), false); - fc.setWorkingDirectory(dir); - fc.createSymlink(new Path("../file"), link, false); + wrapper.mkdir(dir, FsPermission.getDefault(), false); + wrapper.setWorkingDirectory(dir); + wrapper.createSymlink(new Path("../file"), link, false); readFile(link); - assertEquals(new Path("../file"), fc.getLinkTarget(link)); + assertEquals(new Path("../file"), wrapper.getLinkTarget(link)); } - - @Test - /** Test rename file using a path that contains a symlink. The rename should + + @Test(timeout=10000) + /** Test rename file using a path that contains a symlink. The rename should * work as if the path did not contain a symlink */ public void testRenameFileViaSymlink() throws IOException { Path dir = new Path(testBaseDir1()); @@ -795,16 +814,16 @@ public void testRenameFileViaSymlink() throws IOException { Path fileViaLink = new Path(linkToDir, "file"); Path fileNewViaLink = new Path(linkToDir, "fileNew"); createAndWriteFile(file); - fc.createSymlink(dir, linkToDir, false); - fc.rename(fileViaLink, fileNewViaLink); - assertFalse(exists(fc, fileViaLink)); - assertFalse(exists(fc, file)); - assertTrue(exists(fc, fileNewViaLink)); + wrapper.createSymlink(dir, linkToDir, false); + wrapper.rename(fileViaLink, fileNewViaLink); + assertFalse(wrapper.exists(fileViaLink)); + assertFalse(wrapper.exists(file)); + assertTrue(wrapper.exists(fileNewViaLink)); } - @Test - /** Test rename a file through a symlink but this time only the - * destination path has an intermediate symlink. The rename should work + @Test(timeout=10000) + /** Test rename a file through a symlink but this time only the + * destination path has an intermediate symlink. The rename should work * as if the path did not contain a symlink */ public void testRenameFileToDestViaSymlink() throws IOException { Path dir = new Path(testBaseDir1()); @@ -812,19 +831,19 @@ public void testRenameFileToDestViaSymlink() throws IOException { Path linkToDir = new Path(testBaseDir2(), "linkToDir"); Path subDir = new Path(linkToDir, "subDir"); createAndWriteFile(file); - fc.createSymlink(dir, linkToDir, false); - fc.mkdir(subDir, FileContext.DEFAULT_PERM, false); + wrapper.createSymlink(dir, linkToDir, false); + wrapper.mkdir(subDir, FileContext.DEFAULT_PERM, false); try { - fc.rename(file, subDir); + wrapper.rename(file, subDir); fail("Renamed file to a directory"); } catch (IOException e) { // Expected. Both must be directories. assertTrue(unwrapException(e) instanceof IOException); } - assertTrue(exists(fc, file)); + assertTrue(wrapper.exists(file)); } - - @Test + + @Test(timeout=10000) /** Similar tests as the previous ones but rename a directory */ public void testRenameDirViaSymlink() throws IOException { Path baseDir = new Path(testBaseDir1()); @@ -832,17 +851,17 @@ public void testRenameDirViaSymlink() throws IOException { Path linkToDir = new Path(testBaseDir2(), "linkToDir"); Path dirViaLink = new Path(linkToDir, "dir"); Path dirNewViaLink = new Path(linkToDir, "dirNew"); - fc.mkdir(dir, FileContext.DEFAULT_PERM, false); - fc.createSymlink(baseDir, linkToDir, false); - assertTrue(exists(fc, dirViaLink)); - fc.rename(dirViaLink, dirNewViaLink); - assertFalse(exists(fc, dirViaLink)); - assertFalse(exists(fc, dir)); - assertTrue(exists(fc, dirNewViaLink)); + wrapper.mkdir(dir, FileContext.DEFAULT_PERM, false); + wrapper.createSymlink(baseDir, linkToDir, false); + assertTrue(wrapper.exists(dirViaLink)); + wrapper.rename(dirViaLink, dirNewViaLink); + assertFalse(wrapper.exists(dirViaLink)); + assertFalse(wrapper.exists(dir)); + assertTrue(wrapper.exists(dirNewViaLink)); } - - @Test - /** Similar tests as the previous ones but rename a symlink */ + + @Test(timeout=10000) + /** Similar tests as the previous ones but rename a symlink */ public void testRenameSymlinkViaSymlink() throws IOException { Path baseDir = new Path(testBaseDir1()); Path file = new Path(testBaseDir1(), "file"); @@ -851,95 +870,95 @@ public void testRenameSymlinkViaSymlink() throws IOException { Path linkViaLink = new Path(linkToDir, "link"); Path linkNewViaLink = new Path(linkToDir, "linkNew"); createAndWriteFile(file); - fc.createSymlink(file, link, false); - fc.createSymlink(baseDir, linkToDir, false); - fc.rename(linkViaLink, linkNewViaLink); - assertFalse(exists(fc, linkViaLink)); + wrapper.createSymlink(file, link, false); + wrapper.createSymlink(baseDir, linkToDir, false); + wrapper.rename(linkViaLink, linkNewViaLink); + assertFalse(wrapper.exists(linkViaLink)); // Check that we didn't rename the link target - assertTrue(exists(fc, file)); - assertTrue(fc.getFileLinkStatus(linkNewViaLink).isSymlink()); + assertTrue(wrapper.exists(file)); + assertTrue(wrapper.getFileLinkStatus(linkNewViaLink).isSymlink()); readFile(linkNewViaLink); } - @Test + @Test(timeout=10000) /** Test rename a directory to a symlink to a directory */ public void testRenameDirToSymlinkToDir() throws IOException { Path dir1 = new Path(testBaseDir1()); Path subDir = new Path(testBaseDir2(), "subDir"); Path linkToDir = new Path(testBaseDir2(), "linkToDir"); - fc.mkdir(subDir, FileContext.DEFAULT_PERM, false); - fc.createSymlink(subDir, linkToDir, false); + wrapper.mkdir(subDir, FileContext.DEFAULT_PERM, false); + wrapper.createSymlink(subDir, linkToDir, false); try { - fc.rename(dir1, linkToDir, Rename.OVERWRITE); + wrapper.rename(dir1, linkToDir, Rename.OVERWRITE); fail("Renamed directory to a symlink"); } catch (IOException e) { // Expected. Both must be directories. assertTrue(unwrapException(e) instanceof IOException); } - assertTrue(exists(fc, dir1)); - assertTrue(exists(fc, linkToDir)); + assertTrue(wrapper.exists(dir1)); + assertTrue(wrapper.exists(linkToDir)); } - @Test + @Test(timeout=10000) /** Test rename a directory to a symlink to a file */ public void testRenameDirToSymlinkToFile() throws IOException { Path dir1 = new Path(testBaseDir1()); Path file = new Path(testBaseDir2(), "file"); Path linkToFile = new Path(testBaseDir2(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, linkToFile, false); + wrapper.createSymlink(file, linkToFile, false); try { - fc.rename(dir1, linkToFile, Rename.OVERWRITE); + wrapper.rename(dir1, linkToFile, Rename.OVERWRITE); fail("Renamed directory to a symlink"); } catch (IOException e) { // Expected. Both must be directories. assertTrue(unwrapException(e) instanceof IOException); } - assertTrue(exists(fc, dir1)); - assertTrue(exists(fc, linkToFile)); + assertTrue(wrapper.exists(dir1)); + assertTrue(wrapper.exists(linkToFile)); } - @Test + @Test(timeout=10000) /** Test rename a directory to a dangling symlink */ public void testRenameDirToDanglingSymlink() throws IOException { Path dir = new Path(testBaseDir1()); Path link = new Path(testBaseDir2(), "linkToFile"); - fc.createSymlink(new Path("/doesNotExist"), link, false); - try { - fc.rename(dir, link, Rename.OVERWRITE); - fail("Renamed directory to a symlink"); + wrapper.createSymlink(new Path("/doesNotExist"), link, false); + try { + wrapper.rename(dir, link, Rename.OVERWRITE); + fail("Renamed directory to a symlink"); } catch (IOException e) { // Expected. Both must be directories. assertTrue(unwrapException(e) instanceof IOException); } - assertTrue(exists(fc, dir)); - assertTrue(fc.getFileLinkStatus(link) != null); + assertTrue(wrapper.exists(dir)); + assertTrue(wrapper.getFileLinkStatus(link) != null); } - @Test + @Test(timeout=10000) /** Test rename a file to a symlink to a directory */ public void testRenameFileToSymlinkToDir() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path subDir = new Path(testBaseDir1(), "subDir"); Path link = new Path(testBaseDir1(), "link"); - fc.mkdir(subDir, FileContext.DEFAULT_PERM, false); - fc.createSymlink(subDir, link, false); + wrapper.mkdir(subDir, FileContext.DEFAULT_PERM, false); + wrapper.createSymlink(subDir, link, false); createAndWriteFile(file); try { - fc.rename(file, link); - fail("Renamed file to symlink w/o overwrite"); + wrapper.rename(file, link); + fail("Renamed file to symlink w/o overwrite"); } catch (IOException e) { // Expected assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } - fc.rename(file, link, Rename.OVERWRITE); - assertFalse(exists(fc, file)); - assertTrue(exists(fc, link)); - assertTrue(isFile(fc, link)); - assertFalse(fc.getFileLinkStatus(link).isSymlink()); + wrapper.rename(file, link, Rename.OVERWRITE); + assertFalse(wrapper.exists(file)); + assertTrue(wrapper.exists(link)); + assertTrue(wrapper.isFile(link)); + assertFalse(wrapper.getFileLinkStatus(link).isSymlink()); } - @Test + @Test(timeout=10000) /** Test rename a file to a symlink to a file */ public void testRenameFileToSymlinkToFile() throws IOException { Path file1 = new Path(testBaseDir1(), "file1"); @@ -947,61 +966,61 @@ public void testRenameFileToSymlinkToFile() throws IOException { Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file1); createAndWriteFile(file2); - fc.createSymlink(file2, link, false); + wrapper.createSymlink(file2, link, false); try { - fc.rename(file1, link); - fail("Renamed file to symlink w/o overwrite"); + wrapper.rename(file1, link); + fail("Renamed file to symlink w/o overwrite"); } catch (IOException e) { // Expected assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } - fc.rename(file1, link, Rename.OVERWRITE); - assertFalse(exists(fc, file1)); - assertTrue(exists(fc, link)); - assertTrue(isFile(fc, link)); - assertFalse(fc.getFileLinkStatus(link).isSymlink()); + wrapper.rename(file1, link, Rename.OVERWRITE); + assertFalse(wrapper.exists(file1)); + assertTrue(wrapper.exists(link)); + assertTrue(wrapper.isFile(link)); + assertFalse(wrapper.getFileLinkStatus(link).isSymlink()); } - @Test + @Test(timeout=10000) /** Test rename a file to a dangling symlink */ public void testRenameFileToDanglingSymlink() throws IOException { /* NB: Local file system doesn't handle dangling links correctly - * since File.exists(danglinLink) returns false. */ + * since File.exists(danglinLink) returns false. */ if ("file".equals(getScheme())) { return; } Path file1 = new Path(testBaseDir1(), "file1"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file1); - fc.createSymlink(new Path("/doesNotExist"), link, false); + wrapper.createSymlink(new Path("/doesNotExist"), link, false); try { - fc.rename(file1, link); + wrapper.rename(file1, link); } catch (IOException e) { // Expected } - fc.rename(file1, link, Rename.OVERWRITE); - assertFalse(exists(fc, file1)); - assertTrue(exists(fc, link)); - assertTrue(isFile(fc, link)); - assertFalse(fc.getFileLinkStatus(link).isSymlink()); + wrapper.rename(file1, link, Rename.OVERWRITE); + assertFalse(wrapper.exists(file1)); + assertTrue(wrapper.exists(link)); + assertTrue(wrapper.isFile(link)); + assertFalse(wrapper.getFileLinkStatus(link).isSymlink()); } - @Test + @Test(timeout=10000) /** Rename a symlink to a new non-existant name */ public void testRenameSymlinkNonExistantDest() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link1 = new Path(testBaseDir1(), "linkToFile1"); Path link2 = new Path(testBaseDir1(), "linkToFile2"); createAndWriteFile(file); - fc.createSymlink(file, link1, false); - fc.rename(link1, link2); - assertTrue(fc.getFileLinkStatus(link2).isSymlink()); + wrapper.createSymlink(file, link1, false); + wrapper.rename(link1, link2); + assertTrue(wrapper.getFileLinkStatus(link2).isSymlink()); readFile(link2); readFile(file); - assertFalse(exists(fc, link1)); + assertFalse(wrapper.exists(link1)); } - @Test + @Test(timeout=10000) /** Rename a symlink to a file that exists */ public void testRenameSymlinkToExistingFile() throws IOException { Path file1 = new Path(testBaseDir1(), "file"); @@ -1009,46 +1028,46 @@ public void testRenameSymlinkToExistingFile() throws IOException { Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file1); createAndWriteFile(file2); - fc.createSymlink(file2, link, false); + wrapper.createSymlink(file2, link, false); try { - fc.rename(link, file1); + wrapper.rename(link, file1); fail("Renamed w/o passing overwrite"); } catch (IOException e) { // Expected assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } - fc.rename(link, file1, Rename.OVERWRITE); - assertFalse(exists(fc, link)); - assertTrue(fc.getFileLinkStatus(file1).isSymlink()); - assertEquals(file2, fc.getLinkTarget(file1)); + wrapper.rename(link, file1, Rename.OVERWRITE); + assertFalse(wrapper.exists(link)); + assertTrue(wrapper.getFileLinkStatus(file1).isSymlink()); + assertEquals(file2, wrapper.getLinkTarget(file1)); } - @Test + @Test(timeout=10000) /** Rename a symlink to a directory that exists */ public void testRenameSymlinkToExistingDir() throws IOException { Path dir1 = new Path(testBaseDir1()); Path dir2 = new Path(testBaseDir2()); Path subDir = new Path(testBaseDir2(), "subDir"); - Path link = new Path(testBaseDir1(), "linkToDir"); - fc.createSymlink(dir1, link, false); + Path link = new Path(testBaseDir1(), "linkToDir"); + wrapper.createSymlink(dir1, link, false); try { - fc.rename(link, dir2); + wrapper.rename(link, dir2); fail("Renamed link to a directory"); } catch (IOException e) { // Expected. Both must be directories. assertTrue(unwrapException(e) instanceof IOException); } try { - fc.rename(link, dir2, Rename.OVERWRITE); + wrapper.rename(link, dir2, Rename.OVERWRITE); fail("Renamed link to a directory"); } catch (IOException e) { // Expected. Both must be directories. assertTrue(unwrapException(e) instanceof IOException); } // Also fails when dir2 has a sub-directory - fc.mkdir(subDir, FsPermission.getDefault(), false); + wrapper.mkdir(subDir, FsPermission.getDefault(), false); try { - fc.rename(link, dir2, Rename.OVERWRITE); + wrapper.rename(link, dir2, Rename.OVERWRITE); fail("Renamed link to a directory"); } catch (IOException e) { // Expected. Both must be directories. @@ -1056,35 +1075,35 @@ public void testRenameSymlinkToExistingDir() throws IOException { } } - @Test + @Test(timeout=10000) /** Rename a symlink to itself */ public void testRenameSymlinkToItself() throws IOException { Path link = new Path(testBaseDir1(), "linkToFile1"); - fc.createSymlink(new Path("/doestNotExist"), link, false); + wrapper.createSymlink(new Path("/doestNotExist"), link, false); try { - fc.rename(link, link); + wrapper.rename(link, link); } catch (IOException e) { assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } // Fails with overwrite as well try { - fc.rename(link, link, Rename.OVERWRITE); + wrapper.rename(link, link, Rename.OVERWRITE); } catch (IOException e) { assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } } - @Test + @Test(timeout=10000) /** Rename a symlink */ public void testRenameSymlink() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link1 = new Path(testBaseDir1(), "linkToFile1"); - Path link2 = new Path(testBaseDir1(), "linkToFile2"); + Path link2 = new Path(testBaseDir1(), "linkToFile2"); createAndWriteFile(file); - fc.createSymlink(file, link1, false); - fc.rename(link1, link2); - assertTrue(fc.getFileLinkStatus(link2).isSymlink()); - assertFalse(fc.getFileStatus(link2).isDirectory()); + wrapper.createSymlink(file, link1, false); + wrapper.rename(link1, link2); + assertTrue(wrapper.getFileLinkStatus(link2).isSymlink()); + assertFalse(wrapper.getFileStatus(link2).isDirectory()); readFile(link2); readFile(file); try { @@ -1092,15 +1111,15 @@ public void testRenameSymlink() throws IOException { fail("link was not renamed"); } catch (IOException x) { // Expected - } + } } - @Test + @Test(timeout=10000) /** Rename a symlink to the file it links to */ public void testRenameSymlinkToFileItLinksTo() throws IOException { /* NB: The rename is not atomic, so file is deleted before renaming - * linkToFile. In this interval linkToFile is dangling and local file - * system does not handle dangling links because File.exists returns + * linkToFile. In this interval linkToFile is dangling and local file + * system does not handle dangling links because File.exists returns * false for dangling links. */ if ("file".equals(getScheme())) { return; @@ -1108,111 +1127,111 @@ public void testRenameSymlinkToFileItLinksTo() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); try { - fc.rename(link, file); + wrapper.rename(link, file); fail("Renamed symlink to its target"); } catch (IOException e) { assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } // Check the rename didn't happen - assertTrue(isFile(fc, file)); - assertTrue(exists(fc, link)); - assertTrue(isSymlink(fc, link)); - assertEquals(file, fc.getLinkTarget(link)); + assertTrue(wrapper.isFile(file)); + assertTrue(wrapper.exists(link)); + assertTrue(wrapper.isSymlink(link)); + assertEquals(file, wrapper.getLinkTarget(link)); try { - fc.rename(link, file, Rename.OVERWRITE); + wrapper.rename(link, file, Rename.OVERWRITE); fail("Renamed symlink to its target"); } catch (IOException e) { assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } // Check the rename didn't happen - assertTrue(isFile(fc, file)); - assertTrue(exists(fc, link)); - assertTrue(isSymlink(fc, link)); - assertEquals(file, fc.getLinkTarget(link)); + assertTrue(wrapper.isFile(file)); + assertTrue(wrapper.exists(link)); + assertTrue(wrapper.isSymlink(link)); + assertEquals(file, wrapper.getLinkTarget(link)); } - - @Test + + @Test(timeout=10000) /** Rename a symlink to the directory it links to */ public void testRenameSymlinkToDirItLinksTo() throws IOException { /* NB: The rename is not atomic, so dir is deleted before renaming - * linkToFile. In this interval linkToFile is dangling and local file - * system does not handle dangling links because File.exists returns + * linkToFile. In this interval linkToFile is dangling and local file + * system does not handle dangling links because File.exists returns * false for dangling links. */ if ("file".equals(getScheme())) { return; } Path dir = new Path(testBaseDir1(), "dir"); Path link = new Path(testBaseDir1(), "linkToDir"); - fc.mkdir(dir, FileContext.DEFAULT_PERM, false); - fc.createSymlink(dir, link, false); + wrapper.mkdir(dir, FileContext.DEFAULT_PERM, false); + wrapper.createSymlink(dir, link, false); try { - fc.rename(link, dir); + wrapper.rename(link, dir); fail("Renamed symlink to its target"); } catch (IOException e) { assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } // Check the rename didn't happen - assertTrue(isDir(fc, dir)); - assertTrue(exists(fc, link)); - assertTrue(isSymlink(fc, link)); - assertEquals(dir, fc.getLinkTarget(link)); + assertTrue(wrapper.isDir(dir)); + assertTrue(wrapper.exists(link)); + assertTrue(wrapper.isSymlink(link)); + assertEquals(dir, wrapper.getLinkTarget(link)); try { - fc.rename(link, dir, Rename.OVERWRITE); + wrapper.rename(link, dir, Rename.OVERWRITE); fail("Renamed symlink to its target"); } catch (IOException e) { assertTrue(unwrapException(e) instanceof FileAlreadyExistsException); } // Check the rename didn't happen - assertTrue(isDir(fc, dir)); - assertTrue(exists(fc, link)); - assertTrue(isSymlink(fc, link)); - assertEquals(dir, fc.getLinkTarget(link)); + assertTrue(wrapper.isDir(dir)); + assertTrue(wrapper.exists(link)); + assertTrue(wrapper.isSymlink(link)); + assertEquals(dir, wrapper.getLinkTarget(link)); } - - @Test + + @Test(timeout=10000) /** Test rename the symlink's target */ public void testRenameLinkTarget() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path fileNew = new Path(testBaseDir1(), "fileNew"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); - fc.rename(file, fileNew, Rename.OVERWRITE); + wrapper.createSymlink(file, link, false); + wrapper.rename(file, fileNew, Rename.OVERWRITE); try { - readFile(link); + readFile(link); fail("Link should be dangling"); } catch (IOException x) { // Expected } - fc.rename(fileNew, file, Rename.OVERWRITE); + wrapper.rename(fileNew, file, Rename.OVERWRITE); readFile(link); } - @Test + @Test(timeout=10000) /** Test rename a file to path with destination that has symlink parent */ public void testRenameFileWithDestParentSymlink() throws IOException { Path link = new Path(testBaseDir1(), "link"); - Path file1 = new Path(testBaseDir1(), "file1"); - Path file2 = new Path(testBaseDir1(), "file2"); + Path file1 = new Path(testBaseDir1(), "file1"); + Path file2 = new Path(testBaseDir1(), "file2"); Path file3 = new Path(link, "file3"); Path dir2 = new Path(testBaseDir2()); - + // Renaming /dir1/file1 to non-existant file /dir1/link/file3 is OK // if link points to a directory... - fc.createSymlink(dir2, link, false); + wrapper.createSymlink(dir2, link, false); createAndWriteFile(file1); - fc.rename(file1, file3); - assertFalse(exists(fc, file1)); - assertTrue(exists(fc, file3)); - fc.rename(file3, file1); - + wrapper.rename(file1, file3); + assertFalse(wrapper.exists(file1)); + assertTrue(wrapper.exists(file3)); + wrapper.rename(file3, file1); + // But fails if link is dangling... - fc.delete(link, false); - fc.createSymlink(file2, link, false); + wrapper.delete(link, false); + wrapper.createSymlink(file2, link, false); try { - fc.rename(file1, file3); + wrapper.rename(file1, file3); } catch (IOException e) { // Expected assertTrue(unwrapException(e) instanceof FileNotFoundException); @@ -1221,14 +1240,14 @@ public void testRenameFileWithDestParentSymlink() throws IOException { // And if link points to a file... createAndWriteFile(file2); try { - fc.rename(file1, file3); + wrapper.rename(file1, file3); } catch (IOException e) { // Expected assertTrue(unwrapException(e) instanceof ParentNotDirectoryException); - } + } } - - @Test + + @Test(timeout=10000) /** * Create, write, read, append, rename, get the block locations, * checksums, and delete a file using a path with a symlink as an @@ -1242,32 +1261,32 @@ public void testAccessFileViaInterSymlinkAbsTarget() throws IOException { Path linkToDir = new Path(testBaseDir2(), "linkToDir"); Path fileViaLink = new Path(linkToDir, "file"); Path fileNewViaLink = new Path(linkToDir, "fileNew"); - fc.createSymlink(baseDir, linkToDir, false); + wrapper.createSymlink(baseDir, linkToDir, false); createAndWriteFile(fileViaLink); - assertTrue(exists(fc, fileViaLink)); - assertTrue(isFile(fc, fileViaLink)); - assertFalse(isDir(fc, fileViaLink)); - assertFalse(fc.getFileLinkStatus(fileViaLink).isSymlink()); - assertFalse(isDir(fc, fileViaLink)); - assertEquals(fc.getFileStatus(file), - fc.getFileLinkStatus(file)); - assertEquals(fc.getFileStatus(fileViaLink), - fc.getFileLinkStatus(fileViaLink)); + assertTrue(wrapper.exists(fileViaLink)); + assertTrue(wrapper.isFile(fileViaLink)); + assertFalse(wrapper.isDir(fileViaLink)); + assertFalse(wrapper.getFileLinkStatus(fileViaLink).isSymlink()); + assertFalse(wrapper.isDir(fileViaLink)); + assertEquals(wrapper.getFileStatus(file), + wrapper.getFileLinkStatus(file)); + assertEquals(wrapper.getFileStatus(fileViaLink), + wrapper.getFileLinkStatus(fileViaLink)); readFile(fileViaLink); appendToFile(fileViaLink); - fc.rename(fileViaLink, fileNewViaLink); - assertFalse(exists(fc, fileViaLink)); - assertTrue(exists(fc, fileNewViaLink)); + wrapper.rename(fileViaLink, fileNewViaLink); + assertFalse(wrapper.exists(fileViaLink)); + assertTrue(wrapper.exists(fileNewViaLink)); readFile(fileNewViaLink); - assertEquals(fc.getFileBlockLocations(fileNew, 0, 1).length, - fc.getFileBlockLocations(fileNewViaLink, 0, 1).length); - assertEquals(fc.getFileChecksum(fileNew), - fc.getFileChecksum(fileNewViaLink)); - fc.delete(fileNewViaLink, true); - assertFalse(exists(fc, fileNewViaLink)); + assertEquals(wrapper.getFileBlockLocations(fileNew, 0, 1).length, + wrapper.getFileBlockLocations(fileNewViaLink, 0, 1).length); + assertEquals(wrapper.getFileChecksum(fileNew), + wrapper.getFileChecksum(fileNewViaLink)); + wrapper.delete(fileNewViaLink, true); + assertFalse(wrapper.exists(fileNewViaLink)); } - @Test + @Test(timeout=10000) /** * Operate on a file using a path with an intermediate symlink where * the link target was specified as a fully qualified path. @@ -1275,83 +1294,80 @@ public void testAccessFileViaInterSymlinkAbsTarget() throws IOException { public void testAccessFileViaInterSymlinkQualTarget() throws IOException { Path baseDir = new Path(testBaseDir1()); Path file = new Path(testBaseDir1(), "file"); - Path fileNew = new Path(baseDir, "fileNew"); Path linkToDir = new Path(testBaseDir2(), "linkToDir"); Path fileViaLink = new Path(linkToDir, "file"); - Path fileNewViaLink = new Path(linkToDir, "fileNew"); - fc.createSymlink(fc.makeQualified(baseDir), linkToDir, false); + wrapper.createSymlink(wrapper.makeQualified(baseDir), linkToDir, false); createAndWriteFile(fileViaLink); - assertEquals(fc.getFileStatus(file), - fc.getFileLinkStatus(file)); - assertEquals(fc.getFileStatus(fileViaLink), - fc.getFileLinkStatus(fileViaLink)); + assertEquals(wrapper.getFileStatus(file), + wrapper.getFileLinkStatus(file)); + assertEquals(wrapper.getFileStatus(fileViaLink), + wrapper.getFileLinkStatus(fileViaLink)); readFile(fileViaLink); } - @Test + @Test(timeout=10000) /** * Operate on a file using a path with an intermediate symlink where * the link target was specified as a relative path. */ public void testAccessFileViaInterSymlinkRelTarget() throws IOException { assumeTrue(!"file".equals(getScheme())); - Path baseDir = new Path(testBaseDir1()); Path dir = new Path(testBaseDir1(), "dir"); Path file = new Path(dir, "file"); Path linkToDir = new Path(testBaseDir1(), "linkToDir"); Path fileViaLink = new Path(linkToDir, "file"); - fc.mkdir(dir, FileContext.DEFAULT_PERM, false); - fc.createSymlink(new Path("dir"), linkToDir, false); + wrapper.mkdir(dir, FileContext.DEFAULT_PERM, false); + wrapper.createSymlink(new Path("dir"), linkToDir, false); createAndWriteFile(fileViaLink); // Note that getFileStatus returns fully qualified paths even // when called on an absolute path. - assertEquals(fc.makeQualified(file), - fc.getFileStatus(file).getPath()); + assertEquals(wrapper.makeQualified(file), + wrapper.getFileStatus(file).getPath()); // In each case getFileLinkStatus returns the same FileStatus // as getFileStatus since we're not calling it on a link and // FileStatus objects are compared by Path. - assertEquals(fc.getFileStatus(file), - fc.getFileLinkStatus(file)); - assertEquals(fc.getFileStatus(fileViaLink), - fc.getFileLinkStatus(fileViaLink)); - assertEquals(fc.getFileStatus(fileViaLink), - fc.getFileLinkStatus(file)); + assertEquals(wrapper.getFileStatus(file), + wrapper.getFileLinkStatus(file)); + assertEquals(wrapper.getFileStatus(fileViaLink), + wrapper.getFileLinkStatus(fileViaLink)); + assertEquals(wrapper.getFileStatus(fileViaLink), + wrapper.getFileLinkStatus(file)); } - @Test + @Test(timeout=10000) /** Test create, list, and delete a directory through a symlink */ public void testAccessDirViaSymlink() throws IOException { Path baseDir = new Path(testBaseDir1()); Path dir = new Path(testBaseDir1(), "dir"); Path linkToDir = new Path(testBaseDir2(), "linkToDir"); Path dirViaLink = new Path(linkToDir, "dir"); - fc.createSymlink(baseDir, linkToDir, false); - fc.mkdir(dirViaLink, FileContext.DEFAULT_PERM, true); - assertTrue(fc.getFileStatus(dirViaLink).isDirectory()); - FileStatus[] stats = fc.util().listStatus(dirViaLink); + wrapper.createSymlink(baseDir, linkToDir, false); + wrapper.mkdir(dirViaLink, FileContext.DEFAULT_PERM, true); + assertTrue(wrapper.getFileStatus(dirViaLink).isDirectory()); + FileStatus[] stats = wrapper.listStatus(dirViaLink); assertEquals(0, stats.length); - RemoteIterator statsItor = fc.listStatus(dirViaLink); + RemoteIterator statsItor = wrapper.listStatusIterator(dirViaLink); assertFalse(statsItor.hasNext()); - fc.delete(dirViaLink, false); - assertFalse(exists(fc, dirViaLink)); - assertFalse(exists(fc, dir)); + wrapper.delete(dirViaLink, false); + assertFalse(wrapper.exists(dirViaLink)); + assertFalse(wrapper.exists(dir)); } - @Test - /** setTimes affects the target not the link */ + @Test(timeout=10000) + /** setTimes affects the target not the link */ public void testSetTimes() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); - long at = fc.getFileLinkStatus(link).getAccessTime(); - fc.setTimes(link, 2L, 3L); + wrapper.createSymlink(file, link, false); + long at = wrapper.getFileLinkStatus(link).getAccessTime(); + wrapper.setTimes(link, 2L, 3L); // NB: local file systems don't implement setTimes if (!"file".equals(getScheme())) { - assertEquals(at, fc.getFileLinkStatus(link).getAccessTime()); - assertEquals(3, fc.getFileStatus(file).getAccessTime()); - assertEquals(2, fc.getFileStatus(file).getModificationTime()); + assertEquals(at, wrapper.getFileLinkStatus(link).getAccessTime()); + assertEquals(3, wrapper.getFileStatus(file).getAccessTime()); + assertEquals(2, wrapper.getFileStatus(file).getModificationTime()); } } } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestLocalFSFileContextSymlink.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestSymlinkLocalFS.java similarity index 79% rename from hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestLocalFSFileContextSymlink.java rename to hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestSymlinkLocalFS.java index 14924313e5d..ccfe37f5663 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestLocalFSFileContextSymlink.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestSymlinkLocalFS.java @@ -17,23 +17,25 @@ */ package org.apache.hadoop.fs; -import java.io.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import org.apache.hadoop.fs.FileContext; import org.apache.hadoop.fs.permission.FsPermission; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.fs.FileUtil; -import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; import org.junit.Test; -import org.junit.Before; /** - * Test symbolic links using FileContext and LocalFs. + * Test symbolic links using LocalFs. */ -public class TestLocalFSFileContextSymlink extends FileContextSymlinkBaseTest { +abstract public class TestSymlinkLocalFS extends SymlinkBaseTest { @Override protected String getScheme() { @@ -42,12 +44,12 @@ protected String getScheme() { @Override protected String testBaseDir1() throws IOException { - return fileContextTestHelper.getAbsoluteTestRootDir(fc)+"/test1"; + return wrapper.getAbsoluteTestRootDir()+"/test1"; } @Override protected String testBaseDir2() throws IOException { - return fileContextTestHelper.getAbsoluteTestRootDir(fc)+"/test2"; + return wrapper.getAbsoluteTestRootDir()+"/test2"; } @Override @@ -58,13 +60,6 @@ protected URI testURI() { return null; } } - - @Override - @Before - public void setUp() throws Exception { - fc = FileContext.getLocalFSFileContext(); - super.setUp(); - } @Override public void testCreateDanglingLink() throws IOException { @@ -103,32 +98,32 @@ public void testStatDanglingLink() throws IOException { super.testStatDanglingLink(); } - @Test + @Test(timeout=1000) /** lstat a non-existant file using a partially qualified path */ public void testDanglingLinkFilePartQual() throws IOException { Path filePartQual = new Path(getScheme()+":///doesNotExist"); try { - fc.getFileLinkStatus(filePartQual); + wrapper.getFileLinkStatus(filePartQual); fail("Got FileStatus for non-existant file"); } catch (FileNotFoundException f) { // Expected } try { - fc.getLinkTarget(filePartQual); - fail("Got link target for non-existant file"); + wrapper.getLinkTarget(filePartQual); + fail("Got link target for non-existant file"); } catch (FileNotFoundException f) { // Expected } } - @Test + @Test(timeout=1000) /** Stat and lstat a dangling link */ public void testDanglingLink() throws IOException { assumeTrue(!Path.WINDOWS); - Path fileAbs = new Path(testBaseDir1()+"/file"); - Path fileQual = new Path(testURI().toString(), fileAbs); + Path fileAbs = new Path(testBaseDir1()+"/file"); + Path fileQual = new Path(testURI().toString(), fileAbs); Path link = new Path(testBaseDir1()+"/linkToFile"); - fc.createSymlink(fileAbs, link, false); + wrapper.createSymlink(fileAbs, link, false); // Deleting the link using FileContext currently fails because // resolve looks up LocalFs rather than RawLocalFs for the path // so we call ChecksumFs delete (which doesn't delete dangling @@ -137,15 +132,15 @@ public void testDanglingLink() throws IOException { // because the link is not dangling. //assertTrue(fc.delete(link, false)); FileUtil.fullyDelete(new File(link.toUri().getPath())); - fc.createSymlink(fileAbs, link, false); + wrapper.createSymlink(fileAbs, link, false); try { - fc.getFileStatus(link); + wrapper.getFileStatus(link); fail("Got FileStatus for dangling link"); } catch (FileNotFoundException f) { // Expected. File's exists method returns false for dangling links } // We can stat a dangling link - FileStatus fsd = fc.getFileLinkStatus(link); + FileStatus fsd = wrapper.getFileLinkStatus(link); assertEquals(fileQual, fsd.getSymlink()); assertTrue(fsd.isSymlink()); assertFalse(fsd.isDirectory()); @@ -166,10 +161,10 @@ public void testDanglingLink() throws IOException { } // Creating the file makes the link work createAndWriteFile(fileAbs); - fc.getFileStatus(link); + wrapper.getFileStatus(link); } - @Test + @Test(timeout=1000) /** * Test getLinkTarget with a partially qualified target. * NB: Hadoop does not support fully qualified URIs for the @@ -178,21 +173,21 @@ public void testDanglingLink() throws IOException { public void testGetLinkStatusPartQualTarget() throws IOException { Path fileAbs = new Path(testBaseDir1()+"/file"); Path fileQual = new Path(testURI().toString(), fileAbs); - Path dir = new Path(testBaseDir1()); + Path dir = new Path(testBaseDir1()); Path link = new Path(testBaseDir1()+"/linkToFile"); Path dirNew = new Path(testBaseDir2()); Path linkNew = new Path(testBaseDir2()+"/linkToFile"); - fc.delete(dirNew, true); + wrapper.delete(dirNew, true); createAndWriteFile(fileQual); - fc.setWorkingDirectory(dir); + wrapper.setWorkingDirectory(dir); // Link target is partially qualified, we get the same back. - fc.createSymlink(fileQual, link, false); - assertEquals(fileQual, fc.getFileLinkStatus(link).getSymlink()); + wrapper.createSymlink(fileQual, link, false); + assertEquals(fileQual, wrapper.getFileLinkStatus(link).getSymlink()); // Because the target was specified with an absolute path the // link fails to resolve after moving the parent directory. - fc.rename(dir, dirNew); + wrapper.rename(dir, dirNew); // The target is still the old path - assertEquals(fileQual, fc.getFileLinkStatus(linkNew).getSymlink()); + assertEquals(fileQual, wrapper.getFileLinkStatus(linkNew).getSymlink()); try { readFile(linkNew); fail("The link should be dangling now."); @@ -204,7 +199,7 @@ public void testGetLinkStatusPartQualTarget() throws IOException { Path anotherFs = new Path("hdfs://host:1000/dir/file"); FileUtil.fullyDelete(new File(linkNew.toString())); try { - fc.createSymlink(anotherFs, linkNew, false); + wrapper.createSymlink(anotherFs, linkNew, false); fail("Created a local fs link to a non-local fs"); } catch (IOException x) { // Excpected. diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestSymlinkLocalFSFileContext.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestSymlinkLocalFSFileContext.java new file mode 100644 index 00000000000..8d6ac96154c --- /dev/null +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestSymlinkLocalFSFileContext.java @@ -0,0 +1,30 @@ +/** + * 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; + +import org.junit.BeforeClass; + +public class TestSymlinkLocalFSFileContext extends TestSymlinkLocalFS { + + @BeforeClass + public static void testSetup() throws Exception { + FileContext context = FileContext.getLocalFSFileContext(); + wrapper = new FileContextTestWrapper(context); + } + +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestFcHdfsSymlink.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestSymlinkHdfs.java similarity index 63% rename from hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestFcHdfsSymlink.java rename to hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestSymlinkHdfs.java index c59c75db565..f6fd6b8487d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestFcHdfsSymlink.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestSymlinkHdfs.java @@ -36,26 +36,25 @@ import org.apache.hadoop.hdfs.web.WebHdfsFileSystem; import org.apache.hadoop.hdfs.web.WebHdfsTestUtil; import org.apache.hadoop.ipc.RemoteException; +import org.apache.hadoop.test.GenericTestUtils; import org.apache.log4j.Level; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** - * Test symbolic links using FileContext and Hdfs. + * Test symbolic links in Hdfs. */ -public class TestFcHdfsSymlink extends FileContextSymlinkBaseTest { +abstract public class TestSymlinkHdfs extends SymlinkBaseTest { { ((Log4JLogger)NameNode.stateChangeLog).getLogger().setLevel(Level.ALL); } - private static FileContextTestHelper fileContextTestHelper = - new FileContextTestHelper("/tmp/TestFcHdfsSymlink"); - private static MiniDFSCluster cluster; - private static WebHdfsFileSystem webhdfs; - private static DistributedFileSystem dfs; - + protected static MiniDFSCluster cluster; + protected static WebHdfsFileSystem webhdfs; + protected static DistributedFileSystem dfs; + @Override protected String getScheme() { return "hdfs"; @@ -85,90 +84,82 @@ protected IOException unwrapException(IOException e) { } @BeforeClass - public static void testSetUp() throws Exception { + public static void beforeClassSetup() throws Exception { Configuration conf = new HdfsConfiguration(); conf.setBoolean(DFSConfigKeys.DFS_WEBHDFS_ENABLED_KEY, true); conf.set(FsPermission.UMASK_LABEL, "000"); cluster = new MiniDFSCluster.Builder(conf).build(); - fc = FileContext.getFileContext(cluster.getURI(0)); webhdfs = WebHdfsTestUtil.getWebHdfsFileSystem(conf); dfs = cluster.getFileSystem(); } - + @AfterClass - public static void testTearDown() throws Exception { + public static void afterClassTeardown() throws Exception { cluster.shutdown(); } - - @Test + + @Test(timeout=10000) /** Access a file using a link that spans Hdfs to LocalFs */ public void testLinkAcrossFileSystems() throws IOException { - FileContext localFc = FileContext.getLocalFSFileContext(); - Path localDir = new Path("file://"+fileContextTestHelper.getAbsoluteTestRootDir(localFc)+"/test"); - Path localFile = new Path("file://"+fileContextTestHelper.getAbsoluteTestRootDir(localFc)+"/test/file"); + Path localDir = new Path("file://" + wrapper.getAbsoluteTestRootDir() + + "/test"); + Path localFile = new Path("file://" + wrapper.getAbsoluteTestRootDir() + + "/test/file"); Path link = new Path(testBaseDir1(), "linkToFile"); - localFc.delete(localDir, true); - localFc.mkdir(localDir, FileContext.DEFAULT_PERM, true); - localFc.setWorkingDirectory(localDir); - assertEquals(localDir, localFc.getWorkingDirectory()); - createAndWriteFile(localFc, localFile); - fc.createSymlink(localFile, link, false); + FSTestWrapper localWrapper = wrapper.getLocalFSWrapper(); + localWrapper.delete(localDir, true); + localWrapper.mkdir(localDir, FileContext.DEFAULT_PERM, true); + localWrapper.setWorkingDirectory(localDir); + assertEquals(localDir, localWrapper.getWorkingDirectory()); + createAndWriteFile(localWrapper, localFile); + wrapper.createSymlink(localFile, link, false); readFile(link); - assertEquals(fileSize, fc.getFileStatus(link).getLen()); + assertEquals(fileSize, wrapper.getFileStatus(link).getLen()); } - @Test + @Test(timeout=10000) /** Test renaming a file across two file systems using a link */ public void testRenameAcrossFileSystemsViaLink() throws IOException { - FileContext localFc = FileContext.getLocalFSFileContext(); - Path localDir = new Path("file://"+fileContextTestHelper.getAbsoluteTestRootDir(localFc)+"/test"); + Path localDir = new Path("file://" + wrapper.getAbsoluteTestRootDir() + + "/test"); Path hdfsFile = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "link"); Path hdfsFileNew = new Path(testBaseDir1(), "fileNew"); Path hdfsFileNewViaLink = new Path(link, "fileNew"); - localFc.delete(localDir, true); - localFc.mkdir(localDir, FileContext.DEFAULT_PERM, true); - localFc.setWorkingDirectory(localDir); - createAndWriteFile(fc, hdfsFile); - fc.createSymlink(localDir, link, false); + FSTestWrapper localWrapper = wrapper.getLocalFSWrapper(); + localWrapper.delete(localDir, true); + localWrapper.mkdir(localDir, FileContext.DEFAULT_PERM, true); + localWrapper.setWorkingDirectory(localDir); + createAndWriteFile(hdfsFile); + wrapper.createSymlink(localDir, link, false); // Rename hdfs://test1/file to hdfs://test1/link/fileNew // which renames to file://TEST_ROOT/test/fileNew which // spans AbstractFileSystems and therefore fails. try { - fc.rename(hdfsFile, hdfsFileNewViaLink); + wrapper.rename(hdfsFile, hdfsFileNewViaLink); fail("Renamed across file systems"); } catch (InvalidPathException ipe) { - // Expected + // Expected from FileContext + } catch (IllegalArgumentException e) { + // Expected from Filesystem + GenericTestUtils.assertExceptionContains("Wrong FS: ", e); } // Now rename hdfs://test1/link/fileNew to hdfs://test1/fileNew // which renames file://TEST_ROOT/test/fileNew to hdfs://test1/fileNew // which spans AbstractFileSystems and therefore fails. - createAndWriteFile(fc, hdfsFileNewViaLink); + createAndWriteFile(hdfsFileNewViaLink); try { - fc.rename(hdfsFileNewViaLink, hdfsFileNew); + wrapper.rename(hdfsFileNewViaLink, hdfsFileNew); fail("Renamed across file systems"); } catch (InvalidPathException ipe) { - // Expected + // Expected from FileContext + } catch (IllegalArgumentException e) { + // Expected from Filesystem + GenericTestUtils.assertExceptionContains("Wrong FS: ", e); } } - @Test - /** Test access a symlink using AbstractFileSystem */ - public void testAccessLinkFromAbstractFileSystem() throws IOException { - Path file = new Path(testBaseDir1(), "file"); - Path link = new Path(testBaseDir1(), "linkToFile"); - createAndWriteFile(file); - fc.createSymlink(file, link, false); - try { - AbstractFileSystem afs = fc.getDefaultFileSystem(); - afs.open(link); - fail("Opened a link using AFS"); - } catch (UnresolvedLinkException x) { - // Expected - } - } - - @Test + @Test(timeout=10000) /** Test create symlink to / */ public void testCreateLinkToSlash() throws IOException { Path dir = new Path(testBaseDir1()); @@ -177,59 +168,61 @@ public void testCreateLinkToSlash() throws IOException { Path fileViaLink = new Path(testBaseDir1()+"/linkToSlash"+ testBaseDir1()+"/file"); createAndWriteFile(file); - fc.setWorkingDirectory(dir); - fc.createSymlink(new Path("/"), link, false); + wrapper.setWorkingDirectory(dir); + wrapper.createSymlink(new Path("/"), link, false); readFile(fileViaLink); - assertEquals(fileSize, fc.getFileStatus(fileViaLink).getLen()); + assertEquals(fileSize, wrapper.getFileStatus(fileViaLink).getLen()); // Ditto when using another file context since the file system // for the slash is resolved according to the link's parent. - FileContext localFc = FileContext.getLocalFSFileContext(); - Path linkQual = new Path(cluster.getURI(0).toString(), fileViaLink); - assertEquals(fileSize, localFc.getFileStatus(linkQual).getLen()); + if (wrapper instanceof FileContextTestWrapper) { + FSTestWrapper localWrapper = wrapper.getLocalFSWrapper(); + Path linkQual = new Path(cluster.getURI(0).toString(), fileViaLink); + assertEquals(fileSize, localWrapper.getFileStatus(linkQual).getLen()); + } } - @Test + @Test(timeout=10000) /** setPermission affects the target not the link */ - public void testSetPermissionAffectsTarget() throws IOException { + public void testSetPermissionAffectsTarget() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path dir = new Path(testBaseDir2()); Path linkToFile = new Path(testBaseDir1(), "linkToFile"); Path linkToDir = new Path(testBaseDir1(), "linkToDir"); createAndWriteFile(file); - fc.createSymlink(file, linkToFile, false); - fc.createSymlink(dir, linkToDir, false); + wrapper.createSymlink(file, linkToFile, false); + wrapper.createSymlink(dir, linkToDir, false); // Changing the permissions using the link does not modify // the permissions of the link.. - FsPermission perms = fc.getFileLinkStatus(linkToFile).getPermission(); - fc.setPermission(linkToFile, new FsPermission((short)0664)); - fc.setOwner(linkToFile, "user", "group"); - assertEquals(perms, fc.getFileLinkStatus(linkToFile).getPermission()); + FsPermission perms = wrapper.getFileLinkStatus(linkToFile).getPermission(); + wrapper.setPermission(linkToFile, new FsPermission((short)0664)); + wrapper.setOwner(linkToFile, "user", "group"); + assertEquals(perms, wrapper.getFileLinkStatus(linkToFile).getPermission()); // but the file's permissions were adjusted appropriately - FileStatus stat = fc.getFileStatus(file); - assertEquals(0664, stat.getPermission().toShort()); + FileStatus stat = wrapper.getFileStatus(file); + assertEquals(0664, stat.getPermission().toShort()); assertEquals("user", stat.getOwner()); assertEquals("group", stat.getGroup()); // Getting the file's permissions via the link is the same // as getting the permissions directly. assertEquals(stat.getPermission(), - fc.getFileStatus(linkToFile).getPermission()); + wrapper.getFileStatus(linkToFile).getPermission()); // Ditto for a link to a directory - perms = fc.getFileLinkStatus(linkToDir).getPermission(); - fc.setPermission(linkToDir, new FsPermission((short)0664)); - fc.setOwner(linkToDir, "user", "group"); - assertEquals(perms, fc.getFileLinkStatus(linkToDir).getPermission()); - stat = fc.getFileStatus(dir); - assertEquals(0664, stat.getPermission().toShort()); + perms = wrapper.getFileLinkStatus(linkToDir).getPermission(); + wrapper.setPermission(linkToDir, new FsPermission((short)0664)); + wrapper.setOwner(linkToDir, "user", "group"); + assertEquals(perms, wrapper.getFileLinkStatus(linkToDir).getPermission()); + stat = wrapper.getFileStatus(dir); + assertEquals(0664, stat.getPermission().toShort()); assertEquals("user", stat.getOwner()); assertEquals("group", stat.getGroup()); assertEquals(stat.getPermission(), - fc.getFileStatus(linkToDir).getPermission()); + wrapper.getFileStatus(linkToDir).getPermission()); } - @Test + @Test(timeout=10000) /** Create a symlink using a path with scheme but no authority */ public void testCreateWithPartQualPathFails() throws IOException { Path fileWoAuth = new Path("hdfs:///test/file"); @@ -241,27 +234,27 @@ public void testCreateWithPartQualPathFails() throws IOException { // Expected } try { - fc.createSymlink(new Path("foo"), linkWoAuth, false); + wrapper.createSymlink(new Path("foo"), linkWoAuth, false); fail("HDFS requires URIs with schemes have an authority"); } catch (RuntimeException e) { // Expected } } - @Test - /** setReplication affects the target not the link */ + @Test(timeout=10000) + /** setReplication affects the target not the link */ public void testSetReplication() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); - fc.setReplication(link, (short)2); - assertEquals(0, fc.getFileLinkStatus(link).getReplication()); - assertEquals(2, fc.getFileStatus(link).getReplication()); - assertEquals(2, fc.getFileStatus(file).getReplication()); + wrapper.createSymlink(file, link, false); + wrapper.setReplication(link, (short)2); + assertEquals(0, wrapper.getFileLinkStatus(link).getReplication()); + assertEquals(2, wrapper.getFileStatus(link).getReplication()); + assertEquals(2, wrapper.getFileStatus(file).getReplication()); } - @Test + @Test(timeout=10000) /** Test create symlink with a max len name */ public void testCreateLinkMaxPathLink() throws IOException { Path dir = new Path(testBaseDir1()); @@ -283,47 +276,47 @@ public void testCreateLinkMaxPathLink() throws IOException { // Check that it works createAndWriteFile(file); - fc.setWorkingDirectory(dir); - fc.createSymlink(file, link, false); + wrapper.setWorkingDirectory(dir); + wrapper.createSymlink(file, link, false); readFile(link); // Now modify the path so it's too large link = new Path(sb.toString()+"x"); try { - fc.createSymlink(file, link, false); + wrapper.createSymlink(file, link, false); fail("Path name should be too long"); } catch (IOException x) { // Expected } } - @Test + @Test(timeout=10000) /** Test symlink owner */ public void testLinkOwner() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "symlinkToFile"); createAndWriteFile(file); - fc.createSymlink(file, link, false); - FileStatus statFile = fc.getFileStatus(file); - FileStatus statLink = fc.getFileStatus(link); + wrapper.createSymlink(file, link, false); + FileStatus statFile = wrapper.getFileStatus(file); + FileStatus statLink = wrapper.getFileStatus(link); assertEquals(statLink.getOwner(), statFile.getOwner()); } - @Test - /** Test WebHdfsFileSystem.craeteSymlink(..). */ + @Test(timeout=10000) + /** Test WebHdfsFileSystem.createSymlink(..). */ public void testWebHDFS() throws IOException { Path file = new Path(testBaseDir1(), "file"); Path link = new Path(testBaseDir1(), "linkToFile"); createAndWriteFile(file); webhdfs.createSymlink(file, link, false); - fc.setReplication(link, (short)2); - assertEquals(0, fc.getFileLinkStatus(link).getReplication()); - assertEquals(2, fc.getFileStatus(link).getReplication()); - assertEquals(2, fc.getFileStatus(file).getReplication()); + wrapper.setReplication(link, (short)2); + assertEquals(0, wrapper.getFileLinkStatus(link).getReplication()); + assertEquals(2, wrapper.getFileStatus(link).getReplication()); + assertEquals(2, wrapper.getFileStatus(file).getReplication()); } - @Test - /** Test craeteSymlink(..) with quota. */ + @Test(timeout=10000) + /** Test craeteSymlink(..) with quota. */ public void testQuota() throws IOException { final Path dir = new Path(testBaseDir1()); dfs.setQuota(dir, 3, HdfsConstants.QUOTA_DONT_SET); @@ -333,12 +326,12 @@ public void testQuota() throws IOException { //creating the first link should succeed final Path link1 = new Path(dir, "link1"); - fc.createSymlink(file, link1, false); + wrapper.createSymlink(file, link1, false); try { //creating the second link should fail with QuotaExceededException. final Path link2 = new Path(dir, "link2"); - fc.createSymlink(file, link2, false); + wrapper.createSymlink(file, link2, false); fail("Created symlink despite quota violation"); } catch(QuotaExceededException qee) { //expected diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestSymlinkHdfsFileContext.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestSymlinkHdfsFileContext.java new file mode 100644 index 00000000000..d94a5145a97 --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/TestSymlinkHdfsFileContext.java @@ -0,0 +1,52 @@ +/** + * 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; + +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class TestSymlinkHdfsFileContext extends TestSymlinkHdfs { + + private static FileContext fc; + + @BeforeClass + public static void testSetup() throws Exception { + fc = FileContext.getFileContext(cluster.getURI(0)); + wrapper = new FileContextTestWrapper(fc, "/tmp/TestSymlinkHdfsFileContext"); + } + + @Test(timeout=1000) + /** Test access a symlink using AbstractFileSystem */ + public void testAccessLinkFromAbstractFileSystem() throws IOException { + Path file = new Path(testBaseDir1(), "file"); + Path link = new Path(testBaseDir1(), "linkToFile"); + createAndWriteFile(file); + wrapper.createSymlink(file, link, false); + try { + AbstractFileSystem afs = fc.getDefaultFileSystem(); + afs.open(link); + fail("Opened a link using AFS"); + } catch (UnresolvedLinkException x) { + // Expected + } + } +}