You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ha...@apache.org on 2018/09/24 19:08:09 UTC

[47/50] [abbrv] hadoop git commit: YARN-8427. Don't start opportunistic containers at container scheduler/finish event with over-allocation. Contributed by Haibo Chen.

YARN-8427. Don't start opportunistic containers at container scheduler/finish event with over-allocation. Contributed by Haibo Chen.


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/23ad2fbd
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/23ad2fbd
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/23ad2fbd

Branch: refs/heads/YARN-1011
Commit: 23ad2fbd5b151fa0b19b7f224348560b8d29ac83
Parents: 3ff8d3f
Author: Miklos Szegedi <sz...@apache.org>
Authored: Fri Jun 22 10:25:31 2018 -0700
Committer: Haibo Chen <ha...@apache.org>
Committed: Fri Sep 21 17:42:51 2018 -0700

----------------------------------------------------------------------
 .../containermanager/ContainerManagerImpl.java  |   6 +-
 .../monitor/ContainersMonitorImpl.java          |   2 +-
 .../AllocationBasedResourceTracker.java         |   8 +-
 .../scheduler/ContainerScheduler.java           |  38 +++---
 .../scheduler/ResourceUtilizationTracker.java   |   6 +
 .../UtilizationBasedResourceTracker.java        |   2 +-
 ...estContainerSchedulerWithOverAllocation.java | 126 +++++++++++++++++--
 7 files changed, 155 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/23ad2fbd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java
index a08e227..0850f74 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java
@@ -236,7 +236,7 @@ public class ContainerManagerImpl extends CompositeService implements
     this.dirsHandler = dirsHandler;
 
     // ContainerManager level dispatcher.
-    dispatcher = new AsyncDispatcher("NM ContainerManager dispatcher");
+    dispatcher = createDispatcher();
     this.deletionService = deletionContext;
     this.metrics = metrics;
 
@@ -295,6 +295,10 @@ public class ContainerManagerImpl extends CompositeService implements
     this.writeLock = lock.writeLock();
   }
 
