5
0
mirror of https://github.com/apache/sqoop.git synced 2025-05-05 05:59:07 +08:00

SQOOP-2631: Sqoop2: Add tests for shell commands in interactive mode

(Dian Fu via Jarek Jarcec Cecho)
This commit is contained in:
Jarek Jarcec Cecho 2015-11-05 09:56:57 -08:00
parent fa3c77b6a8
commit c173f6a52a
10 changed files with 669 additions and 66 deletions

View File

@ -60,7 +60,7 @@ public Object executeFunction(CommandLine line, boolean isInteractive) throws IO
private Status cloneJob(String jobArg, List<String> args, boolean isInteractive) throws IOException { private Status cloneJob(String jobArg, List<String> args, boolean isInteractive) throws IOException {
printlnResource(Constants.RES_CLONE_CLONING_JOB, jobArg); printlnResource(Constants.RES_CLONE_CLONING_JOB, jobArg);
ConsoleReader reader = new ConsoleReader(); ConsoleReader reader = getConsoleReader();
MJob job = client.getJob(jobArg); MJob job = client.getJob(jobArg);
job.setPersistenceId(MPersistableEntity.PERSISTANCE_ID_DEFAULT); job.setPersistenceId(MPersistableEntity.PERSISTANCE_ID_DEFAULT);

View File

@ -61,15 +61,15 @@ public Object executeFunction(CommandLine line, boolean isInteractive) throws IO
private Status cloneLink(String linkArg, List<String> args, boolean isInteractive) throws IOException { private Status cloneLink(String linkArg, List<String> args, boolean isInteractive) throws IOException {
printlnResource(Constants.RES_CLONE_CLONING_LINK, linkArg); printlnResource(Constants.RES_CLONE_CLONING_LINK, linkArg);
ConsoleReader reader = new ConsoleReader(); ConsoleReader reader = getConsoleReader();
MLink connection = client.getLink(linkArg); MLink link = client.getLink(linkArg);
// Remove persistent id as we're making a clone // Remove persistent id as we're making a clone
connection.setPersistenceId(MPersistableEntity.PERSISTANCE_ID_DEFAULT); link.setPersistenceId(MPersistableEntity.PERSISTANCE_ID_DEFAULT);
Status status = Status.OK; Status status = Status.OK;
ResourceBundle linkConfigBundle = client.getConnectorConfigBundle(connection.getConnectorId()); ResourceBundle linkConfigBundle = client.getConnectorConfigBundle(link.getConnectorId());
if (isInteractive) { if (isInteractive) {
printlnResource(Constants.RES_PROMPT_UPDATE_LINK_CONFIG); printlnResource(Constants.RES_PROMPT_UPDATE_LINK_CONFIG);
@ -81,29 +81,29 @@ private Status cloneLink(String linkArg, List<String> args, boolean isInteractiv
} }
// Fill in data from user // Fill in data from user
if(!fillLinkWithBundle(reader, connection, linkConfigBundle)) { if(!fillLinkWithBundle(reader, link, linkConfigBundle)) {
return null; return null;
} }
status = client.saveLink(connection); status = client.saveLink(link);
} while(!status.canProceed()); } while(!status.canProceed());
} else { } else {
LinkDynamicConfigOptions options = new LinkDynamicConfigOptions(); LinkDynamicConfigOptions options = new LinkDynamicConfigOptions();
options.prepareOptions(connection); options.prepareOptions(link);
CommandLine line = ConfigOptions.parseOptions(options, 0, args, false); CommandLine line = ConfigOptions.parseOptions(options, 0, args, false);
if (fillLink(line, connection)) { if (fillLink(line, link)) {
status = client.saveLink(connection); status = client.saveLink(link);
if (!status.canProceed()) { if (!status.canProceed()) {
printLinkValidationMessages(connection); printLinkValidationMessages(link);
return null; return null;
} }
} else { } else {
printLinkValidationMessages(connection); printLinkValidationMessages(link);
return null; return null;
} }
} }
printlnResource(Constants.RES_CLONE_LINK_SUCCESSFUL, status.name(), connection.getPersistenceId()); printlnResource(Constants.RES_CLONE_LINK_SUCCESSFUL, status.name(), link.getPersistenceId());
return status; return status;
} }

View File

