use of software.amazon.awssdk.aws.greengrass.model.ComponentUpdatePolicyEvents in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentServiceIntegrationTest method GIVEN_device_deployment_not_started_WHEN_new_deployment_THEN_first_deployment_cancelled.
@Test
void GIVEN_device_deployment_not_started_WHEN_new_deployment_THEN_first_deployment_cancelled() throws Exception {
CountDownLatch cdlDeployNonDisruptable = new CountDownLatch(1);
CountDownLatch cdlDeployRedSignal = new CountDownLatch(1);
CountDownLatch cdlRedeployNonDisruptable = new CountDownLatch(1);
Consumer<GreengrassLogMessage> listener = m -> {
if (m.getMessage() != null) {
if (m.getMessage().contains("Current deployment finished") && m.getContexts().get("DeploymentId").equals("deployNonDisruptable")) {
cdlDeployNonDisruptable.countDown();
}
if (m.getMessage().contains("Discarding device deployment") && m.getContexts().get("DEPLOYMENT_ID").equals("deployRedSignal")) {
cdlDeployRedSignal.countDown();
}
if (m.getMessage().contains("Current deployment finished") && m.getContexts().get("DeploymentId").equals("redeployNonDisruptable")) {
cdlRedeployNonDisruptable.countDown();
}
}
};
try (AutoCloseable l = TestUtils.createCloseableLogListener(listener)) {
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithNonDisruptableService.json").toURI(), "deployNonDisruptable", DeploymentType.SHADOW);
CountDownLatch nonDisruptableServiceServiceLatch = new CountDownLatch(1);
kernel.getContext().addGlobalStateChangeListener((service, oldState, newState) -> {
if (service.getName().equals("NonDisruptableService") && newState.equals(State.RUNNING)) {
nonDisruptableServiceServiceLatch.countDown();
}
});
assertTrue(nonDisruptableServiceServiceLatch.await(30, TimeUnit.SECONDS));
try (EventStreamRPCConnection connection = IPCTestUtils.getEventStreamRpcConnection(kernel, "NonDisruptableService")) {
GreengrassCoreIPCClient ipcEventStreamClient = new GreengrassCoreIPCClient(connection);
ipcEventStreamClient.subscribeToComponentUpdates(new SubscribeToComponentUpdatesRequest(), Optional.of(new StreamResponseHandler<ComponentUpdatePolicyEvents>() {
@Override
public void onStreamEvent(ComponentUpdatePolicyEvents streamEvent) {
if (streamEvent.getPreUpdateEvent() != null) {
try {
DeferComponentUpdateRequest deferComponentUpdateRequest = new DeferComponentUpdateRequest();
deferComponentUpdateRequest.setRecheckAfterMs(TimeUnit.SECONDS.toMillis(60));
deferComponentUpdateRequest.setMessage("Test");
ipcEventStreamClient.deferComponentUpdate(deferComponentUpdateRequest, Optional.empty()).getResponse().get(DEFAULT_IPC_API_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
}
}
}
@Override
public boolean onStreamError(Throwable error) {
logger.atError().setCause(error).log("Caught error stream when subscribing for component " + "updates");
return false;
}
@Override
public void onStreamClosed() {
}
}));
assertTrue(cdlDeployNonDisruptable.await(30, TimeUnit.SECONDS));
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithRedSignalService.json").toURI(), "deployRedSignal", DeploymentType.SHADOW);
submitSampleJobDocument(DeploymentServiceIntegrationTest.class.getResource("FleetConfigWithNonDisruptableService.json").toURI(), "redeployNonDisruptable", DeploymentType.SHADOW);
assertTrue(cdlRedeployNonDisruptable.await(15, TimeUnit.SECONDS));
assertTrue(cdlDeployRedSignal.await(1, TimeUnit.SECONDS));
}
}
}
use of software.amazon.awssdk.aws.greengrass.model.ComponentUpdatePolicyEvents in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentTaskIntegrationTest method GIVEN_deployment_in_progress_WHEN_deployment_task_is_cancelled_THEN_stop_processing.
@Test
@Order(99)
@SuppressWarnings({ "PMD.CloseResource", "PMD.AvoidCatchingGenericException" })
void GIVEN_deployment_in_progress_WHEN_deployment_task_is_cancelled_THEN_stop_processing() throws Exception {
Future<DeploymentResult> resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("AddNewServiceWithSafetyCheck.json").toURI(), System.currentTimeMillis());
resultFuture.get(DEPLOYMENT_TIMEOUT, TimeUnit.SECONDS);
String authToken = IPCTestUtils.getAuthTokeForService(kernel, "NonDisruptableService");
final EventStreamRPCConnection clientConnection = IPCTestUtils.connectToGGCOverEventStreamIPC(socketOptions, authToken, kernel);
SubscribeToComponentUpdatesRequest subscribeToComponentUpdatesRequest = new SubscribeToComponentUpdatesRequest();
GreengrassCoreIPCClient greengrassCoreIPCClient = new GreengrassCoreIPCClient(clientConnection);
CompletableFuture<SubscribeToComponentUpdatesResponse> fut = greengrassCoreIPCClient.subscribeToComponentUpdates(subscribeToComponentUpdatesRequest, Optional.of(new StreamResponseHandler<ComponentUpdatePolicyEvents>() {
@Override
public void onStreamEvent(ComponentUpdatePolicyEvents streamEvent) {
if (streamEvent.getPreUpdateEvent() != null) {
DeferComponentUpdateRequest deferComponentUpdateRequest = new DeferComponentUpdateRequest();
deferComponentUpdateRequest.setRecheckAfterMs(Duration.ofSeconds(60).toMillis());
deferComponentUpdateRequest.setMessage("Test");
deferComponentUpdateRequest.setDeploymentId(streamEvent.getPreUpdateEvent().getDeploymentId());
greengrassCoreIPCClient.deferComponentUpdate(deferComponentUpdateRequest, Optional.empty());
}
}
@Override
public boolean onStreamError(Throwable error) {
logger.atError().setCause(error).log("Stream closed due to error");
return false;
}
@Override
public void onStreamClosed() {
}
})).getResponse();
try {
fut.get(DEPLOYMENT_TIMEOUT, TimeUnit.SECONDS);
} catch (Exception e) {
logger.atError().setCause(e).log("Error when subscribing to component updates");
fail("Caught exception when subscribing to component updates");
}
List<String> services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
// should contain main, Nucleus, NonDisruptableService 1.0.0
assertEquals(3, services.size(), "Actual services: " + services);
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "NonDisruptableService"));
CountDownLatch cdlUpdateStarted = new CountDownLatch(1);
CountDownLatch cdlMergeCancelled = new CountDownLatch(1);
Consumer<GreengrassLogMessage> listener = m -> {
if (m.getMessage() != null && m.getMessage().contains("deferred for 60000 millis with message Test")) {
cdlUpdateStarted.countDown();
}
if (m.getMessage() != null && m.getMessage().contains("Cancelled deployment merge future due to interrupt")) {
cdlMergeCancelled.countDown();
}
};
Slf4jLogAdapter.addGlobalListener(listener);
try {
resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("UpdateServiceWithSafetyCheck.json").toURI(), System.currentTimeMillis());
assertTrue(cdlUpdateStarted.await(40, TimeUnit.SECONDS));
resultFuture.cancel(true);
assertTrue(cdlMergeCancelled.await(DEPLOYMENT_TIMEOUT, TimeUnit.SECONDS));
services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
// should contain main, Nucleus, NonDisruptableService 1.0.0
assertEquals(3, services.size());
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "NonDisruptableService"));
assertEquals("1.0.0", kernel.findServiceTopic("NonDisruptableService").find("version").getOnce());
} finally {
Slf4jLogAdapter.removeGlobalListener(listener);
clientConnection.close();
}
}
use of software.amazon.awssdk.aws.greengrass.model.ComponentUpdatePolicyEvents in project aws-greengrass-nucleus by aws-greengrass.
the class IPCServicesTest method GIVEN_LifeCycleEventStreamClient_WHEN_subscribe_to_component_update_THEN_service_receives_update_and_close_stream.
@SuppressWarnings({ "PMD.CloseResource", "PMD.AvoidCatchingGenericException" })
@Test
void GIVEN_LifeCycleEventStreamClient_WHEN_subscribe_to_component_update_THEN_service_receives_update_and_close_stream() throws Exception {
// debug log required for assertion
LogConfig.getRootLogConfig().setLevel(Level.DEBUG);
SubscribeToComponentUpdatesRequest subscribeToComponentUpdatesRequest = new SubscribeToComponentUpdatesRequest();
CountDownLatch cdl = new CountDownLatch(2);
CountDownLatch subscriptionLatch = new CountDownLatch(1);
Slf4jLogAdapter.addGlobalListener(m -> {
m.getMessage().contains("subscribed to component update");
subscriptionLatch.countDown();
});
CompletableFuture<Future> futureFuture = new CompletableFuture<>();
GreengrassCoreIPCClient greengrassCoreIPCClient = new GreengrassCoreIPCClient(clientConnection);
StreamResponseHandler<ComponentUpdatePolicyEvents> responseHandler = new StreamResponseHandler<ComponentUpdatePolicyEvents>() {
@Override
public void onStreamEvent(ComponentUpdatePolicyEvents streamEvent) {
if (streamEvent.getPreUpdateEvent() != null) {
cdl.countDown();
DeferComponentUpdateRequest deferComponentUpdateRequest = new DeferComponentUpdateRequest();
deferComponentUpdateRequest.setRecheckAfterMs(Duration.ofSeconds(1).toMillis());
deferComponentUpdateRequest.setDeploymentId(streamEvent.getPreUpdateEvent().getDeploymentId());
deferComponentUpdateRequest.setMessage("Test");
futureFuture.complete(greengrassCoreIPCClient.deferComponentUpdate(deferComponentUpdateRequest, Optional.empty()).getResponse());
}
if (streamEvent.getPostUpdateEvent() != null) {
cdl.countDown();
}
}
@Override
public boolean onStreamError(Throwable error) {
logger.atError().setCause(error).log("Caught stream error");
return false;
}
@Override
public void onStreamClosed() {
}
};
SubscribeToComponentUpdatesResponseHandler streamHandler = greengrassCoreIPCClient.subscribeToComponentUpdates(subscribeToComponentUpdatesRequest, Optional.of(responseHandler));
CompletableFuture<SubscribeToComponentUpdatesResponse> fut = streamHandler.getResponse();
fut.get(3, TimeUnit.SECONDS);
assertTrue(subscriptionLatch.await(5, TimeUnit.SECONDS));
// GG_NEEDS_REVIEW: TODO: When Cli support safe update setting in local deployment, then create a local deployment here to
// trigger update
LifecycleIPCEventStreamAgent lifecycleIPCEventStreamAgent = kernel.getContext().get(LifecycleIPCEventStreamAgent.class);
PreComponentUpdateEvent event = new PreComponentUpdateEvent();
event.setDeploymentId("abc");
List<Future<DeferComponentUpdateRequest>> futureList = lifecycleIPCEventStreamAgent.sendPreComponentUpdateEvent(event);
assertEquals(1, futureList.size());
futureFuture.get(5, TimeUnit.SECONDS).get(5, TimeUnit.SECONDS);
futureList.get(0).get(5, TimeUnit.SECONDS);
lifecycleIPCEventStreamAgent.sendPostComponentUpdateEvent(new PostComponentUpdateEvent());
assertTrue(cdl.await(TIMEOUT_FOR_LIFECYCLE_SECONDS, TimeUnit.SECONDS));
streamHandler.closeStream();
// Checking if a request can be made on teh same connection after closing the stream
UpdateStateRequest updateStateRequest = new UpdateStateRequest();
updateStateRequest.setState(ReportedLifecycleState.RUNNING);
greengrassCoreIPCClient.updateState(updateStateRequest, Optional.empty()).getResponse().get(3, TimeUnit.SECONDS);
}
use of software.amazon.awssdk.aws.greengrass.model.ComponentUpdatePolicyEvents in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentE2ETest method GIVEN_deployment_in_progress_with_more_jobs_queued_in_cloud_WHEN_cancel_event_received_and_kernel_is_waiting_for_safe_time_THEN_deployment_should_be_canceled.
@Timeout(value = 10, unit = TimeUnit.MINUTES)
@Test
void GIVEN_deployment_in_progress_with_more_jobs_queued_in_cloud_WHEN_cancel_event_received_and_kernel_is_waiting_for_safe_time_THEN_deployment_should_be_canceled() throws Exception {
// First Deployment to have a service running in Kernel which has a safety check that always returns
// false, i.e. keeps waiting forever
CreateDeploymentRequest createDeploymentRequest1 = CreateDeploymentRequest.builder().components(Utils.immutableMap("NonDisruptableService", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
CreateDeploymentResponse result1 = draftAndCreateDeployment(createDeploymentRequest1);
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, result1.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(3), s -> s.equals(JobExecutionStatus.SUCCEEDED));
Consumer<GreengrassLogMessage> logListener = null;
try (EventStreamRPCConnection connection = IPCTestUtils.getEventStreamRpcConnection(kernel, "NonDisruptableService" + testComponentSuffix)) {
GreengrassCoreIPCClient ipcClient = new GreengrassCoreIPCClient(connection);
ipcClient.subscribeToComponentUpdates(new SubscribeToComponentUpdatesRequest(), Optional.of(new StreamResponseHandler<ComponentUpdatePolicyEvents>() {
@Override
public void onStreamEvent(ComponentUpdatePolicyEvents streamEvent) {
if (streamEvent.getPreUpdateEvent() != null) {
logger.atInfo().log("Got pre component update event");
DeferComponentUpdateRequest deferComponentUpdateRequest = new DeferComponentUpdateRequest();
deferComponentUpdateRequest.setRecheckAfterMs(TimeUnit.SECONDS.toMillis(60));
deferComponentUpdateRequest.setMessage("NonDisruptableService");
logger.atInfo().log("Sending defer request");
// Cannot wait inside a callback
ipcClient.deferComponentUpdate(deferComponentUpdateRequest, Optional.empty());
}
}
@Override
public boolean onStreamError(Throwable error) {
logger.atError().setCause(error).log("Caught stream error while subscribing for component update");
return false;
}
@Override
public void onStreamClosed() {
}
}));
CountDownLatch updateRegistered = new CountDownLatch(1);
CountDownLatch deploymentCancelled = new CountDownLatch(1);
logListener = m -> {
if ("register-service-update-action".equals(m.getEventType())) {
updateRegistered.countDown();
}
if (m.getMessage() != null && m.getMessage().contains("Deployment was cancelled")) {
deploymentCancelled.countDown();
}
};
Slf4jLogAdapter.addGlobalListener(logListener);
// Second deployment to update the service which is currently running an important task so deployment should
// keep waiting for a safe time to update
CreateDeploymentRequest createDeploymentRequest2 = CreateDeploymentRequest.builder().deploymentPolicies(DeploymentPolicies.builder().configurationValidationPolicy(DeploymentConfigurationValidationPolicy.builder().timeoutInSeconds(120).build()).failureHandlingPolicy(DO_NOTHING).componentUpdatePolicy(DeploymentComponentUpdatePolicy.builder().action(NOTIFY_COMPONENTS).timeoutInSeconds(120).build()).build()).components(Utils.immutableMap("NonDisruptableService", ComponentDeploymentSpecification.builder().componentVersion("1.0.1").build())).build();
CreateDeploymentResponse result2 = draftAndCreateDeployment(createDeploymentRequest2);
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, result2.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(3), s -> s.equals(JobExecutionStatus.IN_PROGRESS));
// Create one more deployment so that it's queued in cloud
CreateDeploymentRequest createDeploymentRequest3 = CreateDeploymentRequest.builder().deploymentPolicies(DeploymentPolicies.builder().configurationValidationPolicy(DeploymentConfigurationValidationPolicy.builder().timeoutInSeconds(120).build()).failureHandlingPolicy(DO_NOTHING).componentUpdatePolicy(DeploymentComponentUpdatePolicy.builder().action(NOTIFY_COMPONENTS).timeoutInSeconds(120).build()).build()).components(Utils.immutableMap("NonDisruptableService", ComponentDeploymentSpecification.builder().componentVersion("1.0.1").build())).build();
CreateDeploymentResponse result3 = draftAndCreateDeployment(createDeploymentRequest3);
// Wait for the second deployment to start waiting for safe time to update and
// then cancel it's corresponding job from cloud
assertTrue(updateRegistered.await(60, TimeUnit.SECONDS));
UpdateSystemPolicyService updateSystemPolicyService = kernel.getContext().get(UpdateSystemPolicyService.class);
assertThat("The UpdateSystemService should have one pending action.", updateSystemPolicyService.getPendingActions(), IsCollectionWithSize.hasSize(1));
// Get the value of the pending Action
String pendingAction = updateSystemPolicyService.getPendingActions().iterator().next();
// GG_NEEDS_REVIEW: TODO : Call Fleet configuration service's cancel API when ready instead of calling IoT Jobs API
IotJobsUtils.cancelJob(iotClient, result2.iotJobId());
// Wait for indication that cancellation has gone through
assertTrue(deploymentCancelled.await(240, TimeUnit.SECONDS));
// the third deployment may have reached device.
Set<String> pendingActions = updateSystemPolicyService.getPendingActions();
if (pendingActions.size() == 1) {
String newPendingAction = pendingActions.iterator().next();
assertNotEquals(pendingAction, newPendingAction, "The UpdateSystemService's one pending action should be be replaced.");
} else if (pendingActions.size() > 1) {
fail("Deployment not cancelled, pending actions: " + updateSystemPolicyService.getPendingActions());
}
// Now that we've verified that the job got cancelled, let's verify that the next job was picked up
// and put into IN_PROGRESS state
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, result3.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(3), s -> s.equals(JobExecutionStatus.IN_PROGRESS));
// Ensure that main is finished, which is its terminal state, so this means that all updates ought to be done
assertThat(kernel.getMain()::getState, eventuallyEval(is(State.FINISHED)));
assertThat(getCloudDeployedComponent("NonDisruptableService")::getState, eventuallyEval(is(State.RUNNING)));
assertEquals("1.0.0", getCloudDeployedComponent("NonDisruptableService").getConfig().find("version").getOnce());
} finally {
if (logListener != null) {
Slf4jLogAdapter.removeGlobalListener(logListener);
}
}
}
use of software.amazon.awssdk.aws.greengrass.model.ComponentUpdatePolicyEvents in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentE2ETest method GIVEN_some_running_services_WHEN_cancel_event_received_and_kernel_is_waiting_for_disruptable_time_THEN_deployment_should_be_canceled.
@Timeout(value = 10, unit = TimeUnit.MINUTES)
@Test
void GIVEN_some_running_services_WHEN_cancel_event_received_and_kernel_is_waiting_for_disruptable_time_THEN_deployment_should_be_canceled() throws Exception {
// First Deployment to have a service running in Kernel which has a update policy check that always returns
// false, i.e. keeps waiting forever
CreateDeploymentRequest createDeploymentRequest1 = CreateDeploymentRequest.builder().components(Utils.immutableMap("NonDisruptableService", ComponentDeploymentSpecification.builder().componentVersion("1.0.0").build())).build();
CreateDeploymentResponse createDeploymentResult1 = draftAndCreateDeployment(createDeploymentRequest1);
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, createDeploymentResult1.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(3), s -> s.equals(JobExecutionStatus.SUCCEEDED));
CountDownLatch postUpdateEventReceived = new CountDownLatch(1);
Consumer<GreengrassLogMessage> logListener = null;
try (EventStreamRPCConnection connection = IPCTestUtils.getEventStreamRpcConnection(kernel, "NonDisruptableService" + testComponentSuffix)) {
GreengrassCoreIPCClient ipcClient = new GreengrassCoreIPCClient(connection);
ipcClient.subscribeToComponentUpdates(new SubscribeToComponentUpdatesRequest(), Optional.of(new StreamResponseHandler<ComponentUpdatePolicyEvents>() {
@Override
public void onStreamEvent(ComponentUpdatePolicyEvents streamEvent) {
if (streamEvent.getPreUpdateEvent() != null) {
DeferComponentUpdateRequest deferComponentUpdateRequest = new DeferComponentUpdateRequest();
deferComponentUpdateRequest.setRecheckAfterMs(TimeUnit.SECONDS.toMillis(60));
deferComponentUpdateRequest.setMessage("NonDisruptableService");
// Cannot wait for response inside a callback
ipcClient.deferComponentUpdate(deferComponentUpdateRequest, Optional.empty());
}
if (streamEvent.getPostUpdateEvent() != null) {
postUpdateEventReceived.countDown();
}
}
@Override
public boolean onStreamError(Throwable error) {
logger.atError().setCause(error).log("Caught stream error while subscribing for component update");
return false;
}
@Override
public void onStreamClosed() {
}
}));
// Second deployment to update the service which is currently running an important task so deployment should
// wait for a disruptable time to update
CreateDeploymentRequest createDeploymentRequest2 = CreateDeploymentRequest.builder().deploymentPolicies(DeploymentPolicies.builder().failureHandlingPolicy(DO_NOTHING).configurationValidationPolicy(DeploymentConfigurationValidationPolicy.builder().timeoutInSeconds(120).build()).componentUpdatePolicy(DeploymentComponentUpdatePolicy.builder().action(NOTIFY_COMPONENTS).timeoutInSeconds(120).build()).build()).components(Utils.immutableMap("NonDisruptableService", ComponentDeploymentSpecification.builder().componentVersion("1.0.1").build())).build();
CreateDeploymentResponse createDeploymentResult2 = draftAndCreateDeployment(createDeploymentRequest2);
CountDownLatch updateRegistered = new CountDownLatch(1);
CountDownLatch deploymentCancelled = new CountDownLatch(1);
logListener = m -> {
if ("register-service-update-action".equals(m.getEventType())) {
updateRegistered.countDown();
}
if (m.getMessage() != null && m.getMessage().contains("Deployment was cancelled")) {
deploymentCancelled.countDown();
}
};
Slf4jLogAdapter.addGlobalListener(logListener);
IotJobsUtils.waitForJobExecutionStatusToSatisfy(iotClient, createDeploymentResult2.iotJobId(), thingInfo.getThingName(), Duration.ofMinutes(3), s -> s.equals(JobExecutionStatus.IN_PROGRESS));
// Wait for the second deployment to start waiting for safe time to update and
// then cancel it's corresponding job from cloud
assertTrue(updateRegistered.await(60, TimeUnit.SECONDS));
assertThat("The UpdateSystemService should have one pending action.", kernel.getContext().get(UpdateSystemPolicyService.class).getPendingActions(), IsCollectionWithSize.hasSize(1));
// GG_NEEDS_REVIEW: TODO : Call Fleet configuration service's cancel API when ready instead of calling IoT Jobs API
IotJobsUtils.cancelJob(iotClient, createDeploymentResult2.iotJobId());
// Wait for indication that cancellation has gone through
assertTrue(deploymentCancelled.await(60, TimeUnit.SECONDS));
assertThat("The UpdateSystemService's one pending action should be be removed.", kernel.getContext().get(UpdateSystemPolicyService.class).getPendingActions(), IsCollectionWithSize.hasSize(0));
// Component should be told to resume its work since the change it has been waiting for is cancelled
assertTrue(postUpdateEventReceived.await(60, TimeUnit.SECONDS));
// Ensure that main is finished, which is its terminal state, so this means that all updates ought to be done
assertThat(kernel.getMain()::getState, eventuallyEval(is(State.FINISHED)));
assertThat(getCloudDeployedComponent("NonDisruptableService")::getState, eventuallyEval(is(State.RUNNING)));
assertEquals("1.0.0", getCloudDeployedComponent("NonDisruptableService").getConfig().find("version").getOnce());
} finally {
if (logListener != null) {
Slf4jLogAdapter.removeGlobalListener(logListener);
}
}
}
Aggregations