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/container/ContainerImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java index 34be6c9..337bc4e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java @@ -703,7 +703,8 @@ public ContainerImpl(Configuration conf, Dispatcher dispatcher, .addTransition(ContainerState.DONE, ContainerState.DONE, EnumSet.of(ContainerEventType.RESOURCE_FAILED, ContainerEventType.CONTAINER_EXITED_WITH_SUCCESS, - ContainerEventType.CONTAINER_EXITED_WITH_FAILURE)) + ContainerEventType.CONTAINER_EXITED_WITH_FAILURE, + ContainerEventType.CONTAINER_RESOURCES_CLEANEDUP)) // No transition - assuming container is on its way to completion .addTransition(ContainerState.DONE, ContainerState.DONE, ContainerEventType.UPDATE_CONTAINER_TOKEN) @@ -2103,6 +2104,7 @@ public void handle(ContainerEvent event) { LOG.warn("Can't handle this event at current state: Current: [" + oldState + "], eventType: [" + event.getType() + "]," + " container: [" + containerID + "]", e); + onInvalidStateTransition(event.getType(), oldState); } if (newState != null && oldState != newState) { LOG.info("Container " + containerID + " transitioned from " @@ -2206,4 +2208,12 @@ private static void removeDockerContainer(ContainerImpl container) { container.getContainerId().toString()); deletionService.delete(deletionTask); } + + /** + * catch the InvalidStateTransition. + * @param containerEventType + * @param state + */ + protected void onInvalidStateTransition(ContainerEventType containerEventType, + ContainerState state){} } 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/container/TestContainer.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/TestContainer.java index c7094a0..34b689b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/TestContainer.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/TestContainer.java @@ -96,7 +96,6 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainerMetrics; import org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorEvent; import org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorEventType; - import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants; import org.apache.hadoop.yarn.server.nodemanager.containermanager.scheduler.ContainerScheduler; import org.apache.hadoop.yarn.server.nodemanager.containermanager.scheduler.ContainerSchedulerEvent; @@ -437,6 +436,34 @@ public void testInitWhileDone() throws Exception { } @Test + @SuppressWarnings("unchecked") + public void testContainerResourceCleanUpWhileDone() throws Exception { + WrappedContainer wc = null; + try { + wc = new WrappedContainer(6, 314159265358979L, 4344, "yak"); + wc.initContainer(); + wc.localizeResources(); + wc.launchContainer(); + reset(wc.localizerBus); + wc.containerSuccessful(); + wc.containerResourcesCleanup(); + assertEquals(ContainerState.DONE, wc.c.getContainerState()); + verifyOutofBandHeartBeat(wc); + assertNull(wc.c.getLocalizedResources()); + // Now in DONE, issue CONTAINER_RESOURCES_CLEANEDUP + wc.containerResourcesCleanup(); + // Verify still in DONE + assertEquals(ContainerState.DONE, wc.c.getContainerState()); + assertNull(wc.c.getLocalizedResources()); + verifyCleanupCall(wc); + } finally { + if (wc != null) { + wc.finished(); + } + } + } + + @Test @SuppressWarnings("unchecked") // mocked generic public void testDockerContainerInitWhileDone() throws Exception { WrappedContainer wc = null; @@ -1371,7 +1398,14 @@ public void postTransition(ContainerImpl op, ContainerState beforeState, multi.addListener(listener); when(context.getContainerStateTransitionListener()).thenReturn(multi); c = new ContainerImpl(conf, dispatcher, ctxt, null, metrics, identifier, - context); + context) { + @Override + protected void onInvalidStateTransition( + ContainerEventType containerEventType,ContainerState state){ + Assert.assertTrue("ContainerImpl: can't handle " + + containerEventType + " at state " + state, false); + } + }; dispatcher.register(ContainerEventType.class, new EventHandler() { @Override