brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [11/24] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package policy
Date Tue, 18 Aug 2015 11:06:09 GMT
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
deleted file mode 100644
index a67e24d..0000000
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.policy.followthesun;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.basic.EntityLocal;
-import org.apache.brooklyn.api.location.Location;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-
-import org.apache.brooklyn.location.basic.SimulatedLocation;
-
-import brooklyn.policy.loadbalancing.BalanceableContainer;
-import brooklyn.policy.loadbalancing.MockContainerEntity;
-import brooklyn.policy.loadbalancing.MockItemEntity;
-import brooklyn.policy.loadbalancing.MockItemEntityImpl;
-import brooklyn.policy.loadbalancing.Movable;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicates;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-
-public class FollowTheSunPolicySoakTest extends AbstractFollowTheSunPolicyTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(FollowTheSunPolicySoakTest.class);
-    
-    private static final long TIMEOUT_MS = 10*1000;
-    
-    @Test
-    public void testFollowTheSunQuickTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 1;
-        config.numLocations=3;
-        config.numContainersPerLocation = 5;
-        config.numLockedItemsPerLocation = 2;
-        config.numMovableItems = 10;
-    
-        runFollowTheSunSoakTest(config);
-    }
-    
-    @Test
-    public void testLoadBalancingManyItemsQuickTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 1;
-        config.numLocations=2;
-        config.numContainersPerLocation = 3;
-        config.numLockedItemsPerLocation = 2;
-        config.numMovableItems = 10;
-        config.numContainerStopsPerCycle = 1;
-        config.numItemStopsPerCycle = 1;
-    
-        runFollowTheSunSoakTest(config);
-    }
-    
-    @Test(groups={"Integration"}) // takes ~2s
-    public void testLoadBalancingManyItemsNotTooLongTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 1;
-        config.numLocations=3;
-        config.numContainersPerLocation = 5;
-        config.numLockedItemsPerLocation = 2;
-        config.numMovableItems = 500;
-        config.numContainerStopsPerCycle = 1;
-        config.numItemStopsPerCycle = 1;
-    
-        runFollowTheSunSoakTest(config);
-    }
-    
-    @Test(groups={"Integration","Acceptance"}) // integration group, because it's slow to run many cycles
-    public void testLoadBalancingSoakTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 100;
-        config.numLocations=3;
-        config.numContainersPerLocation = 5;
-        config.numLockedItemsPerLocation = 2;
-        config.numMovableItems = 10;
-    
-        runFollowTheSunSoakTest(config);
-    }
-
-    @Test(groups={"Integration","Acceptance"}) // integration group, because it's slow to run many cycles
-    public void testLoadBalancingManyItemsSoakTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 100;
-        config.numLocations=3;
-        config.numContainersPerLocation = 5;
-        config.numLockedItemsPerLocation = 2;
-        config.numMovableItems = 100;
-        config.numContainerStopsPerCycle = 3;
-        config.numItemStopsPerCycle = 10;
-        
-        runFollowTheSunSoakTest(config);
-    }
-
-    @Test(groups={"Integration","Acceptance"}) // integration group, because it's slow to run many cycles
-    public void testLoadBalancingManyManyItemsTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 1;
-        config.numLocations=10;
-        config.numContainersPerLocation = 5;
-        config.numLockedItemsPerLocation = 100;
-        config.numMovableItems = 1000;
-        config.numContainerStopsPerCycle = 0;
-        config.numItemStopsPerCycle = 0;
-        config.timeout_ms = 30*1000;
-        config.verbose = false;
-        
-        runFollowTheSunSoakTest(config);
-    }
-    
-    private void runFollowTheSunSoakTest(RunConfig config) {
-        int numCycles = config.numCycles;
-        int numLocations = config.numLocations;
-        int numContainersPerLocation = config.numContainersPerLocation;
-        int numLockedItemsPerLocation = config.numLockedItemsPerLocation;
-        int numMovableItems = config.numMovableItems;
-        
-        int numContainerStopsPerCycle = config.numContainerStopsPerCycle;
-        int numItemStopsPerCycle = config.numItemStopsPerCycle;
-        long timeout_ms = config.timeout_ms;
-        final boolean verbose = config.verbose;
-        
-        MockItemEntityImpl.totalMoveCount.set(0);
-        
-        List<Location> locations = new ArrayList<Location>();
-        Multimap<Location,MockContainerEntity> containers = HashMultimap.<Location,MockContainerEntity>create();
-        Multimap<Location,MockItemEntity> lockedItems = HashMultimap.<Location,MockItemEntity>create();
-        final List<MockItemEntity> movableItems = new ArrayList<MockItemEntity>();
-        
-        for (int i = 1; i <= numLocations; i++) {
-            String locName = "loc"+i;
-            Location loc = new SimulatedLocation(MutableMap.of("name",locName));
-            locations.add(loc);
-            
-            for (int j = 1; j <= numContainersPerLocation; j++) {
-                MockContainerEntity container = newContainer(app, loc, "container-"+locName+"-"+j);
-                containers.put(loc, container);
-            }
-            for (int j = 1; j <= numLockedItemsPerLocation; j++) {
-                MockContainerEntity container = Iterables.get(containers.get(loc), j%numContainersPerLocation);
-                MockItemEntity item = newLockedItem(app, container, "item-locked-"+locName+"-"+j);
-                lockedItems.put(loc, item);
-            }
-        }
-        
-        for (int i = 1; i <= numMovableItems; i++) {
-            MockContainerEntity container = Iterables.get(containers.values(), i%containers.size());
-            MockItemEntity item = newItem(app, container, "item-movable"+i);
-            movableItems.add(item);
-        }
-
-        for (int i = 1; i <= numCycles; i++) {
-            LOG.info("{}: cycle {}", FollowTheSunPolicySoakTest.class.getSimpleName(), i);
-            
-            // Stop movable items, and start others
-            for (int j = 1; j <= numItemStopsPerCycle; j++) {
-                int itemIndex = random.nextInt(numMovableItems);
-                MockItemEntity itemToStop = movableItems.get(itemIndex);
-                itemToStop.stop();
-                LOG.debug("Unmanaging item {}", itemToStop);
-                Entities.unmanage(itemToStop);
-                movableItems.set(itemIndex, newItem(app, Iterables.get(containers.values(), 0), "item-movable"+itemIndex));
-            }
-
-            // Choose a location to be busiest
-            int locIndex = random.nextInt(numLocations);
-            final Location busiestLocation = locations.get(locIndex);
-            
-            // Repartition the load across the items
-            for (int j = 0; j < numMovableItems; j++) {
-                MockItemEntity item = movableItems.get(j);
-                Map<Entity, Double> workrates = Maps.newLinkedHashMap();
-                
-                for (Map.Entry<Location,MockItemEntity> entry : lockedItems.entries()) {
-                    Location location = entry.getKey();
-                    MockItemEntity source = entry.getValue();
-                    double baseWorkrate = (location == busiestLocation ? 1000 : 100);
-                    double jitter = 10;
-                    double jitteredWorkrate = Math.max(0, baseWorkrate + (random.nextDouble()*jitter*2 - jitter));
-                    workrates.put(source, jitteredWorkrate);
-                }
-                ((EntityLocal)item).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, workrates);
-            }
-
-            // Stop containers, and start others
-            // This offloads the "immovable" items to other containers in the same location!
-            for (int j = 1; j <= numContainerStopsPerCycle; j++) {
-                int containerIndex = random.nextInt(containers.size());
-                MockContainerEntity containerToStop = Iterables.get(containers.values(), containerIndex);
-                Location location = Iterables.get(containerToStop.getLocations(), 0);
-                MockContainerEntity otherContainerInLocation = Iterables.find(containers.get(location), Predicates.not(Predicates.equalTo(containerToStop)), null);
-                containerToStop.offloadAndStop(otherContainerInLocation);
-                LOG.debug("Unmanaging container {}", containerToStop);
-                Entities.unmanage(containerToStop);
-                containers.remove(location, containerToStop);
-                
-                MockContainerEntity containerToAdd = newContainer(app, location, "container-"+location.getDisplayName()+"-new."+i+"."+j);
-                containers.put(location, containerToAdd);
-            }
-
-            // Assert that the items all end up in the location with maximum load-generation
-            Asserts.succeedsEventually(MutableMap.of("timeout", timeout_ms), new Runnable() {
-                public void run() {
-                    Iterable<Location> itemLocs = Iterables.transform(movableItems, new Function<MockItemEntity, Location>() {
-                        public Location apply(MockItemEntity input) {
-                            BalanceableContainer<?> container = input.getAttribute(Movable.CONTAINER);
-                            Collection<Location> locs = (container != null) ? container.getLocations(): null;
-                            return (locs != null && locs.size() > 0) ? Iterables.get(locs, 0) : null;
-                        }});
-                    
-                    Iterable<String> itemLocNames = Iterables.transform(itemLocs, new Function<Location, String>() {
-                        public String apply(Location input) {
-                            return (input != null) ? input.getDisplayName() : null;
-                        }});
-                    String errMsg;
-                    if (verbose) {
-                        errMsg = verboseDumpToString()+"; itemLocs="+itemLocNames;
-                    } else {
-                        Set<String> locNamesInUse = Sets.newLinkedHashSet(itemLocNames);
-                        errMsg = "locsInUse="+locNamesInUse+"; totalMoves="+MockItemEntityImpl.totalMoveCount;
-                    }
-                    
-                    assertEquals(ImmutableList.copyOf(itemLocs), Collections.nCopies(movableItems.size(), busiestLocation), errMsg);
-                }});
-        }
-    }
-    
-    static class RunConfig {
-        int numCycles = 1;
-        int numLocations = 3;
-        int numContainersPerLocation = 5;
-        int numLockedItemsPerLocation = 5;
-        int numMovableItems = 5;
-        int numContainerStopsPerCycle = 0;
-        int numItemStopsPerCycle = 0;
-        long timeout_ms = TIMEOUT_MS;
-        boolean verbose = true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
deleted file mode 100644
index 1f5e5db..0000000
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.policy.followthesun;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.basic.EntityLocal;
-import org.apache.brooklyn.api.event.SensorEvent;
-import org.apache.brooklyn.api.event.SensorEventListener;
-import org.apache.brooklyn.api.location.Location;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-
-import org.apache.brooklyn.location.basic.SimulatedLocation;
-
-import brooklyn.policy.loadbalancing.MockContainerEntity;
-import brooklyn.policy.loadbalancing.MockItemEntity;
-import brooklyn.policy.loadbalancing.Movable;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Function;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-
-public class FollowTheSunPolicyTest extends AbstractFollowTheSunPolicyTest {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(FollowTheSunPolicyTest.class);
-
-    @Test
-    public void testPolicyUpdatesModel() {
-        final MockContainerEntity containerA = newContainer(app, loc1, "A");
-        final MockItemEntity item1 = newItem(app, containerA, "1");
-        final MockItemEntity item2 = newItem(app, containerA, "2");
-        ((EntityLocal)item2).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item1, 11d));
-        
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
-            @Override public void run() {
-                assertEquals(ImmutableSet.of(item1, item2), model.getItems());
-                assertEquals(model.getItemContainer(item1), containerA);
-                assertEquals(model.getItemLocation(item1), loc1);
-                assertEquals(model.getContainerLocation(containerA), loc1);
-                assertEquals(model.getDirectSendsToItemByLocation(), ImmutableMap.of(item2, ImmutableMap.of(loc1, 11d)));
-            }});
-    }
-    
-    @Test
-    public void testPolicyAcceptsLocationFinder() {
-        pool.removePolicy(policy);
-        
-        Function<Entity, Location> customLocationFinder = new Function<Entity, Location>() {
-            @Override public Location apply(Entity input) {
-                return new SimulatedLocation(MutableMap.of("name", "custom location for "+input));
-            }};
-        
-        FollowTheSunPolicy customPolicy = new FollowTheSunPolicy(
-                MutableMap.of("minPeriodBetweenExecs", 0, "locationFinder", customLocationFinder), 
-                MockItemEntity.ITEM_USAGE_METRIC, 
-                model, 
-                FollowTheSunParameters.newDefault());
-        
-        pool.addPolicy(customPolicy);
-        
-        final MockContainerEntity containerA = newContainer(app, loc1, "A");
-        
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
-            @Override public void run() {
-                assertEquals(model.getContainerLocation(containerA).getDisplayName(), "custom location for "+containerA);
-            }});
-    }
-    
-    @Test
-    public void testNoopBalancing() throws Exception {
-        // Set-up containers and items.
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1", Collections.<Entity, Double>emptyMap());
-        MockItemEntity item2 = newItem(app, containerB, "2", Collections.<Entity, Double>emptyMap());
-        
-        Thread.sleep(SHORT_WAIT_MS);
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1), containerB, ImmutableList.of(item2)));
-    }
-    
-    @Test
-    public void testMovesItemToFollowDemand() throws Exception {
-        // Set-up containers and items.
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerB, "2");
-
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 100d));
-        
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.<MockItemEntity>of(), containerB, ImmutableList.of(item1, item2)));
-    }
-    
-    @Test
-    public void testNoopIfDemandIsTiny() throws Exception {
-        // Set-up containers and items.
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerB, "2");
-
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 0.1d));
-        
-        Thread.sleep(SHORT_WAIT_MS);
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1), containerB, ImmutableList.of(item2)));
-    }
-    
-    @Test
-    public void testNoopIfDemandIsSimilarToCurrentLocation() throws Exception {
-        // Set-up containers and items.
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerA, "2");
-        MockItemEntity item3 = newItem(app, containerB, "3");
-        
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 100d, item3, 100.1d));
-        
-        Thread.sleep(SHORT_WAIT_MS);
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1, item2), containerB, ImmutableList.of(item3)));
-    }
-    
-    @Test
-    public void testMoveDecisionIgnoresDemandFromItself() throws Exception {
-        // Set-up containers and items.
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerB, "2");
-        
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item1, 100d));
-        ((EntityLocal)item2).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 100d));
-        
-        Thread.sleep(SHORT_WAIT_MS);
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1), containerB, ImmutableList.of(item2)));
-    }
-    
-    @Test
-    public void testItemRemovedCausesRecalculationOfOptimalLocation() {
-        // Set-up containers and items.
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerA, "2");
-        MockItemEntity item3 = newItem(app, containerB, "3");
-        
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 100d, item3, 1000d));
-        
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item2), containerB, ImmutableList.of(item1, item3)));
-        
-        item3.stop();
-        Entities.unmanage(item3);
-        
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1, item2), containerB, ImmutableList.<MockItemEntity>of()));
-    }
-    
-    @Test
-    public void testItemMovedCausesRecalculationOfOptimalLocationForOtherItems() {
-        // Set-up containers and items.
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerA, "2");
-        MockItemEntity item3 = newItem(app, containerB, "3");
-        
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 100d, item3, 1000d));
-        
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item2), containerB, ImmutableList.of(item1, item3)));
-        
-        item3.move(containerA);
-        
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1, item2, item3), containerB, ImmutableList.<MockItemEntity>of()));
-    }
-    
-    @Test
-    public void testImmovableItemIsNotMoved() {
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newLockedItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerB, "2");
-        
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 100d));
-        
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1), containerB, ImmutableList.of(item2)));
-    }
-    
-    @Test
-    public void testImmovableItemContributesTowardsLoad() {
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newLockedItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerA, "2");
-        
-        ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item1, 100d));
-        
-        assertItemDistributionEventually(ImmutableMap.of(containerA, ImmutableList.of(item1, item2), containerB, ImmutableList.<MockItemEntity>of()));
-    }
-
-    // Marked as "Acceptance" due to time-sensitive nature :-(
-    @Test(groups={"Integration", "Acceptance"}, invocationCount=20)
-    public void testRepeatedRespectsMinPeriodBetweenExecs() throws Exception {
-        testRespectsMinPeriodBetweenExecs();
-    }
-    
-    @Test(groups="Integration")
-    public void testRespectsMinPeriodBetweenExecs() throws Exception {
-        // Failed in jenkins several times, e.g. with event times [2647, 2655] and [1387, 2001].
-        // Aled's guess is that there was a delay notifying the listener the first time
-        // (which happens async), causing the listener to be notified in rapid 
-        // succession. The policy execs probably did happen with a 1000ms separation.
-        // 
-        // Therefore try up to three times to see if we get the desired separation. If the 
-        // minPeriodBetweenExecs wasn't being respected, we'd expect the default 100ms; this 
-        // test would therefore hardly ever pass.
-        final int MAX_ATTEMPTS = 3;
-
-        final long minPeriodBetweenExecs = 1000;
-        final long timePrecision = 250;
-        
-        pool.removePolicy(policy);
-        
-        MockContainerEntity containerA = newContainer(app, loc1, "A");
-        MockContainerEntity containerB = newContainer(app, loc2, "B");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        MockItemEntity item2 = newItem(app, containerB, "2");
-        MockItemEntity item3 = newItem(app, containerA, "3");
-        
-        FollowTheSunPolicy customPolicy = new FollowTheSunPolicy(
-            MutableMap.of("minPeriodBetweenExecs", minPeriodBetweenExecs),
-            MockItemEntity.ITEM_USAGE_METRIC,
-            model,
-            FollowTheSunParameters.newDefault());
-    
-        pool.addPolicy(customPolicy);
-        
-        // Record times that things are moved, by lisening to the container sensor being set
-        final Stopwatch stopwatch = Stopwatch.createStarted();
-        
-        final List<Long> eventTimes = Lists.newCopyOnWriteArrayList();
-        final Semaphore semaphore = new Semaphore(0);
-        
-        app.subscribe(item1, Movable.CONTAINER, new SensorEventListener<Entity>() {
-            @Override public void onEvent(SensorEvent<Entity> event) {
-                long eventTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);
-                LOG.info("Received {} at {}", event, eventTime);
-                eventTimes.add(eventTime);
-                semaphore.release();
-            }});
-
-        String errmsg = "";
-        for (int i = 0; i < MAX_ATTEMPTS; i++) {
-            // Set the workrate, causing the policy to move item1 to item2's location, and wait for it to happen
-            ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item2, 100d));
-            assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            assertEquals(item1.getAttribute(Movable.CONTAINER), containerB);
-            
-            // now cause item1 to be moved to item3's location, and wait for it to happen
-            ((EntityLocal)item1).setAttribute(MockItemEntity.ITEM_USAGE_METRIC, ImmutableMap.<Entity,Double>of(item3, 100d));
-            assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            assertEquals(item1.getAttribute(Movable.CONTAINER), containerA);
-            
-            LOG.info("testRepeatedRespectsMinPeriodBetweenExecs event times: "+eventTimes);
-            assertEquals(eventTimes.size(), 2);
-            if (eventTimes.get(1) - eventTimes.get(0) > (minPeriodBetweenExecs-timePrecision)) {
-                return; // success
-            } else {
-                errmsg += eventTimes;
-                eventTimes.clear();
-            }
-        }
-        
-        fail("Event times never had sufficient gap: "+errmsg);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/ha/ConnectionFailureDetectorTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ConnectionFailureDetectorTest.java b/policy/src/test/java/brooklyn/policy/ha/ConnectionFailureDetectorTest.java
deleted file mode 100644
index bb2a2ec..0000000
--- a/policy/src/test/java/brooklyn/policy/ha/ConnectionFailureDetectorTest.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.policy.ha;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.brooklyn.api.event.Sensor;
-import org.apache.brooklyn.api.event.SensorEvent;
-import org.apache.brooklyn.api.event.SensorEventListener;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.policy.ha.HASensors.FailureDescriptor;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.net.HostAndPort;
-
-public class ConnectionFailureDetectorTest {
-
-    private static final int TIMEOUT_MS = 30*1000;
-    private static final int OVERHEAD = 250;
-    private static final int POLL_PERIOD = 100;
-
-    private ManagementContext managementContext;
-    private TestApplication app;
-    
-    private List<SensorEvent<FailureDescriptor>> events;
-    
-    private ServerSocket serverSocket;
-    private HostAndPort serverSocketAddress;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        events = new CopyOnWriteArrayList<SensorEvent<FailureDescriptor>>();
-        
-        managementContext = new LocalManagementContextForTests();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext);
-        
-        app.getManagementContext().getSubscriptionManager().subscribe(
-                app, 
-                HASensors.CONNECTION_FAILED, 
-                new SensorEventListener<FailureDescriptor>() {
-                    @Override public void onEvent(SensorEvent<FailureDescriptor> event) {
-                        events.add(event);
-                    }
-                });
-        app.getManagementContext().getSubscriptionManager().subscribe(
-                app, 
-                HASensors.CONNECTION_RECOVERED, 
-                new SensorEventListener<FailureDescriptor>() {
-                    @Override public void onEvent(SensorEvent<FailureDescriptor> event) {
-                        events.add(event);
-                    }
-                });
-        
-        serverSocketAddress = startServerSocket();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        stopServerSocket();
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    private HostAndPort startServerSocket() throws Exception {
-        if (serverSocketAddress != null) {
-            serverSocket = new ServerSocket(serverSocketAddress.getPort());
-        } else {
-            for (int i = 40000; i < 40100; i++) {
-                try {
-                    serverSocket = new ServerSocket(i);
-                } catch (IOException e) {
-                    // try next port
-                }
-            }
-            assertNotNull(serverSocket, "Failed to create server socket; no ports free in range!");
-            serverSocketAddress = HostAndPort.fromParts(serverSocket.getInetAddress().getHostAddress(), serverSocket.getLocalPort());
-        }
-        return serverSocketAddress;
-    }
-
-    private void stopServerSocket() throws Exception {
-        if (serverSocket != null) serverSocket.close();
-    }
-
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testNotNotifiedOfFailuresForHealthy() throws Exception {
-        // Create members before and after the policy is registered, to test both scenarios
-        
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress));
-        
-        assertNoEventsContinually();
-    }
-    
-    @Test
-    public void testNotifiedOfFailure() throws Exception {
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress));
-
-        stopServerSocket();
-
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-        assertEquals(events.size(), 1, "events="+events);
-    }
-    
-    @Test
-    public void testNotifiedOfRecovery() throws Exception {
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress));
-        
-        stopServerSocket();
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-
-        // make the connection recover
-        startServerSocket();
-        assertHasEventEventually(HASensors.CONNECTION_RECOVERED, Predicates.<Object>equalTo(app), null);
-        assertEquals(events.size(), 2, "events="+events);
-    }
-    
-    @Test
-    public void testReportsFailureWhenAlreadyDownOnRegisteringPolicy() throws Exception {
-        stopServerSocket();
-
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress));
-
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-    }
-
-    @Test(groups="Integration") // Because slow
-    public void testNotNotifiedOfTemporaryFailuresDuringStabilisationDelay() throws Exception {
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress)
-                .configure(ConnectionFailureDetector.CONNECTION_FAILED_STABILIZATION_DELAY, Duration.ONE_MINUTE));
-        
-        stopServerSocket();
-        Thread.sleep(100);
-        startServerSocket();
-
-        assertNoEventsContinually();
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testNotifiedOfFailureAfterStabilisationDelay() throws Exception {
-        final int stabilisationDelay = 1000;
-        
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress)
-                .configure(ConnectionFailureDetector.CONNECTION_FAILED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        stopServerSocket();
-
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testFailuresThenUpDownResetsStabilisationCount() throws Exception {
-        final long stabilisationDelay = 1000;
-        
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress)
-                .configure(ConnectionFailureDetector.CONNECTION_FAILED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        stopServerSocket();
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-
-        startServerSocket();
-        Thread.sleep(POLL_PERIOD+OVERHEAD);
-        stopServerSocket();
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testNotNotifiedOfTemporaryRecoveryDuringStabilisationDelay() throws Exception {
-        final long stabilisationDelay = 1000;
-        
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress)
-                .configure(ConnectionFailureDetector.CONNECTION_RECOVERED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        stopServerSocket();
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-        events.clear();
-        
-        startServerSocket();
-        Thread.sleep(POLL_PERIOD+OVERHEAD);
-        stopServerSocket();
-
-        assertNoEventsContinually(Duration.of(stabilisationDelay + OVERHEAD));
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testNotifiedOfRecoveryAfterStabilisationDelay() throws Exception {
-        final int stabilisationDelay = 1000;
-        
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress)
-                .configure(ConnectionFailureDetector.CONNECTION_RECOVERED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        stopServerSocket();
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-        events.clear();
-
-        startServerSocket();
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        assertHasEventEventually(HASensors.CONNECTION_RECOVERED, Predicates.<Object>equalTo(app), null);
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testRecoversThenDownUpResetsStabilisationCount() throws Exception {
-        final long stabilisationDelay = 1000;
-        
-        app.addPolicy(PolicySpec.create(ConnectionFailureDetector.class)
-                .configure(ConnectionFailureDetector.ENDPOINT, serverSocketAddress)
-                .configure(ConnectionFailureDetector.CONNECTION_RECOVERED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        stopServerSocket();
-        assertHasEventEventually(HASensors.CONNECTION_FAILED, Predicates.<Object>equalTo(app), null);
-        events.clear();
-        
-        startServerSocket();
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        
-        stopServerSocket();
-        Thread.sleep(POLL_PERIOD+OVERHEAD);
-        startServerSocket();
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-
-        assertHasEventEventually(HASensors.CONNECTION_RECOVERED, Predicates.<Object>equalTo(app), null);
-    }
-
-    private void assertHasEvent(Sensor<?> sensor, Predicate<Object> componentPredicate, Predicate<? super CharSequence> descriptionPredicate) {
-        for (SensorEvent<FailureDescriptor> event : events) {
-            if (event.getSensor().equals(sensor) && 
-                    (componentPredicate == null || componentPredicate.apply(event.getValue().getComponent())) &&
-                    (descriptionPredicate == null || descriptionPredicate.apply(event.getValue().getDescription()))) {
-                return;
-            }
-        }
-        fail("No matching "+sensor+" event found; events="+events);
-    }
-    
-    private void assertHasEventEventually(final Sensor<?> sensor, final Predicate<Object> componentPredicate, final Predicate<? super CharSequence> descriptionPredicate) {
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
-            @Override public void run() {
-                assertHasEvent(sensor, componentPredicate, descriptionPredicate);
-            }});
-    }
-    
-    private void assertNoEventsContinually(Duration duration) {
-        Asserts.succeedsContinually(ImmutableMap.of("timeout", duration), new Runnable() {
-            @Override public void run() {
-                assertTrue(events.isEmpty(), "events="+events);
-            }});
-    }
-    
-    private void assertNoEventsContinually() {
-        Asserts.succeedsContinually(new Runnable() {
-            @Override public void run() {
-                assertTrue(events.isEmpty(), "events="+events);
-            }});
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java b/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
deleted file mode 100644
index e6d01d0..0000000
--- a/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.policy.ha;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.event.Sensor;
-import org.apache.brooklyn.api.event.SensorEvent;
-import org.apache.brooklyn.api.event.SensorEventListener;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.policy.EnricherSpec;
-import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-
-import org.apache.brooklyn.location.basic.SimulatedLocation;
-
-import brooklyn.policy.ha.HASensors.FailureDescriptor;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-public class HaPolicyRebindTest extends RebindTestFixtureWithApp {
-
-    private TestEntity origEntity;
-    private SensorEventListener<FailureDescriptor> eventListener;
-    private List<SensorEvent<FailureDescriptor>> events;
-    
-    @Override
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        super.setUp();
-        origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class));
-        events = Lists.newCopyOnWriteArrayList();
-        eventListener = new SensorEventListener<FailureDescriptor>() {
-            @Override public void onEvent(SensorEvent<FailureDescriptor> event) {
-                events.add(event);
-            }
-        };
-    }
-
-    @Test
-    public void testServiceRestarterWorksAfterRebind() throws Exception {
-        origEntity.addPolicy(PolicySpec.create(ServiceRestarter.class)
-                .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, HASensors.ENTITY_FAILED));
-        
-        TestApplication newApp = rebind();
-        final TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
-        
-        newEntity.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(origEntity, "simulate failure"));
-        
-        Asserts.succeedsEventually(new Runnable() {
-            @Override public void run() {
-                assertEquals(newEntity.getCallHistory(), ImmutableList.of("restart"));
-            }});
-    }
-
-    @Test
-    public void testServiceReplacerWorksAfterRebind() throws Exception {
-        Location origLoc = origManagementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
-        DynamicCluster origCluster = origApp.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(TestEntity.class))
-                .configure(DynamicCluster.INITIAL_SIZE, 3));
-        origApp.start(ImmutableList.<Location>of(origLoc));
-
-        origCluster.addPolicy(PolicySpec.create(ServiceReplacer.class)
-                .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, HASensors.ENTITY_FAILED));
-
-        // rebind
-        TestApplication newApp = rebind();
-        final DynamicCluster newCluster = (DynamicCluster) Iterables.find(newApp.getChildren(), Predicates.instanceOf(DynamicCluster.class));
-
-        // stimulate the policy
-        final Set<Entity> initialMembers = ImmutableSet.copyOf(newCluster.getMembers());
-        final TestEntity e1 = (TestEntity) Iterables.get(initialMembers, 1);
-        
-        newApp.getManagementContext().getSubscriptionManager().subscribe(e1, HASensors.ENTITY_FAILED, eventListener);
-        newApp.getManagementContext().getSubscriptionManager().subscribe(e1, HASensors.ENTITY_RECOVERED, eventListener);
-        
-        e1.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e1, "simulate failure"));
-        
-        // Expect e1 to be replaced
-        Asserts.succeedsEventually(new Runnable() {
-            @Override public void run() {
-                Set<Entity> newMembers = Sets.difference(ImmutableSet.copyOf(newCluster.getMembers()), initialMembers);
-                Set<Entity> removedMembers = Sets.difference(initialMembers, ImmutableSet.copyOf(newCluster.getMembers()));
-                assertEquals(removedMembers, ImmutableSet.of(e1));
-                assertEquals(newMembers.size(), 1);
-                assertEquals(((TestEntity)Iterables.getOnlyElement(newMembers)).getCallHistory(), ImmutableList.of("start"));
-                
-                // TODO e1 not reporting "start" after rebind because callHistory is a field rather than an attribute, so was not persisted
-                Asserts.assertEqualsIgnoringOrder(e1.getCallHistory(), ImmutableList.of("stop"));
-                assertFalse(Entities.isManaged(e1));
-            }});
-    }
-    
-    @Test
-    public void testServiceFailureDetectorWorksAfterRebind() throws Exception {
-        origEntity.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-
-        // rebind
-        TestApplication newApp = rebind();
-        final TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
-
-        newApp.getManagementContext().getSubscriptionManager().subscribe(newEntity, HASensors.ENTITY_FAILED, eventListener);
-
-        newEntity.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(newEntity, Lifecycle.RUNNING);
-        
-        // trigger the failure
-        newEntity.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(newEntity), null);
-        assertEquals(events.size(), 1, "events="+events);
-    }
-    
-    private void assertHasEventEventually(final Sensor<?> sensor, final Predicate<Object> componentPredicate, final Predicate<? super CharSequence> descriptionPredicate) {
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
-            @Override public void run() {
-                assertHasEvent(sensor, componentPredicate, descriptionPredicate);
-            }});
-    }
-    
-    private void assertHasEvent(Sensor<?> sensor, Predicate<Object> componentPredicate, Predicate<? super CharSequence> descriptionPredicate) {
-        for (SensorEvent<FailureDescriptor> event : events) {
-            if (event.getSensor().equals(sensor) && 
-                    (componentPredicate == null || componentPredicate.apply(event.getValue().getComponent())) &&
-                    (descriptionPredicate == null || descriptionPredicate.apply(event.getValue().getDescription()))) {
-                return;
-            }
-        }
-        fail("No matching "+sensor+" event found; events="+events);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorStabilizationTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorStabilizationTest.java b/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorStabilizationTest.java
deleted file mode 100644
index b6c5c7b..0000000
--- a/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorStabilizationTest.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.policy.ha;
-
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.event.Sensor;
-import org.apache.brooklyn.api.event.SensorEvent;
-import org.apache.brooklyn.api.event.SensorEventListener;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.api.policy.EnricherSpec;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.entity.basic.ServiceStateLogicTest;
-import brooklyn.policy.ha.HASensors.FailureDescriptor;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-
-/** also see more primitive tests in {@link ServiceStateLogicTest} */
-public class ServiceFailureDetectorStabilizationTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceFailureDetectorStabilizationTest.class);
-
-    private static final int TIMEOUT_MS = 10*1000;
-    private static final int OVERHEAD = 250;
-
-    private ManagementContext managementContext;
-    private TestApplication app;
-    private TestEntity e1;
-    
-    private List<SensorEvent<FailureDescriptor>> events;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        events = new CopyOnWriteArrayList<SensorEvent<FailureDescriptor>>();
-        
-        managementContext = new LocalManagementContextForTests();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext);
-        e1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        
-        app.getManagementContext().getSubscriptionManager().subscribe(
-                e1, 
-                HASensors.ENTITY_FAILED, 
-                new SensorEventListener<FailureDescriptor>() {
-                    @Override public void onEvent(SensorEvent<FailureDescriptor> event) {
-                        events.add(event);
-                    }
-                });
-        app.getManagementContext().getSubscriptionManager().subscribe(
-                e1, 
-                HASensors.ENTITY_RECOVERED, 
-                new SensorEventListener<FailureDescriptor>() {
-                    @Override public void onEvent(SensorEvent<FailureDescriptor> event) {
-                        events.add(event);
-                    }
-                });
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testNotNotifiedOfTemporaryFailuresDuringStabilisationDelay() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-                .configure(ServiceFailureDetector.ENTITY_FAILED_STABILIZATION_DELAY, Duration.ONE_MINUTE));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        Thread.sleep(100);
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-
-        assertNoEventsContinually();
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testNotifiedOfFailureAfterStabilisationDelay() throws Exception {
-        final int stabilisationDelay = 1000;
-        
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-                .configure(ServiceFailureDetector.ENTITY_FAILED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testFailuresThenUpDownResetsStabilisationCount() throws Exception {
-        LOG.debug("Running testFailuresThenUpDownResetsStabilisationCount");
-        final long stabilisationDelay = 1000;
-        
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-                .configure(ServiceFailureDetector.ENTITY_FAILED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        Thread.sleep(OVERHEAD);
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testNotNotifiedOfTemporaryRecoveryDuringStabilisationDelay() throws Exception {
-        final long stabilisationDelay = 1000;
-        
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-                .configure(ServiceFailureDetector.ENTITY_RECOVERED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        events.clear();
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        Thread.sleep(100);
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertNoEventsContinually(Duration.of(stabilisationDelay + OVERHEAD));
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testNotifiedOfRecoveryAfterStabilisationDelay() throws Exception {
-        final int stabilisationDelay = 1000;
-        
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-                .configure(ServiceFailureDetector.ENTITY_RECOVERED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        events.clear();
-
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        assertHasEventEventually(HASensors.ENTITY_RECOVERED, Predicates.<Object>equalTo(e1), null);
-    }
-    
-    @Test(groups="Integration") // Because slow
-    public void testRecoversThenDownUpResetsStabilisationCount() throws Exception {
-        final long stabilisationDelay = 1000;
-        
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-                .configure(ServiceFailureDetector.ENTITY_RECOVERED_STABILIZATION_DELAY, Duration.of(stabilisationDelay)));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        events.clear();
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        Thread.sleep(OVERHEAD);
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        assertNoEventsContinually(Duration.of(stabilisationDelay - OVERHEAD));
-
-        assertHasEventEventually(HASensors.ENTITY_RECOVERED, Predicates.<Object>equalTo(e1), null);
-    }
-
-    private void assertHasEvent(Sensor<?> sensor, Predicate<Object> componentPredicate, Predicate<? super CharSequence> descriptionPredicate) {
-        for (SensorEvent<FailureDescriptor> event : events) {
-            if (event.getSensor().equals(sensor) && 
-                    (componentPredicate == null || componentPredicate.apply(event.getValue().getComponent())) &&
-                    (descriptionPredicate == null || descriptionPredicate.apply(event.getValue().getDescription()))) {
-                return;
-            }
-        }
-        fail("No matching "+sensor+" event found; events="+events);
-    }
-    
-    private void assertHasEventEventually(final Sensor<?> sensor, final Predicate<Object> componentPredicate, final Predicate<? super CharSequence> descriptionPredicate) {
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
-            @Override public void run() {
-                assertHasEvent(sensor, componentPredicate, descriptionPredicate);
-            }});
-    }
-
-    private void assertNoEventsContinually(Duration duration) {
-        Asserts.succeedsContinually(ImmutableMap.of("timeout", duration), new Runnable() {
-            @Override public void run() {
-                assertTrue(events.isEmpty(), "events="+events);
-            }});
-    }
-    
-    private void assertNoEventsContinually() {
-        Asserts.succeedsContinually(new Runnable() {
-            @Override public void run() {
-                assertTrue(events.isEmpty(), "events="+events);
-            }});
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorTest.java b/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorTest.java
deleted file mode 100644
index 37355cf..0000000
--- a/policy/src/test/java/brooklyn/policy/ha/ServiceFailureDetectorTest.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.policy.ha;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.event.Sensor;
-import org.apache.brooklyn.api.event.SensorEvent;
-import org.apache.brooklyn.api.event.SensorEventListener;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.api.policy.EnricherSpec;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
-import brooklyn.policy.ha.HASensors.FailureDescriptor;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Time;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-
-public class ServiceFailureDetectorTest {
-    private static final Logger log = LoggerFactory.getLogger(ServiceFailureDetectorTest.class);
-
-    private static final int TIMEOUT_MS = 10*1000;
-
-    private ManagementContext managementContext;
-    private TestApplication app;
-    private TestEntity e1;
-    
-    private List<SensorEvent<FailureDescriptor>> events;
-    private SensorEventListener<FailureDescriptor> eventListener;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        events = new CopyOnWriteArrayList<SensorEvent<FailureDescriptor>>();
-        eventListener = new SensorEventListener<FailureDescriptor>() {
-            @Override public void onEvent(SensorEvent<FailureDescriptor> event) {
-                events.add(event);
-            }
-        };
-        
-        managementContext = new LocalManagementContextForTests();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext);
-        e1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        e1.addEnricher(ServiceStateLogic.newEnricherForServiceStateFromProblemsAndUp());
-        
-        app.getManagementContext().getSubscriptionManager().subscribe(e1, HASensors.ENTITY_FAILED, eventListener);
-        app.getManagementContext().getSubscriptionManager().subscribe(e1, HASensors.ENTITY_RECOVERED, eventListener);
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testNotNotifiedOfFailuresForHealthy() throws Exception {
-        // Create members before and after the policy is registered, to test both scenarios
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        assertNoEventsContinually();
-        assertEquals(e1.getAttribute(TestEntity.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING);
-    }
-    
-    @Test
-    public void testNotifiedOfFailure() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        
-        assertEquals(events.size(), 0, "events="+events);
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        assertEquals(events.size(), 1, "events="+events);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-    }
-    
-    @Test
-    public void testNotifiedOfFailureOnProblem() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        
-        assertEquals(events.size(), 0, "events="+events);
-        
-        ServiceProblemsLogic.updateProblemsIndicator(e1, "test", "foo");
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        assertEquals(events.size(), 1, "events="+events);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-    }
-    
-    @Test
-    public void testNotifiedOfFailureOnStateOnFire() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.ON_FIRE);
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        assertEquals(events.size(), 1, "events="+events);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-    }
-    
-    @Test
-    public void testNotifiedOfRecovery() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        // Make the entity fail
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-
-        // And make the entity recover
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        assertHasEventEventually(HASensors.ENTITY_RECOVERED, Predicates.<Object>equalTo(e1), null);
-        assertEquals(events.size(), 2, "events="+events);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-    }
-    
-    @Test
-    public void testNotifiedOfRecoveryFromProblems() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        // Make the entity fail
-        ServiceProblemsLogic.updateProblemsIndicator(e1, "test", "foo");
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-
-        // And make the entity recover
-        ServiceProblemsLogic.clearProblemsIndicator(e1, "test");
-        assertHasEventEventually(HASensors.ENTITY_RECOVERED, Predicates.<Object>equalTo(e1), null);
-        assertEquals(events.size(), 2, "events="+events);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-    }
-    
-    
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testEmitsEntityFailureOnlyIfPreviouslyUp() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        // Make the entity fail
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-        assertNoEventsContinually();
-    }
-    
-    @Test
-    public void testDisablingPreviouslyUpRequirementForEntityFailed() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-            .configure(ServiceFailureDetector.ENTITY_FAILED_ONLY_IF_PREVIOUSLY_UP, false));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-    }
-    
-    @Test
-    public void testDisablingOnFire() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-            .configure(ServiceFailureDetector.SERVICE_ON_FIRE_STABILIZATION_DELAY, Duration.PRACTICALLY_FOREVER));
-        
-        // Make the entity fail
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertEquals(e1.getAttribute(TestEntity.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING);
-    }
-    
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testOnFireAfterDelay() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-            .configure(ServiceFailureDetector.SERVICE_ON_FIRE_STABILIZATION_DELAY, Duration.ONE_SECOND));
-        
-        // Make the entity fail
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertEquals(e1.getAttribute(TestEntity.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING);
-        Time.sleep(Duration.millis(100));
-        assertEquals(e1.getAttribute(TestEntity.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-    }
-    
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testOnFailureDelayFromProblemAndRecover() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-            .configure(ServiceFailureDetector.SERVICE_ON_FIRE_STABILIZATION_DELAY, Duration.ONE_SECOND)
-            .configure(ServiceFailureDetector.ENTITY_RECOVERED_STABILIZATION_DELAY, Duration.ONE_SECOND));
-        
-        // Set the entity to healthy
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        
-        // Make the entity fail; won't set on-fire for 1s but will publish FAILED immediately.
-        ServiceStateLogic.ServiceProblemsLogic.updateProblemsIndicator(e1, "test", "foo");
-        EntityTestUtils.assertAttributeEqualsContinually(ImmutableMap.of("timeout", 100), e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-        assertEquals(e1.getAttribute(TestEntity.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING);
-        
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-        
-        // Now recover: will publish RUNNING immediately, but has 1s stabilisation for RECOVERED
-        ServiceStateLogic.ServiceProblemsLogic.clearProblemsIndicator(e1, "test");
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        
-        assertEquals(events.size(), 1, "events="+events);
-        
-        assertHasEventEventually(HASensors.ENTITY_RECOVERED, Predicates.<Object>equalTo(e1), null);
-        assertEquals(events.size(), 2, "events="+events);
-    }
-    
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testAttendsToServiceState() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        // not counted as failed because not expected to be running
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertNoEventsContinually();
-    }
-
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testOnlyReportsFailureIfRunning() throws Exception {
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class));
-        
-        // Make the entity fail
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.STARTING);
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        assertNoEventsContinually();
-    }
-    
-    @Test
-    public void testReportsFailureWhenAlreadyDownOnRegisteringPolicy() throws Exception {
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        e1.setAttribute(TestEntity.SERVICE_UP, false);
-
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-            .configure(ServiceFailureDetector.ENTITY_FAILED_ONLY_IF_PREVIOUSLY_UP, false));
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-    }
-    
-    @Test
-    public void testReportsFailureWhenAlreadyOnFireOnRegisteringPolicy() throws Exception {
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.ON_FIRE);
-
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-            .configure(ServiceFailureDetector.ENTITY_FAILED_ONLY_IF_PREVIOUSLY_UP, false));
-
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-    }
-    
-    @Test(groups="Integration") // Has a 1.5 second wait
-    public void testRepublishedFailure() throws Exception {
-        Duration republishPeriod = Duration.millis(100);
-
-        e1.addEnricher(EnricherSpec.create(ServiceFailureDetector.class)
-                .configure(ServiceFailureDetector.ENTITY_FAILED_REPUBLISH_TIME, republishPeriod));
-            
-        // Set the entity to healthy
-        e1.setAttribute(TestEntity.SERVICE_UP, true);
-        ServiceStateLogic.setExpectedState(e1, Lifecycle.RUNNING);
-        EntityTestUtils.assertAttributeEqualsEventually(e1, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        
-        // Make the entity fail;
-        ServiceStateLogic.ServiceProblemsLogic.updateProblemsIndicator(e1, "test", "foo");
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-        assertHasEventEventually(HASensors.ENTITY_FAILED, Predicates.<Object>equalTo(e1), null);
-
-        //wait for at least 10 republish events (~1 sec)
-        assertEventsSizeEventually(10);
-
-        // Now recover
-        ServiceStateLogic.ServiceProblemsLogic.clearProblemsIndicator(e1, "test");
-        EntityTestUtils.assertAttributeEqualsEventually(e1, TestEntity.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        assertHasEventEventually(HASensors.ENTITY_RECOVERED, Predicates.<Object>equalTo(e1), null);
-
-        //once recovered check no more failed events emitted periodically
-        assertEventsSizeContiniually(events.size());
-
-        SensorEvent<FailureDescriptor> prevEvent = null;
-        for (SensorEvent<FailureDescriptor> event : events) {
-            if (prevEvent != null) {
-                long repeatOffset = event.getTimestamp() - prevEvent.getTimestamp();
-                long deviation = Math.abs(repeatOffset - republishPeriod.toMilliseconds());
-                if (deviation > republishPeriod.toMilliseconds()/10 &&
-                        //warn only if recovered is too far away from the last failure
-                        (!event.getSensor().equals(HASensors.ENTITY_RECOVERED) ||
-                        repeatOffset > republishPeriod.toMilliseconds())) {
-                    log.error("The time between failure republish (" + repeatOffset + "ms) deviates too much from the expected " + republishPeriod + ". prevEvent=" + prevEvent + ", event=" + event);
-                }
-            }
-            prevEvent = event;
-        }
-        
-        //make sure no republish takes place after recovered
-        assertEquals(prevEvent.getSensor(), HASensors.ENTITY_RECOVERED);
-    }
-    
-    private void assertEventsSizeContiniually(final int size) {
-        Asserts.succeedsContinually(MutableMap.of("timeout", 500), new Runnable() {
-            @Override
-            public void run() {
-                assertTrue(events.size() == size, "assertEventsSizeContiniually expects " + size + " events but found " + events.size() + ": " + events);
-            }
-        });
-    }
-
-    private void assertEventsSizeEventually(final int size) {
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
-            @Override
-            public void run() {
-                assertTrue(events.size() >= size, "assertEventsSizeContiniually expects at least " + size + " events but found " + events.size() + ": " + events);
-            }
-        });
-    }
-
-    private void assertHasEvent(Sensor<?> sensor, Predicate<Object> componentPredicate, Predicate<? super CharSequence> descriptionPredicate) {
-        for (SensorEvent<FailureDescriptor> event : events) {
-            if (event.getSensor().equals(sensor) && 
-                    (componentPredicate == null || componentPredicate.apply(event.getValue().getComponent())) &&
-                    (descriptionPredicate == null || descriptionPredicate.apply(event.getValue().getDescription()))) {
-                return;
-            }
-        }
-        fail("No matching "+sensor+" event found; events="+events);
-    }
-    
-    private void assertHasEventEventually(final Sensor<?> sensor, final Predicate<Object> componentPredicate, final Predicate<? super CharSequence> descriptionPredicate) {
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
-            @Override public void run() {
-                assertHasEvent(sensor, componentPredicate, descriptionPredicate);
-            }});
-    }
-    
-    private void assertNoEventsContinually() {
-        Asserts.succeedsContinually(new Runnable() {
-            @Override public void run() {
-                assertTrue(events.isEmpty(), "events="+events);
-            }});
-    }
-}


Mime
View raw message