+ * - Compile the code with container-executor.conf.dir set to the location you
+ * want for testing.
+ *
+ * > mvn clean install -Dcontainer-executor.conf.dir=/etc/hadoop -DskipTests
+ *
+ *
+ * - Set up
${container-executor.conf.dir}/taskcontroller.cfg
+ * taskcontroller.cfg needs to be owned by root and have in it the proper
+ * config values.
+ *
+ * > cat /etc/hadoop/taskcontroller.cfg
+ * mapreduce.cluster.local.dir=/tmp/hadoop/nm-local/
+ * hadoop.log.dir=/tmp/hadoop/nm-log
+ * mapreduce.tasktracker.group=mapred
+ * #depending on the user id of the application.submitter option
+ * min.user.id=1
+ * > sudo chown root:root /etc/hadoop/taskcontroller.cfg
+ * > sudo chmod 444 /etc/hadoop/taskcontroller.cfg
+ *
+ *
+ * - iMove the binary and set proper permissions on it. It needs to be owned
+ * by root, the group needs to be the group configured in taskcontroller.cfg,
+ * and it needs the setuid bit set. (The build will also overwrite it so you
+ * need to move it to a place that you can support it.
+ *
+ * > cp ./hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/c/container-executor/container-executor /tmp/
+ * > sudo chown root:mapred /tmp/container-executor
+ * > sudo chmod 4550 /tmp/container-executor
+ *
+ *
+ * - Run the tests with the execution enabled (The user you run the tests as
+ * needs to be part of the group from the config.
+ *
+ * mvn test -Dtest=TestLinuxContainerExecutor -Dapplication.submitter=nobody -Dcontainer-executor.path=/tmp/container-executor
+ *
+ *
+ */
public class TestLinuxContainerExecutor {
-//
-// private static final Log LOG = LogFactory
-// .getLog(TestLinuxContainerExecutor.class);
-//
-// // TODO: FIXME
-// private static File workSpace = new File("target",
-// TestLinuxContainerExecutor.class.getName() + "-workSpace");
-//
-// @Before
-// public void setup() throws IOException {
-// FileContext.getLocalFSFileContext().mkdir(
-// new Path(workSpace.getAbsolutePath()), null, true);
-// workSpace.setReadable(true, false);
-// workSpace.setExecutable(true, false);
-// workSpace.setWritable(true, false);
-// }
-//
-// @After
-// public void tearDown() throws AccessControlException, FileNotFoundException,
-// UnsupportedFileSystemException, IOException {
-// FileContext.getLocalFSFileContext().delete(
-// new Path(workSpace.getAbsolutePath()), true);
-// }
-//
- @Test
- public void testCommandFilePreparation() throws IOException {
-// LinuxContainerExecutor executor = new LinuxContainerExecutor(new String[] {
-// "/bin/echo", "hello" }, null, null, "nobody"); // TODO: fix user name
-// executor.prepareCommandFile(workSpace.getAbsolutePath());
-//
-// // Now verify the contents of the commandFile
-// File commandFile = new File(workSpace, LinuxContainerExecutor.COMMAND_FILE);
-// BufferedReader reader = new BufferedReader(new FileReader(commandFile));
-// Assert.assertEquals("/bin/echo hello", reader.readLine());
-// Assert.assertEquals(null, reader.readLine());
-// Assert.assertTrue(commandFile.canExecute());
+ private static final Log LOG = LogFactory
+ .getLog(TestLinuxContainerExecutor.class);
+
+ private static File workSpace = new File("target",
+ TestLinuxContainerExecutor.class.getName() + "-workSpace");
+
+ private LinuxContainerExecutor exec = null;
+ private String appSubmitter = null;
+
+ @Before
+ public void setup() throws Exception {
+ FileContext.getLocalFSFileContext().mkdir(
+ new Path(workSpace.getAbsolutePath()), null, true);
+ workSpace.setReadable(true, false);
+ workSpace.setExecutable(true, false);
+ workSpace.setWritable(true, false);
+ String exec_path = System.getProperty("container-executor.path");
+ if(exec_path != null && !exec_path.isEmpty()) {
+ Configuration conf = new Configuration(false);
+ LOG.info("Setting "+YarnConfiguration.NM_LINUX_CONTAINER_EXECUTOR_PATH
+ +"="+exec_path);
+ conf.set(YarnConfiguration.NM_LINUX_CONTAINER_EXECUTOR_PATH, exec_path);
+ exec = new LinuxContainerExecutor();
+ exec.setConf(conf);
+ }
+ appSubmitter = System.getProperty("application.submitter");
+ if(appSubmitter == null || appSubmitter.isEmpty()) {
+ appSubmitter = "nobody";
+ }
}
-//
-// @Test
-// public void testContainerLaunch() throws IOException {
-// String containerExecutorPath = System
-// .getProperty("container-executor-path");
-// if (containerExecutorPath == null || containerExecutorPath.equals("")) {
-// LOG.info("Not Running test for lack of container-executor-path");
-// return;
-// }
-//
-// String applicationSubmitter = "nobody";
-//
-// File touchFile = new File(workSpace, "touch-file");
-// LinuxContainerExecutor executor = new LinuxContainerExecutor(new String[] {
-// "touch", touchFile.getAbsolutePath() }, workSpace, null,
-// applicationSubmitter);
-// executor.setCommandExecutorPath(containerExecutorPath);
-// executor.execute();
-//
-// FileStatus fileStatus = FileContext.getLocalFSFileContext().getFileStatus(
-// new Path(touchFile.getAbsolutePath()));
-// Assert.assertEquals(applicationSubmitter, fileStatus.getOwner());
-// }
-//
-// @Test
-// public void testContainerKill() throws IOException, InterruptedException,
-// IllegalArgumentException, SecurityException, IllegalAccessException,
-// NoSuchFieldException {
-// String containerExecutorPath = System
-// .getProperty("container-executor-path");
-// if (containerExecutorPath == null || containerExecutorPath.equals("")) {
-// LOG.info("Not Running test for lack of container-executor-path");
-// return;
-// }
-//
-// String applicationSubmitter = "nobody";
-// final LinuxContainerExecutor executor = new LinuxContainerExecutor(
-// new String[] { "sleep", "100" }, workSpace, null, applicationSubmitter);
-// executor.setCommandExecutorPath(containerExecutorPath);
-// new Thread() {
-// public void run() {
-// try {
-// executor.execute();
-// } catch (IOException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
-// };
-// }.start();
-//
-// String pid;
-// while ((pid = executor.getPid()) == null) {
-// LOG.info("Sleeping for 5 seconds before checking if "
-// + "the process is alive.");
-// Thread.sleep(5000);
-// }
-// LOG.info("Going to check the liveliness of the process with pid " + pid);
-//
-// LinuxContainerExecutor checkLiveliness = new LinuxContainerExecutor(
-// new String[] { "kill", "-0", "-" + pid }, workSpace, null,
-// applicationSubmitter);
-// checkLiveliness.setCommandExecutorPath(containerExecutorPath);
-// checkLiveliness.execute();
-//
-// LOG.info("Process is alive. "
-// + "Sleeping for 5 seconds before killing the process.");
-// Thread.sleep(5000);
-// LOG.info("Going to killing the process.");
-//
-// executor.kill();
-//
-// LOG.info("Sleeping for 5 seconds before checking if "
-// + "the process is alive.");
-// Thread.sleep(5000);
-// LOG.info("Going to check the liveliness of the process.");
-//
-// // TODO: fix
-// checkLiveliness = new LinuxContainerExecutor(new String[] { "kill", "-0",
-// "-" + pid }, workSpace, null, applicationSubmitter);
-// checkLiveliness.setCommandExecutorPath(containerExecutorPath);
-// boolean success = false;
-// try {
-// checkLiveliness.execute();
-// success = true;
-// } catch (IOException e) {
-// success = false;
-// }
-//
-// Assert.assertFalse(success);
-// }
-}
\ No newline at end of file
+
+ @After
+ public void tearDown() throws Exception {
+ FileContext.getLocalFSFileContext().delete(
+ new Path(workSpace.getAbsolutePath()), true);
+ }
+
+ private boolean shouldRun() {
+ if(exec == null) {
+ LOG.warn("Not running test because container-executor.path is not set");
+ return false;
+ }
+ return true;
+ }
+
+ private String writeScriptFile(String ... cmd) throws IOException {
+ File f = File.createTempFile("TestLinuxContainerExecutor", ".sh");
+ f.deleteOnExit();
+ PrintWriter p = new PrintWriter(new FileOutputStream(f));
+ p.println("#!/bin/sh");
+ p.print("exec");
+ for(String part: cmd) {
+ p.print(" '");
+ p.print(part.replace("\\", "\\\\").replace("'", "\\'"));
+ p.print("'");
+ }
+ p.println();
+ p.close();
+ return f.getAbsolutePath();
+ }
+
+ private int id = 0;
+ private synchronized int getNextId() {
+ id += 1;
+ return id;
+ }
+
+ private ContainerId getNextContainerId() {
+ ContainerId cId = mock(ContainerId.class);
+ String id = "CONTAINER_"+getNextId();
+ when(cId.toString()).thenReturn(id);
+ return cId;
+ }
+
+
+ private int runAndBlock(String ... cmd) throws IOException {
+ return runAndBlock(getNextContainerId(), cmd);
+ }
+
+ private int runAndBlock(ContainerId cId, String ... cmd) throws IOException {
+ String appId = "APP_"+getNextId();
+ Container container = mock(Container.class);
+ ContainerLaunchContext context = mock(ContainerLaunchContext.class);
+ HashMap