use of com.aws.greengrass.lifecyclemanager.GreengrassService in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentTaskIntegrationTest method GIVEN_services_running_WHEN_new_service_breaks_failure_handling_policy_do_nothing_THEN_service_stays_broken.
/**
* First deployment starts some services. Second deployment tries to add a service that breaks and removes an
* existing service but the failure handling policy is to do nothing As a result, no corrective action will be taken
* on failure
*
* @throws Exception
*/
@Test
@Order(10)
void GIVEN_services_running_WHEN_new_service_breaks_failure_handling_policy_do_nothing_THEN_service_stays_broken(ExtensionContext context) throws Exception {
Future<DeploymentResult> resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("YellowAndRedSignal.json").toURI(), System.currentTimeMillis());
resultFuture.get(DEPLOYMENT_TIMEOUT, TimeUnit.SECONDS);
List<String> services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
// should contain main, Nucleus, YellowSignal and RedSignal
assertEquals(4, services.size());
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "YellowSignal", "RedSignal"));
groupToRootComponentsTopics.lookupTopics("RedSignal").replaceAndWait(ImmutableMap.of(GROUP_TO_ROOT_COMPONENTS_VERSION_KEY, "1.0.0"));
groupToRootComponentsTopics.lookupTopics("YellowSignal").replaceAndWait(ImmutableMap.of(GROUP_TO_ROOT_COMPONENTS_VERSION_KEY, "1.0.0"));
ignoreExceptionUltimateCauseOfType(context, ServiceUpdateException.class);
preloadLocalStoreContent();
resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("FailureDoNothingDeployment.json").toURI(), System.currentTimeMillis());
DeploymentResult result = resultFuture.get(DEPLOYMENT_TIMEOUT, TimeUnit.SECONDS);
services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
// should contain main, Nucleus, RedSignal, BreakingService, Mosquitto and GreenSignal
assertEquals(6, services.size());
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "RedSignal", "BreakingService", "Mosquitto", "GreenSignal"));
assertEquals(State.BROKEN, kernel.locate("BreakingService").getState());
assertEquals(DeploymentResult.DeploymentStatus.FAILED_ROLLBACK_NOT_REQUESTED, result.getDeploymentStatus());
}
use of com.aws.greengrass.lifecyclemanager.GreengrassService in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentTaskIntegrationTest method GIVEN_services_running_WHEN_new_service_breaks_failure_handling_policy_rollback_THEN_services_are_rolled_back.
/**
* First deployment starts some services. Second deployment tries to add a service that breaks and removes an
* existing service and the failure handling policy is to rollback As a result, kernel should be reverted to the
* state before deployment
*
* @throws Exception
*/
@Test
@Order(11)
void GIVEN_services_running_WHEN_new_service_breaks_failure_handling_policy_rollback_THEN_services_are_rolled_back(ExtensionContext context) throws Exception {
Map<String, Object> pkgDetails = new HashMap<>();
pkgDetails.put(GROUP_TO_ROOT_COMPONENTS_VERSION_KEY, "1.0.0");
groupToRootComponentsTopics.lookupTopics("RedSignal").replaceAndWait(pkgDetails);
groupToRootComponentsTopics.lookupTopics("YellowSignal").replaceAndWait(pkgDetails);
Future<DeploymentResult> resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("YellowAndRedSignal.json").toURI(), System.currentTimeMillis());
resultFuture.get(DEPLOYMENT_TIMEOUT, TimeUnit.SECONDS);
List<String> services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
// should contain main, Nucleus, YellowSignal and RedSignal
assertEquals(4, services.size());
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "YellowSignal", "RedSignal"));
ignoreExceptionUltimateCauseOfType(context, ServiceUpdateException.class);
groupToRootComponentsTopics.lookupTopics("YellowSignal").remove();
groupToRootComponentsTopics.lookupTopics("BreakingService").replaceAndWait(ImmutableMap.of(GROUP_TO_ROOT_COMPONENTS_VERSION_KEY, "1.0.0"));
preloadLocalStoreContent();
resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("FailureRollbackDeployment.json").toURI(), System.currentTimeMillis());
DeploymentResult result = resultFuture.get(60, TimeUnit.SECONDS);
services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
// should contain main, Nucleus, YellowSignal, RedSignal
assertEquals(4, services.size());
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "YellowSignal", "RedSignal"));
assertThrows(ServiceLoadException.class, () -> kernel.locate("BreakingService"));
assertThrows(ServiceLoadException.class, () -> kernel.locate("Mosquitto"));
assertThrows(ServiceLoadException.class, () -> kernel.locate("GreenSignal"));
assertEquals(DeploymentResult.DeploymentStatus.FAILED_ROLLBACK_COMPLETE, result.getDeploymentStatus());
}
use of com.aws.greengrass.lifecyclemanager.GreengrassService in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentTaskIntegrationTest method GIVEN_broken_service_WHEN_new_service_breaks_failure_handling_policy_rollback_THEN_services_are_rolled_back.
/**
* This test verifies that if a deployment has a broken service and then a new deployment comes which removes that
* one, but fails for a different reason and rolls back, then it is able to roll back successfully.
*/
@Test
@Order(12)
void GIVEN_broken_service_WHEN_new_service_breaks_failure_handling_policy_rollback_THEN_services_are_rolled_back(ExtensionContext context) throws Exception {
ignoreExceptionUltimateCauseOfType(context, ServiceUpdateException.class);
// Deploy a broken config with no rollback
Future<DeploymentResult> resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("FailureDoNothingDeployment.json").toURI(), System.currentTimeMillis());
resultFuture.get(60, TimeUnit.SECONDS);
List<String> services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "BreakingService", "RedSignal", "GreenSignal", "Mosquitto"));
// Deploy a new broken config (using a different service) which does rollback
preloadLocalStoreContent();
resultFuture = submitSampleJobDocument(DeploymentTaskIntegrationTest.class.getResource("Failure2RollbackDeployment.json").toURI(), System.currentTimeMillis());
DeploymentResult result = resultFuture.get(60, TimeUnit.SECONDS);
services = kernel.orderedDependencies().stream().filter(greengrassService -> greengrassService instanceof GenericExternalService).map(GreengrassService::getName).collect(Collectors.toList());
// Make sure that it rolls back to the previous state
assertThat(services, containsInAnyOrder("main", DEFAULT_NUCLEUS_COMPONENT_NAME, "BreakingService", "RedSignal", "GreenSignal", "Mosquitto"));
assertEquals(DeploymentResult.DeploymentStatus.FAILED_ROLLBACK_COMPLETE, result.getDeploymentStatus());
}
use of com.aws.greengrass.lifecyclemanager.GreengrassService in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentConfigMergingTest method GIVEN_kernel_running_single_service_WHEN_merge_change_adding_nested_dependency_THEN_dependent_services_start_and_service_restarts.
@Test
void GIVEN_kernel_running_single_service_WHEN_merge_change_adding_nested_dependency_THEN_dependent_services_start_and_service_restarts() throws Throwable {
// GIVEN
ConfigPlatformResolver.initKernelWithMultiPlatformConfig(kernel, getClass().getResource("single_service.yaml"));
CountDownLatch mainRunning = new CountDownLatch(1);
kernel.getContext().addGlobalStateChangeListener((service, oldState, newState) -> {
if (service.getName().equals("main") && newState.equals(State.RUNNING)) {
mainRunning.countDown();
}
});
kernel.launch();
assertTrue(mainRunning.await(5, TimeUnit.SECONDS));
// WHEN
CountDownLatch mainRestarted = new CountDownLatch(1);
AtomicBoolean newService2Started = new AtomicBoolean(false);
AtomicBoolean newServiceStarted = new AtomicBoolean(false);
// Check that new_service2 starts, then new_service, and then main gets restarted
kernel.getContext().addGlobalStateChangeListener((service, oldState, newState) -> {
if (service.getName().equals("new_service2") && newState.equals(State.RUNNING)) {
newService2Started.set(true);
}
if (newService2Started.get() && service.getName().equals("new_service") && newState.equals(State.RUNNING)) {
newServiceStarted.set(true);
}
// Only count main as started if its dependency (new_service) has already been started
if (newServiceStarted.get() && service.getName().equals("main") && newState.equals(State.FINISHED) && oldState.equals(State.STARTING)) {
mainRestarted.countDown();
}
});
List<String> serviceList = kernel.getMain().getDependencies().keySet().stream().map(GreengrassService::getName).collect(Collectors.toList());
serviceList.add("new_service");
deploymentConfigMerger.mergeInNewConfig(testDeployment(), new HashMap<String, Object>() {
{
put(SERVICES_NAMESPACE_TOPIC, new HashMap<String, Object>() {
{
put("main", new HashMap<String, Object>() {
{
put(SERVICE_DEPENDENCIES_NAMESPACE_TOPIC, serviceList);
}
});
put("new_service", new HashMap<String, Object>() {
{
put(SERVICE_LIFECYCLE_NAMESPACE_TOPIC, new HashMap<String, Object>() {
{
put(LIFECYCLE_RUN_NAMESPACE_TOPIC, "echo done");
}
});
put(SERVICE_DEPENDENCIES_NAMESPACE_TOPIC, Arrays.asList("new_service2"));
}
});
put("new_service2", new HashMap<String, Object>() {
{
put(SERVICE_LIFECYCLE_NAMESPACE_TOPIC, new HashMap<String, Object>() {
{
put(LIFECYCLE_RUN_NAMESPACE_TOPIC, "echo done");
}
});
}
});
put(DEFAULT_NUCLEUS_COMPONENT_NAME, getNucleusConfig());
}
});
}
}).get(60, TimeUnit.SECONDS);
// THEN
assertTrue(newService2Started.get());
assertTrue(newServiceStarted.get());
assertTrue(mainRestarted.await(10, TimeUnit.SECONDS));
assertThat(kernel.orderedDependencies().stream().map(GreengrassService::getName).collect(Collectors.toList()), containsInRelativeOrder("new_service2", "new_service", "main"));
}
use of com.aws.greengrass.lifecyclemanager.GreengrassService in project aws-greengrass-nucleus by aws-greengrass.
the class DeploymentConfigMergingTest method GIVEN_kernel_running_service_WHEN_run_with_change_THEN_service_restarts.
@Test
void GIVEN_kernel_running_service_WHEN_run_with_change_THEN_service_restarts() throws Throwable {
if (!PlatformResolver.isWindows) {
assumeCanSudoShell(kernel);
}
// GIVEN
ConfigPlatformResolver.initKernelWithMultiPlatformConfig(kernel, getClass().getResource("config_run_with_user.yaml"));
List<String> stdouts = new ArrayList<>();
try (AutoCloseable l = createCloseableLogListener((m) -> {
String messageOnStdout = m.getMessage();
if (messageOnStdout != null && (messageOnStdout.contains("run as") || messageOnStdout.contains("install as"))) {
stdouts.add(messageOnStdout);
}
})) {
Runnable waitForUserService = createServiceStateChangeWaiter(kernel, "user_service", 10, State.FINISHED);
kernel.launch();
waitForUserService.run();
String expectedUsername = PlatformResolver.isWindows ? WINDOWS_TEST_UESRNAME : "nobody";
assertThat(stdouts, hasItem(Matchers.containsString("install as " + expectedUsername)));
assertThat(stdouts, hasItem(Matchers.containsString("run as " + expectedUsername)));
GreengrassService userService = kernel.locate("user_service");
// WHEN
Runnable serviceRestarts = createServiceStateChangeWaiter(kernel, "user_service", 10, State.NEW, State.FINISHED);
Runnable serviceFinishes = createServiceStateChangeWaiter(kernel, "user_service", 10, State.FINISHED);
stdouts.clear();
List<String> serviceList = kernel.getMain().getDependencies().keySet().stream().map(GreengrassService::getName).collect(Collectors.toList());
deploymentConfigMerger.mergeInNewConfig(testDeployment(), new HashMap<String, Object>() {
{
put(SERVICES_NAMESPACE_TOPIC, new HashMap<String, Object>() {
{
put("main", new HashMap<String, Object>() {
{
put(SERVICE_DEPENDENCIES_NAMESPACE_TOPIC, serviceList);
}
});
put("user_service", new HashMap<String, Object>() {
{
put(RUN_WITH_NAMESPACE_TOPIC, new HashMap<String, Object>() {
{
// set to current user running test
put("posixUser", SystemUtils.USER_NAME);
put("windowsUser", WINDOWS_TEST_UESRNAME_2);
}
});
putAll(userService.getConfig().toPOJO());
}
});
put(DEFAULT_NUCLEUS_COMPONENT_NAME, getNucleusConfig());
}
});
}
}).get(60, TimeUnit.SECONDS);
// THEN
serviceRestarts.run();
serviceFinishes.run();
// Check user
for (String s : Arrays.asList("install as %s", "run as %s")) {
assertThat(stdouts, hasItem(Matchers.containsString(String.format(s, PlatformResolver.isWindows ? WINDOWS_TEST_UESRNAME_2 : SystemUtils.USER_NAME))));
}
}
}
Aggregations