| /** |
| * 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.tools.util; |
| |
| import org.apache.hadoop.tools.DistCpOptions.FileAttribute; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.FileSystem; |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.fs.FileStatus; |
| import org.apache.hadoop.fs.permission.FsPermission; |
| import org.apache.hadoop.hdfs.MiniDFSCluster; |
| import org.apache.hadoop.io.IOUtils; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.junit.Assert; |
| import org.junit.Test; |
| import org.junit.BeforeClass; |
| import org.junit.AfterClass; |
| |
| import java.util.EnumSet; |
| import java.util.Random; |
| import java.util.Stack; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| |
| public class TestDistCpUtils { |
| private static final Log LOG = LogFactory.getLog(TestDistCpUtils.class); |
| |
| private static final Configuration config = new Configuration(); |
| private static MiniDFSCluster cluster; |
| |
| @BeforeClass |
| public static void create() throws IOException { |
| cluster = new MiniDFSCluster.Builder(config).numDataNodes(1).format(true) |
| .build(); |
| } |
| |
| @AfterClass |
| public static void destroy() { |
| if (cluster != null) { |
| cluster.shutdown(); |
| } |
| } |
| |
| @Test |
| public void testGetRelativePathRoot() { |
| Path root = new Path("/tmp/abc"); |
| Path child = new Path("/tmp/abc/xyz/file"); |
| Assert.assertEquals(DistCpUtils.getRelativePath(root, child), "/xyz/file"); |
| |
| root = new Path("/"); |
| child = new Path("/a"); |
| Assert.assertEquals(DistCpUtils.getRelativePath(root, child), "/a"); |
| } |
| |
| @Test |
| public void testPackAttributes() { |
| EnumSet<FileAttribute> attributes = EnumSet.noneOf(FileAttribute.class); |
| Assert.assertEquals(DistCpUtils.packAttributes(attributes), ""); |
| |
| attributes.add(FileAttribute.REPLICATION); |
| Assert.assertEquals(DistCpUtils.packAttributes(attributes), "R"); |
| Assert.assertEquals(attributes, DistCpUtils.unpackAttributes("R")); |
| |
| attributes.add(FileAttribute.BLOCKSIZE); |
| Assert.assertEquals(DistCpUtils.packAttributes(attributes), "RB"); |
| Assert.assertEquals(attributes, DistCpUtils.unpackAttributes("RB")); |
| |
| attributes.add(FileAttribute.USER); |
| Assert.assertEquals(DistCpUtils.packAttributes(attributes), "RBU"); |
| Assert.assertEquals(attributes, DistCpUtils.unpackAttributes("RBU")); |
| |
| attributes.add(FileAttribute.GROUP); |
| Assert.assertEquals(DistCpUtils.packAttributes(attributes), "RBUG"); |
| Assert.assertEquals(attributes, DistCpUtils.unpackAttributes("RBUG")); |
| |
| attributes.add(FileAttribute.PERMISSION); |
| Assert.assertEquals(DistCpUtils.packAttributes(attributes), "RBUGP"); |
| Assert.assertEquals(attributes, DistCpUtils.unpackAttributes("RBUGP")); |
| } |
| |
| @Test |
| public void testPreserve() { |
| try { |
| FileSystem fs = FileSystem.get(config); |
| EnumSet<FileAttribute> attributes = EnumSet.noneOf(FileAttribute.class); |
| |
| |
| Path path = new Path("/tmp/abc"); |
| Path src = new Path("/tmp/src"); |
| fs.mkdirs(path); |
| fs.mkdirs(src); |
| FileStatus srcStatus = fs.getFileStatus(src); |
| |
| FsPermission noPerm = new FsPermission((short) 0); |
| fs.setPermission(path, noPerm); |
| fs.setOwner(path, "nobody", "nobody"); |
| |
| DistCpUtils.preserve(fs, path, srcStatus, attributes); |
| FileStatus target = fs.getFileStatus(path); |
| Assert.assertEquals(target.getPermission(), noPerm); |
| Assert.assertEquals(target.getOwner(), "nobody"); |
| Assert.assertEquals(target.getGroup(), "nobody"); |
| |
| attributes.add(FileAttribute.PERMISSION); |
| DistCpUtils.preserve(fs, path, srcStatus, attributes); |
| target = fs.getFileStatus(path); |
| Assert.assertEquals(target.getPermission(), srcStatus.getPermission()); |
| Assert.assertEquals(target.getOwner(), "nobody"); |
| Assert.assertEquals(target.getGroup(), "nobody"); |
| |
| attributes.add(FileAttribute.GROUP); |
| attributes.add(FileAttribute.USER); |
| DistCpUtils.preserve(fs, path, srcStatus, attributes); |
| target = fs.getFileStatus(path); |
| Assert.assertEquals(target.getPermission(), srcStatus.getPermission()); |
| Assert.assertEquals(target.getOwner(), srcStatus.getOwner()); |
| Assert.assertEquals(target.getGroup(), srcStatus.getGroup()); |
| |
| fs.delete(path, true); |
| fs.delete(src, true); |
| } catch (IOException e) { |
| LOG.error("Exception encountered ", e); |
| Assert.fail("Preserve test failure"); |
| } |
| } |
| |
| private static Random rand = new Random(); |
| |
| public static String createTestSetup(FileSystem fs) throws IOException { |
| return createTestSetup("/tmp1", fs, FsPermission.getDefault()); |
| } |
| |
| public static String createTestSetup(FileSystem fs, |
| FsPermission perm) throws IOException { |
| return createTestSetup("/tmp1", fs, perm); |
| } |
| |
| public static String createTestSetup(String baseDir, |
| FileSystem fs, |
| FsPermission perm) throws IOException { |
| String base = getBase(baseDir); |
| fs.mkdirs(new Path(base + "/newTest/hello/world1")); |
| fs.mkdirs(new Path(base + "/newTest/hello/world2/newworld")); |
| fs.mkdirs(new Path(base + "/newTest/hello/world3/oldworld")); |
| fs.setPermission(new Path(base + "/newTest"), perm); |
| fs.setPermission(new Path(base + "/newTest/hello"), perm); |
| fs.setPermission(new Path(base + "/newTest/hello/world1"), perm); |
| fs.setPermission(new Path(base + "/newTest/hello/world2"), perm); |
| fs.setPermission(new Path(base + "/newTest/hello/world2/newworld"), perm); |
| fs.setPermission(new Path(base + "/newTest/hello/world3"), perm); |
| fs.setPermission(new Path(base + "/newTest/hello/world3/oldworld"), perm); |
| createFile(fs, base + "/newTest/1"); |
| createFile(fs, base + "/newTest/hello/2"); |
| createFile(fs, base + "/newTest/hello/world3/oldworld/3"); |
| createFile(fs, base + "/newTest/hello/world2/4"); |
| return base; |
| } |
| |
| private static String getBase(String base) { |
| String location = String.valueOf(rand.nextLong()); |
| return base + "/" + location; |
| } |
| |
| public static void delete(FileSystem fs, String path) { |
| try { |
| if (fs != null) { |
| if (path != null) { |
| fs.delete(new Path(path), true); |
| } |
| } |
| } catch (IOException e) { |
| LOG.warn("Exception encountered ", e); |
| } |
| } |
| |
| public static void createFile(FileSystem fs, String filePath) throws IOException { |
| OutputStream out = fs.create(new Path(filePath)); |
| IOUtils.closeStream(out); |
| } |
| |
| public static boolean checkIfFoldersAreInSync(FileSystem fs, String targetBase, String sourceBase) |
| throws IOException { |
| Path base = new Path(targetBase); |
| |
| Stack<Path> stack = new Stack<Path>(); |
| stack.push(base); |
| while (!stack.isEmpty()) { |
| Path file = stack.pop(); |
| if (!fs.exists(file)) continue; |
| FileStatus[] fStatus = fs.listStatus(file); |
| if (fStatus == null || fStatus.length == 0) continue; |
| |
| for (FileStatus status : fStatus) { |
| if (status.isDirectory()) { |
| stack.push(status.getPath()); |
| } |
| Assert.assertTrue(fs.exists(new Path(sourceBase + "/" + |
| DistCpUtils.getRelativePath(new Path(targetBase), status.getPath())))); |
| } |
| } |
| return true; |
| } |
| } |