You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mapreduce-commits@hadoop.apache.org by vi...@apache.org on 2011/03/22 08:43:24 UTC

svn commit: r1084088 - in /hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager: ./ src/main/java/org/apache/hadoop/yarn/server/nodemanager/ src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ src/ma...

Author: vinodkv
Date: Tue Mar 22 07:43:24 2011
New Revision: 1084088

URL: http://svn.apache.org/viewvc?rev=1084088&view=rev
Log:
Implementation of killing of containers. Contributed by Vinod Kumar Vavilapalli.

Added:
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerExitEvent.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManagerWithLCE.java
Modified:
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/pom.xml
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerEventType.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/DummyContainerManager.java
    hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManager.java

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/pom.xml
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/pom.xml?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/pom.xml (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/pom.xml Tue Mar 22 07:43:24 2011
@@ -52,7 +52,7 @@
                   <workDir>src/main/c/container-executor</workDir>
                 </configuration>
                 <goals>
-<!--                  <goal>autoreconf</goal>-->
+                  <goal>autoreconf</goal>
                 </goals>
               </execution>
               <execution>
@@ -77,8 +77,8 @@
                 </configuration>
                 <goals>
                   <!-- always clean, to ensure conf dir regenerated -->
-<!--                  <goal>make-clean</goal>-->
-<!--                  <goal>configure</goal>-->
+                  <goal>make-clean</goal>
+                  <goal>configure</goal>
                 </goals>
               </execution>
               <execution>
@@ -89,7 +89,7 @@
                   <workDir>src/main/c/container-executor</workDir>
                 </configuration>
                 <goals>
-<!--                  <goal>make-install</goal>-->
+                  <goal>make-install</goal>
                 </goals>
               </execution>
             </executions>

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java Tue Mar 22 07:43:24 2011
@@ -19,7 +19,10 @@
 package org.apache.hadoop.yarn.server.nodemanager;
 
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -28,16 +31,19 @@ import org.apache.hadoop.conf.Configurat
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.util.Shell.ShellCommandExecutor;
-import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
+import org.apache.hadoop.yarn.ContainerID;
 import org.apache.hadoop.yarn.LocalizationProtocol;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
 
 public abstract class ContainerExecutor implements Configurable {
 
-  static final Log LOG = LogFactory.getLog(ContainerExecutor.class);
+  private static final Log LOG = LogFactory.getLog(ContainerExecutor.class);
   final public static FsPermission TASK_LAUNCH_SCRIPT_PERMISSION =
     FsPermission.createImmutable((short) 0700);
 
   private Configuration conf;
+  protected ConcurrentMap<ContainerID, ShellCommandExecutor> launchCommandObjs =
+      new ConcurrentHashMap<ContainerID, ShellCommandExecutor>();
 
   @Override
   public void setConf(Configuration conf) {
@@ -72,19 +78,40 @@ public abstract class ContainerExecutor 
       throws IOException, InterruptedException;
 
   /**
-   * Launch the container on the node.
-   * @param launchCtxt 
+   * Launch the container on the node. This is a blocking call and returns only
+   * when the container exits.
+   * 
+   * @param launchCtxt
    */
   public abstract int launchContainer(Container container, Path nmLocal,
       String user, String appId, List<Path> appDirs, String stdout,
       String stderr) throws IOException;
 
-  public abstract boolean signalContainer(String user, int pid, Signal signal)
-      throws IOException, InterruptedException;
+  public abstract boolean signalContainer(String user, String pid,
+      Signal signal)
+      throws IOException;
 
   public abstract void deleteAsUser(String user, Path subDir, Path... basedirs)
       throws IOException, InterruptedException;
 
+  public enum ExitCode {
+    KILLED(137);
+    private final int code;
+
+    private ExitCode(int exitCode) {
+      this.code = exitCode;
+    }
+
+    public int getExitCode() {
+      return code;
+    }
+
+    @Override
+    public String toString() {
+      return String.valueOf(code);
+    }
+  }
+
   /**
    * The constants for the signals.
    */
@@ -115,6 +142,41 @@ public abstract class ContainerExecutor 
     }
   }
 
+  /**
+   * Get the process-identifier for the container
+   * 
+   * @param containerID
+   * @return the processid of the container if it has already launched,
+   *         otherwise return null
+   */
+  public String getProcessId(ContainerID containerID) {
+    String pid = null;
+    ShellCommandExecutor shExec = launchCommandObjs.get(containerID);
+    if (shExec == null) {
+      // This container isn't even launched yet.
+      return pid;
+    }
+    Process proc = shExec.getProcess();
+    if (proc == null) {
+      // This happens if the command is not yet started
+      return pid;
+    }
+    try {
+      Field pidField = proc.getClass().getDeclaredField("pid");
+      pidField.setAccessible(true);
+      pid = ((Integer) pidField.get(proc)).toString();
+    } catch (SecurityException e) {
+      // SecurityManager not expected with yarn. Ignore.
+    } catch (NoSuchFieldException e) {
+      // Yarn only on UNIX for now. Ignore.
+    } catch (IllegalArgumentException e) {
+      ;
+    } catch (IllegalAccessException e) {
+      ;
+    }
+    return pid;
+  }
+
   public static final boolean isSetsidAvailable = isSetsidSupported();
   private static boolean isSetsidSupported() {
     ShellCommandExecutor shexec = null;
@@ -134,11 +196,13 @@ public abstract class ContainerExecutor 
 
   public static class DelayedProcessKiller extends Thread {
     private final String user;
-    private final int pid;
+    private final String pid;
     private final long delay;
     private final Signal signal;
     private final ContainerExecutor containerExecutor;
-    public DelayedProcessKiller(String user, int pid, long delay, Signal signal,
+
+    public DelayedProcessKiller(String user, String pid, long delay,
+        Signal signal,
         ContainerExecutor containerExecutor) {
       this.user = user;
       this.pid = pid;

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java Tue Mar 22 07:43:24 2011
@@ -41,7 +41,8 @@ import org.apache.hadoop.yarn.Localizati
 
 public class DefaultContainerExecutor extends ContainerExecutor {
 
-  static final Log LOG = LogFactory.getLog(DefaultContainerExecutor.class);
+  private static final Log LOG = LogFactory
+      .getLog(DefaultContainerExecutor.class);
 
   private final FileContext lfs;
 
@@ -120,6 +121,7 @@ public class DefaultContainerExecutor ex
           new String[] { "bash", "-c", launchDst.toUri().getPath().toString() };
       shExec = new ShellCommandExecutor(command,
           new File(appWorkDir.toUri().getPath()));
+      launchCommandObjs.put(container.getLaunchContext().id, shExec);
       shExec.execute();
     } catch (Exception e) {
       if (null == shExec) {
@@ -129,16 +131,18 @@ public class DefaultContainerExecutor ex
       LOG.warn("Exit code from task is : " + exitCode);
       logOutput(shExec.getOutput());
       return exitCode;
+    } finally {
+      launchCommandObjs.remove(container.getLaunchContext().id);
     }
     return 0;
   }
 
   @Override
-  public boolean signalContainer(String user, int pid, Signal signal)
-      throws IOException, InterruptedException {
-    final int sigpid = ContainerExecutor.isSetsidAvailable
-      ? -1 * pid
-      : pid;
+  public boolean signalContainer(String user, String pid, Signal signal)
+      throws IOException {
+    final String sigpid = ContainerExecutor.isSetsidAvailable
+        ? "-" + pid
+        : pid;
     try {
       sendSignal(sigpid, Signal.NULL);
     } catch (ExitCodeException e) {
@@ -164,9 +168,9 @@ public class DefaultContainerExecutor ex
    * @param signal signal to send
    * (for logging).
    */
-  protected void sendSignal(int pid, Signal signal) throws IOException {
+  protected void sendSignal(String pid, Signal signal) throws IOException {
     ShellCommandExecutor shexec = null;
-      String[] arg = { "kill", "-" + signal.getValue(), Integer.toString(pid) };
+      String[] arg = { "kill", "-" + signal.getValue(), pid };
       shexec = new ShellCommandExecutor(arg);
     shexec.execute();
   }

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java Tue Mar 22 07:43:24 2011
@@ -25,6 +25,8 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.util.Shell.ExitCodeException;
@@ -37,8 +39,11 @@ import org.apache.hadoop.yarn.Localizati
 
 public class LinuxContainerExecutor extends ContainerExecutor {
 
+  private static final Log LOG = LogFactory
+      .getLog(LinuxContainerExecutor.class);
+
   private String containerExecutorExe;
-  private static final String CONTAINER_EXECUTOR_EXEC_KEY =
+  protected static final String CONTAINER_EXECUTOR_EXEC_KEY =
     NMConfig.NM_PREFIX + "linux-container-executor.path";
   
   @Override
@@ -163,6 +168,7 @@ public class LinuxContainerExecutor exte
                     appToken.toUri().getPath().toString()));
     String[] commandArray = command.toArray(new String[command.size()]);
     ShellCommandExecutor shExec = new ShellCommandExecutor(commandArray);
+    launchCommandObjs.put(container.getLaunchContext().id, shExec);
     // DEBUG
     LOG.info("launchContainer: " + Arrays.toString(commandArray));
     if (LOG.isDebugEnabled()) {
@@ -187,6 +193,8 @@ public class LinuxContainerExecutor exte
         logOutput(shExec.getOutput());
       }
       return exitCode;
+    } finally {
+      launchCommandObjs.remove(container.getLaunchContext().id);
     }
     if (LOG.isDebugEnabled()) {
       LOG.debug("Output from LinuxTaskController's launchTask follows:");
@@ -196,8 +204,30 @@ public class LinuxContainerExecutor exte
   }
 
   @Override
-  public boolean signalContainer(String user, int pid, Signal signal)
-      throws IOException, InterruptedException {
+  public boolean signalContainer(String user, String pid, Signal signal)
+      throws IOException {
+
+    String[] command =
+        new String[] { containerExecutorExe,
+                   user,
+                   Integer.toString(Commands.SIGNAL_TASK.getValue()),
+                   pid,
+                   Integer.toString(signal.getValue()) };
+    ShellCommandExecutor shExec = new ShellCommandExecutor(command);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("signalTask: " + Arrays.toString(command));
+    }
+    try {
+      shExec.execute();
+    } catch (ExitCodeException e) {
+      int ret_code = shExec.getExitCode();
+      if (ret_code == ResultCode.INVALID_TASK_PID.getValue()) {
+        return false;
+      }
+      logOutput(shExec.getOutput());
+      throw new IOException("Problem signalling container " + pid + " with " +
+                            signal + "; exit = " + ret_code);
+    }
     return true;
   }
 

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/NodeManager.java Tue Mar 22 07:43:24 2011
@@ -121,7 +121,7 @@ public class NodeManager extends Composi
     super.start();
   }
 
-  static class NMContext implements Context {
+  public static class NMContext implements Context {
 
     private final ConcurrentMap<ApplicationID, Application> applications =
         new ConcurrentHashMap<ApplicationID, Application>();

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerEventType.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerEventType.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerEventType.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerEventType.java Tue Mar 22 07:43:24 2011
@@ -34,5 +34,5 @@ public enum ContainerEventType {
   CONTAINER_LAUNCHED,
   CONTAINER_EXITED_WITH_SUCCESS,
   CONTAINER_EXITED_WITH_FAILURE,
-  CONTAINER_CLEANEDUP_AFTER_KILL,
+  CONTAINER_KILLED_ON_REQUEST,
 }

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerExitEvent.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerExitEvent.java?rev=1084088&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerExitEvent.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerExitEvent.java Tue Mar 22 07:43:24 2011
@@ -0,0 +1,35 @@
+/**
+* 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.yarn.server.nodemanager.containermanager.container;
+
+import org.apache.hadoop.yarn.ContainerID;
+
+public class ContainerExitEvent extends ContainerEvent {
+  private int exitCode;
+
+  public ContainerExitEvent(ContainerID cID, ContainerEventType eventType,
+      int exitCode) {
+    super(cID, eventType);
+    this.exitCode = exitCode;
+  }
+
+  public int getExitCode() {
+    return this.exitCode;
+  }
+}

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java Tue Mar 22 07:43:24 2011
@@ -23,6 +23,9 @@ import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.yarn.ContainerID;
+import org.apache.hadoop.yarn.ContainerLaunchContext;
+import org.apache.hadoop.yarn.ContainerStatus;
 import org.apache.hadoop.yarn.event.Dispatcher;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.AuxServicesEvent;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.AuxServicesEventType;
@@ -37,15 +40,12 @@ import org.apache.hadoop.yarn.state.Sing
 import org.apache.hadoop.yarn.state.StateMachine;
 import org.apache.hadoop.yarn.state.StateMachineFactory;
 import org.apache.hadoop.yarn.util.AvroUtil;
-import org.apache.hadoop.yarn.ApplicationID;
-import org.apache.hadoop.yarn.ContainerID;
-import org.apache.hadoop.yarn.ContainerLaunchContext;
-import org.apache.hadoop.yarn.ContainerStatus;
 
 public class ContainerImpl implements Container {
 
   private final Dispatcher dispatcher;
   private final ContainerLaunchContext launchContext;
+  private int exitCode;
 
   private static final Log LOG = LogFactory.getLog(Container.class);
 
@@ -114,7 +114,7 @@ public class ContainerImpl implements Co
     // From KILLING State.
     .addTransition(ContainerState.KILLING,
         ContainerState.CONTAINER_CLEANEDUP_AFTER_KILL,
-        ContainerEventType.CONTAINER_CLEANEDUP_AFTER_KILL,
+        ContainerEventType.CONTAINER_KILLED_ON_REQUEST,
         new ContainerKilledTransition())
     .addTransition(ContainerState.KILLING, ContainerState.KILLING,
         ContainerEventType.KILL_CONTAINER)
@@ -178,7 +178,7 @@ public class ContainerImpl implements Co
     ContainerStatus containerStatus = new ContainerStatus();
     containerStatus.state = getCurrentState();
     containerStatus.containerID = this.launchContext.id;
-    // TODO: Exit status.
+    containerStatus.exitStatus = exitCode;
     return containerStatus;
   }
 
@@ -241,6 +241,9 @@ public class ContainerImpl implements Co
   static class ExitedWithFailureTransition extends ContainerTransition {
     @Override
     public void transition(ContainerImpl container, ContainerEvent event) {
+      ContainerExitEvent exitEvent = (ContainerExitEvent) event;
+      container.exitCode = exitEvent.getExitCode();
+
       // TODO: Add containerWorkDir to the deletion service.
       // TODO: Add containerOuputDir to the deletion service.
 
@@ -280,6 +283,9 @@ public class ContainerImpl implements Co
       SingleArcTransition<ContainerImpl, ContainerEvent> {
     @Override
     public void transition(ContainerImpl container, ContainerEvent event) {
+      ContainerExitEvent exitEvent = (ContainerExitEvent) event;
+      container.exitCode = exitEvent.getExitCode();
+
       // The process/process-grp is killed. Decrement reference counts and
       // cleanup resources
       container.dispatcher.getEventHandler().handle(

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java Tue Mar 22 07:43:24 2011
@@ -37,14 +37,16 @@ import org.apache.hadoop.security.Creden
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.TokenIdentifier;
 import org.apache.hadoop.util.Shell.ExitCodeException;
+import org.apache.hadoop.yarn.ContainerLaunchContext;
 import org.apache.hadoop.yarn.event.Dispatcher;
 import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
+import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.ExitCode;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerEvent;
 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.localizer.ApplicationLocalizer;
-import org.apache.hadoop.yarn.ContainerLaunchContext;
 
 public class ContainerLaunch implements Callable<Integer> {
 
@@ -94,11 +96,11 @@ public class ContainerLaunch implements 
         
         tokensOut = lfs.create(tokensPath, EnumSet.of(CREATE, OVERWRITE));
         Credentials creds = new Credentials();
-        if (container.getLaunchContext().containerTokens != null) {
+        if (launchContext.containerTokens != null) {
           // TODO: Is the conditional the correct way of checking?
           DataInputByteBuffer buf = new DataInputByteBuffer();
-          container.getLaunchContext().containerTokens.rewind();
-          buf.reset(container.getLaunchContext().containerTokens);
+          launchContext.containerTokens.rewind();
+          buf.reset(launchContext.containerTokens);
           creds.readTokenStorageStream(buf);
           for (Token<? extends TokenIdentifier> tk : creds.getAllTokens()) {
             LOG.debug(tk.getService() + " = " + tk.toString());
@@ -112,19 +114,28 @@ public class ContainerLaunch implements 
         }
       }
       dispatcher.getEventHandler().handle(new ContainerEvent(
-            container.getLaunchContext().id,
+            launchContext.id,
             ContainerEventType.CONTAINER_LAUNCHED));
       ret =
         exec.launchContainer(container, launchSysDir, user, app.toString(),
             appDirs, null, null);
+      if (ret == ExitCode.KILLED.getExitCode()) {
+        // If the process was killed, Send container_cleanedup_after_kill and
+        // just break out of this method.
+        dispatcher.getEventHandler().handle(
+            new ContainerExitEvent(launchContext.id,
+                ContainerEventType.CONTAINER_KILLED_ON_REQUEST, ret));
+        return ret;
+      }
+
       if (ret != 0) {
         throw new ExitCodeException(ret, "Container failed");
       }
     } catch (Throwable e) {
       LOG.warn("Failed to launch container", e);
-      dispatcher.getEventHandler().handle(new ContainerEvent(
+      dispatcher.getEventHandler().handle(new ContainerExitEvent(
             launchContext.id,
-            ContainerEventType.CONTAINER_EXITED_WITH_FAILURE));
+            ContainerEventType.CONTAINER_EXITED_WITH_FAILURE, ret));
       return ret;
     }
     LOG.info("Container " + container + " succeeded " + launchContext.id);

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java Tue Mar 22 07:43:24 2011
@@ -18,6 +18,11 @@
 
 package org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher;
 
+import static org.apache.hadoop.yarn.server.nodemanager.NMConfig.DEFAULT_NM_LOCAL_DIR;
+import static org.apache.hadoop.yarn.server.nodemanager.NMConfig.DEFAULT_NM_LOG_DIR;
+import static org.apache.hadoop.yarn.server.nodemanager.NMConfig.NM_LOCAL_DIR;
+import static org.apache.hadoop.yarn.server.nodemanager.NMConfig.NM_LOG_DIR;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -31,24 +36,25 @@ import java.util.concurrent.Future;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileContext;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.yarn.ContainerID;
 import org.apache.hadoop.yarn.YarnException;
 import org.apache.hadoop.yarn.event.Dispatcher;
 import org.apache.hadoop.yarn.event.EventHandler;
 import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
+import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.Signal;
 import org.apache.hadoop.yarn.server.nodemanager.Context;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
-import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerEvent;
-import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerEventType;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ApplicationLocalizer;
 import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ResourceLocalizationService;
 import org.apache.hadoop.yarn.service.AbstractService;
 
-import org.apache.hadoop.yarn.ContainerID;
-import org.apache.hadoop.yarn.ContainerLaunchContext;
-
-import static org.apache.hadoop.yarn.server.nodemanager.NMConfig.*;
-
+/**
+ * The launcher for the containers. This service should be started only after
+ * the {@link ResourceLocalizationService} is started as it depends on creation
+ * of system directories on the local file-system.
+ * 
+ */
 public class ContainersLauncher extends AbstractService
     implements EventHandler<ContainersLauncherEvent> {
 
@@ -60,8 +66,19 @@ public class ContainersLauncher extends 
   private List<Path> logDirs;
   private List<Path> localDirs;
   private List<Path> sysDirs;
-  private final Map<ContainerID,Future<Integer>> running =
-    Collections.synchronizedMap(new HashMap<ContainerID,Future<Integer>>());
+
+  private static final class RunningContainer {
+    public RunningContainer(String string, Future<Integer> submit) {
+      this.user = string;
+      this.runningcontainer = submit;
+    }
+
+    String user;
+    Future<Integer> runningcontainer;
+  }
+
+  private final Map<ContainerID, RunningContainer> running =
+    Collections.synchronizedMap(new HashMap<ContainerID, RunningContainer>());
 
   public ContainersLauncher(Context context, Dispatcher dispatcher,
       ContainerExecutor exec) {
@@ -113,6 +130,7 @@ public class ContainersLauncher extends 
     // TODO: ContainersLauncher launches containers one by one!!
     Container container = event.getContainer();
     ContainerID containerId = container.getLaunchContext().id;
+    String userName = container.getLaunchContext().user.toString();
     switch (event.getType()) {
       case LAUNCH_CONTAINER:
         Application app =
@@ -120,8 +138,7 @@ public class ContainersLauncher extends 
         List<Path> appDirs = new ArrayList<Path>(localDirs.size());
         for (Path p : localDirs) {
           Path usersdir = new Path(p, ApplicationLocalizer.USERCACHE);
-          Path userdir = new Path(usersdir,
-              container.getLaunchContext().user.toString());
+          Path userdir = new Path(usersdir, userName);
           Path appsdir = new Path(userdir, ApplicationLocalizer.APPCACHE);
           appDirs.add(new Path(appsdir, app.toString()));
         }
@@ -131,17 +148,35 @@ public class ContainersLauncher extends 
         ContainerLaunch launch =
           new ContainerLaunch(dispatcher, exec, app,
               event.getContainer(), appSysDir, appDirs);
-        running.put(containerId, containerLauncher.submit(launch));
+        running.put(containerId,
+            new RunningContainer(userName,
+                containerLauncher.submit(launch)));
         break;
       case CLEANUP_CONTAINER:
-        Future<Integer> rContainer = running.remove(containerId);
+        RunningContainer rContainerDatum = running.remove(containerId);
+        Future<Integer> rContainer = rContainerDatum.runningcontainer;
         if (rContainer != null) {
-          // TODO needs to kill the container
+  
+          if (rContainer.isDone()) {
+            // The future is already done by this time.
+            break;
+          }
+  
+          // Cancel the future so that it won't be launched if it isn't already.
           rContainer.cancel(false);
+  
+          // Kill the container
+          String processId = exec.getProcessId(containerId);
+          if (processId != null) {
+            try {
+              exec.signalContainer(rContainerDatum.user,
+                  processId, Signal.KILL);
+            } catch (IOException e) {
+              // TODO Auto-generated catch block
+              e.printStackTrace();
+            }
+          }
         }
-      dispatcher.getEventHandler().handle(
-          new ContainerEvent(containerId,
-              ContainerEventType.CONTAINER_CLEANEDUP_AFTER_KILL));
         break;
     }
   }

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/DummyContainerManager.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/DummyContainerManager.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/DummyContainerManager.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/DummyContainerManager.java Tue Mar 22 07:43:24 2011
@@ -106,7 +106,7 @@ class DummyContainerManager extends Cont
         case CLEANUP_CONTAINER:
           dispatcher.getEventHandler().handle(
               new ContainerEvent(containerId,
-                  ContainerEventType.CONTAINER_CLEANEDUP_AFTER_KILL));
+                  ContainerEventType.CONTAINER_KILLED_ON_REQUEST));
           break;
         }
       }

Modified: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManager.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManager.java?rev=1084088&r1=1084087&r2=1084088&view=diff
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManager.java (original)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManager.java Tue Mar 22 07:43:24 2011
@@ -35,30 +35,25 @@ import org.apache.commons.logging.LogFac
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileContext;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.UnsupportedFileSystemException;
 import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
-import org.apache.hadoop.yarn.conf.YarnConfiguration;
-import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor;
-import org.apache.hadoop.yarn.server.nodemanager.Context;
-import org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor;
-import org.apache.hadoop.yarn.server.nodemanager.DeletionService;
-import org.apache.hadoop.yarn.server.nodemanager.NMConfig;
-import org.apache.hadoop.yarn.server.nodemanager.NodeStatusUpdater;
-import org.apache.hadoop.yarn.server.nodemanager.NodeStatusUpdaterImpl;
-import org.apache.hadoop.yarn.server.nodemanager.NodeManager.NMContext;
-import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl;
-import org.apache.hadoop.yarn.server.nodemanager.containermanager.application.ApplicationImpl;
-import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ApplicationLocalizer;
-import org.apache.hadoop.yarn.service.Service.STATE;
-import org.apache.hadoop.yarn.util.AvroUtil;
 import org.apache.hadoop.yarn.ApplicationID;
 import org.apache.hadoop.yarn.ContainerID;
 import org.apache.hadoop.yarn.ContainerLaunchContext;
 import org.apache.hadoop.yarn.ContainerState;
+import org.apache.hadoop.yarn.ContainerStatus;
 import org.apache.hadoop.yarn.LocalResource;
 import org.apache.hadoop.yarn.LocalResourceType;
 import org.apache.hadoop.yarn.LocalResourceVisibility;
-import org.apache.hadoop.yarn.Resource;
 import org.apache.hadoop.yarn.URL;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.ExitCode;
+import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.Signal;
+import org.apache.hadoop.yarn.server.nodemanager.NodeManager.NMContext;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.ApplicationLocalizer;
+import org.apache.hadoop.yarn.service.Service.STATE;
+import org.apache.hadoop.yarn.util.AvroUtil;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -69,17 +64,23 @@ public class TestContainerManager {
     DefaultMetricsSystem.setMiniClusterMode(true);
   }
 
+  protected FileContext localFS;
+
+  public TestContainerManager() throws UnsupportedFileSystemException {
+    localFS = FileContext.getLocalFSFileContext();
+  }
+
   private static Log LOG = LogFactory.getLog(TestContainerManager.class);
 
-  private static File localDir = new File("target",
+  protected static File localDir = new File("target",
       TestContainerManager.class.getName() + "-localDir").getAbsoluteFile();
 
-  private static File tmpDir = new File("target",
+  protected static File tmpDir = new File("target",
       TestContainerManager.class.getName() + "-tmpDir");
 
-  private Configuration conf = new YarnConfiguration();
+  protected Configuration conf = new YarnConfiguration();
   private Context context = new NMContext();
-  private ContainerExecutor exec = new DefaultContainerExecutor();
+  private ContainerExecutor exec;
   private DeletionService delSrvc = new DeletionService(exec);
   private NodeStatusUpdater nodeStatusUpdater = new NodeStatusUpdaterImpl(context) {
     @Override
@@ -96,9 +97,12 @@ public class TestContainerManager {
 
   private ContainerManagerImpl containerManager = null;
 
+  protected ContainerExecutor createContainerExecutor() {
+    return new DefaultContainerExecutor();
+  }
+
   @Before
   public void setup() throws IOException {
-    FileContext localFS = FileContext.getLocalFSFileContext();
     localFS.delete(new Path(localDir.getAbsolutePath()), true);
     localFS.delete(new Path(tmpDir.getAbsolutePath()), true);
     localDir.mkdir();
@@ -109,13 +113,14 @@ public class TestContainerManager {
     String bindAddress = "0.0.0.0:5555";
     conf.set(NMConfig.NM_BIND_ADDRESS, bindAddress);
     conf.set(NMConfig.NM_LOCAL_DIR, localDir.getAbsolutePath());
+    exec = createContainerExecutor();
     containerManager =
         new ContainerManagerImpl(context, exec, delSrvc, nodeStatusUpdater);
     containerManager.init(conf);
   }
 
   @After
-  public void tearDown() {
+  public void tearDown() throws IOException, InterruptedException {
     if (containerManager != null
         && containerManager.getServiceState() == STATE.STARTED) {
       containerManager.stop();
@@ -158,7 +163,7 @@ public class TestContainerManager {
     cId.appID = appId;
     container.id = cId;
 
-    String user = "dummy-user";
+    String user = "nobody";
     container.user = user;
 
     // ////// Construct the container-spec.
@@ -167,7 +172,7 @@ public class TestContainerManager {
     containerLaunchContext.resources =
         new HashMap<CharSequence, LocalResource>();
     URL resource_alpha =
-        AvroUtil.getYarnUrlFromPath(FileContext.getLocalFSFileContext()
+        AvroUtil.getYarnUrlFromPath(localFS
             .makeQualified(new Path(file.getAbsolutePath())));
     LocalResource rsrc_alpha = new LocalResource();
     rsrc_alpha.resource = resource_alpha;
@@ -210,16 +215,22 @@ public class TestContainerManager {
   }
 
   @Test
-  public void testContainerLaunchAndStop() throws IOException, InterruptedException {
+  public void testContainerLaunchAndStop() throws IOException,
+      InterruptedException {
     containerManager.start();
 
     File scriptFile = new File(tmpDir, "scriptFile.sh");
     PrintWriter fileWriter = new PrintWriter(scriptFile);
-    File outputFile = new File(tmpDir, "output.txt").getAbsoluteFile();
-    fileWriter.write("echo Hello World! > " + outputFile);
+    File processStartFile =
+        new File(tmpDir, "start_file.txt").getAbsoluteFile();
+    fileWriter.write("umask 0"); // So that start file is readable by the test.
+    fileWriter.write("\necho Hello World! > " + processStartFile);
+    fileWriter.write("\necho $$ >> " + processStartFile);
+    fileWriter.write("\nsleep 100");
     fileWriter.close();
 
-    ContainerLaunchContext containerLaunchContext = new ContainerLaunchContext();
+    ContainerLaunchContext containerLaunchContext =
+        new ContainerLaunchContext();
 
     // ////// Construct the Container-id
     ApplicationID appId = new ApplicationID();
@@ -227,13 +238,13 @@ public class TestContainerManager {
     cId.appID = appId;
     containerLaunchContext.id = cId;
 
-    String user = "dummy-user";
+    String user = "nobody";
     containerLaunchContext.user = user;
 
     containerLaunchContext.resources =
         new HashMap<CharSequence, LocalResource>();
     URL resource_alpha =
-        AvroUtil.getYarnUrlFromPath(FileContext.getLocalFSFileContext()
+        AvroUtil.getYarnUrlFromPath(localFS
             .makeQualified(new Path(scriptFile.getAbsolutePath())));
     LocalResource rsrc_alpha = new LocalResource();
     rsrc_alpha.resource = resource_alpha;
@@ -249,18 +260,47 @@ public class TestContainerManager {
     commandArgs.add(scriptFile.getAbsolutePath());
     containerLaunchContext.command = commandArgs;
     containerManager.startContainer(containerLaunchContext);
-
-    DummyContainerManager.waitForContainerState(containerManager, cId,
-        ContainerState.COMPLETE);
-
-    Assert.assertTrue("OutputFile doesn't exist!", outputFile.exists());
+ 
+    int timeoutSecs = 0;
+    while (!processStartFile.exists() && timeoutSecs++ < 20) {
+      Thread.sleep(1000);
+      LOG.info("Waiting for process start-file to be created");
+    }
+    Assert.assertTrue("ProcessStartFile doesn't exist!",
+        processStartFile.exists());
     
     // Now verify the contents of the file
-    BufferedReader reader = new BufferedReader(new FileReader(outputFile));
+    BufferedReader reader =
+        new BufferedReader(new FileReader(processStartFile));
     Assert.assertEquals("Hello World!", reader.readLine());
+    // Get the pid of the process
+    String pid = reader.readLine().trim();
+    // No more lines
     Assert.assertEquals(null, reader.readLine());
 
-    // TODO: test the stop functionality.
+    // Now test the stop functionality.
+
+    // Assert that the process is alive
+    Assert.assertTrue("Process is not alive!",
+        exec.signalContainer(user,
+            pid, Signal.NULL));
+    // Once more
+    Assert.assertTrue("Process is not alive!",
+        exec.signalContainer(user,
+            pid, Signal.NULL));
+
+    containerManager.stopContainer(cId);
+
+    DummyContainerManager.waitForContainerState(containerManager, cId,
+        ContainerState.COMPLETE);
+    ContainerStatus containerStatus = containerManager.getContainerStatus(cId);
+    Assert.assertEquals(ExitCode.KILLED.getExitCode(),
+        containerStatus.exitStatus);
+
+    // Assert that the process is not alive anymore
+    Assert.assertFalse("Process is still alive!",
+        exec.signalContainer(user,
+            pid, Signal.NULL));
   }
 
 //  @Test

Added: hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManagerWithLCE.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManagerWithLCE.java?rev=1084088&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManagerWithLCE.java (added)
+++ hadoop/mapreduce/branches/MR-279/yarn/yarn-server/yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerManagerWithLCE.java Tue Mar 22 07:43:24 2011
@@ -0,0 +1,107 @@
+/**
+* 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.yarn.server.nodemanager;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.UnsupportedFileSystemException;
+import org.apache.hadoop.fs.permission.FsPermission;
+
+public class TestContainerManagerWithLCE extends TestContainerManager {
+
+  private static final Log LOG = LogFactory
+      .getLog(TestContainerManagerWithLCE.class);
+
+  public TestContainerManagerWithLCE() throws UnsupportedFileSystemException {
+    super();
+  }
+
+  static {
+    localDir =
+        new File("target",
+            TestContainerManagerWithLCE.class.getName() + "-localDir")
+            .getAbsoluteFile();
+    tmpDir = new File("target",
+        TestContainerManagerWithLCE.class.getName() + "-tmpDir");
+  }
+
+  @Override
+  public void setup() throws IOException {
+    // Don't run the test if the binary is not available.
+    if (!shouldRunTest()) {
+      LOG.info("LCE binary path is not passed. Not running the test");
+      return;
+    }
+    super.setup();
+    localFS.setPermission(new Path(localDir.getCanonicalPath()),
+        new FsPermission(
+            (short) 0777));
+    localFS.setPermission(new Path(tmpDir.getCanonicalPath()),
+        new FsPermission(
+            (short) 0777));
+  }
+
+  @Override
+  public void tearDown() throws IOException, InterruptedException {
+    super.tearDown();
+    FileUtil.chmod(localDir.getAbsolutePath(), "777", true);
+    localFS.delete(new Path(localDir.getCanonicalPath()), true);
+  }
+
+  @Override
+  public void testContainerSetup() throws IOException, InterruptedException {
+    // No cleanup as of now. Only one test for now. TODO: FIX
+  }
+
+  @Override
+  public void testContainerManagerInitialization() throws IOException {
+    // No cleanup as of now. Only one test for now. TODO: FIX
+  }
+
+  @Override
+  public void testContainerLaunchAndStop() throws IOException,
+      InterruptedException {
+    // Don't run the test if the binary is not available.
+    if (!shouldRunTest()) {
+      LOG.info("LCE binary path is not passed. Not running the test");
+      return;
+    }
+    super.testContainerLaunchAndStop();
+  }
+
+  private boolean shouldRunTest() {
+    return System
+        .getProperty(LinuxContainerExecutor.CONTAINER_EXECUTOR_EXEC_KEY) != null;
+  }
+
+  @Override
+  protected ContainerExecutor createContainerExecutor() {
+    super.conf.set(LinuxContainerExecutor.CONTAINER_EXECUTOR_EXEC_KEY, System
+        .getProperty(LinuxContainerExecutor.CONTAINER_EXECUTOR_EXEC_KEY));
+    LinuxContainerExecutor linuxContainerExecutor =
+        new LinuxContainerExecutor();
+    linuxContainerExecutor.setConf(super.conf);
+    return linuxContainerExecutor;
+  }
+}