/** * 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; import java.util.Map; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hdfs.DFSConfigKeys; import org.apache.hadoop.hdfs.MiniDFSCluster; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.tools.util.DistCpTestUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.google.common.collect.Maps; /** * Tests distcp in combination with HDFS raw.* XAttrs. */ public class TestDistCpWithRawXAttrs { private static MiniDFSCluster cluster; private static Configuration conf; private static FileSystem fs; private static final String rawName1 = "raw.a1"; private static final byte[] rawValue1 = {0x37, 0x38, 0x39}; private static final String userName1 = "user.a1"; private static final byte[] userValue1 = {0x38, 0x38, 0x38}; private static final Path dir1 = new Path("/src/dir1"); private static final Path subDir1 = new Path(dir1, "subdir1"); private static final Path file1 = new Path("/src/file1"); private static final String rawRootName = "/.reserved/raw"; private static final String rootedDestName = "/dest"; private static final String rootedSrcName = "/src"; private static final String rawDestName = "/.reserved/raw/dest"; private static final String rawSrcName = "/.reserved/raw/src"; @BeforeClass public static void init() throws Exception { conf = new Configuration(); conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_XATTRS_ENABLED_KEY, true); cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).format(true) .build(); cluster.waitActive(); fs = cluster.getFileSystem(); } @AfterClass public static void shutdown() { IOUtils.cleanup(null, fs); if (cluster != null) { cluster.shutdown(); } } /* Test that XAttrs and raw.* XAttrs are preserved when appropriate. */ @Test public void testPreserveRawXAttrs1() throws Exception { final String relSrc = "/./.reserved/../.reserved/raw/../raw/src/../src"; final String relDst = "/./.reserved/../.reserved/raw/../raw/dest/../dest"; doTestPreserveRawXAttrs(relSrc, relDst, "-px", true, true, DistCpConstants.SUCCESS); doTestStandardPreserveRawXAttrs("-px", true); final Path savedWd = fs.getWorkingDirectory(); try { fs.setWorkingDirectory(new Path("/.reserved/raw")); doTestPreserveRawXAttrs("../.." + rawSrcName, "../.." + rawDestName, "-px", true, true, DistCpConstants.SUCCESS); } finally { fs.setWorkingDirectory(savedWd); } } /* Test that XAttrs are not preserved and raw.* are when appropriate. */ @Test public void testPreserveRawXAttrs2() throws Exception { doTestStandardPreserveRawXAttrs("-p", false); } /* Test that XAttrs are not preserved and raw.* are when appropriate. */ @Test public void testPreserveRawXAttrs3() throws Exception { doTestStandardPreserveRawXAttrs(null, false); } @Test public void testPreserveRawXAttrs4() throws Exception { doTestStandardPreserveRawXAttrs("-update -delete", false); } private static Path[] pathnames = { new Path("dir1"), new Path("dir1/subdir1"), new Path("file1") }; private static void makeFilesAndDirs(FileSystem fs) throws Exception { fs.delete(new Path("/src"), true); fs.delete(new Path("/dest"), true); fs.mkdirs(subDir1); fs.create(file1).close(); } private void initXAttrs() throws Exception { makeFilesAndDirs(fs); for (Path p : pathnames) { fs.setXAttr(new Path(rawRootName + "/src", p), rawName1, rawValue1); fs.setXAttr(new Path(rawRootName + "/src", p), userName1, userValue1); } } private void doTestStandardPreserveRawXAttrs(String options, boolean expectUser) throws Exception { doTestPreserveRawXAttrs(rootedSrcName, rootedDestName, options, false, expectUser, DistCpConstants.SUCCESS); doTestPreserveRawXAttrs(rootedSrcName, rawDestName, options, false, expectUser, DistCpConstants.INVALID_ARGUMENT); doTestPreserveRawXAttrs(rawSrcName, rootedDestName, options, false, expectUser, DistCpConstants.INVALID_ARGUMENT); doTestPreserveRawXAttrs(rawSrcName, rawDestName, options, true, expectUser, DistCpConstants.SUCCESS); } private void doTestPreserveRawXAttrs(String src, String dest, String preserveOpts, boolean expectRaw, boolean expectUser, int expectedExitCode) throws Exception { initXAttrs(); DistCpTestUtils.assertRunDistCp(expectedExitCode, src, dest, preserveOpts, conf); if (expectedExitCode == DistCpConstants.SUCCESS) { Map<String, byte[]> xAttrs = Maps.newHashMap(); for (Path p : pathnames) { xAttrs.clear(); if (expectRaw) { xAttrs.put(rawName1, rawValue1); } if (expectUser) { xAttrs.put(userName1, userValue1); } DistCpTestUtils.assertXAttrs(new Path(dest, p), fs, xAttrs); } } } }