/** * 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 java.util.ArrayList; import java.util.List; import java.util.Random; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.impl.Log4JLogger; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CopyFilesBase.MyFile; import org.apache.hadoop.hdfs.MiniDFSCluster; import org.apache.hadoop.hdfs.server.datanode.DataNode; import org.apache.hadoop.hdfs.server.namenode.FSNamesystem; import org.apache.hadoop.mapred.MiniMRCluster; import org.apache.hadoop.tools.DistCp; import org.apache.hadoop.util.ToolRunner; import org.apache.log4j.Level; import org.mortbay.log.Log; import junit.framework.TestCase; public class TestCopyFilesDistcp extends TestCase { { ((Log4JLogger)LogFactory.getLog(TestCopyFilesDistcp.class) ).getLogger().setLevel(Level.OFF); DataNode.LOG.getLogger().setLevel(Level.OFF); ((Log4JLogger)FSNamesystem.LOG).getLogger().setLevel(Level.OFF); ((Log4JLogger)DistCp.LOG).getLogger().setLevel(Level.ALL); } enum DistcpType { NORMAL, FASTCOPY, COPYBYCHUNK } public void testSkipUnderConstrunctionFile() throws Exception { performDistcpWithUnderConstructionFile(DistcpType.NORMAL); } public void testSkipUnderConstrunctionFileWithFastCopy() throws Exception { performDistcpWithUnderConstructionFile(DistcpType.FASTCOPY); } public void testSkipUnderConstrunctionFileWithCopyByChunk() throws Exception { performDistcpWithUnderConstructionFile(DistcpType.COPYBYCHUNK); } public void performDistcpWithUnderConstructionFile(DistcpType type) throws Exception { String namenode = null; MiniDFSCluster dfs = null; MiniMRCluster mr = null; try { Configuration conf = new Configuration(); dfs = new MiniDFSCluster(conf, 3, true, null); FileSystem fs = dfs.getFileSystem(); namenode = fs.getUri().toString(); mr = new MiniMRCluster(3, namenode, 1); MyFile[] files = TestCopyFiles.createFiles(fs.getUri(), "/srcdat"); // create a under construction files MyFile f = new MyFile(); Path p = new Path(new Path("/srcdat"), f.getName()); FSDataOutputStream out = fs.create(p); byte[] toWrite = new byte[f.getSize()]; new Random(f.getSeed()).nextBytes(toWrite); out.write(toWrite); out.flush(); Log.info("Created under construction file: " + p); Path destRoot = new Path("/destdat"); Path destPath = new Path(destRoot, f.getName()); String option = ""; if (type.equals(DistcpType.FASTCOPY)) { option = "-usefastcopy"; } else if (type.equals(DistcpType.COPYBYCHUNK)) { option = "-copybychunk"; } Configuration job = mr.createJobConf(); List<String> args = new ArrayList<String>(); args.add("-m"); args.add("100"); args.add("-skipunderconstruction"); if (!option.equals("")) { args.add(option); } args.add("-log"); args.add(namenode + "/logs"); args.add(namenode + "/srcdat"); args.add(namenode + "/destdat"); ToolRunner.run(new DistCp(job),args.toArray(new String[] {})); assertTrue("Source and destination directories do not match.", TestCopyFiles.checkFiles(fs, "/destdat", files)); // the under construction file should be skipped. assertFalse(fs.exists(destPath)); // close the under construction file. out.close(); // copy again fs.delete(destRoot, true); args.clear(); args.add("-m"); args.add("100"); args.add("-skipunderconstruction"); if (!option.equals("")) { args.add(option); } args.add("-log"); args.add(namenode + "/logs2"); args.add(namenode + "/srcdat"); args.add(namenode + "/destdat"); ToolRunner.run(new DistCp(job),args.toArray(new String[] {})); MyFile[] moreFiles = new MyFile[files.length + 1]; int i = 0; for (i = 0; i < files.length; i++) { moreFiles[i] = files[i]; } moreFiles[i] = f; assertTrue("Source and destination directories do not match.", TestCopyFiles.checkFiles(fs, "/destdat", moreFiles)); } finally { if (dfs != null) { dfs.shutdown(); } if (mr != null) { mr.shutdown(); } } } }