|
@@ -19,6 +19,9 @@
|
|
|
package org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher;
|
|
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
|
+import static org.junit.Assert.assertThat;
|
|
|
+import static org.junit.Assert.fail;
|
|
|
+import static org.junit.matchers.JUnitMatchers.*;
|
|
|
import static org.mockito.Mockito.mock;
|
|
|
import static org.mockito.Mockito.when;
|
|
|
|
|
@@ -27,6 +30,7 @@ import java.io.File;
|
|
|
import java.io.FileOutputStream;
|
|
|
import java.io.FileReader;
|
|
|
import java.io.IOException;
|
|
|
+import java.io.PrintStream;
|
|
|
import java.io.PrintWriter;
|
|
|
import java.nio.ByteBuffer;
|
|
|
import java.util.ArrayList;
|
|
@@ -37,7 +41,6 @@ import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
import org.junit.Assert;
|
|
|
-
|
|
|
import org.apache.commons.codec.binary.Base64;
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.fs.FileUtil;
|
|
@@ -76,6 +79,7 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.BaseContainerM
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerEventType;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerExitEvent;
|
|
|
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.ShellScriptBuilder;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ContainerLocalizer;
|
|
|
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
|
|
|
import org.apache.hadoop.yarn.util.Apps;
|
|
@@ -83,6 +87,7 @@ import org.apache.hadoop.yarn.util.AuxiliaryServiceHelper;
|
|
|
import org.apache.hadoop.yarn.util.ConverterUtils;
|
|
|
import org.apache.hadoop.yarn.util.LinuxResourceCalculatorPlugin;
|
|
|
import org.apache.hadoop.yarn.util.ResourceCalculatorPlugin;
|
|
|
+import org.junit.Assume;
|
|
|
import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
|
|
@@ -743,18 +748,18 @@ public class TestContainerLaunch extends BaseContainerManagerTest {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Test
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testDelayedKill() throws Exception {
|
|
|
internalKillTest(true);
|
|
|
}
|
|
|
|
|
|
- @Test
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testImmediateKill() throws Exception {
|
|
|
internalKillTest(false);
|
|
|
}
|
|
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
- @Test
|
|
|
+ @Test (timeout = 10000)
|
|
|
public void testCallFailureWithNullLocalizedResources() {
|
|
|
Container container = mock(Container.class);
|
|
|
when(container.getContainerId()).thenReturn(ContainerId.newInstance(
|
|
@@ -792,4 +797,166 @@ public class TestContainerLaunch extends BaseContainerManagerTest {
|
|
|
return containerToken;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test that script exists with non-zero exit code when command fails.
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ @Test (timeout = 10000)
|
|
|
+ public void testShellScriptBuilderNonZeroExitCode() throws IOException {
|
|
|
+ ShellScriptBuilder builder = ShellScriptBuilder.create();
|
|
|
+ builder.command(Arrays.asList(new String[] {"unknownCommand"}));
|
|
|
+ File shellFile = Shell.appendScriptExtension(tmpDir, "testShellScriptBuilderError");
|
|
|
+ PrintStream writer = new PrintStream(new FileOutputStream(shellFile));
|
|
|
+ builder.write(writer);
|
|
|
+ writer.close();
|
|
|
+ try {
|
|
|
+ FileUtil.setExecutable(shellFile, true);
|
|
|
+
|
|
|
+ Shell.ShellCommandExecutor shexc = new Shell.ShellCommandExecutor(
|
|
|
+ new String[]{shellFile.getAbsolutePath()}, tmpDir);
|
|
|
+ try {
|
|
|
+ shexc.execute();
|
|
|
+ fail("builder shell command was expected to throw");
|
|
|
+ }
|
|
|
+ catch(IOException e) {
|
|
|
+ // expected
|
|
|
+ System.out.println("Received an expected exception: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally {
|
|
|
+ FileUtil.fullyDelete(shellFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final String expectedMessage = "The command line has a length of";
|
|
|
+
|
|
|
+ @Test (timeout = 10000)
|
|
|
+ public void testWindowsShellScriptBuilderCommand() throws IOException {
|
|
|
+ String callCmd = "@call ";
|
|
|
+
|
|
|
+ // Test is only relevant on Windows
|
|
|
+ Assume.assumeTrue(Shell.WINDOWS);
|
|
|
+
|
|
|
+ // The tests are built on assuming 8191 max command line length
|
|
|
+ assertEquals(8191, Shell.WINDOWS_MAX_SHELL_LENGHT);
|
|
|
+
|
|
|
+ ShellScriptBuilder builder = ShellScriptBuilder.create();
|
|
|
+
|
|
|
+ // Basic tests: less length, exact length, max+1 length
|
|
|
+ builder.command(Arrays.asList(
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("A", 1024)));
|
|
|
+ builder.command(Arrays.asList(
|
|
|
+ org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "E", Shell.WINDOWS_MAX_SHELL_LENGHT - callCmd.length())));
|
|
|
+ try {
|
|
|
+ builder.command(Arrays.asList(
|
|
|
+ org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "X", Shell.WINDOWS_MAX_SHELL_LENGHT -callCmd.length() + 1)));
|
|
|
+ fail("longCommand was expected to throw");
|
|
|
+ } catch(IOException e) {
|
|
|
+ assertThat(e.getMessage(), containsString(expectedMessage));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Composite tests, from parts: less, exact and +
|
|
|
+ builder.command(Arrays.asList(
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("A", 1024),
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("A", 1024),
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("A", 1024)));
|
|
|
+
|
|
|
+ // buildr.command joins the command parts with an extra space
|
|
|
+ builder.command(Arrays.asList(
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("E", 4095),
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("E", 2047),
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("E", 2047 - callCmd.length())));
|
|
|
+
|
|
|
+ try {
|
|
|
+ builder.command(Arrays.asList(
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("X", 4095),
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("X", 2047),
|
|
|
+ org.apache.commons.lang.StringUtils.repeat("X", 2048 - callCmd.length())));
|
|
|
+ fail("long commands was expected to throw");
|
|
|
+ } catch(IOException e) {
|
|
|
+ assertThat(e.getMessage(), containsString(expectedMessage));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test (timeout = 10000)
|
|
|
+ public void testWindowsShellScriptBuilderEnv() throws IOException {
|
|
|
+ // Test is only relevant on Windows
|
|
|
+ Assume.assumeTrue(Shell.WINDOWS);
|
|
|
+
|
|
|
+ // The tests are built on assuming 8191 max command line length
|
|
|
+ assertEquals(8191, Shell.WINDOWS_MAX_SHELL_LENGHT);
|
|
|
+
|
|
|
+ ShellScriptBuilder builder = ShellScriptBuilder.create();
|
|
|
+
|
|
|
+ // test env
|
|
|
+ builder.env("somekey", org.apache.commons.lang.StringUtils.repeat("A", 1024));
|
|
|
+ builder.env("somekey", org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "A", Shell.WINDOWS_MAX_SHELL_LENGHT - ("@set somekey=").length()));
|
|
|
+ try {
|
|
|
+ builder.env("somekey", org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "A", Shell.WINDOWS_MAX_SHELL_LENGHT - ("@set somekey=").length()) + 1);
|
|
|
+ fail("long env was expected to throw");
|
|
|
+ } catch(IOException e) {
|
|
|
+ assertThat(e.getMessage(), containsString(expectedMessage));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test (timeout = 10000)
|
|
|
+ public void testWindowsShellScriptBuilderMkdir() throws IOException {
|
|
|
+ String mkDirCmd = "@if not exist \"\" mkdir \"\"";
|
|
|
+
|
|
|
+ // Test is only relevant on Windows
|
|
|
+ Assume.assumeTrue(Shell.WINDOWS);
|
|
|
+
|
|
|
+ // The tests are built on assuming 8191 max command line length
|
|
|
+ assertEquals(8191, Shell.WINDOWS_MAX_SHELL_LENGHT);
|
|
|
+
|
|
|
+ ShellScriptBuilder builder = ShellScriptBuilder.create();
|
|
|
+
|
|
|
+ // test mkdir
|
|
|
+ builder.mkdir(new Path(org.apache.commons.lang.StringUtils.repeat("A", 1024)));
|
|
|
+ builder.mkdir(new Path(org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "E", (Shell.WINDOWS_MAX_SHELL_LENGHT - mkDirCmd.length())/2)));
|
|
|
+ try {
|
|
|
+ builder.mkdir(new Path(org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "X", (Shell.WINDOWS_MAX_SHELL_LENGHT - mkDirCmd.length())/2 +1)));
|
|
|
+ fail("long mkdir was expected to throw");
|
|
|
+ } catch(IOException e) {
|
|
|
+ assertThat(e.getMessage(), containsString(expectedMessage));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test (timeout = 10000)
|
|
|
+ public void testWindowsShellScriptBuilderLink() throws IOException {
|
|
|
+ // Test is only relevant on Windows
|
|
|
+ Assume.assumeTrue(Shell.WINDOWS);
|
|
|
+
|
|
|
+ String linkCmd = "@" +Shell.WINUTILS + " symlink \"\" \"\"";
|
|
|
+
|
|
|
+ // The tests are built on assuming 8191 max command line length
|
|
|
+ assertEquals(8191, Shell.WINDOWS_MAX_SHELL_LENGHT);
|
|
|
+
|
|
|
+ ShellScriptBuilder builder = ShellScriptBuilder.create();
|
|
|
+
|
|
|
+ // test link
|
|
|
+ builder.link(new Path(org.apache.commons.lang.StringUtils.repeat("A", 1024)),
|
|
|
+ new Path(org.apache.commons.lang.StringUtils.repeat("B", 1024)));
|
|
|
+ builder.link(
|
|
|
+ new Path(org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "E", (Shell.WINDOWS_MAX_SHELL_LENGHT - linkCmd.length())/2)),
|
|
|
+ new Path(org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "F", (Shell.WINDOWS_MAX_SHELL_LENGHT - linkCmd.length())/2)));
|
|
|
+ try {
|
|
|
+ builder.link(
|
|
|
+ new Path(org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "X", (Shell.WINDOWS_MAX_SHELL_LENGHT - linkCmd.length())/2 + 1)),
|
|
|
+ new Path(org.apache.commons.lang.StringUtils.repeat(
|
|
|
+ "Y", (Shell.WINDOWS_MAX_SHELL_LENGHT - linkCmd.length())/2) + 1));
|
|
|
+ fail("long link was expected to throw");
|
|
|
+ } catch(IOException e) {
|
|
|
+ assertThat(e.getMessage(), containsString(expectedMessage));
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|