HADOOP-10965. Print fully qualified path in CommandWithDestination error messages. Contributed by John Zhuge.
(cherry picked from commit 8bfaa80037365c0790083313a905d1e7d88b0682)
This commit is contained in:
parent
c7d843af3b
commit
a61a90c562
@ -33,6 +33,7 @@ public class PathIOException extends IOException {
|
|||||||
// uris with no authority
|
// uris with no authority
|
||||||
private String operation;
|
private String operation;
|
||||||
private String path;
|
private String path;
|
||||||
|
private String fullyQualifiedPath;
|
||||||
private String targetPath;
|
private String targetPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,6 +69,11 @@ protected PathIOException(String path, String error, Throwable cause) {
|
|||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PathIOException withFullyQualifiedPath(String fqPath) {
|
||||||
|
fullyQualifiedPath = fqPath;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Format:
|
/** Format:
|
||||||
* cmd: {operation} `path' {to `target'}: error string
|
* cmd: {operation} `path' {to `target'}: error string
|
||||||
*/
|
*/
|
||||||
@ -85,6 +91,9 @@ public String getMessage() {
|
|||||||
if (getCause() != null) {
|
if (getCause() != null) {
|
||||||
message.append(": " + getCause().getMessage());
|
message.append(": " + getCause().getMessage());
|
||||||
}
|
}
|
||||||
|
if (fullyQualifiedPath != null && !fullyQualifiedPath.equals(path)) {
|
||||||
|
message.append(": ").append(formatPath(fullyQualifiedPath));
|
||||||
|
}
|
||||||
return message.toString();
|
return message.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,8 @@ protected void processArguments(LinkedList<PathData> args)
|
|||||||
throw new PathExistsException(dst.toString());
|
throw new PathExistsException(dst.toString());
|
||||||
}
|
}
|
||||||
} else if (!dst.parentExists()) {
|
} else if (!dst.parentExists()) {
|
||||||
throw new PathNotFoundException(dst.toString());
|
throw new PathNotFoundException(dst.toString())
|
||||||
|
.withFullyQualifiedPath(dst.path.toUri().toString());
|
||||||
}
|
}
|
||||||
super.processArguments(args);
|
super.processArguments(args);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ protected void processPath(PathData item) throws IOException {
|
|||||||
@Override
|
@Override
|
||||||
protected void processNonexistentPath(PathData item) throws IOException {
|
protected void processNonexistentPath(PathData item) throws IOException {
|
||||||
if (!item.parentExists()) {
|
if (!item.parentExists()) {
|
||||||
throw new PathNotFoundException(item.toString());
|
throw new PathNotFoundException(item.toString())
|
||||||
|
.withFullyQualifiedPath(item.path.toUri().toString());
|
||||||
}
|
}
|
||||||
touchz(item);
|
touchz(item);
|
||||||
}
|
}
|
||||||
|
@ -18,18 +18,28 @@
|
|||||||
|
|
||||||
package org.apache.hadoop.fs;
|
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 static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
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.conf.Configuration;
|
||||||
|
import org.apache.hadoop.util.StringUtils;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TestFsShellCopy {
|
public class TestFsShellCopy {
|
||||||
|
static final Log LOG = LogFactory.getLog(TestFsShellCopy.class);
|
||||||
|
|
||||||
static Configuration conf;
|
static Configuration conf;
|
||||||
static FsShell shell;
|
static FsShell shell;
|
||||||
static LocalFileSystem lfs;
|
static LocalFileSystem lfs;
|
||||||
@ -42,9 +52,10 @@ public static void setup() throws Exception {
|
|||||||
lfs = FileSystem.getLocal(conf);
|
lfs = FileSystem.getLocal(conf);
|
||||||
testRootDir = lfs.makeQualified(new Path(
|
testRootDir = lfs.makeQualified(new Path(
|
||||||
System.getProperty("test.build.data","test/build/data"),
|
System.getProperty("test.build.data","test/build/data"),
|
||||||
"testShellCopy"));
|
"testFsShellCopy"));
|
||||||
|
|
||||||
lfs.mkdirs(testRootDir);
|
lfs.mkdirs(testRootDir);
|
||||||
|
lfs.setWorkingDirectory(testRootDir);
|
||||||
srcPath = new Path(testRootDir, "srcFile");
|
srcPath = new Path(testRootDir, "srcFile");
|
||||||
dstPath = new Path(testRootDir, "dstFile");
|
dstPath = new Path(testRootDir, "dstFile");
|
||||||
}
|
}
|
||||||
@ -62,6 +73,16 @@ public void prepFiles() throws Exception {
|
|||||||
assertTrue(lfs.exists(lfs.getChecksumFile(srcPath)));
|
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
|
@Test
|
||||||
public void testCopyNoCrc() throws Exception {
|
public void testCopyNoCrc() throws Exception {
|
||||||
shellRun(0, "-get", srcPath.toString(), dstPath.toString());
|
shellRun(0, "-get", srcPath.toString(), dstPath.toString());
|
||||||
@ -95,10 +116,6 @@ private void checkPath(Path p, boolean expectChecksum) throws IOException {
|
|||||||
assertEquals(expectChecksum, hasChecksum);
|
assertEquals(expectChecksum, hasChecksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shellRun(int n, String ... args) throws Exception {
|
|
||||||
assertEquals(n, shell.run(args));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCopyFileFromLocal() throws Exception {
|
public void testCopyFileFromLocal() throws Exception {
|
||||||
Path testRoot = new Path(testRootDir, "testPutFile");
|
Path testRoot = new Path(testRootDir, "testPutFile");
|
||||||
@ -571,4 +588,23 @@ private String pathAsString(Path p) {
|
|||||||
String s = (p == null) ? Path.CUR_DIR : p.toString();
|
String s = (p == null) ? Path.CUR_DIR : p.toString();
|
||||||
return s.isEmpty() ? Path.CUR_DIR : s;
|
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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user