Repository: brooklyn-server Updated Branches: refs/heads/master 48ff670c0 -> 6f148be98
Add more assertions to SoftwareProcessEntityFeedRebindTest Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/63fb8345 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/63fb8345 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/63fb8345 Branch: refs/heads/master Commit: 63fb8345fbb2f60b7d86087378b53107a656bc93 Parents: 38fff65 Author: Aled Sage <[email protected]> Authored: Thu Aug 11 15:04:13 2016 +0100 Committer: Aled Sage <[email protected]> Committed: Thu Aug 11 15:08:20 2016 +0100 ---------------------------------------------------------------------- .../SoftwareProcessEntityFeedRebindTest.java | 130 ++++++++++++++++--- 1 file changed, 113 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/63fb8345/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityFeedRebindTest.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityFeedRebindTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityFeedRebindTest.java index 506ff39..aaac53d 100644 --- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityFeedRebindTest.java +++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityFeedRebindTest.java @@ -18,6 +18,7 @@ */ package org.apache.brooklyn.entity.software.base; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import java.util.List; @@ -26,21 +27,24 @@ import java.util.concurrent.Callable; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntityLocal; import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.entity.ImplementedBy; import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.core.entity.Attributes; import org.apache.brooklyn.core.entity.BrooklynConfigKeys; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.EntityAsserts; +import org.apache.brooklyn.core.entity.RecordingSensorEventListener; +import org.apache.brooklyn.core.entity.lifecycle.Lifecycle; import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp; import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.core.test.entity.TestApplication; import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityRebindTest.MyProvisioningLocation; -import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityTest.MyService; -import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityTest.MyServiceImpl; import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityTest.SimulatedDriver; import org.apache.brooklyn.feed.function.FunctionFeed; import org.apache.brooklyn.feed.function.FunctionPollConfig; import org.apache.brooklyn.location.ssh.SshMachineLocation; +import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,21 +65,37 @@ public class SoftwareProcessEntityFeedRebindTest extends RebindTestFixtureWithAp @Test public void testFeedsDoNotPollUntilManaged() throws Exception { - runFeedsDoNotPollUntilManaged(1); + runFeedsDoNotPollUntilManaged(1, Duration.millis(250)); } @Test(groups="Integeration") public void testFeedsDoNotPollUntilManagedManyEntities() throws Exception { - runFeedsDoNotPollUntilManaged(100); + runFeedsDoNotPollUntilManaged(100, Duration.ONE_SECOND); } - - protected void runFeedsDoNotPollUntilManaged(int numEntities) throws Exception { - List<MyService> origEs = Lists.newArrayList(); + + /** + * Test for https://issues.apache.org/jira/browse/BROOKLYN-322. + * + * The entity registers a couple of feeds: the standard connectServiceUpIsRunning, and a custom + * poller that is registered during init (and persisted). We do a few assertions after rebind: + * <ol> + * <li>The persisted-feed is active (so changes the sensor value) + * <li>The persisted-feed did not executed before the entity was managed. + * <li>The driver.isRunning (called periodically by connectServiceUpIsRunning) was never + * called before the entity was managed. + * <li>The entity's state was never reported as faulty. We check the service.state, service.isUp + * and the service.process.isRunning. + * </ol> + * + * This tests both the underlying cause, and the symptoms. + */ + protected void runFeedsDoNotPollUntilManaged(int numEntities, Duration delayAfterRebind) throws Exception { + List<MyServiceWithFeeds> origEs = Lists.newArrayList(); LOG.info("Creating "+numEntities+" entities"); for (int i = 0; i < numEntities; i++) { - origEs.add(origApp.createAndManageChild(EntitySpec.create(MyService.class) - .impl(MyServiceWithFeedsImpl.class) + origEs.add(origApp.createAndManageChild(EntitySpec.create(MyServiceWithFeeds.class) + .configure(SoftwareProcess.SERVICE_PROCESS_IS_RUNNING_POLL_PERIOD, Duration.millis(10)) .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true))); } @@ -84,26 +104,59 @@ public class SoftwareProcessEntityFeedRebindTest extends RebindTestFixtureWithAp .displayName("mylocname")); origApp.start(ImmutableList.of(origLoc)); + for (Entity child : origApp.getChildren()) { + EntityAsserts.assertAttributeEquals(child, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING); + EntityAsserts.assertAttributeEquals(child, Attributes.SERVICE_UP, Boolean.TRUE); + EntityAsserts.assertAttributeEquals(child, SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, Boolean.TRUE); + } + LOG.info("Rebinding "+numEntities+" entities"); newApp = (TestApplication) rebind(); - List<Entity> newEs = ImmutableList.copyOf(newApp.getChildren()); - LOG.info("Checking state of "+numEntities+" entities"); - for (Entity newE : newEs) { + // Slight pause is to give the feeds a chance to execute, to publish their event(s) + Duration.sleep(delayAfterRebind); + + LOG.info("Checking state of "+numEntities+" entities, after rebind"); + for (Entity newERaw : newApp.getChildren()) { + MyServiceWithFeeds newE = (MyServiceWithFeeds) newERaw; EntityAsserts.assertAttributeChangesEventually(newE, MyServiceWithFeeds.COUNTER); - assertFalse(((MyServiceWithFeeds)newE).isFeedCalledWhenNotManaged()); - SimulatedDriverWithFeeds driver = (SimulatedDriverWithFeeds) ((MyServiceWithFeeds)newE).getDriver(); + assertFalse(newE.isFeedCalledWhenNotManaged()); + + SimulatedDriverWithFeeds driver = (SimulatedDriverWithFeeds) newE.getDriver(); assertFalse(driver.isRunningCalledWhenNotManaged); + + List<Lifecycle> states = newE.getServiceStateEvents(); + Lifecycle currentState = newE.sensors().get(Attributes.SERVICE_STATE_ACTUAL); + List<Boolean> ups = newE.getServiceUpEvents(); + Boolean currentUp = newE.sensors().get(Attributes.SERVICE_UP); + List<Boolean> processRunnings = newE.getProcessRunningEvents(); + Boolean currentProcessRunning = newE.sensors().get(SoftwareProcess.SERVICE_PROCESS_IS_RUNNING); + String errMsg = "Entity "+newE+": states="+states+"; current="+currentState+"; ups="+ups+"; current="+currentUp+"; processRunnings="+processRunnings+"; current="+currentProcessRunning; + LOG.info(errMsg); + assertFalse(states.contains(Lifecycle.ON_FIRE), errMsg); + assertEquals(currentState, Lifecycle.RUNNING, errMsg); + assertFalse(ups.contains(Boolean.FALSE), errMsg); + assertEquals(currentUp, Boolean.TRUE, errMsg); + assertFalse(processRunnings.contains(Boolean.FALSE), errMsg); + assertEquals(currentProcessRunning, Boolean.TRUE, errMsg); } } - public static interface MyServiceWithFeeds extends MyService { + @ImplementedBy(MyServiceWithFeedsImpl.class) + public static interface MyServiceWithFeeds extends SoftwareProcess { AttributeSensor<Integer> COUNTER = Sensors.newIntegerSensor("counter"); + SoftwareProcessDriver getDriver(); + List<Lifecycle> getServiceStateEvents(); + List<Boolean> getServiceUpEvents(); + List<Boolean> getProcessRunningEvents(); boolean isFeedCalledWhenNotManaged(); } - public static class MyServiceWithFeedsImpl extends MyServiceImpl implements MyServiceWithFeeds { + public static class MyServiceWithFeedsImpl extends SoftwareProcessImpl implements MyServiceWithFeeds { + protected RecordingSensorEventListener<Lifecycle> stateListener; + protected RecordingSensorEventListener<Boolean> upListener; + protected RecordingSensorEventListener<Boolean> processRunningListener; protected FunctionFeed functionFeed; protected boolean feedCalledWhenNotManaged; @@ -113,6 +166,29 @@ public class SoftwareProcessEntityFeedRebindTest extends RebindTestFixtureWithAp } @Override + public List<Lifecycle> getServiceStateEvents() { + return getServiceStateEvents(stateListener); + } + + @Override + public List<Boolean> getServiceUpEvents() { + return getServiceStateEvents(upListener); + } + + @Override + public List<Boolean> getProcessRunningEvents() { + return getServiceStateEvents(processRunningListener); + } + + private <T> List<T> getServiceStateEvents(RecordingSensorEventListener<T> listener) { + if (stateListener == null) { + return ImmutableList.of(); + } else { + return MutableList.copyOf(listener.getEventValues()).asUnmodifiable(); + } + } + + @Override public void init() { super.init(); @@ -135,6 +211,26 @@ public class SoftwareProcessEntityFeedRebindTest extends RebindTestFixtureWithAp } })) .build()); + + subscribeToServiceState(); + } + + @Override + public void rebind() { + super.rebind(); + + subscribeToServiceState(); + } + + protected void subscribeToServiceState() { + stateListener = new RecordingSensorEventListener<Lifecycle>(); + subscriptions().subscribe(this, SERVICE_STATE_ACTUAL, stateListener); + + upListener = new RecordingSensorEventListener<Boolean>(); + subscriptions().subscribe(this, SERVICE_UP, upListener); + + processRunningListener = new RecordingSensorEventListener<Boolean>(); + subscriptions().subscribe(this, SERVICE_PROCESS_IS_RUNNING, processRunningListener); } @Override @@ -169,7 +265,7 @@ public class SoftwareProcessEntityFeedRebindTest extends RebindTestFixtureWithAp isRunningCalledWhenNotManaged = true; throw new IllegalStateException("Entity "+entity+" is not managed in driver.isRunning"); } - return super.isRunning(); + return true; } } }
