Java Code Examples for org.apache.brooklyn.core.test.entity.TestApplication#createAndManageChild()
The following examples show how to use
org.apache.brooklyn.core.test.entity.TestApplication#createAndManageChild() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: BindDnsServerIntegrationTest.java From brooklyn-library with Apache License 2.0 | 6 votes |
@Test(groups = "Integration") public void testOneARecordAndNoCnameRecordsWhenEntitiesHaveSameName() { TestApplication app = origManagementContext.getEntityManager().createEntity(EntitySpec.create(TestApplication.class)); EnricherSpec<?> dnsEnricher = Enrichers.builder().transforming(Attributes.HOSTNAME) .computing(Functions.constant("my-name")) .publishing(PrefixAndIdEnricher.SENSOR) .build(); EntitySpec<EmptySoftwareProcess> emptySoftwareProcessSpec = EntitySpec.create(EmptySoftwareProcess.class) .enricher(dnsEnricher); dns = app.createAndManageChild(EntitySpec.create(BindDnsServer.class, TestBindDnsServerImpl.class) .configure(BindDnsServer.HOSTNAME_SENSOR, PrefixAndIdEnricher.SENSOR)); // App DNS will listen to cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class) .configure(DynamicCluster.MEMBER_SPEC, emptySoftwareProcessSpec) .configure(DynamicCluster.INITIAL_SIZE, 3)); app.start(ImmutableList.of(app.newLocalhostProvisioningLocation())); assertDnsEntityEventuallyHasActiveMembers(1); // All of the entities publish the same domain name so there should be a single DNS entry and no CNAMEs. assertMapSizes(1, 1, 0, 1); }
Example 2
Source File: CloudMachineNamerTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testLengthMaxPermittedForMachineName() { TestApplication app = mgmt.getEntityManager().createEntity(EntitySpec.create(TestApplication.class).displayName("TistApp")); TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt")); ConfigBag cfg = new ConfigBag() .configure(CloudLocationConfig.CALLER_CONTEXT, child); BasicCloudMachineNamer namer = new BasicCloudMachineNamer(); // name max length is set to 9, because the constructed name will look like "br-ntsb50" // br - 2 chars // dash (-) - 1 char // timeStamp - 6 chars namer.setDefaultMachineNameMaxLength(2 + 1 + 6); String result = namer.generateNewMachineUniqueName(cfg); Assert.assertEquals(result.length(), 2 + 1 + 6); }
Example 3
Source File: CloudMachineNamerTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testLengthReservedForNameInGroup() { TestApplication app = mgmt.getEntityManager().createEntity(EntitySpec.create(TestApplication.class).displayName("TistApp")); TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt")); ConfigBag cfg = new ConfigBag() .configure(CloudLocationConfig.CALLER_CONTEXT, child); BasicCloudMachineNamer namer = new BasicCloudMachineNamer(); namer.setDefaultMachineNameMaxLength(20); namer.setDefaultMachineNameSeparatorAndSaltLength(":I", 5); String groupId = namer.generateNewGroupId(cfg); Assert.assertEquals(13, groupId.length(), "groupId="+groupId); String machineId = namer.generateNewMachineUniqueNameFromGroupId(cfg, groupId); Assert.assertEquals(20, machineId.length(), "machineId="+machineId); // separator is not sanitized -- caller should know what they are doing there! Assert.assertTrue(machineId.startsWith(groupId+"-i"), "machineId="+machineId); }
Example 4
Source File: UsageResourceTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testListAndGetMachineUsage() throws Exception { Location location = getManagementContext().getLocationManager().createLocation(LocationSpec.create(DynamicLocalhostMachineProvisioningLocation.class)); TestApplication app = getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestApplication.class)); SoftwareProcessEntityTest.MyService entity = app.createAndManageChild(org.apache.brooklyn.api.entity.EntitySpec.create(SoftwareProcessEntityTest.MyService.class)); Calendar preStart = new GregorianCalendar(); app.start(ImmutableList.of(location)); Calendar postStart = new GregorianCalendar(); Location machine = Iterables.getOnlyElement(entity.getLocations()); // All machines Response response = client().path("/usage/machines").get(); assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Iterable<UsageStatistics> usages = response.readEntity(new GenericType<List<UsageStatistics>>() {}); UsageStatistics usage = Iterables.getOnlyElement(usages); assertMachineUsage(usage, app.getId(), machine.getId(), ImmutableList.of(Status.ACCEPTED), roundDown(preStart), postStart); // Specific machine response = client().path("/usage/machines/"+machine.getId()).get(); assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); usage = response.readEntity(new GenericType<UsageStatistics>() {}); assertMachineUsage(usage, app.getId(), machine.getId(), ImmutableList.of(Status.ACCEPTED), roundDown(preStart), postStart); }
Example 5
Source File: CloudMachineNamerTest.java From brooklyn-server with Apache License 2.0 | 6 votes |
@Test public void testGenerateNewMachineName() { TestApplication app = mgmt.getEntityManager().createEntity(EntitySpec.create(TestApplication.class).displayName("TistApp")); TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt")); ConfigBag cfg = new ConfigBag() .configure(CloudLocationConfig.CALLER_CONTEXT, child); BasicCloudMachineNamer namer = new BasicCloudMachineNamer(); String result = namer.generateNewMachineUniqueName(cfg); Assert.assertTrue(result.length() <= namer.getMaxNameLength(cfg)); String user = Strings.maxlen(System.getProperty("user.name"), 4).toLowerCase(); Assert.assertTrue(result.indexOf(user) >= 0); Assert.assertTrue(result.indexOf("-tistapp-") >= 0); Assert.assertTrue(result.indexOf("-testent-") >= 0); Assert.assertTrue(result.indexOf("-"+Strings.maxlen(app.getId(), 4).toLowerCase()) >= 0); Assert.assertTrue(result.indexOf("-"+Strings.maxlen(child.getId(), 4).toLowerCase()) >= 0); }
Example 6
Source File: ItemsInContainersGroupTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
private MockContainerEntity newContainer(TestApplication app, String name, String membership) { MockContainerEntity container = app.createAndManageChild(EntitySpec.create(MockContainerEntity.class) .displayName(name) .configure(MockContainerEntity.MOCK_MEMBERSHIP, membership)); container.start(ImmutableList.of(loc)); return container; }
Example 7
Source File: AbstractLoadBalancingPolicyTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
protected static MockItemEntity newLockedItem(TestApplication app, MockContainerEntity container, String name, double workrate) { MockItemEntity item = app.createAndManageChild(EntitySpec.create(MockItemEntity.class) .displayName(name) .configure(Movable.IMMOVABLE, true)); LOG.debug("Managed new item {} on container {}", item, container); item.move(container); item.sensors().set(TEST_METRIC, (int)workrate); return item; }
Example 8
Source File: CloudMachineNamerTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
@Test public void testSanitizesNewMachineName() { TestApplication app = mgmt.getEntityManager().createEntity(EntitySpec.create(TestApplication.class).displayName("T_%$()\r\n\t[]*.!App")); TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("ent")); ConfigBag cfg = new ConfigBag() .configure(CloudLocationConfig.CALLER_CONTEXT, child); CloudMachineNamer namer = new BasicCloudMachineNamer(); String result = namer.generateNewMachineUniqueName(cfg); assertTrue(result.indexOf("t-ap") >= 0, "result="+result); for (int c : "_%$()\r\n\t[]*.!".getBytes()) { assertFalse(result.contains(new String(new char [] {(char)c})), "result="+result); } }
Example 9
Source File: ConfigKeyConstraintTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
@DataProvider(name = "brooklynObjects") public Object[][] createBrooklynObjects() throws Exception { EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class) .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution()); setUp(); TestApplication app = mgmt.getEntityManager().createEntity(appSpec); EntityRequiringConfigKeyInRange entity = app.createAndManageChild(EntitySpec.create(EntityRequiringConfigKeyInRange.class) .configure(EntityRequiringConfigKeyInRange.RANGE, 5)); Policy policy = entity.policies().add(PolicySpec.create(TestPolicy.class)); Location location = app.newSimulatedLocation(); return new Object[][]{{entity}, {policy}, {location}}; }
Example 10
Source File: AbstractFollowTheSunPolicyTest.java From brooklyn-server with Apache License 2.0 | 5 votes |
/** * Creates a new container that will take "delay" millis to complete its start-up. */ protected MockContainerEntity newAsyncContainer(TestApplication app, Location loc, String name, long delay) { // FIXME Is this comment true? // Annoyingly, can't set parent until after the threshold config has been defined. MockContainerEntity container = app.createAndManageChild(EntitySpec.create(MockContainerEntity.class) .displayName(name) .configure(MockContainerEntity.DELAY, delay)); LOG.debug("Managed new container {}", container); container.start(ImmutableList.of(loc)); return container; }
Example 11
Source File: HazelcastTestHelper.java From brooklyn-library with Apache License 2.0 | 5 votes |
public static void testHazelcastCluster(TestApplication app, Location loc) { HazelcastCluster cluster = app.createAndManageChild(EntitySpec.create(HazelcastCluster.class) .configure(HazelcastCluster.INITIAL_SIZE, 3) .configure(HazelcastCluster.MEMBER_SPEC, EntitySpec.create(HazelcastNode.class))); app.start(ImmutableList.of(loc)); EntityAsserts.assertAttributeEqualsEventually(cluster, HazelcastNode.SERVICE_UP, true); HazelcastNode first = (HazelcastNode) Iterables.get(cluster.getMembers(), 0); HazelcastNode second = (HazelcastNode) Iterables.get(cluster.getMembers(), 1); assertNodesUpAndInCluster(first, second); EntityAsserts.assertAttributeEqualsEventually(cluster, Attributes.SERVICE_UP, true); }
Example 12
Source File: JettyWebAppFixtureIntegrationTest.java From brooklyn-library with Apache License 2.0 | 5 votes |
@Override @DataProvider(name = "basicEntities") public Object[][] basicEntities() { TestApplication jettyApp = newTestApplication(); Jetty6Server jetty = jettyApp.createAndManageChild(EntitySpec.create(Jetty6Server.class) .configure(Jetty6Server.HTTP_PORT, PortRanges.fromString(DEFAULT_HTTP_PORT))); return new JavaWebAppSoftwareProcess[][] { new JavaWebAppSoftwareProcess[] {jetty} }; }
Example 13
Source File: TomcatServerWebAppFixtureIntegrationTest.java From brooklyn-library with Apache License 2.0 | 5 votes |
@Override @DataProvider(name = "basicEntities") public Object[][] basicEntities() { TestApplication tomcatApp = newTestApplication(); TomcatServer tomcat = tomcatApp.createAndManageChild(EntitySpec.create(TomcatServer.class) .configure(TomcatServer.HTTP_PORT, PortRanges.fromString(DEFAULT_HTTP_PORT))); File keystoreFile; try { keystoreFile = createTemporaryKeyStore("myname", "mypass"); keystoreFile.deleteOnExit(); } catch (Exception e) { throw Exceptions.propagate(e); } TestApplication tomcatHttpsApp = newTestApplication(); TomcatServer httpsTomcat = tomcatHttpsApp.createAndManageChild(EntitySpec.create(TomcatServer.class) .configure(TomcatServer.ENABLED_PROTOCOLS, ImmutableSet.of("https")) .configure(TomcatServer.HTTPS_SSL_CONFIG, new HttpsSslConfig().keyAlias("myname").keystorePassword("mypass").keystoreUrl(keystoreFile.getAbsolutePath()))); return new JavaWebAppSoftwareProcess[][] { new JavaWebAppSoftwareProcess[] { tomcat }, new JavaWebAppSoftwareProcess[] { httpsTomcat } }; }
Example 14
Source File: Tomcat8ServerWebAppFixtureIntegrationTest.java From brooklyn-library with Apache License 2.0 | 5 votes |
@Override @DataProvider(name = "basicEntities") public Object[][] basicEntities() { TestApplication tomcatApp = newTestApplication(); Tomcat8Server tomcat = tomcatApp.createAndManageChild(EntitySpec.create(Tomcat8Server.class) .configure(Tomcat8Server.HTTP_PORT, PortRanges.fromString(DEFAULT_HTTP_PORT))); File keystoreFile; try { keystoreFile = createTemporaryKeyStore("myname", "mypass"); keystoreFile.deleteOnExit(); } catch (Exception e) { throw Exceptions.propagate(e); } TestApplication tomcatHttpsApp = newTestApplication(); Tomcat8Server httpsTomcat = tomcatHttpsApp.createAndManageChild(EntitySpec.create(Tomcat8Server.class) .configure(Tomcat8Server.ENABLED_PROTOCOLS, ImmutableSet.of("https")) .configure(Tomcat8Server.HTTPS_SSL_CONFIG, new HttpsSslConfig().keyAlias("myname").keystorePassword("mypass").keystoreUrl(keystoreFile.getAbsolutePath()))); return new JavaWebAppSoftwareProcess[][] { new JavaWebAppSoftwareProcess[] { tomcat }, new JavaWebAppSoftwareProcess[] { httpsTomcat } }; }
Example 15
Source File: BindDnsServerIntegrationTest.java From brooklyn-library with Apache License 2.0 | 5 votes |
@Test(groups = "Integration") public void testDuplicateAAndCnameRecordsAreIgnored() { TestApplication app = origManagementContext.getEntityManager().createEntity(EntitySpec.create(TestApplication.class)); EnricherSpec<?> enricher1 = Enrichers.builder().transforming(Attributes.HOSTNAME) .computing(Functions.constant("my-name-1")) .publishing(PrefixAndIdEnricher.SENSOR) .build(); EnricherSpec<?> enricher2 = Enrichers.builder().transforming(Attributes.HOSTNAME) .computing(Functions.constant("my-name-2")) .publishing(PrefixAndIdEnricher.SENSOR) .build(); dns = app.createAndManageChild(EntitySpec.create(BindDnsServer.class, TestBindDnsServerImpl.class) .configure(BindDnsServer.HOSTNAME_SENSOR, PrefixAndIdEnricher.SENSOR)); // Expect one of my-name-{1,2} to be used as the A record the other to be used as the CNAME. // Expect all duplicate records to be ignored. app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class).enricher(enricher1)); app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class).enricher(enricher1)); app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class).enricher(enricher1)); app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class).enricher(enricher2)); app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class).enricher(enricher2)); app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class).enricher(enricher2)); app.start(ImmutableList.of(app.newLocalhostProvisioningLocation())); assertDnsEntityEventuallyHasActiveMembers(2); assertMapSizes(2, 1, 1, 1); }
Example 16
Source File: BindDnsServerIntegrationTest.java From brooklyn-library with Apache License 2.0 | 5 votes |
@Override protected TestApplication createApp() { TestApplication app = origManagementContext.getEntityManager().createEntity(EntitySpec.create(TestApplication.class)); dns = app.createAndManageChild(EntitySpec.create(BindDnsServer.class, TestBindDnsServerImpl.class) .configure(BindDnsServer.ENTITY_FILTER, Predicates.instanceOf(EmptySoftwareProcess.class)) .configure(BindDnsServer.HOSTNAME_SENSOR, PrefixAndIdEnricher.SENSOR)); EntitySpec<EmptySoftwareProcess> memberSpec = EntitySpec.create(EmptySoftwareProcess.class) .enricher(EnricherSpec.create(PrefixAndIdEnricher.class) .configure(PrefixAndIdEnricher.PREFIX, "dns-integration-test-") .configure(PrefixAndIdEnricher.MONITOR, Attributes.HOSTNAME)); cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class) .configure(DynamicCluster.MEMBER_SPEC, memberSpec) .configure(DynamicCluster.INITIAL_SIZE, 3)); return app; }
Example 17
Source File: BindDnsServerLiveTest.java From brooklyn-library with Apache License 2.0 | 5 votes |
public static void testBindStartsAndUpdates(TestApplication app, Location testLocation) throws Exception { DynamicCluster cluster; BindDnsServer dns; SameServerEntity sse = app.createAndManageChild(EntitySpec.create(SameServerEntity.class)); EntitySpec<EmptySoftwareProcess> memberSpec = EntitySpec.create(EmptySoftwareProcess.class) .enricher(EnricherSpec.create(PrefixAndIdEnricher.class) .configure(PrefixAndIdEnricher.PREFIX, "dns-live-test-") .configure(PrefixAndIdEnricher.MONITOR, Attributes.HOSTNAME)); cluster = sse.addChild(EntitySpec.create(DynamicCluster.class) .configure(DynamicCluster.MEMBER_SPEC, memberSpec) .configure(DynamicCluster.INITIAL_SIZE, 1)); dns = sse.addChild((EntitySpec.create(BindDnsServer.class) .configure(BindDnsServer.ENTITY_FILTER, Predicates.instanceOf(EmptySoftwareProcess.class)) .configure(BindDnsServer.HOSTNAME_SENSOR, PrefixAndIdEnricher.SENSOR))); app.start(ImmutableList.of(testLocation)); EntityAsserts.assertAttributeEqualsEventually(dns, Attributes.SERVICE_UP, true); logDnsMappings(dns); assertEquals(dns.getAttribute(BindDnsServer.ADDRESS_MAPPINGS).entries().size(), 1); assertEquals(dns.getAttribute(BindDnsServer.A_RECORDS).size(), 1); assertEquals(dns.getAttribute(BindDnsServer.CNAME_RECORDS).size(), 0); // Harder to make assertions on PTR because the entity servers might not be in the right CIDR cluster.resize(2); waitForNumberOfAddressMappings(dns, 2); logDnsMappings(dns); assertEquals(dns.getAttribute(BindDnsServer.ADDRESS_MAPPINGS).entries().size(), 2); assertEquals(dns.getAttribute(BindDnsServer.A_RECORDS).size(), 1); assertEquals(dns.getAttribute(BindDnsServer.CNAME_RECORDS).size(), 1); cluster.resize(1); waitForNumberOfAddressMappings(dns, 1); logDnsMappings(dns); assertEquals(dns.getAttribute(BindDnsServer.ADDRESS_MAPPINGS).entries().size(), 1); assertEquals(dns.getAttribute(BindDnsServer.A_RECORDS).size(), 1); assertEquals(dns.getAttribute(BindDnsServer.CNAME_RECORDS).size(), 0); }
Example 18
Source File: MySqlClusterTestHelper.java From brooklyn-library with Apache License 2.0 | 4 votes |
public static MySqlCluster initCluster(TestApplication app, Location location, EntitySpec<MySqlCluster> spec) { MySqlCluster mysql = app.createAndManageChild(spec); app.start(ImmutableList.of(location)); log.info("MySQL started"); return mysql; }
Example 19
Source File: ServerShutdownTest.java From brooklyn-server with Apache License 2.0 | 4 votes |
@Test public void testStopAppThenShutdownAndStopAppsWaitsForFirstStop() throws InterruptedException { ReflectiveEntityDriverFactory f = ((BasicEntityDriverManager)getManagementContext().getEntityDriverManager()).getReflectiveDriverFactory(); f.addClassFullNameMapping("org.apache.brooklyn.entity.software.base.EmptySoftwareProcessDriver", "org.apache.brooklyn.rest.resources.ServerResourceTest$EmptySoftwareProcessTestDriver"); // Second stop on SoftwareProcess could return early, while the first stop is still in progress // This causes the app to shutdown prematurely, leaking machines. EntityManager emgr = getManagementContext().getEntityManager(); EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class); TestApplication app = emgr.createEntity(appSpec); EntitySpec<StopLatchEntity> latchEntitySpec = EntitySpec.create(StopLatchEntity.class); final StopLatchEntity entity = app.createAndManageChild(latchEntitySpec); app.start(ImmutableSet.of(app.newLocalhostProvisioningLocation())); EntityAsserts.assertAttributeEquals(entity, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING); try { final Task<Void> firstStop = app.invoke(Startable.STOP, ImmutableMap.<String, Object>of()); Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertTrue(entity.isBlocked()); } }); final AtomicReference<Exception> shutdownError = new AtomicReference<>(); // Can't use ExecutionContext as it will be stopped on shutdown Thread shutdownThread = new Thread() { @Override public void run() { try { MultivaluedMap<String, String> formData = new MultivaluedHashMap<>(); formData.add("stopAppsFirst", "true"); formData.add("shutdownTimeout", "0"); formData.add("requestTimeout", "0"); formData.add("delayForHttpReturn", "0"); client().path("/server/shutdown").type(MediaType.APPLICATION_FORM_URLENCODED).post(formData); } catch (Exception e) { log.error("Shutdown request error", e); shutdownError.set(e); throw Exceptions.propagate(e); } } }; shutdownThread.start(); //shutdown must wait until the first stop completes (or time out) Asserts.succeedsContinually(new Runnable() { @Override public void run() { assertFalse(firstStop.isDone()); assertEquals(getManagementContext().getApplications().size(), 1); assertFalse(shutdownListener.isRequested()); } }); // NOTE test is not fully deterministic. Depending on thread scheduling this will // execute before or after ServerResource.shutdown does the app stop loop. This // means that the shutdown code might not see the app at all. In any case though // the test must succeed. entity.unblock(); Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertTrue(firstStop.isDone()); assertTrue(shutdownListener.isRequested()); assertFalse(getManagementContext().isRunning()); } }); shutdownThread.join(); assertNull(shutdownError.get(), "Shutdown request error, logged above"); } finally { // Be sure we always unblock entity stop even in the case of an exception. // In the success path the entity is already unblocked above. entity.unblock(); } }
Example 20
Source File: SoftwareProcessEntityTest.java From brooklyn-server with Apache License 2.0 | 4 votes |
@Test public void testDoubleStopApp() { ReflectiveEntityDriverFactory f = ((BasicEntityDriverManager)mgmt.getEntityDriverManager()).getReflectiveDriverFactory(); f.addClassFullNameMapping(EmptySoftwareProcessDriver.class.getName(), MinimalEmptySoftwareProcessTestDriver.class.getName()); // Second stop on SoftwareProcess will return early, while the first stop is still in progress // This causes the app to shutdown prematurely, leaking machines. EntityManager emgr = mgmt.getEntityManager(); EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class); final TestApplication app = emgr.createEntity(appSpec); emgr.manage(app); EntitySpec<?> latchEntitySpec = EntitySpec.create(EmptySoftwareProcess.class); final Entity entity = app.createAndManageChild(latchEntitySpec); final ReleaseLatchLocation loc = mgmt.getLocationManager().createLocation(LocationSpec.create(ReleaseLatchLocation.class)); try { app.start(ImmutableSet.of(loc)); EntityAsserts.assertAttributeEquals(entity, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING); final Task<Void> firstStop = app.invoke(Startable.STOP, ImmutableMap.<String, Object>of()); // Wait until first task tries to release the location, at this point the entity's reference // to the location is already cleared. Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertTrue(loc.isBlocked()); } }); // Subsequent stops will end quickly - no location to release, // while the first one is still releasing the machine. final Task<Void> secondStop = app.invoke(Startable.STOP, ImmutableMap.<String, Object>of());; Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertTrue(secondStop.isDone()); } }); // Since second stop succeeded the app will get unmanaged. Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertTrue(!Entities.isManaged(entity)); assertTrue(!Entities.isManaged(app)); } }); // Unmanage will cancel the first task Asserts.succeedsEventually(new Runnable() { @Override public void run() { assertTrue(firstStop.isDone()); } }); } finally { // We still haven't unblocked the location release, but entity is already unmanaged. // Double STOP on an application could leak locations!!! loc.unblock(); } }