From f9cb0b2447b02d93fe2b39496320cb1c920be3ff Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 15:06:19 +0100 Subject: [PATCH 1/9] repeater now respects its timeout more tightly --- .../main/java/org/apache/brooklyn/util/repeat/Repeater.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/repeat/Repeater.java b/utils/common/src/main/java/org/apache/brooklyn/util/repeat/Repeater.java index b08050b19c..a04f58c8a8 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/util/repeat/Repeater.java +++ b/utils/common/src/main/java/org/apache/brooklyn/util/repeat/Repeater.java @@ -90,7 +90,7 @@ public class Repeater implements Callable { private Predicate rethrowImmediatelyCondition = Exceptions.isFatalPredicate(); private boolean warnOnUnRethrownException = true; private boolean shutdown = false; - private ExecutorService executor = MoreExecutors.sameThreadExecutor(); + private ExecutorService executor = MoreExecutors.newDirectExecutorService(); public Repeater() { this(null); @@ -367,6 +367,9 @@ public ReferenceWithError runKeepingError() { try { while (true) { Duration delayThisIteration = delayOnIteration.apply(iterations); + if (timer.isNotPaused() && delayThisIteration.isLongerThan(timer.getDurationRemaining())) { + delayThisIteration = timer.getDurationRemaining(); + } iterations++; Future call = executor.submit(body); From 20f4908c94a46c19a85cbbea0891b652cbfc99dc Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 15:06:47 +0100 Subject: [PATCH 2/9] lower big timeouts in DefaultConnectivityResolverTest --- .../DefaultConnectivityResolverTest.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java index 33a019ae75..8b1bc5bad1 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java @@ -68,7 +68,7 @@ public void testObtainsHostnameFromAwsMachine() throws Exception { JcloudsLocationConfig.LOOKUP_AWS_HOSTNAME, true)); ConnectivityResolverOptions options = newResolveOptions() .waitForConnectable(true) - .pollForReachableAddresses(Predicates.alwaysTrue(), Duration.ONE_SECOND, true) + .pollForReachableAddresses(Predicates.alwaysTrue(), Duration.millis(1), true) .userCredentials(credential) .build(); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); @@ -92,7 +92,7 @@ public RecordingSshTool.CustomResponse generate(RecordingSshTool.ExecParams exec initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of()); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); final ConfigBag config = ConfigBag.newInstance(ImmutableMap.of( - JcloudsLocationConfig.WAIT_FOR_SSHABLE, "1ms")); + JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms")); assertTrue(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), LoginCredentials.builder().user(allowedUser).password("password1").build(), config, false)); @@ -114,7 +114,7 @@ public RecordingWinRmTool.CustomResponse generate(RecordingWinRmTool.ExecParams initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of()); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); final ConfigBag config = ConfigBag.newInstance(ImmutableMap.of( - JcloudsLocationConfig.WAIT_FOR_WINRM_AVAILABLE, "1ms")); + JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms")); assertTrue(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), LoginCredentials.builder().user(allowedUser).password("password1").build(), config, true)); @@ -146,11 +146,9 @@ public RecordingSshTool.CustomResponse generate(RecordingSshTool.ExecParams exec }); ConfigBag config = ConfigBag.newInstance(ImmutableMap.of( JcloudsLocationConfig.LOOKUP_AWS_HOSTNAME, false, - JcloudsLocationConfig.WAIT_FOR_SSHABLE, "1ms", + JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms", JcloudsLocation.CUSTOM_CREDENTIALS, credential)); - ConnectivityResolverOptions options = newResolveOptions() - .pollForReachableAddresses(Predicates.in(reachableIps), Duration.ONE_SECOND, true) - .build(); + ConnectivityResolverOptions options = newResolveOptionsForIps(reachableIps).build(); // Chooses authorisedHostAndPort when credentials are tested. DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(ImmutableMap.of( @@ -192,9 +190,7 @@ public void testMode(NetworkMode mode, Set reachableIps, String exp initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of( JcloudsLocationConfig.CONNECTIVITY_RESOLVER, customizer)); - ConnectivityResolverOptions options = newResolveOptions() - .pollForReachableAddresses(Predicates.in(reachableIps), Duration.ONE_SECOND, true) - .build(); + ConnectivityResolverOptions options = newResolveOptionsForIps(reachableIps).build(); ConfigBag configBag = ConfigBag.newInstance(); ManagementAddressResolveResult result = customizer.resolve(jcloudsLocation, newNodeMetadata(), configBag, options); @@ -223,9 +219,7 @@ public void testModeUnavailable(NetworkMode mode, Set reachableIps) initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of( JcloudsLocationConfig.CONNECTIVITY_RESOLVER, customizer)); - ConnectivityResolverOptions options = newResolveOptions() - .pollForReachableAddresses(Predicates.in(reachableIps), Duration.ONE_SECOND, true) - .build(); + ConnectivityResolverOptions options = newResolveOptionsForIps(reachableIps).build(); ConfigBag configBag = ConfigBag.newInstance(); customizer.resolve(jcloudsLocation, newNodeMetadata(), configBag, options); } @@ -234,6 +228,11 @@ private ConnectivityResolverOptions.Builder newResolveOptions() { return ConnectivityResolverOptions.builder() .initialCredentials(credential); } + + private ConnectivityResolverOptions.Builder newResolveOptionsForIps(Set reachableIps) { + return newResolveOptions(). + pollForReachableAddresses(Predicates.in(reachableIps), Duration.millis(1), true); + } private NodeMetadata newNodeMetadata() { return new NodeMetadataBuilder() From bf69b0c0b8d0ce482592f41de6582fdbccf2c01f Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 15:07:20 +0100 Subject: [PATCH 3/9] don't wait on generic incomplete Future items when evaluating immediately --- .../org/apache/brooklyn/util/core/task/ValueResolver.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java index ffaa817457..afd6109adf 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java @@ -443,6 +443,10 @@ protected Maybe getMaybeInternal() { //including tasks, above if (!vfuture.isDone()) { + if (isEvaluatingImmediately()) { + return ImmediateSupplier.ImmediateValueNotAvailableException.newAbsentWithExceptionSupplier(); + } + Callable callable = new Callable() { @Override public Maybe call() throws Exception { From bd461adb4e0ebf882cbbedd55f4c6a7b6b54ebca Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 16:08:13 +0100 Subject: [PATCH 4/9] backoff more slowly when checking assertions, cause tests to run a bit quicker --- .../src/main/java/org/apache/brooklyn/test/Asserts.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java index 443d42b919..b5cdcbc499 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java +++ b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java @@ -993,7 +993,10 @@ public static T succeedsEventually(Map flags, Callable c) { } long sleepTime = Math.min(sleepTimeBetweenAttempts, expireTime-System.currentTimeMillis()); if (sleepTime > 0) Thread.sleep(sleepTime); - sleepTimeBetweenAttempts = Math.min(sleepTimeBetweenAttempts*2, maxPeriod.toMilliseconds()); + sleepTimeBetweenAttempts = Math.min( + // grow by 1.5x; doubling causes longer extra waits than we like in tests + sleepTimeBetweenAttempts + Math.max(1, sleepTimeBetweenAttempts/2), + maxPeriod.toMilliseconds()); } log.info("succeedsEventually exceeded max attempts or timeout - {} attempts lasting {} ms, for {}", new Object[] {attempt, System.currentTimeMillis()-startTime, c}); From 661d92f5692b62e9130ed0f3d79fc6c5597f214d Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 16:10:02 +0100 Subject: [PATCH 5/9] use iteration limit to make several tests run quicker (not wait 1s) --- .../java/org/apache/brooklyn/test/framework/BaseTest.java | 6 ++++++ .../org/apache/brooklyn/test/framework/TestSensorImpl.java | 2 +- .../brooklyn/test/framework/TestWinrmCommandImpl.java | 1 + .../brooklyn/test/framework/TestWinrmCommandTest.java | 6 ++++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java b/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java index 2ae552dce3..5689b6c981 100644 --- a/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java +++ b/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java @@ -44,6 +44,12 @@ public interface BaseTest extends TargetableTestComponent, Startable { ConfigKey TIMEOUT = ConfigKeys.newConfigKey(Duration.class, "timeout", "Time to wait on result", Duration.seconds(1)); + /** + * The max number of iterations to run before throwing an exception. + */ + ConfigKey ITERATION_LIMIT = ConfigKeys.newConfigKey(Integer.class, "iterations", "Max iterations to try to get result", + Integer.MAX_VALUE); + /** * Max time between checking the assertion (exponential backoff to this limit). */ diff --git a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java index 6dae5ea999..9cf5b213a7 100644 --- a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java +++ b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java @@ -77,7 +77,7 @@ public Object get() { } }; TestFrameworkAssertions.checkAssertionsEventually(new AssertionOptions(sensor.get(), supplier) - .timeout(timeout).backoffToPeriod(backoffToPeriod) + .maxAttempts(getConfig(ITERATION_LIMIT)).timeout(timeout).backoffToPeriod(backoffToPeriod) .assertions(assertions).abortConditions(abortConditions)); setUpAndRunState(true, Lifecycle.RUNNING); diff --git a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestWinrmCommandImpl.java b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestWinrmCommandImpl.java index 3dc2545a93..f0d5b8b49c 100644 --- a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestWinrmCommandImpl.java +++ b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestWinrmCommandImpl.java @@ -107,6 +107,7 @@ public void execute() { // See identical comment in `TestSshCommandImpl`. ReferenceWithError result = Repeater.create("Running winrm-command tests") .limitTimeTo(timeout) + .limitIterationsTo(getRequiredConfig(ITERATION_LIMIT)) .backoffTo((backoffToPeriod != null) ? backoffToPeriod : Duration.millis(500)) .until(new Callable() { @Override diff --git a/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestWinrmCommandTest.java b/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestWinrmCommandTest.java index ff387e55f0..e5a2c52829 100644 --- a/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestWinrmCommandTest.java +++ b/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestWinrmCommandTest.java @@ -37,6 +37,7 @@ import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.LocationSpec; +import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.entity.TestEntity; import org.apache.brooklyn.location.winrm.WinRmMachineLocation; @@ -141,6 +142,7 @@ public void shouldFailUsingSuccessfulExitAsDefaultCondition() { RecordingWinRmTool.setCustomResponse(cmd, new RecordingWinRmTool.CustomResponse(1, null, null)); TestWinrmCommand test = app.createAndManageChild(EntitySpec.create(TestWinrmCommand.class) + .configure(TestWinrmCommand.ITERATION_LIMIT, 1) .configure(TARGET_ENTITY, testEntity) .configure(COMMAND, cmd)); @@ -177,6 +179,7 @@ public void shouldFailOnUnmatchedStdout() { RecordingWinRmTool.setCustomResponse(cmd, new RecordingWinRmTool.CustomResponse(0, "wrongstdout", null)); TestWinrmCommand test = app.createAndManageChild(EntitySpec.create(TestWinrmCommand.class) + .configure(TestWinrmCommand.ITERATION_LIMIT, 1) .configure(TARGET_ENTITY, testEntity) .configure(COMMAND, cmd) .configure(ASSERT_OUT, makeAssertions(ImmutableMap.of(CONTAINS, "mystdout")))); @@ -197,6 +200,7 @@ public void shouldFailOnUnmatchedStderr() { RecordingWinRmTool.setCustomResponse(cmd, new RecordingWinRmTool.CustomResponse(0, null, "wrongstderr")); TestWinrmCommand test = app.createAndManageChild(EntitySpec.create(TestWinrmCommand.class) + .configure(TestWinrmCommand.ITERATION_LIMIT, 1) .configure(TARGET_ENTITY, testEntity) .configure(COMMAND, cmd) .configure(ASSERT_ERR, makeAssertions(ImmutableMap.of(CONTAINS, "mystderr")))); @@ -218,6 +222,7 @@ public void shouldNotBeUpIfAssertionsFail() { Map equals255 = ImmutableMap.of(EQUALS, 255); TestWinrmCommand test = app.createAndManageChild(EntitySpec.create(TestWinrmCommand.class) + .configure(TestWinrmCommand.ITERATION_LIMIT, 1) .configure(TARGET_ENTITY, testEntity) .configure(COMMAND, "uptime") .configure(ASSERT_STATUS, makeAssertions(equalsOne, equals255))); @@ -226,6 +231,7 @@ public void shouldNotBeUpIfAssertionsFail() { app.start(ImmutableList.of()); Asserts.shouldHaveFailedPreviously(); } catch (Exception e) { + Entities.dumpInfo(app); Asserts.expectedFailureContains(e, "exit code expected equals 1 but found 0", "exit code expected equals 255 but found 0"); } From e1778fc8f506af52f0512b83214c4bac26773991 Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 16:10:44 +0100 Subject: [PATCH 6/9] don't wait synchronously for service_up on an application if we know there is an error --- .../brooklyn/core/entity/AbstractApplication.java | 6 ++++-- .../core/entity/lifecycle/ServiceStateLogic.java | 12 +++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java index 86007cd540..3cbee660b9 100644 --- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java +++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractApplication.java @@ -181,14 +181,16 @@ public void start(Collection locations) { } catch (Exception e) { recordApplicationEvent(Lifecycle.ON_FIRE); + ServiceStateLogic.setExpectedStateRunningWithErrors(this); + // no need to log here; the effector invocation should do that throw Exceptions.propagate(e); } finally { ServiceStateLogic.ServiceNotUpLogic.clearNotUpIndicator(this, Attributes.SERVICE_STATE_ACTUAL); - ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING); } - + + ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING); setExpectedStateAndRecordLifecycleEvent(Lifecycle.RUNNING); logApplicationLifecycle("Started"); diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java b/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java index 386eb56be0..bfde0735d3 100644 --- a/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java +++ b/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java @@ -156,7 +156,17 @@ public static void updateMapSensorEntry(Entity entity, AttributeSens } public static void setExpectedState(Entity entity, Lifecycle state) { - waitBrieflyForServiceUpIfStateIsRunning(entity, state); + setExpectedState(entity, state, entity.getAttribute(SERVICE_STATE_ACTUAL)!=null && entity.getAttribute(SERVICE_STATE_ACTUAL)!=Lifecycle.ON_FIRE); + } + + public static void setExpectedStateRunningWithErrors(Entity entity) { + setExpectedState(entity, Lifecycle.RUNNING, false); + } + + private static void setExpectedState(Entity entity, Lifecycle state, boolean waitBrieflyForServiceUpIfRunning) { + if (waitBrieflyForServiceUpIfRunning) { + waitBrieflyForServiceUpIfStateIsRunning(entity, state); + } ((EntityInternal)entity).sensors().set(Attributes.SERVICE_STATE_EXPECTED, new Lifecycle.Transition(state, new Date())); Maybe enricher = EntityAdjuncts.tryFindWithUniqueTag(entity.enrichers(), ComputeServiceState.DEFAULT_ENRICHER_UNIQUE_TAG); From ce061afc6cd30cbc53598895fcdddd7e11e18e2f Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 17:38:21 +0100 Subject: [PATCH 7/9] undo and document buggy deprecation of WAIT_FOR_SSHABLE --- .../core/location/cloud/CloudLocationConfig.java | 14 ++++++++++---- .../jclouds/DefaultConnectivityResolverTest.java | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/apache/brooklyn/core/location/cloud/CloudLocationConfig.java b/core/src/main/java/org/apache/brooklyn/core/location/cloud/CloudLocationConfig.java index d5051eaf63..43aa7af5c4 100644 --- a/core/src/main/java/org/apache/brooklyn/core/location/cloud/CloudLocationConfig.java +++ b/core/src/main/java/org/apache/brooklyn/core/location/cloud/CloudLocationConfig.java @@ -102,14 +102,20 @@ public interface CloudLocationConfig { "Other keys prefixed with pollForFirstReachableAddress.predicate. will be passed to the Map constructor of the Predicate implementation.", Networking.IsReachablePredicate.class); - /** @deprecated since 0.11.0 use {@link #POLL_FOR_FIRST_REACHABLE_ADDRESS} instead. */ - @Deprecated + // FIXME we would like to deprecate this but POLL_FOR_FIRST_REACHABLE_ADDRESS does not have the same behaviour; + // just look at the usages of the two fields to see different treatment of the first as opposed to the second; + // implementations should probably use ConfigBag.getDeprecatedKey(...) to support both for a transition period. + // in addition, remove the settings of this key in DefaultConnectivityResolverTest and observe tests timeout forever + // (see the commit where this comment is introduced to fix tests in that class which attempted to migrate) + // /** @deprecated since 0.11.0 use {@link #POLL_FOR_FIRST_REACHABLE_ADDRESS} instead. */ + // @Deprecated ConfigKey WAIT_FOR_SSHABLE = ConfigKeys.newStringConfigKey("waitForSshable", "Whether and how long to wait for a newly provisioned VM to be accessible via ssh; " + "if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '5m' (the default) or a number of milliseconds", "5m"); - /** @deprecated since 0.11.0 use {@link #POLL_FOR_FIRST_REACHABLE_ADDRESS} instead. */ - @Deprecated + // FIXME as WAIT_FOR_SSHABLE above + // /** @deprecated since 0.11.0 use {@link #POLL_FOR_FIRST_REACHABLE_ADDRESS} instead. */ + // @Deprecated ConfigKey WAIT_FOR_WINRM_AVAILABLE = ConfigKeys.newStringConfigKey("waitForWinRmAvailable", "Whether and how long to wait for a newly provisioned VM to be accessible via WinRm; " + "if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '30m' (the default) or a number of milliseconds", "30m"); diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java index 8b1bc5bad1..6088c54e76 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolverTest.java @@ -92,6 +92,7 @@ public RecordingSshTool.CustomResponse generate(RecordingSshTool.ExecParams exec initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of()); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); final ConfigBag config = ConfigBag.newInstance(ImmutableMap.of( + JcloudsLocationConfig.WAIT_FOR_SSHABLE, "1ms", JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms")); assertTrue(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), @@ -114,6 +115,7 @@ public RecordingWinRmTool.CustomResponse generate(RecordingWinRmTool.ExecParams initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of()); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); final ConfigBag config = ConfigBag.newInstance(ImmutableMap.of( + JcloudsLocationConfig.WAIT_FOR_WINRM_AVAILABLE, "1ms", JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms")); assertTrue(customizer.checkCredential( jcloudsLocation, HostAndPort.fromParts("10.0.0.234", 22), @@ -146,6 +148,7 @@ public RecordingSshTool.CustomResponse generate(RecordingSshTool.ExecParams exec }); ConfigBag config = ConfigBag.newInstance(ImmutableMap.of( JcloudsLocationConfig.LOOKUP_AWS_HOSTNAME, false, + JcloudsLocationConfig.WAIT_FOR_SSHABLE, "1ms", JcloudsLocationConfig.POLL_FOR_FIRST_REACHABLE_ADDRESS, "1ms", JcloudsLocation.CUSTOM_CREDENTIALS, credential)); ConnectivityResolverOptions options = newResolveOptionsForIps(reachableIps).build(); From cca032fc09135de8bd57791b67dd6de10fa6b82a Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 20:41:17 +0100 Subject: [PATCH 8/9] remove some "continually" assertions not in integration tests a simple assertion is probably sufficient; if continual assertion is really required a new integration test variant should be added --- .../network/OnPublicNetworkEnricherTest.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/core/src/test/java/org/apache/brooklyn/core/network/OnPublicNetworkEnricherTest.java b/core/src/test/java/org/apache/brooklyn/core/network/OnPublicNetworkEnricherTest.java index 0bf40c7eef..533ea34847 100644 --- a/core/src/test/java/org/apache/brooklyn/core/network/OnPublicNetworkEnricherTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/network/OnPublicNetworkEnricherTest.java @@ -38,7 +38,6 @@ import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.entity.TestEntity; import org.apache.brooklyn.location.ssh.SshMachineLocation; -import org.apache.brooklyn.test.Asserts; import org.apache.brooklyn.util.time.Duration; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; @@ -159,7 +158,7 @@ public void testIgnoresWhenInvalidAttribute(AttributeSensor sensor, T sen entity.enrichers().add(EnricherSpec.create(OnPublicNetworkEnricher.class) .configure(OnPublicNetworkEnricher.SENSORS, ImmutableList.of(sensor))); - EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", VERY_SHORT_WAIT), entity, Sensors.newStringSensor(sensor.getName()+".mapped.public"), null); + EntityAsserts.assertAttributeEquals(entity, Sensors.newStringSensor(sensor.getName()+".mapped.public"), null); } @Test @@ -199,7 +198,7 @@ public void testIgnoresWhenNoMapping() throws Exception { entity.enrichers().add(EnricherSpec.create(OnPublicNetworkEnricher.class) .configure(OnPublicNetworkEnricher.SENSORS, ImmutableList.of(Attributes.HTTP_PORT))); - EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", VERY_SHORT_WAIT), entity, Sensors.newStringSensor(Attributes.HTTP_PORT.getName()+".mapped.public"), null); + EntityAsserts.assertAttributeEquals(entity, Sensors.newStringSensor(Attributes.HTTP_PORT.getName()+".mapped.public"), null); } @Test @@ -212,7 +211,7 @@ public void testIgnoresWhenNoMachine() throws Exception { entity.enrichers().add(EnricherSpec.create(OnPublicNetworkEnricher.class) .configure(OnPublicNetworkEnricher.SENSORS, ImmutableList.of(Attributes.HTTP_PORT))); - EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", VERY_SHORT_WAIT), entity, Sensors.newStringSensor(Attributes.HTTP_PORT.getName()+".mapped.public"), null); + EntityAsserts.assertAttributeEquals(entity, Sensors.newStringSensor(Attributes.HTTP_PORT.getName()+".mapped.public"), null); } @Test @@ -225,7 +224,7 @@ public void testIgnoresWithNoPort() throws Exception { entity.enrichers().add(EnricherSpec.create(OnPublicNetworkEnricher.class) .configure(OnPublicNetworkEnricher.SENSORS, ImmutableList.of(TestEntity.NAME))); - EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", VERY_SHORT_WAIT), entity, Sensors.newStringSensor(TestEntity.NAME.getName()+".mapped.public"), null); + EntityAsserts.assertAttributeEquals(entity, Sensors.newStringSensor(TestEntity.NAME.getName()+".mapped.public"), null); } @Test @@ -291,15 +290,12 @@ public void testIgnoresNonMatchingSensors() throws Exception { entity.enrichers().add(EnricherSpec.create(OnPublicNetworkEnricher.class)); - Asserts.succeedsContinually(ImmutableMap.of("timeout", VERY_SHORT_WAIT), new Runnable() { - @Override public void run() { - Map, Object> allSensors = entity.sensors().getAll(); - String errMsg = "sensors="+allSensors; - for (AttributeSensor sensor : allSensors.keySet()) { - String name = sensor.getName(); - assertFalse(name.startsWith("my.different") && sensor.getName().contains("public"), errMsg); - } - }}); + Map, Object> allSensors = entity.sensors().getAll(); + String errMsg = "sensors="+allSensors; + for (AttributeSensor sensor : allSensors.keySet()) { + String name = sensor.getName(); + assertFalse(name.startsWith("my.different") && sensor.getName().contains("public"), errMsg); + } } @Test @@ -446,7 +442,10 @@ protected void assertAttributeEqualsEventually(String sensorName, String expecte protected void assertAttributeEqualsContinually(String sensorName, String expectedVal, Duration duration) throws Exception { try { - EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", duration), entity, Sensors.newStringSensor(sensorName), expectedVal); + // EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", duration), entity, Sensors.newStringSensor(sensorName), expectedVal); + // TODO "continually" not actually asserted here because these aren't integration tests; + // ideally would have two variants of such tests + EntityAsserts.assertAttributeEquals(entity, Sensors.newStringSensor(sensorName), expectedVal); } catch (Exception e) { throw new Exception("Failed assertion for sensor '"+sensorName+"'; attributes are "+entity.sensors().getAll(), e); } From db882bbc9581becfedb718054a5f0976db5e1d24 Mon Sep 17 00:00:00 2001 From: Alex Heneveld Date: Tue, 25 Apr 2017 16:08:49 +0100 Subject: [PATCH 9/9] misc test speed-ups --- .../ReloadBrooklynPropertiesTest.java | 5 ++- .../entity/group/DynamicClusterImpl.java | 9 +++-- .../entity/AbstractApplicationLegacyTest.java | 2 +- .../core/entity/trait/FailingEntityImpl.java | 4 +- .../internal/LocalManagementContextTest.java | 26 ++++++++++++- .../core/mgmt/rebind/RebindLocationTest.java | 1 - .../entity/group/DynamicClusterTest.java | 14 +------ .../LoopOverGroupMembersTestCaseTest.java | 37 ++++++------------- .../util/stream/StreamGobblerTest.java | 3 ++ 9 files changed, 53 insertions(+), 48 deletions(-) diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java index 929ab89d27..2bdc319e07 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java @@ -28,6 +28,7 @@ import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.EntityAsserts; import org.apache.brooklyn.core.entity.trait.Startable; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; import org.apache.brooklyn.util.core.ResourceUtils; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.stream.Streams; @@ -46,7 +47,9 @@ public class ReloadBrooklynPropertiesTest { @BeforeMethod(alwaysRun=true) public void setup() { - brooklynMgmt = new BrooklynCampPlatformLauncherNoServer().launch().getBrooklynMgmt(); + brooklynMgmt = new BrooklynCampPlatformLauncherNoServer(). + useManagementContext(LocalManagementContextForTests.newInstance()). + launch().getBrooklynMgmt(); } @AfterMethod(alwaysRun=true) diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java index a207ec6b37..03eec38db2 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java +++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java @@ -408,12 +408,13 @@ public void start(Collection locsO) { try { doStart(); DynamicTasks.waitForLast(); + ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING); } catch (Exception e) { ServiceProblemsLogic.updateProblemsIndicator(this, START, "start failed with error: "+e); + ServiceStateLogic.setExpectedStateRunningWithErrors(this); + throw Exceptions.propagate(e); - } finally { - ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING); } } @@ -956,8 +957,8 @@ public Entity addNode(@Nullable Location loc, Map extraFlags) { .putAll(extraFlags) .put(CLUSTER_MEMBER_ID, sensors().get(NEXT_CLUSTER_MEMBER_ID).get()) .build(); - if (LOG.isDebugEnabled()) { - LOG.debug("Creating and adding a node to cluster {}({}) with properties {}", new Object[] { this, getId(), Sanitizer.sanitize(createFlags) }); + if (LOG.isTraceEnabled()) { + LOG.trace("Creating and adding a node to cluster {}({}) with properties {}", new Object[] { this, getId(), Sanitizer.sanitize(createFlags) }); } // TODO should refactor to have a createNodeSpec; and spec should support initial sensor values diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/AbstractApplicationLegacyTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/AbstractApplicationLegacyTest.java index 68ac612118..1ae56cf616 100644 --- a/core/src/test/java/org/apache/brooklyn/core/entity/AbstractApplicationLegacyTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/entity/AbstractApplicationLegacyTest.java @@ -81,7 +81,7 @@ public void tearDown() throws Exception { // App and its children will be implicitly managed on first effector call on app. // Will cause the implicit creation of a new management context! - @Test + @Test(groups="Integration") // Implicit creation is deprecaed and can be removed, plus the test is slow public void testStartAndStopUnmanagedAppAutomanagesTheAppAndChildren() throws Exception { // deliberately unmanaged TestApplication app2 = new TestApplicationImpl(); diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/trait/FailingEntityImpl.java b/core/src/test/java/org/apache/brooklyn/core/entity/trait/FailingEntityImpl.java index bc7f48387d..a5b5efc83e 100644 --- a/core/src/test/java/org/apache/brooklyn/core/entity/trait/FailingEntityImpl.java +++ b/core/src/test/java/org/apache/brooklyn/core/entity/trait/FailingEntityImpl.java @@ -42,7 +42,7 @@ public void start(Collection locs) { if (Boolean.TRUE.equals(getConfig(SET_SERVICE_DOWN_ON_FAILURE))) { ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING); sensors().set(SERVICE_UP, false); - ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING); + ServiceStateLogic.setExpectedStateRunningWithErrors(this); } callHistory.add("start"); @@ -78,7 +78,7 @@ public void restart() { sensors().set(SERVICE_UP, false); ServiceStateLogic.setExpectedState(this, Lifecycle.STOPPED); ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING); - ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING); + ServiceStateLogic.setExpectedStateRunningWithErrors(this); } callHistory.add("restart"); diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextTest.java index 60677779ad..b77e68596b 100644 --- a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContextTest.java @@ -23,6 +23,7 @@ import java.io.File; import java.io.IOException; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.apache.brooklyn.api.location.Location; @@ -31,8 +32,11 @@ import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.internal.BrooklynProperties; import org.apache.brooklyn.core.internal.BrooklynProperties.Factory.Builder; +import org.apache.brooklyn.core.server.BrooklynServerConfig; import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.os.Os; +import org.apache.brooklyn.util.text.Strings; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -59,15 +63,21 @@ public void tearDown() throws Exception { @Test public void testReloadPropertiesFromBuilder() throws IOException { - String globalPropertiesContents = "brooklyn.location.localhost.displayName=myname"; + String globalPropertiesContents = toMapString( LocalManagementContextForTests.builder(true) + .useAdditionalProperties(MutableMap.of("brooklyn.location.localhost.displayName", "myname")) + .buildProperties() ); Files.write(globalPropertiesContents, globalPropertiesFile, Charsets.UTF_8); + Builder propsBuilder = BrooklynProperties.Factory.builderDefault() .globalPropertiesFile(globalPropertiesFile.getAbsolutePath()); // no builder support in LocalManagementContextForTests (we are testing that the builder's files are reloaded so we need it here) context = new LocalManagementContext(propsBuilder); Location location = context.getLocationRegistry().getLocationManaged("localhost"); assertEquals(location.getDisplayName(), "myname"); - String newGlobalPropertiesContents = "brooklyn.location.localhost.displayName=myname2"; + + String newGlobalPropertiesContents = toMapString( LocalManagementContextForTests.builder(true) + .useAdditionalProperties(MutableMap.of("brooklyn.location.localhost.displayName", "myname2")) + .buildProperties() ); Files.write(newGlobalPropertiesContents, globalPropertiesFile, Charsets.UTF_8); context.reloadBrooklynProperties(); Location location2 = context.getLocationRegistry().getLocationManaged("localhost"); @@ -75,6 +85,18 @@ public void testReloadPropertiesFromBuilder() throws IOException { assertEquals(location2.getDisplayName(), "myname2"); } + private String toMapString(BrooklynProperties buildProperties) { + StringBuilder s = new StringBuilder(); + Map props = buildProperties.asMapWithStringKeys(); + for (String key: props.keySet()) { + s.append(key); + s.append("="); + s.append(props.get(key)); + s.append("\n"); + } + return s.toString(); + } + @Test public void testReloadPropertiesFromProperties() throws IOException { String globalPropertiesContents = "brooklyn.location.localhost.displayName=myname"; diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindLocationTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindLocationTest.java index 7af5127d75..9de240cf8d 100644 --- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindLocationTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindLocationTest.java @@ -36,7 +36,6 @@ import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.location.AbstractLocation; -import org.apache.brooklyn.core.mgmt.rebind.BasicLocationRebindSupport; import org.apache.brooklyn.core.mgmt.rebind.RebindEntityTest.MyEntity; import org.apache.brooklyn.core.test.entity.TestApplication; import org.apache.brooklyn.test.Asserts; diff --git a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java index f2d74dc3d9..b0e115c6fd 100644 --- a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java +++ b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java @@ -35,7 +35,6 @@ import java.util.concurrent.Callable; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -972,16 +971,6 @@ public void testWithNonStartableEntity() throws Exception { assertTrue(cluster.getAttribute(Attributes.SERVICE_UP)); } - private Throwable unwrapException(Throwable e) { - if (e instanceof ExecutionException) { - return unwrapException(e.getCause()); - } else if (e instanceof org.codehaus.groovy.runtime.InvokerInvocationException) { - return unwrapException(e.getCause()); - } else { - return e; - } - } - @Test public void testDifferentFirstMemberSpec() throws Exception { DynamicCluster cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class) @@ -1020,6 +1009,7 @@ public void testDifferentFirstMemberSpec() throws Exception { @Test public void testPrefersMemberSpecLocation() throws Exception { + @SuppressWarnings("deprecation") DynamicCluster cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class) .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(TestEntity.class) .location(loc2)) @@ -1124,7 +1114,7 @@ public void testResizeStrategies() throws Exception { ImmutableList.Builder sensorMatchingStrategiesBuilder = ImmutableList.builder(); for (int i = 0; i < clusterSize; i++){ - SensorMatchingRemovalStrategy sensorMatchingRemovalStrategy = new SensorMatchingRemovalStrategy(); + SensorMatchingRemovalStrategy sensorMatchingRemovalStrategy = new SensorMatchingRemovalStrategy<>(); sensorMatchingRemovalStrategy.config().set(SensorMatchingRemovalStrategy.SENSOR, TestEntity.SEQUENCE); sensorMatchingRemovalStrategy.config().set(SensorMatchingRemovalStrategy.DESIRED_VALUE, i); sensorMatchingStrategiesBuilder.add(sensorMatchingRemovalStrategy); diff --git a/test-framework/src/test/java/org/apache/brooklyn/test/framework/LoopOverGroupMembersTestCaseTest.java b/test-framework/src/test/java/org/apache/brooklyn/test/framework/LoopOverGroupMembersTestCaseTest.java index 09dba5a7ea..17797bb228 100644 --- a/test-framework/src/test/java/org/apache/brooklyn/test/framework/LoopOverGroupMembersTestCaseTest.java +++ b/test-framework/src/test/java/org/apache/brooklyn/test/framework/LoopOverGroupMembersTestCaseTest.java @@ -27,48 +27,35 @@ import java.util.Map; import java.util.Set; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.entity.Group; -import org.apache.brooklyn.api.location.LocationSpec; -import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.entity.EntityAsserts; import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey; import org.apache.brooklyn.core.test.entity.TestApplication; import org.apache.brooklyn.entity.group.DynamicGroup; import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess; -import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation; import org.apache.brooklyn.util.collections.MutableSet; -import org.apache.brooklyn.util.text.Identifiers; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; public class LoopOverGroupMembersTestCaseTest { private TestApplication app; private Group testGroup; - private ManagementContext managementContext; - private LocalhostMachineProvisioningLocation loc; - private String testId; private final String SENSOR_VAL = "Hello World!"; private static final AttributeSensorAndConfigKey STRING_SENSOR = ConfigKeys.newSensorAndConfigKey(String.class, "string-sensor", "String Sensor"); @BeforeMethod public void setup() { - testId = Identifiers.makeRandomId(8); app = TestApplication.Factory.newManagedInstanceForTests(); - managementContext = app.getManagementContext(); - - loc = managementContext.getLocationManager() - .createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class) - .configure("name", testId)); testGroup = app.createAndManageChild(EntitySpec.create(DynamicGroup.class)); } @@ -142,7 +129,7 @@ public void testMultipleChildrenWhichAllFail() { } } - @Test + @Test(groups="Integration") // because slow; LoopOver needs changing if we want to allow different specs for failing and passing public void testMultipleChildrenOneOfWhichFails() { Set emptySoftwareProcesses = addMultipleEmptySoftwareProcessesToGroup(3); EntitySpec testSpec = createPassingTestSensorSpec(); @@ -202,7 +189,7 @@ public void testOneChildWhichFails() { @Test public void testNoTarget() { - EmptySoftwareProcess emptySoftwareProcess = addEmptySoftwareProcessToGroup(); + addEmptySoftwareProcessToGroup(); EntitySpec testSpec = createFailingTestSensorSpec(); LoopOverGroupMembersTestCase loopOverGroupMembersTestCase = app.createAndManageChild(EntitySpec.create(LoopOverGroupMembersTestCase.class)); @@ -216,7 +203,7 @@ public void testNoTarget() { @Test public void testNotTargetingGroup() { - EmptySoftwareProcess emptySoftwareProcess = addEmptySoftwareProcessToGroup(); + addEmptySoftwareProcessToGroup(); EntitySpec testSpec = createFailingTestSensorSpec(); LoopOverGroupMembersTestCase loopOverGroupMembersTestCase = app.createAndManageChild(EntitySpec.create(LoopOverGroupMembersTestCase.class)); @@ -231,8 +218,7 @@ public void testNotTargetingGroup() { @Test public void testNoSpec() { - EmptySoftwareProcess emptySoftwareProcess = addEmptySoftwareProcessToGroup(); - EntitySpec testSpec = createFailingTestSensorSpec(); + addEmptySoftwareProcessToGroup(); LoopOverGroupMembersTestCase loopOverGroupMembersTestCase = app.createAndManageChild(EntitySpec.create(LoopOverGroupMembersTestCase.class)); loopOverGroupMembersTestCase.config().set(LoopOverGroupMembersTestCase.TARGET_ENTITY, testGroup); @@ -251,6 +237,7 @@ private EntitySpec createFailingTestSensorSpec() { return EntitySpec.create(TestSensor.class) .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName()) + .configure(TestSensor.ITERATION_LIMIT, 1) .configure(TestSensor.ASSERTIONS, assertions); } diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamGobblerTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamGobblerTest.java index a4b9cb81d0..3ace7bebf7 100644 --- a/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamGobblerTest.java +++ b/utils/common/src/test/java/org/apache/brooklyn/util/stream/StreamGobblerTest.java @@ -61,13 +61,16 @@ public void testGobbleMultiLineBlockingStream() throws Exception { gobbler.start(); try { pipedOutputStream.write("line1\n".getBytes()); + pipedOutputStream.flush(); assertEqualsEventually(out, "line1" + NL); pipedOutputStream.write("line2\n".getBytes()); + pipedOutputStream.flush(); assertEqualsEventually(out, "line1" + NL + "line2" + NL); pipedOutputStream.write("line".getBytes()); pipedOutputStream.write("3\n".getBytes()); + pipedOutputStream.flush(); assertEqualsEventually(out, "line1" + NL + "line2" + NL + "line3" + NL); pipedOutputStream.close();