@Test(timeout = 60000)
public void testContainerPromoteAfterContainerStart() throws Exception {

  HashMap<NodeId, MockNM> nodes = new HashMap<>();
  MockNM nm1 = new MockNM("h1:1234", 4096, rm.getResourceTrackerService());
  nodes.put(nm1.getNodeId(), nm1);
  MockNM nm2 = new MockNM("h2:1234", 4096, rm.getResourceTrackerService());
  nodes.put(nm2.getNodeId(), nm2);
  nm1.registerNode();
  nm2.registerNode();
  nm1.nodeHeartbeat(oppContainersStatus, true);
  nm2.nodeHeartbeat(oppContainersStatus, true);
  OpportunisticContainerAllocatorAMService amservice =
      (OpportunisticContainerAllocatorAMService) rm
          .getApplicationMasterService();
  MockRMAppSubmissionData data =
      MockRMAppSubmissionData.Builder.createWithMemory(1 * GB, rm)
          .withAppName("app")
          .withUser("user")
          .withAcls(null)
          .withQueue("default")
          .withUnmanagedAM(false)
          .build();
  RMApp app1 = MockRMAppSubmitter.submit(rm, data);
  MockAM am1 = MockRM.launchAndRegisterAM(app1, rm, nm2);
  ResourceScheduler scheduler = rm.getResourceScheduler();
  // All nodes 1 to 2 will be applicable for scheduling.
  nm1.nodeHeartbeat(oppContainersStatus, true);
  nm2.nodeHeartbeat(oppContainersStatus, true);
  GenericTestUtils.waitFor(() ->
      amservice.getLeastLoadedNodes().size() == 2, 10, 10 * 100);
  QueueMetrics metrics = ((CapacityScheduler) scheduler).getRootQueue()
      .getMetrics();
  // Verify Metrics
  verifyMetrics(metrics, 7168, 7, 1024, 1, 1);
  AllocateResponse allocateResponse = am1.allocate(
      Arrays.asList(ResourceRequest.newInstance(Priority.newInstance(1),
          "*", Resources.createResource(1 * GB), 2, true, null,
          ExecutionTypeRequest.newInstance(
              ExecutionType.OPPORTUNISTIC, true))),
      null);
  List<Container> allocatedContainers = allocateResponse
      .getAllocatedContainers();
  Assert.assertEquals(2, allocatedContainers.size());
  Container container = allocatedContainers.get(0);
  MockNM allocNode = nodes.get(container.getNodeId());
  // Start Container in NM
  allocNode.nodeHeartbeat(Arrays.asList(
      ContainerStatus.newInstance(container.getId(),
          ExecutionType.OPPORTUNISTIC, ContainerState.RUNNING, "", 0)),
      true);
  rm.drainEvents();
  // Verify that container is actually running wrt the RM..
  RMContainer rmContainer = ((CapacityScheduler) scheduler)
      .getApplicationAttempt(
          container.getId().getApplicationAttemptId()).getRMContainer(
          container.getId());
  Assert.assertEquals(RMContainerState.RUNNING, rmContainer.getState());
  // Verify Metrics After OPP allocation (Nothing should change)
  verifyMetrics(metrics, 7168, 7, 1024, 1, 1);
  am1.sendContainerUpdateRequest(
      Arrays.asList(UpdateContainerRequest.newInstance(0,
          container.getId(), ContainerUpdateType.PROMOTE_EXECUTION_TYPE,
          null, ExecutionType.GUARANTEED)));
  // Verify Metrics After OPP allocation (Nothing should change again)
  verifyMetrics(metrics, 7168, 7, 1024, 1, 1);
  // Send Promotion req again... this should result in update error
  allocateResponse = am1.sendContainerUpdateRequest(
      Arrays.asList(UpdateContainerRequest.newInstance(0,
          container.getId(), ContainerUpdateType.PROMOTE_EXECUTION_TYPE,
          null, ExecutionType.GUARANTEED)));
  Assert.assertEquals(0, allocateResponse.getUpdatedContainers().size());
  Assert.assertEquals(1, allocateResponse.getUpdateErrors().size());
  Assert.assertEquals("UPDATE_OUTSTANDING_ERROR",
      allocateResponse.getUpdateErrors().get(0).getReason());
  Assert.assertEquals(container.getId(),
      allocateResponse.getUpdateErrors().get(0)
          .getUpdateContainerRequest().getContainerId());
  // Start Container in NM
  allocNode.nodeHeartbeat(Arrays.asList(
      ContainerStatus.newInstance(container.getId(),
          ExecutionType.OPPORTUNISTIC, ContainerState.RUNNING, "", 0)),
      true);
  rm.drainEvents();
  allocateResponse =  am1.allocate(new ArrayList<>(), new ArrayList<>());
  Assert.assertEquals(1, allocateResponse.getUpdatedContainers().size());
  Container uc =
      allocateResponse.getUpdatedContainers().get(0).getContainer();
  Assert.assertEquals(ExecutionType.GUARANTEED, uc.getExecutionType());
  Assert.assertEquals(uc.getId(), container.getId());
  Assert.assertEquals(uc.getVersion(), container.getVersion() + 1);
  // Verify that the Container is still in RUNNING state wrt RM..
  rmContainer = ((CapacityScheduler) scheduler)
      .getApplicationAttempt(
          uc.getId().getApplicationAttemptId()).getRMContainer(uc.getId());
  Assert.assertEquals(RMContainerState.RUNNING, rmContainer.getState());
  // Verify Metrics After OPP allocation :
  // Allocated cores+mem should have increased, available should decrease
  verifyMetrics(metrics, 6144, 6, 2048, 2, 2);
}