HADOOP-10965. Print fully qualified path in CommandWithDestination error messages. Contributed by John Zhuge.

This commit is contained in:
Andrew Wang 2016-03-28 14:13:48 -07:00
parent 524bc3c33a
commit 8bfaa80037
5 changed files with 145 additions and 10 deletions

View File

@ -33,6 +33,7 @@ public class PathIOException extends IOException {
// uris with no authority
private String operation;
private String path;
private String fullyQualifiedPath;
private String targetPath;
/**
@ -68,6 +69,11 @@ protected PathIOException(String path, String error, Throwable cause) {
this.path = path;
}
public PathIOException withFullyQualifiedPath(String fqPath) {
fullyQualifiedPath = fqPath;
return this;
}
/** Format:
* cmd: {operation} `path' {to `target'}: error string
*/
@ -85,6 +91,9 @@ public String getMessage() {
if (getCause() != null) {
message.append(": " + getCause().getMessage());
}
if (fullyQualifiedPath != null && !fullyQualifiedPath.equals(path)) {
message.append(": ").append(formatPath(fullyQualifiedPath));
}
return message.toString();
}

View File

@ -220,7 +220,8 @@ protected void processArguments(LinkedList<PathData> args)
throw new PathExistsException(dst.toString());
}
} else if (!dst.parentExists()) {
throw new PathNotFoundException(dst.toString());
throw new PathNotFoundException(dst.toString())
.withFullyQualifiedPath(dst.path.toUri().toString());
}
super.processArguments(args);
}

View File

@ -72,7 +72,8 @@ protected void processPath(PathData item) throws IOException {
@Override
protected void processNonexistentPath(PathData item) throws IOException {
if (!item.parentExists()) {
throw new PathNotFoundException(item.toString());
throw new PathNotFoundException(item.toString())
.withFullyQualifiedPath(item.path.toUri().toString());
}
touchz(item);
}

View File

@ -18,18 +18,28 @@
package org.apache.hadoop.fs;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import java.io.File;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.util.StringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestFsShellCopy {
public class TestFsShellCopy {
static final Log LOG = LogFactory.getLog(TestFsShellCopy.class);
static Configuration conf;
static FsShell shell;
static LocalFileSystem lfs;
@ -42,9 +52,10 @@ public static void setup() throws Exception {
lfs = FileSystem.getLocal(conf);
testRootDir = lfs.makeQualified(new Path(
System.getProperty("test.build.data","test/build/data"),
"testShellCopy"));
"testFsShellCopy"));
lfs.mkdirs(testRootDir);
lfs.mkdirs(testRootDir);
lfs.setWorkingDirectory(testRootDir);
srcPath = new Path(testRootDir, "srcFile");
dstPath = new Path(testRootDir, "dstFile");
}
@ -62,6 +73,16 @@ public void prepFiles() throws Exception {
assertTrue(lfs.exists(lfs.getChecksumFile(srcPath)));
}
private void shellRun(int n, String ... args) throws Exception {
assertEquals(n, shell.run(args));
}
private int shellRun(String... args) throws Exception {
int exitCode = shell.run(args);
LOG.info("exit " + exitCode + " - " + StringUtils.join(" ", args));
return exitCode;
}
@Test
public void testCopyNoCrc() throws Exception {
shellRun(0, "-get", srcPath.toString(), dstPath.toString());
@ -95,10 +116,6 @@ private void checkPath(Path p, boolean expectChecksum) throws IOException {
assertEquals(expectChecksum, hasChecksum);
}
private void shellRun(int n, String ... args) throws Exception {
assertEquals(n, shell.run(args));
}
@Test
public void testCopyFileFromLocal() throws Exception {
Path testRoot = new Path(testRootDir, "testPutFile");
@ -571,4 +588,23 @@ private String pathAsString(Path p) {
String s = (p == null) ? Path.CUR_DIR : p.toString();
return s.isEmpty() ? Path.CUR_DIR : s;
}
/**
* Test copy to a path with non-existent parent directory.
*/
@Test
public void testCopyNoParent() throws Exception {
final String noDirName = "noDir";
final Path noDir = new Path(noDirName);
lfs.delete(noDir, true);
assertThat(lfs.exists(noDir), is(false));
assertThat("Expected failed put to a path without parent directory",
shellRun("-put", srcPath.toString(), noDirName + "/foo"), is(not(0)));
// Note the trailing '/' in the target path.
assertThat("Expected failed copyFromLocal to a non-existent directory",
shellRun("-copyFromLocal", srcPath.toString(), noDirName + "/"),
is(not(0)));
}
}

View File

@ -0,0 +1,88 @@
/**
* 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.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.util.StringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestFsShellTouch {
static final Log LOG = LogFactory.getLog(TestFsShellTouch.class);
static FsShell shell;
static LocalFileSystem lfs;
static Path testRootDir;
@BeforeClass
public static void setup() throws Exception {
Configuration conf = new Configuration();
shell = new FsShell(conf);
lfs = FileSystem.getLocal(conf);
testRootDir = lfs.makeQualified(new Path(
System.getProperty("test.build.data","test/build/data"),
"testFsShell"));
lfs.mkdirs(testRootDir);
lfs.setWorkingDirectory(testRootDir);
}
@Before
public void prepFiles() throws Exception {
lfs.setVerifyChecksum(true);
lfs.setWriteChecksum(true);
}
private int shellRun(String... args) throws Exception {
int exitCode = shell.run(args);
LOG.info("exit " + exitCode + " - " + StringUtils.join(" ", args));
return exitCode;
}
@Test
public void testTouchz() throws Exception {
// Ensure newFile does not exist
final String newFileName = "newFile";
final Path newFile = new Path(newFileName);
lfs.delete(newFile, true);
assertThat(lfs.exists(newFile), is(false));
assertThat("Expected successful touchz on a new file",
shellRun("-touchz", newFileName), is(0));
shellRun("-ls", newFileName);
assertThat("Expected successful touchz on an existing zero-length file",
shellRun("-touchz", newFileName), is(0));
// Ensure noDir does not exist
final String noDirName = "noDir";
final Path noDir = new Path(noDirName);
lfs.delete(noDir, true);
assertThat(lfs.exists(noDir), is(false));
assertThat("Expected failed touchz in a non-existent directory",
shellRun("-touchz", noDirName + "/foo"), is(not(0)));
}
}