HDFS-10556. DistCpOptions should be validated automatically. Contributed by Mingliang Liu.
(cherry picked from commit 856bc4e28b
)
This commit is contained in:
parent
9c46f99cc6
commit
d17265f467
|
@ -163,6 +163,7 @@ public class DistCpOptions {
|
||||||
* @param atomicCommit - boolean switch
|
* @param atomicCommit - boolean switch
|
||||||
*/
|
*/
|
||||||
public void setAtomicCommit(boolean atomicCommit) {
|
public void setAtomicCommit(boolean atomicCommit) {
|
||||||
|
validate(DistCpOptionSwitch.ATOMIC_COMMIT, atomicCommit);
|
||||||
this.atomicCommit = atomicCommit;
|
this.atomicCommit = atomicCommit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +182,7 @@ public class DistCpOptions {
|
||||||
* @param syncFolder - boolean switch
|
* @param syncFolder - boolean switch
|
||||||
*/
|
*/
|
||||||
public void setSyncFolder(boolean syncFolder) {
|
public void setSyncFolder(boolean syncFolder) {
|
||||||
|
validate(DistCpOptionSwitch.SYNC_FOLDERS, syncFolder);
|
||||||
this.syncFolder = syncFolder;
|
this.syncFolder = syncFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +201,22 @@ public class DistCpOptions {
|
||||||
* @param deleteMissing - boolean switch
|
* @param deleteMissing - boolean switch
|
||||||
*/
|
*/
|
||||||
public void setDeleteMissing(boolean deleteMissing) {
|
public void setDeleteMissing(boolean deleteMissing) {
|
||||||
|
validate(DistCpOptionSwitch.DELETE_MISSING, deleteMissing);
|
||||||
this.deleteMissing = deleteMissing;
|
this.deleteMissing = deleteMissing;
|
||||||
|
ignoreDeleteMissingIfUseDiff();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -delete and -diff are mutually exclusive.
|
||||||
|
* For backward compatibility, we ignore the -delete option here, instead of
|
||||||
|
* throwing an IllegalArgumentException. See HDFS-10397 for more discussion.
|
||||||
|
*/
|
||||||
|
private void ignoreDeleteMissingIfUseDiff() {
|
||||||
|
if (deleteMissing && useDiff) {
|
||||||
|
OptionsParser.LOG.warn("-delete and -diff are mutually exclusive. " +
|
||||||
|
"The -delete option will be ignored.");
|
||||||
|
deleteMissing = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,6 +271,7 @@ public class DistCpOptions {
|
||||||
* @param overwrite - boolean switch
|
* @param overwrite - boolean switch
|
||||||
*/
|
*/
|
||||||
public void setOverwrite(boolean overwrite) {
|
public void setOverwrite(boolean overwrite) {
|
||||||
|
validate(DistCpOptionSwitch.OVERWRITE, overwrite);
|
||||||
this.overwrite = overwrite;
|
this.overwrite = overwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +287,7 @@ public class DistCpOptions {
|
||||||
* update option and CRC is not skipped.
|
* update option and CRC is not skipped.
|
||||||
*/
|
*/
|
||||||
public void setAppend(boolean append) {
|
public void setAppend(boolean append) {
|
||||||
|
validate(DistCpOptionSwitch.APPEND, append);
|
||||||
this.append = append;
|
this.append = append;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,9 +304,11 @@ public class DistCpOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUseDiff(boolean useDiff, String fromSnapshot, String toSnapshot) {
|
public void setUseDiff(boolean useDiff, String fromSnapshot, String toSnapshot) {
|
||||||
|
validate(DistCpOptionSwitch.DIFF, useDiff);
|
||||||
this.useDiff = useDiff;
|
this.useDiff = useDiff;
|
||||||
this.fromSnapshot = fromSnapshot;
|
this.fromSnapshot = fromSnapshot;
|
||||||
this.toSnapshot = toSnapshot;
|
this.toSnapshot = toSnapshot;
|
||||||
|
ignoreDeleteMissingIfUseDiff();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disableUsingDiff() {
|
public void disableUsingDiff() {
|
||||||
|
@ -311,6 +332,7 @@ public class DistCpOptions {
|
||||||
* @param skipCRC - boolean switch
|
* @param skipCRC - boolean switch
|
||||||
*/
|
*/
|
||||||
public void setSkipCRC(boolean skipCRC) {
|
public void setSkipCRC(boolean skipCRC) {
|
||||||
|
validate(DistCpOptionSwitch.SKIP_CRC, skipCRC);
|
||||||
this.skipCRC = skipCRC;
|
this.skipCRC = skipCRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,15 +587,20 @@ public class DistCpOptions {
|
||||||
this.filtersFile = filtersFilename;
|
this.filtersFile = filtersFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate() {
|
public void validate(DistCpOptionSwitch option, boolean value) {
|
||||||
if (useDiff && deleteMissing) {
|
|
||||||
// -delete and -diff are mutually exclusive. For backward compatibility,
|
boolean syncFolder = (option == DistCpOptionSwitch.SYNC_FOLDERS ?
|
||||||
// we ignore the -delete option here, instead of throwing an
|
value : this.syncFolder);
|
||||||
// IllegalArgumentException. See HDFS-10397 for more discussion.
|
boolean overwrite = (option == DistCpOptionSwitch.OVERWRITE ?
|
||||||
OptionsParser.LOG.warn("-delete and -diff are mutually exclusive. " +
|
value : this.overwrite);
|
||||||
"The -delete option will be ignored.");
|
boolean deleteMissing = (option == DistCpOptionSwitch.DELETE_MISSING ?
|
||||||
setDeleteMissing(false);
|
value : this.deleteMissing);
|
||||||
}
|
boolean atomicCommit = (option == DistCpOptionSwitch.ATOMIC_COMMIT ?
|
||||||
|
value : this.atomicCommit);
|
||||||
|
boolean skipCRC = (option == DistCpOptionSwitch.SKIP_CRC ?
|
||||||
|
value : this.skipCRC);
|
||||||
|
boolean append = (option == DistCpOptionSwitch.APPEND ? value : this.append);
|
||||||
|
boolean useDiff = (option == DistCpOptionSwitch.DIFF ? value : this.useDiff);
|
||||||
|
|
||||||
if (syncFolder && atomicCommit) {
|
if (syncFolder && atomicCommit) {
|
||||||
throw new IllegalArgumentException("Atomic commit can't be used with " +
|
throw new IllegalArgumentException("Atomic commit can't be used with " +
|
||||||
|
|
|
@ -88,26 +88,14 @@ public class OptionsParser {
|
||||||
|
|
||||||
DistCpOptions option = parseSourceAndTargetPaths(command);
|
DistCpOptions option = parseSourceAndTargetPaths(command);
|
||||||
|
|
||||||
option.setIgnoreFailures(
|
//Process all the other option switches and set options appropriately
|
||||||
command.hasOption(DistCpOptionSwitch.IGNORE_FAILURES.getSwitch()));
|
if (command.hasOption(DistCpOptionSwitch.IGNORE_FAILURES.getSwitch())) {
|
||||||
|
option.setIgnoreFailures(true);
|
||||||
|
}
|
||||||
|
|
||||||
option.setAtomicCommit(
|
if (command.hasOption(DistCpOptionSwitch.ATOMIC_COMMIT.getSwitch())) {
|
||||||
command.hasOption(DistCpOptionSwitch.ATOMIC_COMMIT.getSwitch()));
|
option.setAtomicCommit(true);
|
||||||
|
}
|
||||||
option.setSyncFolder(
|
|
||||||
command.hasOption(DistCpOptionSwitch.SYNC_FOLDERS.getSwitch()));
|
|
||||||
|
|
||||||
option.setOverwrite(
|
|
||||||
command.hasOption(DistCpOptionSwitch.OVERWRITE.getSwitch()));
|
|
||||||
|
|
||||||
option.setAppend(
|
|
||||||
command.hasOption(DistCpOptionSwitch.APPEND.getSwitch()));
|
|
||||||
|
|
||||||
option.setDeleteMissing(
|
|
||||||
command.hasOption(DistCpOptionSwitch.DELETE_MISSING.getSwitch()));
|
|
||||||
|
|
||||||
option.setSkipCRC(
|
|
||||||
command.hasOption(DistCpOptionSwitch.SKIP_CRC.getSwitch()));
|
|
||||||
|
|
||||||
if (command.hasOption(DistCpOptionSwitch.WORK_PATH.getSwitch()) &&
|
if (command.hasOption(DistCpOptionSwitch.WORK_PATH.getSwitch()) &&
|
||||||
option.shouldAtomicCommit()) {
|
option.shouldAtomicCommit()) {
|
||||||
|
@ -123,6 +111,25 @@ public class OptionsParser {
|
||||||
option.setLogPath(new Path(getVal(command, DistCpOptionSwitch.LOG_PATH.getSwitch())));
|
option.setLogPath(new Path(getVal(command, DistCpOptionSwitch.LOG_PATH.getSwitch())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command.hasOption(DistCpOptionSwitch.SYNC_FOLDERS.getSwitch())) {
|
||||||
|
option.setSyncFolder(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.hasOption(DistCpOptionSwitch.OVERWRITE.getSwitch())) {
|
||||||
|
option.setOverwrite(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.hasOption(DistCpOptionSwitch.APPEND.getSwitch())) {
|
||||||
|
option.setAppend(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.hasOption(DistCpOptionSwitch.DELETE_MISSING.getSwitch())) {
|
||||||
|
option.setDeleteMissing(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.hasOption(DistCpOptionSwitch.SKIP_CRC.getSwitch())) {
|
||||||
|
option.setSkipCRC(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (command.hasOption(DistCpOptionSwitch.BLOCKING.getSwitch())) {
|
if (command.hasOption(DistCpOptionSwitch.BLOCKING.getSwitch())) {
|
||||||
option.setBlocking(false);
|
option.setBlocking(false);
|
||||||
|
@ -162,8 +169,6 @@ public class OptionsParser {
|
||||||
DistCpOptionSwitch.FILTERS.getSwitch()));
|
DistCpOptionSwitch.FILTERS.getSwitch()));
|
||||||
}
|
}
|
||||||
|
|
||||||
option.validate();
|
|
||||||
|
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,510 @@
|
||||||
|
/**
|
||||||
|
* 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 org.apache.hadoop.fs.Path;
|
||||||
|
import org.apache.hadoop.tools.DistCpOptions.FileAttribute;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.test.GenericTestUtils.assertExceptionContains;
|
||||||
|
import static org.apache.hadoop.tools.DistCpOptions.maxNumListstatusThreads;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is to test constructing {@link DistCpOptions} manually with setters.
|
||||||
|
*
|
||||||
|
* The test cases in this class is very similar to the parser test, see
|
||||||
|
* {@link TestOptionsParser}.
|
||||||
|
*/
|
||||||
|
public class TestDistCpOptions {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetIgnoreFailure() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertFalse(options.shouldIgnoreFailures());
|
||||||
|
|
||||||
|
options.setIgnoreFailures(true);
|
||||||
|
Assert.assertTrue(options.shouldIgnoreFailures());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetOverwrite() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertFalse(options.shouldOverwrite());
|
||||||
|
|
||||||
|
options.setOverwrite(true);
|
||||||
|
Assert.assertTrue(options.shouldOverwrite());
|
||||||
|
|
||||||
|
try {
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
Assert.fail("Update and overwrite aren't allowed together");
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogPath() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertNull(options.getLogPath());
|
||||||
|
|
||||||
|
final Path logPath = new Path("hdfs://localhost:8020/logs");
|
||||||
|
options.setLogPath(logPath);
|
||||||
|
Assert.assertEquals(logPath, options.getLogPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetBlokcing() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertTrue(options.shouldBlock());
|
||||||
|
|
||||||
|
options.setBlocking(false);
|
||||||
|
Assert.assertFalse(options.shouldBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetBandwidth() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertEquals(DistCpConstants.DEFAULT_BANDWIDTH_MB,
|
||||||
|
options.getMapBandwidth());
|
||||||
|
|
||||||
|
options.setMapBandwidth(11);
|
||||||
|
Assert.assertEquals(11, options.getMapBandwidth());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AssertionError.class)
|
||||||
|
public void testSetNonPositiveBandwidth() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setMapBandwidth(-11);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AssertionError.class)
|
||||||
|
public void testSetZeroBandwidth() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setMapBandwidth(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSkipCRC() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertFalse(options.shouldSkipCRC());
|
||||||
|
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setSkipCRC(true);
|
||||||
|
Assert.assertTrue(options.shouldSyncFolder());
|
||||||
|
Assert.assertTrue(options.shouldSkipCRC());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAtomicCommit() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertFalse(options.shouldAtomicCommit());
|
||||||
|
|
||||||
|
options.setAtomicCommit(true);
|
||||||
|
Assert.assertTrue(options.shouldAtomicCommit());
|
||||||
|
|
||||||
|
try {
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
Assert.fail("Atomic and sync folders were mutually exclusive");
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetWorkPath() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertNull(options.getAtomicWorkPath());
|
||||||
|
|
||||||
|
options.setAtomicCommit(true);
|
||||||
|
Assert.assertNull(options.getAtomicWorkPath());
|
||||||
|
|
||||||
|
final Path workPath = new Path("hdfs://localhost:8020/work");
|
||||||
|
options.setAtomicWorkPath(workPath);
|
||||||
|
Assert.assertEquals(workPath,
|
||||||
|
options.getAtomicWorkPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSyncFolders() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertFalse(options.shouldSyncFolder());
|
||||||
|
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
Assert.assertTrue(options.shouldSyncFolder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetDeleteMissing() {
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertFalse(options.shouldDeleteMissing());
|
||||||
|
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setDeleteMissing(true);
|
||||||
|
Assert.assertTrue(options.shouldSyncFolder());
|
||||||
|
Assert.assertTrue(options.shouldDeleteMissing());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setOverwrite(true);
|
||||||
|
options.setDeleteMissing(true);
|
||||||
|
Assert.assertTrue(options.shouldOverwrite());
|
||||||
|
Assert.assertTrue(options.shouldDeleteMissing());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setDeleteMissing(true);
|
||||||
|
fail("Delete missing should fail without update or overwrite options");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertExceptionContains("Delete missing is applicable only with update " +
|
||||||
|
"or overwrite options", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setDeleteMissing(true);
|
||||||
|
options.setUseDiff(true, "s1", "s2");
|
||||||
|
assertFalse("-delete should be ignored when -diff is specified",
|
||||||
|
options.shouldDeleteMissing());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
fail("Got unexpected IllegalArgumentException: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSSLConf() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertNull(options.getSslConfigurationFile());
|
||||||
|
|
||||||
|
options.setSslConfigurationFile("/tmp/ssl-client.xml");
|
||||||
|
Assert.assertEquals("/tmp/ssl-client.xml",
|
||||||
|
options.getSslConfigurationFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetMaps() {
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertEquals(DistCpConstants.DEFAULT_MAPS, options.getMaxMaps());
|
||||||
|
|
||||||
|
options.setMaxMaps(1);
|
||||||
|
Assert.assertEquals(1, options.getMaxMaps());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setMaxMaps(0);
|
||||||
|
Assert.assertEquals(1, options.getMaxMaps());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetNumListtatusThreads() {
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
// If command line argument isn't set, we expect .getNumListstatusThreads
|
||||||
|
// option to be zero (so that we know when to override conf properties).
|
||||||
|
Assert.assertEquals(0, options.getNumListstatusThreads());
|
||||||
|
|
||||||
|
options.setNumListstatusThreads(12);
|
||||||
|
Assert.assertEquals(12, options.getNumListstatusThreads());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setNumListstatusThreads(0);
|
||||||
|
Assert.assertEquals(0, options.getNumListstatusThreads());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore large number of threads.
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setNumListstatusThreads(maxNumListstatusThreads * 2);
|
||||||
|
Assert.assertEquals(maxNumListstatusThreads,
|
||||||
|
options.getNumListstatusThreads());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSourceListing() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertEquals(new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
options.getSourceFileListing());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AssertionError.class)
|
||||||
|
public void testMissingTarget() {
|
||||||
|
new DistCpOptions(new Path("hdfs://localhost:8020/source/first"), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToString() {
|
||||||
|
DistCpOptions option = new DistCpOptions(new Path("abc"), new Path("xyz"));
|
||||||
|
final String val = "DistCpOptions{atomicCommit=false, syncFolder=false, "
|
||||||
|
+ "deleteMissing=false, ignoreFailures=false, overwrite=false, "
|
||||||
|
+ "skipCRC=false, blocking=true, numListstatusThreads=0, maxMaps=20, "
|
||||||
|
+ "mapBandwidth=100, sslConfigurationFile='null', "
|
||||||
|
+ "copyStrategy='uniformsize', preserveStatus=[], "
|
||||||
|
+ "preserveRawXattrs=false, atomicWorkPath=null, logPath=null, "
|
||||||
|
+ "sourceFileListing=abc, sourcePaths=null, targetPath=xyz, "
|
||||||
|
+ "targetPathExists=true, filtersFile='null'}";
|
||||||
|
String optionString = option.toString();
|
||||||
|
Assert.assertEquals(val, optionString);
|
||||||
|
Assert.assertNotSame(DistCpOptionSwitch.ATOMIC_COMMIT.toString(),
|
||||||
|
DistCpOptionSwitch.ATOMIC_COMMIT.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopyStrategy() {
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertEquals(DistCpConstants.UNIFORMSIZE,
|
||||||
|
options.getCopyStrategy());
|
||||||
|
options.setCopyStrategy("dynamic");
|
||||||
|
Assert.assertEquals("dynamic", options.getCopyStrategy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTargetPath() {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertEquals(new Path("hdfs://localhost:8020/target/"),
|
||||||
|
options.getTargetPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPreserve() {
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.BLOCKSIZE));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.REPLICATION));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.PERMISSION));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.USER));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.GROUP));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.CHECKSUMTYPE));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.preserve(FileAttribute.ACL);
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.BLOCKSIZE));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.REPLICATION));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.PERMISSION));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.USER));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.GROUP));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.CHECKSUMTYPE));
|
||||||
|
Assert.assertTrue(options.shouldPreserve(FileAttribute.ACL));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source/")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.preserve(FileAttribute.BLOCKSIZE);
|
||||||
|
options.preserve(FileAttribute.REPLICATION);
|
||||||
|
options.preserve(FileAttribute.PERMISSION);
|
||||||
|
options.preserve(FileAttribute.USER);
|
||||||
|
options.preserve(FileAttribute.GROUP);
|
||||||
|
options.preserve(FileAttribute.CHECKSUMTYPE);
|
||||||
|
|
||||||
|
Assert.assertTrue(options.shouldPreserve(FileAttribute.BLOCKSIZE));
|
||||||
|
Assert.assertTrue(options.shouldPreserve(FileAttribute.REPLICATION));
|
||||||
|
Assert.assertTrue(options.shouldPreserve(FileAttribute.PERMISSION));
|
||||||
|
Assert.assertTrue(options.shouldPreserve(FileAttribute.USER));
|
||||||
|
Assert.assertTrue(options.shouldPreserve(FileAttribute.GROUP));
|
||||||
|
Assert.assertTrue(options.shouldPreserve(FileAttribute.CHECKSUMTYPE));
|
||||||
|
Assert.assertFalse(options.shouldPreserve(FileAttribute.XATTR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppendOption() {
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source/")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setAppend(true);
|
||||||
|
Assert.assertTrue(options.shouldAppend());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// make sure -append is only valid when -update is specified
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source/")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setAppend(true);
|
||||||
|
fail("Append should fail if update option is not specified");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertExceptionContains(
|
||||||
|
"Append is valid only with update options", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// make sure -append is invalid when skipCrc is specified
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
Collections.singletonList(new Path("hdfs://localhost:8020/source/")),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setAppend(true);
|
||||||
|
options.setSkipCRC(true);
|
||||||
|
fail("Append should fail if skipCrc option is specified");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertExceptionContains(
|
||||||
|
"Append is disallowed when skipping CRC", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDiffOption() {
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setUseDiff(true, "s1", "s2");
|
||||||
|
Assert.assertTrue(options.shouldUseDiff());
|
||||||
|
Assert.assertEquals("s1", options.getFromSnapshot());
|
||||||
|
Assert.assertEquals("s2", options.getToSnapshot());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setUseDiff(true, "s1", ".");
|
||||||
|
Assert.assertTrue(options.shouldUseDiff());
|
||||||
|
Assert.assertEquals("s1", options.getFromSnapshot());
|
||||||
|
Assert.assertEquals(".", options.getToSnapshot());
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure -diff is only valid when -update is specified
|
||||||
|
try {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setUseDiff(true, "s1", "s2");
|
||||||
|
fail("-diff should fail if -update option is not specified");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertExceptionContains(
|
||||||
|
"Diff is valid only with update options", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setSyncFolder(true);
|
||||||
|
options.setUseDiff(true, "s1", "s2");
|
||||||
|
options.setDeleteMissing(true);
|
||||||
|
assertFalse("-delete should be ignored when -diff is specified",
|
||||||
|
options.shouldDeleteMissing());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
fail("Got unexpected IllegalArgumentException: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setUseDiff(true, "s1", "s2");
|
||||||
|
options.setDeleteMissing(true);
|
||||||
|
fail("-diff should fail if -update option is not specified");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertExceptionContains(
|
||||||
|
"Diff is valid only with update options", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
options.setDeleteMissing(true);
|
||||||
|
options.setUseDiff(true, "s1", "s2");
|
||||||
|
fail("-delete should fail if -update option is not specified");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertExceptionContains("Delete missing is applicable only with update " +
|
||||||
|
"or overwrite options", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExclusionsOption() {
|
||||||
|
DistCpOptions options = new DistCpOptions(
|
||||||
|
new Path("hdfs://localhost:8020/source/first"),
|
||||||
|
new Path("hdfs://localhost:8020/target/"));
|
||||||
|
Assert.assertNull(options.getFiltersFile());
|
||||||
|
|
||||||
|
options.setFiltersFile("/tmp/filters.txt");
|
||||||
|
Assert.assertEquals("/tmp/filters.txt", options.getFiltersFile());
|
||||||
|
}
|
||||||
|
}
|
|
@ -715,19 +715,6 @@ public class TestOptionsParser {
|
||||||
fail("Got unexpected IllegalArgumentException: " + e.getMessage());
|
fail("Got unexpected IllegalArgumentException: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
options = OptionsParser.parse(new String[] {
|
|
||||||
"-diff", "s1", "s2", "-delete",
|
|
||||||
"hdfs://localhost:9820/source/first",
|
|
||||||
"hdfs://localhost:9820/target/" });
|
|
||||||
fail("-diff should fail if -update option is not specified");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
assertFalse("-delete should be ignored when -diff is specified",
|
|
||||||
options.shouldDeleteMissing());
|
|
||||||
GenericTestUtils.assertExceptionContains(
|
|
||||||
"Diff is valid only with update options", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
OptionsParser.parse(new String[] { "-diff", "s1", "s2",
|
OptionsParser.parse(new String[] { "-diff", "s1", "s2",
|
||||||
"-delete", "-overwrite",
|
"-delete", "-overwrite",
|
||||||
|
|
Loading…
Reference in New Issue