+  protected AsyncDispatcher createDispatcher() {
+    return new AsyncDispatcher("NM ContainerManager dispatcher");
+  }
+
   @Override
   public void serviceInit(Configuration conf) throws Exception {
 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/23ad2fbd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java
index a045d78..8f72b56 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java
@@ -271,7 +271,7 @@ public class ContainersMonitorImpl extends AbstractService implements
   /**
    * Check all prerequisites for NM over-allocation.
    */
-  private void checkOverAllocationPrerequisites() throws YarnException {
+  protected void checkOverAllocationPrerequisites() throws YarnException {
     // LinuxContainerExecutor is required to enable overallocation
     if (!(containerExecutor instanceof LinuxContainerExecutor)) {
       throw new YarnException(LinuxContainerExecutor.class.getName() +

http://git-wip-us.apache.org/repos/asf/hadoop/blob/23ad2fbd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/AllocationBasedResourceTracker.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/AllocationBasedResourceTracker.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/AllocationBasedResourceTracker.java
index 86b3698..a3e19eb 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/AllocationBasedResourceTracker.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/AllocationBasedResourceTracker.java
@@ -56,11 +56,8 @@ public class AllocationBasedResourceTracker
     return this.containersAllocation;
   }
 
-  /**
-   * Get the amount of resources that have not been allocated to containers.
-   * @return Resource resources that have not been allocated to containers.
-   */
-  protected Resource getUnallocatedResources() {
+  @Override
+  public Resource getUnallocatedResources() {
     // unallocated resources = node capacity - containers allocation
     // = -(container allocation - node capacity)
     ResourceUtilization allocationClone =
@@ -80,7 +77,6 @@ public class AllocationBasedResourceTracker
     return unallocated;
   }
 
-
   @Override
   public Resource getAvailableResources() {
     return getUnallocatedResources();

http://git-wip-us.apache.org/repos/asf/hadoop/blob/23ad2fbd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ContainerScheduler.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ContainerScheduler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ContainerScheduler.java
index 0bebe44..0d7de67 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ContainerScheduler.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ContainerScheduler.java
@@ -218,7 +218,9 @@ public class ContainerScheduler extends AbstractService implements
       startPendingContainers(false);
       break;
     case SCHEDULE_CONTAINERS:
-      startPendingContainers(true);
+      // try to launch OPPORTUNISTIC containers allowing over-allocation if the
+      // node utilization is low.
+      startOpportunisticContainers(utilizationTracker.getAvailableResources());
       break;
     default:
       LOG.error("Unknown event arrived at ContainerScheduler: "
@@ -410,11 +412,7 @@ public class ContainerScheduler extends AbstractService implements
         this.metrics.completeOpportunisticContainer(container.getResource());
       }
 
-      // In case of over-allocation being turned on, we may need to reclaim
-      // more resources since the opportunistic containers that have been
-      // killed or paused may have not released as much resource as we need.
-      boolean reclaimOpportunisticResources = context.isOverAllocationEnabled();
-      startPendingContainers(reclaimOpportunisticResources);
+      startPendingContainers(false);
     }
   }
 
@@ -434,22 +432,32 @@ public class ContainerScheduler extends AbstractService implements
       return;
     }
 
+    boolean guaranteedContainersLaunched = startGuaranteedContainers(
+        reclaimOpportunisticResources);
+
+    if (guaranteedContainersLaunched) {
+      // if all GUARANTEED containers are launched, try to launch OPPORTUNISTIC
+      // containers with unallocated resources only.
+      startOpportunisticContainers(
+          utilizationTracker.getUnallocatedResources());
+    }
+  }
+
+  private boolean startGuaranteedContainers(
+      boolean reclaimOpportunisticResources) {
     Resource available = utilizationTracker.getAvailableResources();
 
     // Start guaranteed containers that are queued, if resources available.
     boolean allGuaranteedContainersLaunched =
         startGuaranteedContainers(available);
-    // Start opportunistic containers, if resources available, which is true
-    // if all guaranteed containers in queue have been launched.
-    if (allGuaranteedContainersLaunched) {
-      startOpportunisticContainers(available);
-    } else {
+
+    if (!allGuaranteedContainersLaunched && reclaimOpportunisticResources) {
       // If not all guaranteed containers in queue are launched, we may need
       // to reclaim resources from opportunistic containers that are running.
-      if (reclaimOpportunisticResources) {
-        reclaimOpportunisticContainerResources();
-      }
+      reclaimOpportunisticContainerResources();
     }
+
+    return allGuaranteedContainersLaunched;
   }
 
   /**
@@ -693,8 +701,6 @@ public class ContainerScheduler extends AbstractService implements
    *
    * If the node is over-allocating itself, this may cause not enough
    * OPPORTUNISTIC containers being killed/paused in cases where the running
-   * OPPORTUNISTIC containers are not consuming fully their resource requests.
-   * We'd check again upon container completion events to see if more running
    * OPPORTUNISTIC containers need to be killed/paused.
    *
    * @return the amount of resource needed to be reclaimed for this container

http://git-wip-us.apache.org/repos/asf/hadoop/blob/23ad2fbd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ResourceUtilizationTracker.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ResourceUtilizationTracker.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ResourceUtilizationTracker.java
index 98d99c6..7a7c78e 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ResourceUtilizationTracker.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/ResourceUtilizationTracker.java
@@ -45,6 +45,12 @@ public interface ResourceUtilizationTracker {
   Resource getAvailableResources();
 
   /**
+   * Get the amount of resources left un-allocated.
+   * @return Resource unallocated resources
+   */
+  Resource getUnallocatedResources();
+
+  /**
    * Add Container's resources to Node Utilization upon container launch.
    * @param container Container.
    */

http://git-wip-us.apache.org/repos/asf/hadoop/blob/23ad2fbd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/UtilizationBasedResourceTracker.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/UtilizationBasedResourceTracker.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/UtilizationBasedResourceTracker.java
index 6f9bc82..f976700 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/UtilizationBasedResourceTracker.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/UtilizationBasedResourceTracker.java
@@ -61,7 +61,7 @@ public class UtilizationBasedResourceTracker
 
   @Override
   public Resource getAvailableResources() {
-    Resource resourceBasedOnAllocation = getUnallocatedResources();
+    Resource resourceBasedOnAllocation = super.getUnallocatedResources();
     Resource resourceBasedOnUtilization =
         getResourcesAvailableBasedOnUtilization();
     if (LOG.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/hadoop/blob/23ad2fbd/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/TestContainerSchedulerWithOverAllocation.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/TestContainerSchedulerWithOverAllocation.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/TestContainerSchedulerWithOverAllocation.java
index 384b116..183d868 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/TestContainerSchedulerWithOverAllocation.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/scheduler/TestContainerSchedulerWithOverAllocation.java
@@ -37,6 +37,7 @@ import org.apache.hadoop.yarn.api.records.ResourceUtilization;
 import org.apache.hadoop.yarn.api.records.Token;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.hadoop.yarn.event.DrainDispatcher;
 import org.apache.hadoop.yarn.exceptions.ConfigurationException;
 import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.security.NMTokenIdentifier;
@@ -114,6 +115,9 @@ public class TestContainerSchedulerWithOverAllocation
     conf.setFloat(
         YarnConfiguration.NM_OVERALLOCATION_MEMORY_UTILIZATION_THRESHOLD,
         0.75f);
+    // disable the monitor thread in ContainersMonitor to allow control over
+    // when opportunistic containers are launched with over-allocation
+    conf.setBoolean(YarnConfiguration.NM_CONTAINER_MONITOR_ENABLED, false);
     super.setup();
   }
 
@@ -190,6 +194,27 @@ public class TestContainerSchedulerWithOverAllocation
                 BuilderUtils.newResource(512, 1), false))
     ));
 
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .drainAsyncEvents();
+
+    // this container is not expected to be started immediately because
+    // opportunistic containers cannot be started if the node would be
+    // over-allocated
+    BaseContainerManagerTest.waitForContainerSubState(
+        containerManager, createContainerId(2), ContainerSubState.SCHEDULED);
+
+    verifyContainerStatuses(new HashMap<ContainerId, ContainerSubState>() {
+      {
+        put(createContainerId(0), ContainerSubState.RUNNING);
+        put(createContainerId(1), ContainerSubState.RUNNING);
+        put(createContainerId(2), ContainerSubState.SCHEDULED);
+      }
+    });
+
+    // try to start opportunistic containers out of band.
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .startContainersOutOfBandUponLowUtilization();
+
     // this container is expected to be started immediately because there
     // are (memory: 1024, vcore: 0.625) available based on over-allocation
     BaseContainerManagerTest.waitForContainerSubState(
@@ -244,6 +269,16 @@ public class TestContainerSchedulerWithOverAllocation
             createStartContainerRequest(2,
                 BuilderUtils.newResource(512, 1), false))
     ));
