### Question:
ApplicationLifecycleManager { public void ensureRunning() throws InterruptedException { for (int i = 0; i < 30; i++) { ApplicationDetail detail = detailSupplier.get(); ApplicationStatus currentStatus = detail.applicationStatus(); switch (currentStatus) { case READY: start(detail); break; case STARTING: case UPDATING: break; case RUNNING: return; default: throw new IllegalStateException("application in unexpected state: " + currentStatus); } Thread.sleep(statusPollingInterval); } throw new IllegalStateException("timed out waiting for application to start"); } ApplicationLifecycleManager(String applicationName);  ApplicationLifecycleManager(KinesisAnalyticsClient client,
                                       String applicationName,
                                       long statusPollingIntervalMs); void ensureRunning(); void ensureStopped();  }### Answer:
@Test public void ensureRunning_GivenRunningApplication_ShouldRequestStatusExactlyOnce() throws InterruptedException { Mockito.when(client.describeApplication(describeApplicationRequest)) .thenReturn(withStatus(ApplicationStatus.RUNNING)); manager.ensureRunning(); Mockito.verify(client).describeApplication(describeApplicationRequest); }
@Test public void ensureRunning_GivenDeletingApplication_ShouldThrow() throws InterruptedException { Mockito.when(client.describeApplication(describeApplicationRequest)) .thenReturn(withStatus(ApplicationStatus.DELETING)); try { manager.ensureRunning(); Assert.fail("expected exception starting an application that is being deleted"); } catch (IllegalStateException expectedException) { } Mockito.verify(client).describeApplication(describeApplicationRequest); }
@Test public void ensureRunning_GivenTimeoutWaitingForRunning_ShouldThrow() throws InterruptedException { Mockito.when(client.describeApplication(describeApplicationRequest)) .thenReturn(withStatus(ApplicationStatus.STARTING)); try { manager.ensureRunning(); Assert.fail("expected timeout waiting for application to finish starting"); } catch (IllegalStateException expectedException) { } Mockito.verify(client, Mockito.times(30)) .describeApplication(describeApplicationRequest); }
@Test public void ensureRunning_GivenReadyThenRunningApplication_ShouldStartApplicationFromLastStoppedPoint() throws InterruptedException { String inputId = UUID.randomUUID().toString(); ApplicationDetail applicationDetail = ApplicationDetail.builder() .applicationStatus(ApplicationStatus.READY) .inputDescriptions(InputDescription.builder().inputId(inputId).build()) .build(); Mockito.when(client.describeApplication(describeApplicationRequest)) .thenReturn(DescribeApplicationResponse.builder().applicationDetail(applicationDetail).build()) .thenReturn(withStatus(ApplicationStatus.RUNNING)); manager.ensureRunning(); ArgumentCaptor<StartApplicationRequest> requestCaptor = ArgumentCaptor.forClass(StartApplicationRequest.class); Mockito.verify(client).startApplication(requestCaptor.capture()); List<InputConfiguration> inputConfigurationList = requestCaptor.getValue().inputConfigurations(); Assert.assertThat( "start request should have only one input configuration", inputConfigurationList, Matchers.hasSize(1) ); InputConfiguration inputConfiguration = inputConfigurationList.get(0); Assert.assertEquals("input configuration id should match input description", inputId, inputConfiguration.id()); InputStartingPosition actualStartingPosition = inputConfiguration .inputStartingPositionConfiguration().inputStartingPosition(); Assert.assertEquals( "starting position should be last stopped point", InputStartingPosition.LAST_STOPPED_POINT, actualStartingPosition ); }