/* * 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.swift; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.swift.util.SwiftTestUtils; import org.junit.Test; import java.io.IOException; import static org.apache.hadoop.fs.swift.util.SwiftTestUtils.compareByteArrays; import static org.apache.hadoop.fs.swift.util.SwiftTestUtils.dataset; import static org.apache.hadoop.fs.swift.util.SwiftTestUtils.readBytesToString; import static org.apache.hadoop.fs.swift.util.SwiftTestUtils.readDataset; import static org.apache.hadoop.fs.swift.util.SwiftTestUtils.writeDataset; public class TestSwiftFileSystemRename extends SwiftFileSystemBaseTest { /** * Rename a file into a directory * * @throws Exception */ @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameFileIntoExistingDirectory() throws Exception { assumeRenameSupported(); Path src = path("/test/olddir/file"); createFile(src); Path dst = path("/test/new/newdir"); fs.mkdirs(dst); rename(src, dst, true, false, true); Path newFile = path("/test/new/newdir/file"); if (!fs.exists(newFile)) { String ls = ls(dst); LOG.info(ls(path("/test/new"))); LOG.info(ls(path("/test/hadoop"))); fail("did not find " + newFile + " - directory: " + ls); } assertTrue("Destination changed", fs.exists(path("/test/new/newdir/file"))); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameFile() throws Exception { assumeRenameSupported(); final Path old = new Path("/test/alice/file"); final Path newPath = new Path("/test/bob/file"); fs.mkdirs(newPath.getParent()); final FSDataOutputStream fsDataOutputStream = fs.create(old); final byte[] message = "Some data".getBytes(); fsDataOutputStream.write(message); fsDataOutputStream.close(); assertTrue(fs.exists(old)); rename(old, newPath, true, false, true); final FSDataInputStream bobStream = fs.open(newPath); final byte[] bytes = new byte[512]; final int read = bobStream.read(bytes); bobStream.close(); final byte[] buffer = new byte[read]; System.arraycopy(bytes, 0, buffer, 0, read); assertEquals(new String(message), new String(buffer)); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameDirectory() throws Exception { assumeRenameSupported(); final Path old = new Path("/test/data/logs"); final Path newPath = new Path("/test/var/logs"); fs.mkdirs(old); fs.mkdirs(newPath.getParent()); assertTrue(fs.exists(old)); rename(old, newPath, true, false, true); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameTheSameDirectory() throws Exception { assumeRenameSupported(); final Path old = new Path("/test/usr/data"); fs.mkdirs(old); rename(old, old, false, true, true); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameDirectoryIntoExistingDirectory() throws Exception { assumeRenameSupported(); Path src = path("/test/olddir/dir"); fs.mkdirs(src); createFile(path("/test/olddir/dir/file1")); createFile(path("/test/olddir/dir/subdir/file2")); Path dst = path("/test/new/newdir"); fs.mkdirs(dst); //this renames into a child rename(src, dst, true, false, true); assertExists("new dir", path("/test/new/newdir/dir")); assertExists("Renamed nested file1", path("/test/new/newdir/dir/file1")); assertPathDoesNotExist("Nested file1 should have been deleted", path("/test/olddir/dir/file1")); assertExists("Renamed nested subdir", path("/test/new/newdir/dir/subdir/")); assertExists("file under subdir", path("/test/new/newdir/dir/subdir/file2")); assertPathDoesNotExist("Nested /test/hadoop/dir/subdir/file2 still exists", path("/test/olddir/dir/subdir/file2")); } /** * trying to rename a directory onto itself should fail, * preserving everything underneath. */ @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameDirToSelf() throws Throwable { assumeRenameSupported(); Path parentdir = path("/test/parentdir"); fs.mkdirs(parentdir); Path child = new Path(parentdir, "child"); createFile(child); rename(parentdir, parentdir, false, true, true); //verify the child is still there assertIsFile(child); } /** * Assert that root directory renames are not allowed * * @throws Exception on failures */ @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameRootDirForbidden() throws Exception { assumeRenameSupported(); rename(path("/"), path("/test/newRootDir"), false, true, false); } /** * Assert that renaming a parent directory to be a child * of itself is forbidden * * @throws Exception on failures */ @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameChildDirForbidden() throws Exception { assumeRenameSupported(); Path parentdir = path("/test/parentdir"); fs.mkdirs(parentdir); Path childFile = new Path(parentdir, "childfile"); createFile(childFile); //verify one level down Path childdir = new Path(parentdir, "childdir"); rename(parentdir, childdir, false, true, false); //now another level fs.mkdirs(childdir); Path childchilddir = new Path(childdir, "childdir"); rename(parentdir, childchilddir, false, true, false); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameFileAndVerifyContents() throws IOException { assumeRenameSupported(); final Path filePath = new Path("/test/home/user/documents/file.txt"); final Path newFilePath = new Path("/test/home/user/files/file.txt"); mkdirs(newFilePath.getParent()); int len = 1024; byte[] dataset = dataset(len, 'A', 26); writeDataset(fs, filePath, dataset, len, len, false); rename(filePath, newFilePath, true, false, true); byte[] dest = readDataset(fs, newFilePath, len); compareByteArrays(dataset, dest, len); String reread = readBytesToString(fs, newFilePath, 20); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testMoveFileUnderParent() throws Throwable { if (!renameSupported()) return; Path filepath = path("test/file"); createFile(filepath); //HDFS expects rename src, src -> true rename(filepath, filepath, true, true, true); //verify the file is still there assertIsFile(filepath); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testMoveDirUnderParent() throws Throwable { if (!renameSupported()) { return; } Path testdir = path("test/dir"); fs.mkdirs(testdir); Path parent = testdir.getParent(); //the outcome here is ambiguous, so is not checked fs.rename(testdir, parent); assertExists("Source directory has been deleted ", testdir); } /** * trying to rename a file onto itself should succeed (it's a no-op) */ @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameFileToSelf() throws Throwable { if (!renameSupported()) return; Path filepath = path("test/file"); createFile(filepath); //HDFS expects rename src, src -> true rename(filepath, filepath, true, true, true); //verify the file is still there assertIsFile(filepath); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenamedConsistence() throws IOException { assumeRenameSupported(); describe("verify that overwriting a file with new data doesn't impact" + " the existing content"); final Path filePath = new Path("/test/home/user/documents/file.txt"); final Path newFilePath = new Path("/test/home/user/files/file.txt"); mkdirs(newFilePath.getParent()); int len = 1024; byte[] dataset = dataset(len, 'A', 26); byte[] dataset2 = dataset(len, 'a', 26); writeDataset(fs, filePath, dataset, len, len, false); rename(filePath, newFilePath, true, false, true); SwiftTestUtils.writeAndRead(fs, filePath, dataset2, len, len, false, true); byte[] dest = readDataset(fs, newFilePath, len); compareByteArrays(dataset, dest, len); String reread = readBytesToString(fs, newFilePath, 20); } @Test(timeout = SWIFT_TEST_TIMEOUT) public void testRenameMissingFile() throws Throwable { assumeRenameSupported(); Path path = path("/test/RenameMissingFile"); Path path2 = path("/test/RenameMissingFileDest"); mkdirs(path("test")); rename(path, path2, false, false, false); } }