+
+    // try to start opportunistic containers out of band because they can
+    // not be launched at container scheduler event if the node would be
+    // over-allocated.
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .startContainersOutOfBandUponLowUtilization();
+
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .drainAsyncEvents();
+
     // this container will not start immediately because there is not
     // enough resource available at the moment either in terms of
     // resources unallocated or in terms of the actual utilization
@@ -299,6 +334,27 @@ public class TestContainerSchedulerWithOverAllocation
                 BuilderUtils.newResource(512, 1), false))
     ));
 
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .drainAsyncEvents();
+
+    // this container is not expected to be started immediately because
+    // opportunistic containers cannot be started if the node would be
+    // over-allocated
+    BaseContainerManagerTest.waitForContainerSubState(
+        containerManager, createContainerId(2), ContainerSubState.SCHEDULED);
+
+    verifyContainerStatuses(new HashMap<ContainerId, ContainerSubState>() {
+      {
+        put(createContainerId(0), ContainerSubState.RUNNING);
+        put(createContainerId(1), ContainerSubState.RUNNING);
+        put(createContainerId(2), ContainerSubState.SCHEDULED);
+      }
+    });
+
+    // try to start opportunistic containers out of band.
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .startContainersOutOfBandUponLowUtilization();
+
     // this container is expected to be started because there is resources
     // available because the actual utilization is very low
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
@@ -355,6 +411,9 @@ public class TestContainerSchedulerWithOverAllocation
     containerManager.startContainers(
         StartContainersRequest.newInstance(moreContainerRequests));
 
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .drainAsyncEvents();
+
     // All OPPORTUNISTIC containers but the last one should be queued.
     // The last OPPORTUNISTIC container to launch should be killed.
     BaseContainerManagerTest.waitForContainerState(
@@ -580,13 +639,27 @@ public class TestContainerSchedulerWithOverAllocation
           }
         }
     ));
-    // All three GUARANTEED containers are all expected to start
-    // because the containers utilization is low (0 at the point)
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .drainAsyncEvents();
+
+    // Two OPPORTUNISTIC containers are expected to start with the
+    // unallocated resources, but one will be queued because no
+    // over-allocation is allowed at container scheduler events.
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
         createContainerId(0), ContainerSubState.RUNNING);
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
         createContainerId(1), ContainerSubState.RUNNING);
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
+        createContainerId(2), ContainerSubState.SCHEDULED);
+
+    // try to start the opportunistic container out of band because it can
+    // not be launched at container scheduler event if the node would be
+    // over-allocated.
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .startContainersOutOfBandUponLowUtilization();
+
+    // now the queued opportunistic container should also start
+    BaseContainerManagerTest.waitForContainerSubState(containerManager,
         createContainerId(2), ContainerSubState.RUNNING);
 
     // the containers utilization is low
