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;
         }
     }
 }

Reply via email to