@ -73,7 +73,7 @@ public Object executeFunction(CommandLine line, boolean isInteractive) throws IO
private Status createJob(String fromLinkArg, String toLinkArg, List<String> args, boolean isInteractive) throws IOException { private Status createJob(String fromLinkArg, String toLinkArg, List<String> args, boolean isInteractive) throws IOException {
printlnResource(Constants.RES_CREATE_CREATING_JOB, fromLinkArg, toLinkArg); printlnResource(Constants.RES_CREATE_CREATING_JOB, fromLinkArg, toLinkArg);
ConsoleReader reader = new ConsoleReader(); ConsoleReader reader = getConsoleReader();
MJob job = getClient().createJob(fromLinkArg, toLinkArg); MJob job = getClient().createJob(fromLinkArg, toLinkArg);
MConnector fromConnector = getClient().getConnector(job.getFromConnectorId()); MConnector fromConnector = getClient().getConnector(job.getFromConnectorId());

View File

@ -86,7 +86,7 @@ private Status createLink(CommandLine line, List<String> args, boolean isInterac
printlnResource(Constants.RES_CREATE_CREATING_LINK, connectorName); printlnResource(Constants.RES_CREATE_CREATING_LINK, connectorName);
} }
ConsoleReader reader = new ConsoleReader(); ConsoleReader reader = getConsoleReader();
ResourceBundle connectorConfigBundle = getClient().getConnectorConfigBundle(cid); ResourceBundle connectorConfigBundle = getClient().getConnectorConfigBundle(cid);

View File

@ -23,12 +23,15 @@
import org.apache.sqoop.shell.core.Constants; import org.apache.sqoop.shell.core.Constants;
import org.codehaus.groovy.tools.shell.IO; import org.codehaus.groovy.tools.shell.IO;
import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import jline.ConsoleReader;
/** /**
* Static internal environment of the shell shared across all commands and * Static internal environment of the shell shared across all commands and
* functions. * functions.
@ -56,6 +59,7 @@ private ShellEnvironment() {
static ResourceBundle resource = ResourceBundle.getBundle(Constants.RESOURCE_NAME, Locale.getDefault()); static ResourceBundle resource = ResourceBundle.getBundle(Constants.RESOURCE_NAME, Locale.getDefault());
static SqoopClient client = new SqoopClient(getServerUrl()); static SqoopClient client = new SqoopClient(getServerUrl());
static IO io; static IO io;
static ConsoleReader consoleReader;
public static String getEnv(String variable, String defaultValue) { public static String getEnv(String variable, String defaultValue) {
String value = System.getenv(variable); String value = System.getenv(variable);
@ -169,6 +173,18 @@ public static long getPollTimeout() {
return pollTimeout; return pollTimeout;
} }
public static void setConsoleReader(ConsoleReader reader) {
consoleReader = reader;
}
@edu.umd.cs.findbugs.annotations.SuppressWarnings({"LI_LAZY_INIT_STATIC"})
public static ConsoleReader getConsoleReader() throws IOException {
if (consoleReader == null) {
consoleReader = new ConsoleReader();
}
return consoleReader;
}
public static String resourceString(String resourceName) { public static String resourceString(String resourceName) {
return resource.getString(resourceName); return resource.getString(resourceName);
} }

View File

@ -61,7 +61,7 @@ public Object executeFunction(CommandLine line, boolean isInteractive) throws IO
private Status updateJob(String jobArg, List<String> args, boolean isInteractive) throws IOException { private Status updateJob(String jobArg, List<String> args, boolean isInteractive) throws IOException {
printlnResource(Constants.RES_SQOOP_UPDATING_JOB, jobArg); printlnResource(Constants.RES_SQOOP_UPDATING_JOB, jobArg);
ConsoleReader reader = new ConsoleReader(); ConsoleReader reader = getConsoleReader();
// TODO(SQOOP-1634): using from/to and driver config id, this call can be avoided // TODO(SQOOP-1634): using from/to and driver config id, this call can be avoided
MJob job = client.getJob(jobArg); MJob job = client.getJob(jobArg);

View File

@ -60,7 +60,7 @@ public Object executeFunction(CommandLine line, boolean isInteractive) throws IO
private Status updateLink(String linkArg, List<String> args, boolean isInteractive) throws IOException { private Status updateLink(String linkArg, List<String> args, boolean isInteractive) throws IOException {
printlnResource(Constants.RES_SQOOP_UPDATING_LINK, linkArg); printlnResource(Constants.RES_SQOOP_UPDATING_LINK, linkArg);
ConsoleReader reader = new ConsoleReader(); ConsoleReader reader = getConsoleReader();
// TODO(SQOOP-1634): using link config id, this call can be avoided // TODO(SQOOP-1634): using link config id, this call can be avoided
MLink link = client.getLink(linkArg); MLink link = client.getLink(linkArg);

View File

@ -21,19 +21,43 @@
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;
import jline.ConsoleReader;
import org.apache.commons.lang.StringUtils;
import org.apache.sqoop.client.SqoopClient; import org.apache.sqoop.client.SqoopClient;
import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.common.SqoopException;
import org.apache.sqoop.model.InputEditable;
import org.apache.sqoop.model.MBooleanInput;
import org.apache.sqoop.model.MConfig; import org.apache.sqoop.model.MConfig;
import org.apache.sqoop.model.MDateTimeInput;
import org.apache.sqoop.model.MDriverConfig; import org.apache.sqoop.model.MDriverConfig;
import org.apache.sqoop.model.MEnumInput;
import org.apache.sqoop.model.MFromConfig; import org.apache.sqoop.model.MFromConfig;
import org.apache.sqoop.model.MInput;
import org.apache.sqoop.model.MIntegerInput;
import org.apache.sqoop.model.MJob; import org.apache.sqoop.model.MJob;
import org.apache.sqoop.model.MLink; import org.apache.sqoop.model.MLink;
import org.apache.sqoop.model.MLinkConfig; import org.apache.sqoop.model.MLinkConfig;
import org.apache.sqoop.model.MListInput;
import org.apache.sqoop.model.MLongInput;
import org.apache.sqoop.model.MMapInput;
import org.apache.sqoop.model.MStringInput;
import org.apache.sqoop.model.MToConfig; import org.apache.sqoop.model.MToConfig;
import org.apache.sqoop.model.MValidator; import org.apache.sqoop.model.MValidator;
import org.apache.sqoop.shell.core.Constants; import org.apache.sqoop.shell.core.Constants;
@ -41,22 +65,41 @@
import org.apache.sqoop.utils.MapResourceBundle; import org.apache.sqoop.utils.MapResourceBundle;
import org.apache.sqoop.validation.Status; import org.apache.sqoop.validation.Status;
import org.codehaus.groovy.tools.shell.Groovysh; import org.codehaus.groovy.tools.shell.Groovysh;
import org.testng.Assert;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
public class TestCloneCommand { public class TestCloneCommand {
CloneCommand cloneCmd; CloneCommand cloneCmd;
SqoopClient client; SqoopClient client;
ConsoleReader reader;
ResourceBundle resourceBundle;
ByteArrayInputStream in;
byte[] data;
@BeforeTest(alwaysRun = true) @BeforeTest(alwaysRun = true)
public void setup() { public void setup() throws IOException {
Groovysh shell = new Groovysh(); Groovysh shell = new Groovysh();
cloneCmd = new CloneCommand(shell); cloneCmd = new CloneCommand(shell);
ShellEnvironment.setInteractive(false); ShellEnvironment.setInteractive(false);
ShellEnvironment.setIo(shell.getIo()); ShellEnvironment.setIo(shell.getIo());
client = mock(SqoopClient.class); client = mock(SqoopClient.class);
ShellEnvironment.setClient(client); ShellEnvironment.setClient(client);
data = new byte[1000];
in = new ByteArrayInputStream(data);
reader = new ConsoleReader(in, new OutputStreamWriter(System.out));
ShellEnvironment.setConsoleReader(reader);
resourceBundle = new ResourceBundle() {
@Override
protected Object handleGetObject(String key) {
return "fake_translated_value";
}
@Override
public Enumeration<String> getKeys() {
return Collections.emptyEnumeration();
}
};
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@ -69,27 +112,62 @@ public void testCloneLink() {
// clone link -lid link_test // clone link -lid link_test
Status status = (Status) cloneCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid", "link_test")); Status status = (Status) cloneCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid", "link_test"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
// Missing argument for option lid // Missing argument for option lid
try { try {
cloneCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid")); cloneCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid"));
Assert.fail("Update link should fail as parameters aren't complete!"); fail("Update link should fail as parameters aren't complete!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing argument for option")); assertTrue(e.getMessage().contains("Missing argument for option"));
} }
// Missing option lid // Missing option lid
try { try {
cloneCmd.execute(Arrays.asList(Constants.FN_LINK)); cloneCmd.execute(Arrays.asList(Constants.FN_LINK));
Assert.fail("Update link should fail as option lid is missing"); fail("Update link should fail as option lid is missing");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing required option")); assertTrue(e.getMessage().contains("Missing required option"));
} }
} }
@Test
public void testCloneLinkInteractive() {
ShellEnvironment.setInteractive(true);
initEnv();
MLink link = new MLink(1, new MLinkConfig(getConfig("CONFIGFROMNAME"), new ArrayList<MValidator>()));
when(client.getLink("link_test")).thenReturn(link);
when(client.getConnectorConfigBundle(1L)).thenReturn(resourceBundle);
when(client.saveLink(link)).thenReturn(Status.OK);
// clone link -lid link_test
initData("linkname\r" + // link name
"abc\r" + // for input with name "String"
"12345\r" + // for input with name "Integer"
"56789\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\rk2=v2\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"12345678\r"); // for input with name "DateTime"
Status status = (Status) cloneCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid", "link_test"));
assertTrue(status != null && status == Status.OK);
assertEquals(link.getName(), "linkname");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getStringInput("CONFIGFROMNAME.String").getValue(), "abc");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getIntegerInput("CONFIGFROMNAME.Integer").getValue().intValue(), 12345);
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getLongInput("CONFIGFROMNAME.Long").getValue().longValue(), 56789);
assertTrue((link.getConnectorLinkConfig("CONFIGFROMNAME").getBooleanInput("CONFIGFROMNAME.Boolean").getValue()));
HashMap<String, String> map = new HashMap<String, String>();
map.put("k1", "v1");
map.put("k2", "v2");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getMapInput("CONFIGFROMNAME.Map").getValue(), map);
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getEnumInput("CONFIGFROMNAME.Enum").getValue(), "YES");
assertEquals(StringUtils.join(link.getConnectorLinkConfig("CONFIGFROMNAME").getListInput("CONFIGFROMNAME.List").getValue(), "&"), "l1&l2&l3");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getDateTimeInput("CONFIGFROMNAME.DateTime").getValue().getMillis(), 12345678);
}
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@Test @Test
public void testCloneJob() { public void testCloneJob() {
@ -102,26 +180,141 @@ public void testCloneJob() {
when(client.getDriverConfigBundle()).thenReturn(new MapResourceBundle(new HashMap())); when(client.getDriverConfigBundle()).thenReturn(new MapResourceBundle(new HashMap()));
when(client.saveJob(job)).thenReturn(Status.OK); when(client.saveJob(job)).thenReturn(Status.OK);
// update job -jid job_test // clone job -jid job_test
Status status = (Status) cloneCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid", "job_test")); Status status = (Status) cloneCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid", "job_test"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
// Missing argument for option jid // Missing argument for option jid
try { try {
cloneCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid")); cloneCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid"));
Assert.fail("Update job should fail as parameters aren't complete!"); fail("Update job should fail as parameters aren't complete!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing argument for option")); assertTrue(e.getMessage().contains("Missing argument for option"));
} }
// Missing option jid // Missing option jid
try { try {
cloneCmd.execute(Arrays.asList(Constants.FN_JOB)); cloneCmd.execute(Arrays.asList(Constants.FN_JOB));
Assert.fail("Update job should fail as option jid is missing"); fail("Update job should fail as option jid is missing");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing required option")); assertTrue(e.getMessage().contains("Missing required option"));
}
}
@Test
public void testCloneJobInteractive() {
ShellEnvironment.setInteractive(true);
initEnv();
MJob job = new MJob(1, 2, 1, 2, new MFromConfig(getConfig("fromJobConfig"), new ArrayList<MValidator>()),
new MToConfig(getConfig("toJobConfig"), new ArrayList<MValidator>()),
new MDriverConfig(getConfig("driverConfig"), new ArrayList<MValidator>()));
when(client.getJob("job_test")).thenReturn(job);
when(client.getConnectorConfigBundle(any(Long.class))).thenReturn(resourceBundle);
when(client.getDriverConfigBundle()).thenReturn(resourceBundle);
when(client.saveJob(job)).thenReturn(Status.OK);
// clone job -jid job_test
initData("jobname\r" + // job name
// From job config
"abc\r" + // for input with name "String"
"12345\r" + // for input with name "Integer"
"56789\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\rk2=v2\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"12345678\r" + // for input with name "DateTime"
// To job config
"def\r" + // for input with name "String"
"11111\r" + // for input with name "Integer"
"22222\r" + // for input with name "Long"
"false\r" + // for input with name "Boolean"
"k3=v3\rk4=v4\r\r" + // for input with name "Map"
"1\r" + // for input with name "Enum"
"l4\rl5\rl6\r\r" + // for input with name "List"
"1234567\r" + // for input with name "DateTime"
// Driver config
"hij\r" + // for input with name "String"
"33333\r" + // for input with name "Integer"
"44444\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"7654321\r"); // for input with name "DateTime"
Status status = (Status) cloneCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid", "job_test"));
assertTrue(status != null && status == Status.OK);
assertEquals(job.getName(), "jobname");
// check from job config
assertEquals(job.getFromJobConfig().getStringInput("fromJobConfig.String").getValue(), "abc");
assertEquals(job.getFromJobConfig().getIntegerInput("fromJobConfig.Integer").getValue().intValue(), 12345);
assertEquals((job.getFromJobConfig().getLongInput("fromJobConfig.Long").getValue()).longValue(), 56789);
assertTrue((job.getFromJobConfig().getBooleanInput("fromJobConfig.Boolean").getValue()));
HashMap<String, String> map = new HashMap<String, String>();
map.put("k1", "v1");
map.put("k2", "v2");
assertEquals(job.getFromJobConfig().getMapInput("fromJobConfig.Map").getValue(), map);
assertEquals(job.getFromJobConfig().getEnumInput("fromJobConfig.Enum").getValue(), "YES");
assertEquals(StringUtils.join(job.getFromJobConfig().getListInput("fromJobConfig.List").getValue(), "&"), "l1&l2&l3");
assertEquals(job.getFromJobConfig().getDateTimeInput("fromJobConfig.DateTime").getValue().getMillis(), 12345678);
// check to job config
assertEquals(job.getToJobConfig().getStringInput("toJobConfig.String").getValue(), "def");
assertEquals(job.getToJobConfig().getIntegerInput("toJobConfig.Integer").getValue().intValue(), 11111);
assertEquals(job.getToJobConfig().getLongInput("toJobConfig.Long").getValue().longValue(), 22222);
assertFalse(job.getToJobConfig().getBooleanInput("toJobConfig.Boolean").getValue());
map = new HashMap<String, String>();
map.put("k3", "v3");
map.put("k4", "v4");
assertEquals(job.getToJobConfig().getMapInput("toJobConfig.Map").getValue(), map);
assertEquals(job.getToJobConfig().getEnumInput("toJobConfig.Enum").getValue(), "NO");
assertEquals(StringUtils.join(job.getToJobConfig().getListInput("toJobConfig.List").getValue(), "&"), "l4&l5&l6");
assertEquals(job.getToJobConfig().getDateTimeInput("toJobConfig.DateTime").getValue().getMillis(), 1234567);
// check driver config
assertEquals(job.getDriverConfig().getStringInput("driverConfig.String").getValue(), "hij");
assertEquals(job.getDriverConfig().getIntegerInput("driverConfig.Integer").getValue().intValue(), 33333);
assertEquals(job.getDriverConfig().getLongInput("driverConfig.Long").getValue().longValue(), 44444);
assertTrue(job.getDriverConfig().getBooleanInput("driverConfig.Boolean").getValue());
map = new HashMap<String, String>();
map.put("k1", "v1");
assertEquals(job.getDriverConfig().getMapInput("driverConfig.Map").getValue(), map);
assertEquals(job.getDriverConfig().getEnumInput("driverConfig.Enum").getValue(), "YES");
assertEquals(StringUtils.join(job.getDriverConfig().getListInput("driverConfig.List").getValue(), "&"), "l1&l2&l3");
assertEquals(job.getDriverConfig().getDateTimeInput("driverConfig.DateTime").getValue().getMillis(), 7654321);
}
@SuppressWarnings("unchecked")
private List<MConfig> getConfig(String configName) {
List<MInput<?>> list = new ArrayList<MInput<?>>();
list.add(new MStringInput(configName + "." + "String", false, InputEditable.ANY, StringUtils.EMPTY, (short)30, Collections.EMPTY_LIST));
list.add(new MIntegerInput(configName + "." + "Integer", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MLongInput(configName + "." + "Long", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MBooleanInput(configName + "." + "Boolean", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MMapInput(configName + "." + "Map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MEnumInput(configName + "." + "Enum", false, InputEditable.ANY, StringUtils.EMPTY, new String[] {"YES", "NO"}, Collections.EMPTY_LIST));
list.add(new MListInput(configName + "." + "List", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MDateTimeInput(configName + "." + "DateTime", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
List<MConfig> configs = new ArrayList<MConfig>();
configs.add(new MConfig(configName, list, Collections.EMPTY_LIST));
return configs;
}
private void initData(String destData) {
byte[] destDataBytes = destData.getBytes();
System.arraycopy(destDataBytes, 0, data, 0, destDataBytes.length);
in.reset();
}
private void initEnv() {
in.reset();
for (int i = 0; i < data.length; i++) {
data[i] = '\0';
} }
} }
} }

View File

@ -18,44 +18,88 @@
package org.apache.sqoop.shell; package org.apache.sqoop.shell;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;
import jline.ConsoleReader;
import org.apache.commons.lang.StringUtils;
import org.apache.sqoop.client.SqoopClient; import org.apache.sqoop.client.SqoopClient;
import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.common.SqoopException;
import org.apache.sqoop.model.InputEditable;
import org.apache.sqoop.model.MBooleanInput;
import org.apache.sqoop.model.MConfig; import org.apache.sqoop.model.MConfig;
import org.apache.sqoop.model.MConnector; import org.apache.sqoop.model.MConnector;
import org.apache.sqoop.model.MDateTimeInput;
import org.apache.sqoop.model.MDriverConfig; import org.apache.sqoop.model.MDriverConfig;
import org.apache.sqoop.model.MEnumInput;
import org.apache.sqoop.model.MFromConfig; import org.apache.sqoop.model.MFromConfig;
import org.apache.sqoop.model.MInput;
import org.apache.sqoop.model.MIntegerInput;
import org.apache.sqoop.model.MJob; import org.apache.sqoop.model.MJob;
import org.apache.sqoop.model.MLink; import org.apache.sqoop.model.MLink;
import org.apache.sqoop.model.MLinkConfig; import org.apache.sqoop.model.MLinkConfig;
import org.apache.sqoop.model.MListInput;
import org.apache.sqoop.model.MLongInput;
import org.apache.sqoop.model.MMapInput;
import org.apache.sqoop.model.MStringInput;
import org.apache.sqoop.model.MToConfig; import org.apache.sqoop.model.MToConfig;
import org.apache.sqoop.model.MValidator; import org.apache.sqoop.model.MValidator;
import org.apache.sqoop.shell.core.Constants; import org.apache.sqoop.shell.core.Constants;
import org.apache.sqoop.shell.core.ShellError; import org.apache.sqoop.shell.core.ShellError;
import org.apache.sqoop.validation.Status; import org.apache.sqoop.validation.Status;
import org.codehaus.groovy.tools.shell.Groovysh; import org.codehaus.groovy.tools.shell.Groovysh;
import org.testng.Assert;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
public class TestCreateCommand { public class TestCreateCommand {
CreateCommand createCmd; CreateCommand createCmd;
SqoopClient client; SqoopClient client;
ConsoleReader reader;
ResourceBundle resourceBundle;
ByteArrayInputStream in;
byte[] data;
@BeforeTest(alwaysRun = true) @BeforeTest(alwaysRun = true)
public void setup() { public void setup() throws IOException {
Groovysh shell = new Groovysh(); Groovysh shell = new Groovysh();
createCmd = new CreateCommand(shell); createCmd = new CreateCommand(shell);
ShellEnvironment.setInteractive(false); ShellEnvironment.setInteractive(false);
ShellEnvironment.setIo(shell.getIo()); ShellEnvironment.setIo(shell.getIo());
client = mock(SqoopClient.class); client = mock(SqoopClient.class);
ShellEnvironment.setClient(client); ShellEnvironment.setClient(client);
data = new byte[1000];
in = new ByteArrayInputStream(data);
reader = new ConsoleReader(in, new OutputStreamWriter(System.out));
ShellEnvironment.setConsoleReader(reader);
resourceBundle = new ResourceBundle() {
@Override
protected Object handleGetObject(String key) {
return "fake_translated_value";
}
@Override
public Enumeration<String> getKeys() {
return Collections.emptyEnumeration();
}
};
} }
@Test @Test
@ -66,19 +110,19 @@ public void testCreateLink() {
// create link -c connector_test // create link -c connector_test
Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_LINK, "-c", "connector_test")); Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_LINK, "-c", "connector_test"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
// create link -cid connector_test // create link -cid connector_test
status = (Status) createCmd.execute(Arrays.asList(Constants.FN_LINK, "-cid", "connector_test")); status = (Status) createCmd.execute(Arrays.asList(Constants.FN_LINK, "-cid", "connector_test"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
// incorrect command: create link -c // incorrect command: create link -c
try { try {
status = (Status) createCmd.execute(Arrays.asList(Constants.FN_LINK, "-c")); status = (Status) createCmd.execute(Arrays.asList(Constants.FN_LINK, "-c"));
Assert.fail("Create link should fail as connector id/name is missing!"); fail("Create link should fail as connector id/name is missing!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing argument for option")); assertTrue(e.getMessage().contains("Missing argument for option"));
} }
} }
@ -89,12 +133,48 @@ public void testCreateLinkWithNonExistingConnector() {
try { try {
createCmd.execute(Arrays.asList(Constants.FN_LINK, "-c", "connector_test")); createCmd.execute(Arrays.asList(Constants.FN_LINK, "-c", "connector_test"));
Assert.fail("Create link should fail as requested connector doesn't exist!"); fail("Create link should fail as requested connector doesn't exist!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(TestShellError.TEST_SHELL_0000, e.getErrorCode()); assertEquals(TestShellError.TEST_SHELL_0000, e.getErrorCode());
} }
} }
@Test
public void testCreateLinkInteractive() {
ShellEnvironment.setInteractive(true);
initEnv();
when(client.getConnector("connector_test")).thenReturn(new MConnector("", "", "", null, null, null));
MLink link = new MLink(1, new MLinkConfig(getConfig("CONFIGFROMNAME"), new ArrayList<MValidator>()));
when(client.createLink("connector_test")).thenReturn(link);
when(client.saveLink(any(MLink.class))).thenReturn(Status.OK);
when(client.getConnectorConfigBundle(any(Long.class))).thenReturn(resourceBundle);
// create link -c connector_test
initData("linkname\r" + // link name
"abc\r" + // for input with name "String"
"12345\r" + // for input with name "Integer"
"56789\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\rk2=v2\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"12345678\r"); // for input with name "DateTime"
Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_LINK, "-c", "connector_test"));
assertTrue(status != null && status == Status.OK);
assertEquals(link.getName(), "linkname");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getStringInput("CONFIGFROMNAME.String").getValue(), "abc");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getIntegerInput("CONFIGFROMNAME.Integer").getValue().intValue(), 12345);
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getLongInput("CONFIGFROMNAME.Long").getValue().longValue(), 56789);
assertTrue((link.getConnectorLinkConfig("CONFIGFROMNAME").getBooleanInput("CONFIGFROMNAME.Boolean").getValue()));
HashMap<String, String> map = new HashMap<String, String>();
map.put("k1", "v1");
map.put("k2", "v2");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getMapInput("CONFIGFROMNAME.Map").getValue(), map);
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getEnumInput("CONFIGFROMNAME.Enum").getValue(), "YES");
assertEquals(StringUtils.join(link.getConnectorLinkConfig("CONFIGFROMNAME").getListInput("CONFIGFROMNAME.List").getValue(), "&"), "l1&l2&l3");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getDateTimeInput("CONFIGFROMNAME.DateTime").getValue().getMillis(), 12345678);
}
@Test @Test
public void testCreateJob() { public void testCreateJob() {
MConnector fromConnector = new MConnector("connector_from", "", "", null, new MFromConfig(new ArrayList<MConfig>(), new ArrayList<MValidator>()), null); MConnector fromConnector = new MConnector("connector_from", "", "", null, new MFromConfig(new ArrayList<MConfig>(), new ArrayList<MValidator>()), null);
@ -109,15 +189,15 @@ public void testCreateJob() {
// create job -f link_from -to link_to // create job -f link_from -to link_to
Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_JOB, "-f", "link_from", "-to", "link_to")); Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_JOB, "-f", "link_from", "-to", "link_to"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
// incorrect command: create job -f link_from // incorrect command: create job -f link_from
try { try {
status = (Status) createCmd.execute(Arrays.asList(Constants.FN_JOB, "-f", "link_from")); status = (Status) createCmd.execute(Arrays.asList(Constants.FN_JOB, "-f", "link_from"));
Assert.fail("Create Job should fail as the to link id/name is missing!"); fail("Create Job should fail as the to link id/name is missing!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing required option")); assertTrue(e.getMessage().contains("Missing required option"));
} }
} }
@ -127,16 +207,135 @@ public void testCreateJobWithNonExistingLink() {
try { try {
createCmd.execute(Arrays.asList(Constants.FN_JOB, "-f", "link_from", "-to", "link_to")); createCmd.execute(Arrays.asList(Constants.FN_JOB, "-f", "link_from", "-to", "link_to"));
Assert.fail("Create Job should fail as from link doesn't exist!"); fail("Create Job should fail as from link doesn't exist!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(TestShellError.TEST_SHELL_0000, e.getErrorCode()); assertEquals(TestShellError.TEST_SHELL_0000, e.getErrorCode());
} }
} }
@Test
public void testCreateJobInteractive() {
ShellEnvironment.setInteractive(true);
initEnv();
MConnector fromConnector = new MConnector("connector_from", "", "", null, new MFromConfig(new ArrayList<MConfig>(), new ArrayList<MValidator>()), null);
MConnector toConnector = new MConnector("connector_to", "", "", null, null, new MToConfig(new ArrayList<MConfig>(), new ArrayList<MValidator>()));
MJob job = new MJob(1, 2, 1, 2, new MFromConfig(getConfig("fromJobConfig"), new ArrayList<MValidator>()),
new MToConfig(getConfig("toJobConfig"), new ArrayList<MValidator>()),
new MDriverConfig(getConfig("driverConfig"), new ArrayList<MValidator>()));
when(client.createJob("link_from", "link_to")).thenReturn(job);
when(client.getConnector(1)).thenReturn(fromConnector);
when(client.getConnector(2)).thenReturn(toConnector);
when(client.saveJob(any(MJob.class))).thenReturn(Status.OK);
when(client.getConnectorConfigBundle(any(Long.class))).thenReturn(resourceBundle);
when(client.getDriverConfigBundle()).thenReturn(resourceBundle);
// create job -f link_from -to link_to
initData("jobname\r" + // job name
// From job config
"abc\r" + // for input with name "String"
"12345\r" + // for input with name "Integer"
"56789\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\rk2=v2\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"12345678\r" + // for input with name "DateTime"
// To job config
"def\r" + // for input with name "String"
"11111\r" + // for input with name "Integer"
"22222\r" + // for input with name "Long"
"false\r" + // for input with name "Boolean"
"k3=v3\rk4=v4\r\r" + // for input with name "Map"
"1\r" + // for input with name "Enum"
"l4\rl5\rl6\r\r" + // for input with name "List"
"1234567\r" + // for input with name "DateTime"
// Driver config
"hij\r" + // for input with name "String"
"33333\r" + // for input with name "Integer"
"44444\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"7654321\r"); // for input with name "DateTime"
Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_JOB, "-f", "link_from", "-to", "link_to"));
assertTrue(status != null && status == Status.OK);
assertEquals(job.getName(), "jobname");
// check from job config
assertEquals(job.getFromJobConfig().getStringInput("fromJobConfig.String").getValue(), "abc");
assertEquals(job.getFromJobConfig().getIntegerInput("fromJobConfig.Integer").getValue().intValue(), 12345);
assertEquals((job.getFromJobConfig().getLongInput("fromJobConfig.Long").getValue()).longValue(), 56789);
assertTrue((job.getFromJobConfig().getBooleanInput("fromJobConfig.Boolean").getValue()));
HashMap<String, String> map = new HashMap<String, String>();
map.put("k1", "v1");
map.put("k2", "v2");
assertEquals(job.getFromJobConfig().getMapInput("fromJobConfig.Map").getValue(), map);
assertEquals(job.getFromJobConfig().getEnumInput("fromJobConfig.Enum").getValue(), "YES");
assertEquals(StringUtils.join(job.getFromJobConfig().getListInput("fromJobConfig.List").getValue(), "&"), "l1&l2&l3");
assertEquals(job.getFromJobConfig().getDateTimeInput("fromJobConfig.DateTime").getValue().getMillis(), 12345678);
// check to job config
assertEquals(job.getToJobConfig().getStringInput("toJobConfig.String").getValue(), "def");
assertEquals(job.getToJobConfig().getIntegerInput("toJobConfig.Integer").getValue().intValue(), 11111);
assertEquals(job.getToJobConfig().getLongInput("toJobConfig.Long").getValue().longValue(), 22222);
assertFalse(job.getToJobConfig().getBooleanInput("toJobConfig.Boolean").getValue());
map = new HashMap<String, String>();
map.put("k3", "v3");
map.put("k4", "v4");
assertEquals(job.getToJobConfig().getMapInput("toJobConfig.Map").getValue(), map);
assertEquals(job.getToJobConfig().getEnumInput("toJobConfig.Enum").getValue(), "NO");
assertEquals(StringUtils.join(job.getToJobConfig().getListInput("toJobConfig.List").getValue(), "&"), "l4&l5&l6");
assertEquals(job.getToJobConfig().getDateTimeInput("toJobConfig.DateTime").getValue().getMillis(), 1234567);
// check driver config
assertEquals(job.getDriverConfig().getStringInput("driverConfig.String").getValue(), "hij");
assertEquals(job.getDriverConfig().getIntegerInput("driverConfig.Integer").getValue().intValue(), 33333);
assertEquals(job.getDriverConfig().getLongInput("driverConfig.Long").getValue().longValue(), 44444);
assertTrue(job.getDriverConfig().getBooleanInput("driverConfig.Boolean").getValue());
map = new HashMap<String, String>();
map.put("k1", "v1");
assertEquals(job.getDriverConfig().getMapInput("driverConfig.Map").getValue(), map);
assertEquals(job.getDriverConfig().getEnumInput("driverConfig.Enum").getValue(), "YES");
assertEquals(StringUtils.join(job.getDriverConfig().getListInput("driverConfig.List").getValue(), "&"), "l1&l2&l3");
assertEquals(job.getDriverConfig().getDateTimeInput("driverConfig.DateTime").getValue().getMillis(), 7654321);
}
@Test @Test
public void testCreateRole() { public void testCreateRole() {
// create role -r role_test // create role -r role_test
Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_ROLE, "-r", "role_test")); Status status = (Status) createCmd.execute(Arrays.asList(Constants.FN_ROLE, "-r", "role_test"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
}
@SuppressWarnings("unchecked")
private List<MConfig> getConfig(String configName) {
List<MInput<?>> list = new ArrayList<MInput<?>>();
list.add(new MStringInput(configName + "." + "String", false, InputEditable.ANY, StringUtils.EMPTY, (short)30, Collections.EMPTY_LIST));
list.add(new MIntegerInput(configName + "." + "Integer", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MLongInput(configName + "." + "Long", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MBooleanInput(configName + "." + "Boolean", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MMapInput(configName + "." + "Map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MEnumInput(configName + "." + "Enum", false, InputEditable.ANY, StringUtils.EMPTY, new String[] {"YES", "NO"}, Collections.EMPTY_LIST));
list.add(new MListInput(configName + "." + "List", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MDateTimeInput(configName + "." + "DateTime", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
List<MConfig> configs = new ArrayList<MConfig>();
configs.add(new MConfig(configName, list, Collections.EMPTY_LIST));
return configs;
}
private void initData(String destData) {
byte[] destDataBytes = destData.getBytes();
System.arraycopy(destDataBytes, 0, data, 0, destDataBytes.length);
in.reset();
}
private void initEnv() {
in.reset();
for (int i = 0; i < data.length; i++) {
data[i] = '\0';
}
} }
} }

View File

@ -21,19 +21,44 @@
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;
import jline.ConsoleReader;
import org.apache.commons.lang.StringUtils;
import org.apache.sqoop.client.SqoopClient; import org.apache.sqoop.client.SqoopClient;
import org.apache.sqoop.common.SqoopException; import org.apache.sqoop.common.SqoopException;
import org.apache.sqoop.model.InputEditable;
import org.apache.sqoop.model.MBooleanInput;
import org.apache.sqoop.model.MConfig; import org.apache.sqoop.model.MConfig;
import org.apache.sqoop.model.MConnector;
import org.apache.sqoop.model.MDateTimeInput;
import org.apache.sqoop.model.MDriverConfig; import org.apache.sqoop.model.MDriverConfig;
import org.apache.sqoop.model.MEnumInput;
import org.apache.sqoop.model.MFromConfig; import org.apache.sqoop.model.MFromConfig;
import org.apache.sqoop.model.MInput;
import org.apache.sqoop.model.MIntegerInput;
import org.apache.sqoop.model.MJob; import org.apache.sqoop.model.MJob;
import org.apache.sqoop.model.MLink; import org.apache.sqoop.model.MLink;
import org.apache.sqoop.model.MLinkConfig; import org.apache.sqoop.model.MLinkConfig;
import org.apache.sqoop.model.MListInput;
import org.apache.sqoop.model.MLongInput;
import org.apache.sqoop.model.MMapInput;
import org.apache.sqoop.model.MStringInput;
import org.apache.sqoop.model.MToConfig; import org.apache.sqoop.model.MToConfig;
import org.apache.sqoop.model.MValidator; import org.apache.sqoop.model.MValidator;
import org.apache.sqoop.shell.core.Constants; import org.apache.sqoop.shell.core.Constants;
@ -41,22 +66,41 @@
import org.apache.sqoop.utils.MapResourceBundle; import org.apache.sqoop.utils.MapResourceBundle;
import org.apache.sqoop.validation.Status; import org.apache.sqoop.validation.Status;
import org.codehaus.groovy.tools.shell.Groovysh; import org.codehaus.groovy.tools.shell.Groovysh;
import org.testng.Assert;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
public class TestUpdateCommand { public class TestUpdateCommand {
UpdateCommand updateCmd; UpdateCommand updateCmd;
SqoopClient client; SqoopClient client;
ConsoleReader reader;
ResourceBundle resourceBundle;
ByteArrayInputStream in;
byte[] data;
@BeforeTest(alwaysRun = true) @BeforeTest(alwaysRun = true)
public void setup() { public void setup() throws IOException {
Groovysh shell = new Groovysh(); Groovysh shell = new Groovysh();
updateCmd = new UpdateCommand(shell); updateCmd = new UpdateCommand(shell);
ShellEnvironment.setInteractive(false); ShellEnvironment.setInteractive(false);
ShellEnvironment.setIo(shell.getIo()); ShellEnvironment.setIo(shell.getIo());
client = mock(SqoopClient.class); client = mock(SqoopClient.class);
ShellEnvironment.setClient(client); ShellEnvironment.setClient(client);
data = new byte[1000];
in = new ByteArrayInputStream(data);
reader = new ConsoleReader(in, new OutputStreamWriter(System.out));
ShellEnvironment.setConsoleReader(reader);
resourceBundle = new ResourceBundle() {
@Override
protected Object handleGetObject(String key) {
return "fake_translated_value";
}
@Override
public Enumeration<String> getKeys() {
return Collections.emptyEnumeration();
}
};
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@ -69,27 +113,63 @@ public void testUpdateLink() throws InterruptedException {
// update link -lid link_test // update link -lid link_test
Status status = (Status) updateCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid", "link_test")); Status status = (Status) updateCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid", "link_test"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
// Missing argument for option lid // Missing argument for option lid
try { try {
updateCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid")); updateCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid"));
Assert.fail("Update link should fail as parameters aren't complete!"); fail("Update link should fail as parameters aren't complete!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing argument for option")); assertTrue(e.getMessage().contains("Missing argument for option"));
} }
// Missing option lid // Missing option lid
try { try {
updateCmd.execute(Arrays.asList(Constants.FN_LINK)); updateCmd.execute(Arrays.asList(Constants.FN_LINK));
Assert.fail("Update link should fail as option lid is missing"); fail("Update link should fail as option lid is missing");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing required option")); assertTrue(e.getMessage().contains("Missing required option"));
} }
} }
@Test
public void testUpdateLinkInteractive() {
ShellEnvironment.setInteractive(true);
initEnv();
when(client.getConnector("connector_test")).thenReturn(new MConnector("", "", "", null, null, null));
MLink link = new MLink(1, new MLinkConfig(getConfig("CONFIGFROMNAME"), new ArrayList<MValidator>()));
when(client.getLink("link_test")).thenReturn(link);
when(client.updateLink(link)).thenReturn(Status.OK);
when(client.getConnectorConfigBundle(any(Long.class))).thenReturn(resourceBundle);
// update link -lid link_test
initData("linkname\r" + // link name
"abc\r" + // for input with name "String"
"12345\r" + // for input with name "Integer"
"56789\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\rk2=v2\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"12345678\r"); // for input with name "DateTime"
Status status = (Status) updateCmd.execute(Arrays.asList(Constants.FN_LINK, "-lid", "link_test"));
assertTrue(status != null && status == Status.OK);
assertEquals(link.getName(), "linkname");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getStringInput("CONFIGFROMNAME.String").getValue(), "abc");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getIntegerInput("CONFIGFROMNAME.Integer").getValue().intValue(), 12345);
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getLongInput("CONFIGFROMNAME.Long").getValue().longValue(), 56789);
assertTrue((link.getConnectorLinkConfig("CONFIGFROMNAME").getBooleanInput("CONFIGFROMNAME.Boolean").getValue()));
HashMap<String, String> map = new HashMap<String, String>();
map.put("k1", "v1");
map.put("k2", "v2");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getMapInput("CONFIGFROMNAME.Map").getValue(), map);
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getEnumInput("CONFIGFROMNAME.Enum").getValue(), "YES");
assertEquals(StringUtils.join(link.getConnectorLinkConfig("CONFIGFROMNAME").getListInput("CONFIGFROMNAME.List").getValue(), "&"), "l1&l2&l3");
assertEquals(link.getConnectorLinkConfig("CONFIGFROMNAME").getDateTimeInput("CONFIGFROMNAME.DateTime").getValue().getMillis(), 12345678);
}
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@Test @Test
public void testUpdateJob() throws InterruptedException { public void testUpdateJob() throws InterruptedException {
@ -104,24 +184,139 @@ public void testUpdateJob() throws InterruptedException {
// update job -jid job_test // update job -jid job_test
Status status = (Status) updateCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid", "job_test")); Status status = (Status) updateCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid", "job_test"));
Assert.assertTrue(status != null && status == Status.OK); assertTrue(status != null && status == Status.OK);
// Missing argument for option jid // Missing argument for option jid
try { try {
updateCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid")); updateCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid"));
Assert.fail("Update job should fail as parameters aren't complete!"); fail("Update job should fail as parameters aren't complete!");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing argument for option")); assertTrue(e.getMessage().contains("Missing argument for option"));
} }
// Missing option jid // Missing option jid
try { try {
updateCmd.execute(Arrays.asList(Constants.FN_JOB)); updateCmd.execute(Arrays.asList(Constants.FN_JOB));
Assert.fail("Update job should fail as option jid is missing"); fail("Update job should fail as option jid is missing");
} catch (SqoopException e) { } catch (SqoopException e) {
Assert.assertEquals(ShellError.SHELL_0003, e.getErrorCode()); assertEquals(ShellError.SHELL_0003, e.getErrorCode());
Assert.assertTrue(e.getMessage().contains("Missing required option")); assertTrue(e.getMessage().contains("Missing required option"));
}
}
@Test
public void testUpdateJobInteractive() {
ShellEnvironment.setInteractive(true);
initEnv();
MJob job = new MJob(1, 2, 1, 2, new MFromConfig(getConfig("fromJobConfig"), new ArrayList<MValidator>()),
new MToConfig(getConfig("toJobConfig"), new ArrayList<MValidator>()),
new MDriverConfig(getConfig("driverConfig"), new ArrayList<MValidator>()));
when(client.getJob("job_test")).thenReturn(job);
when(client.getConnectorConfigBundle(any(Long.class))).thenReturn(resourceBundle);
when(client.getDriverConfigBundle()).thenReturn(resourceBundle);
when(client.updateJob(job)).thenReturn(Status.OK);
// update job -jid job_test
initData("jobname\r" + // job name
// From job config
"abc\r" + // for input with name "String"
"12345\r" + // for input with name "Integer"
"56789\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\rk2=v2\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"12345678\r" + // for input with name "DateTime"
// To job config
"def\r" + // for input with name "String"
"11111\r" + // for input with name "Integer"
"22222\r" + // for input with name "Long"
"false\r" + // for input with name "Boolean"
"k3=v3\rk4=v4\r\r" + // for input with name "Map"
"1\r" + // for input with name "Enum"
"l4\rl5\rl6\r\r" + // for input with name "List"
"1234567\r" + // for input with name "DateTime"
// Driver config
"hij\r" + // for input with name "String"
"33333\r" + // for input with name "Integer"
"44444\r" + // for input with name "Long"
"true\r" + // for input with name "Boolean"
"k1=v1\r\r" + // for input with name "Map"
"0\r" + // for input with name "Enum"
"l1\rl2\rl3\r\r" + // for input with name "List"
"7654321\r"); // for input with name "DateTime"
Status status = (Status) updateCmd.execute(Arrays.asList(Constants.FN_JOB, "-jid", "job_test"));
assertTrue(status != null && status == Status.OK);
assertEquals(job.getName(), "jobname");
// check from job config
assertEquals(job.getFromJobConfig().getStringInput("fromJobConfig.String").getValue(), "abc");
assertEquals(job.getFromJobConfig().getIntegerInput("fromJobConfig.Integer").getValue().intValue(), 12345);
assertEquals((job.getFromJobConfig().getLongInput("fromJobConfig.Long").getValue()).longValue(), 56789);
assertTrue((job.getFromJobConfig().getBooleanInput("fromJobConfig.Boolean").getValue()));
HashMap<String, String> map = new HashMap<String, String>();
map.put("k1", "v1");
map.put("k2", "v2");
assertEquals(job.getFromJobConfig().getMapInput("fromJobConfig.Map").getValue(), map);
assertEquals(job.getFromJobConfig().getEnumInput("fromJobConfig.Enum").getValue(), "YES");
assertEquals(StringUtils.join(job.getFromJobConfig().getListInput("fromJobConfig.List").getValue(), "&"), "l1&l2&l3");
assertEquals(job.getFromJobConfig().getDateTimeInput("fromJobConfig.DateTime").getValue().getMillis(), 12345678);
// check to job config
assertEquals(job.getToJobConfig().getStringInput("toJobConfig.String").getValue(), "def");
assertEquals(job.getToJobConfig().getIntegerInput("toJobConfig.Integer").getValue().intValue(), 11111);
assertEquals(job.getToJobConfig().getLongInput("toJobConfig.Long").getValue().longValue(), 22222);
assertFalse(job.getToJobConfig().getBooleanInput("toJobConfig.Boolean").getValue());
map = new HashMap<String, String>();
map.put("k3", "v3");
map.put("k4", "v4");
assertEquals(job.getToJobConfig().getMapInput("toJobConfig.Map").getValue(), map);
assertEquals(job.getToJobConfig().getEnumInput("toJobConfig.Enum").getValue(), "NO");
assertEquals(StringUtils.join(job.getToJobConfig().getListInput("toJobConfig.List").getValue(), "&"), "l4&l5&l6");
assertEquals(job.getToJobConfig().getDateTimeInput("toJobConfig.DateTime").getValue().getMillis(), 1234567);
// check driver config
assertEquals(job.getDriverConfig().getStringInput("driverConfig.String").getValue(), "hij");
assertEquals(job.getDriverConfig().getIntegerInput("driverConfig.Integer").getValue().intValue(), 33333);
assertEquals(job.getDriverConfig().getLongInput("driverConfig.Long").getValue().longValue(), 44444);
assertTrue(job.getDriverConfig().getBooleanInput("driverConfig.Boolean").getValue());
map = new HashMap<String, String>();
map.put("k1", "v1");
assertEquals(job.getDriverConfig().getMapInput("driverConfig.Map").getValue(), map);
assertEquals(job.getDriverConfig().getEnumInput("driverConfig.Enum").getValue(), "YES");
assertEquals(StringUtils.join(job.getDriverConfig().getListInput("driverConfig.List").getValue(), "&"), "l1&l2&l3");
assertEquals(job.getDriverConfig().getDateTimeInput("driverConfig.DateTime").getValue().getMillis(), 7654321);
}
@SuppressWarnings("unchecked")
private List<MConfig> getConfig(String configName) {
List<MInput<?>> list = new ArrayList<MInput<?>>();
list.add(new MStringInput(configName + "." + "String", false, InputEditable.ANY, StringUtils.EMPTY, (short)30, Collections.EMPTY_LIST));
list.add(new MIntegerInput(configName + "." + "Integer", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MLongInput(configName + "." + "Long", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MBooleanInput(configName + "." + "Boolean", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MMapInput(configName + "." + "Map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MEnumInput(configName + "." + "Enum", false, InputEditable.ANY, StringUtils.EMPTY, new String[] {"YES", "NO"}, Collections.EMPTY_LIST));
list.add(new MListInput(configName + "." + "List", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
list.add(new MDateTimeInput(configName + "." + "DateTime", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
List<MConfig> configs = new ArrayList<MConfig>();
configs.add(new MConfig(configName, list, Collections.EMPTY_LIST));
return configs;
}
private void initData(String destData) {
byte[] destDataBytes = destData.getBytes();
System.arraycopy(destDataBytes, 0, data, 0, destDataBytes.length);
in.reset();
}
private void initEnv() {
in.reset();
for (int i = 0; i < data.length; i++) {
data[i] = '\0';
} }
} }
} }