@@ -625,7 +698,6 @@ public class TestContainerSchedulerWithOverAllocation
    * and fourth OPPORTUNISTIC container (which releases no resources) and
    * then the second OPPORTUNISTIC container.
    */
-  @Test
   public void
       testKillOppContainersConservativelyWithOverallocationHighUtilization()
           throws Exception {
@@ -730,7 +802,7 @@ public class TestContainerSchedulerWithOverAllocation
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
         createContainerId(2), ContainerSubState.RUNNING);
 
-    // the contianers utilization is at the overallocation threshold
+    // the container utilization is at the overallocation threshold
     setContainerResourceUtilization(
         ResourceUtilization.newInstance(1536, 0, 1.0f/2));
 
@@ -740,7 +812,7 @@ public class TestContainerSchedulerWithOverAllocation
             add(createStartContainerRequest(3,
                 BuilderUtils.newResource(512, 1), false));
             add(createStartContainerRequest(4,
-                BuilderUtils.newResource(512, 1), false));
+                BuilderUtils.newResource(800, 1), false));
           }
         }
     ));
@@ -759,12 +831,35 @@ public class TestContainerSchedulerWithOverAllocation
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
         createContainerId(2), ContainerSubState.DONE);
 
-    // the two OPPORTUNISTIC containers are expected to start together
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .drainAsyncEvents();
+
+    // only one OPPORTUNISTIC container is start because no over-allocation
+    // is allowed to start OPPORTUNISTIC containers at container finish event.
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
         createContainerId(3), ContainerSubState.RUNNING);
     BaseContainerManagerTest.waitForContainerSubState(containerManager,
-        createContainerId(4), ContainerSubState.RUNNING);
+        createContainerId(4), ContainerSubState.SCHEDULED);
+
+    verifyContainerStatuses(new HashMap<ContainerId, ContainerSubState>() {
+      {
+        put(createContainerId(0), ContainerSubState.RUNNING);
+        put(createContainerId(1), ContainerSubState.RUNNING);
+        put(createContainerId(2), ContainerSubState.DONE);
+        put(createContainerId(3), ContainerSubState.RUNNING);
+        put(createContainerId(4), ContainerSubState.SCHEDULED);
+      }
+    });
 
+    // now try to start the OPPORTUNISTIC container that was queued because
+    // we don't start OPPORTUNISTIC containers at container finish event if
+    // the node would be over-allocated
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .startContainersOutOfBandUponLowUtilization();
+    ((LongRunningContainerSimulatingContainersManager) containerManager)
+        .drainAsyncEvents();
+    BaseContainerManagerTest.waitForContainerSubState(containerManager,
+        createContainerId(4), ContainerSubState.RUNNING);
     verifyContainerStatuses(new HashMap<ContainerId, ContainerSubState>() {
       {
         put(createContainerId(0), ContainerSubState.RUNNING);
@@ -817,7 +912,7 @@ public class TestContainerSchedulerWithOverAllocation
     setContainerResourceUtilization(
         ResourceUtilization.newInstance(1536, 0, 1.0f/2));
 
-    // try to start containers out of band.
+    // try to start opportunistic containers out of band.
     ((LongRunningContainerSimulatingContainersManager)containerManager)
         .startContainersOutOfBandUponLowUtilization();
 
@@ -937,6 +1032,11 @@ public class TestContainerSchedulerWithOverAllocation
       return ugi;
     }
 
+    @Override
+    protected AsyncDispatcher createDispatcher() {
+      return new DrainDispatcher();
+    }
+
     /**
      * Create a container launcher that signals container processes
      * with a dummy pid. The container processes are simulated in
@@ -977,6 +1077,10 @@ public class TestContainerSchedulerWithOverAllocation
       ((ContainerMonitorForOverallocationTest) getContainersMonitor())
           .attemptToStartContainersUponLowUtilization();
     }
+
+    public void drainAsyncEvents() {
+      ((DrainDispatcher) dispatcher).await();
+    }
   }
 
   /**
@@ -1113,6 +1217,12 @@ public class TestContainerSchedulerWithOverAllocation
           containerResourceUsage, System.currentTimeMillis());
     }
 
+    @Override
+    protected void checkOverAllocationPrerequisites() {
+      // do not check
+    }
+
+
     public void setContainerResourceUsage(
         ResourceUtilization containerResourceUsage) {
       this.containerResourceUsage = containerResourceUsage;


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org