http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java 
b/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
deleted file mode 100644
index c679224..0000000
--- a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
+++ /dev/null
@@ -1,340 +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.assertNotEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-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.management.ManagementContext;
-import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.core.util.config.ConfigBag;
-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.Assert;
-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.EntityInternal;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.QuorumCheck;
-import 
brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.trait.FailingEntity;
-
-import org.apache.brooklyn.location.basic.SimulatedLocation;
-
-import brooklyn.policy.ha.HASensors.FailureDescriptor;
-import brooklyn.test.Asserts;
-import brooklyn.util.javalang.JavaClassNames;
-
-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 ServiceReplacerTest {
-
-    private static final Logger log = 
LoggerFactory.getLogger(ServiceReplacerTest.class);
-    
-    private ManagementContext managementContext;
-    private TestApplication app;
-    private SimulatedLocation loc;
-    private SensorEventListener<Object> eventListener;
-    private List<SensorEvent<?>> events;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = new LocalManagementContextForTests();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, 
managementContext);
-        loc = 
managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
-        events = Lists.newCopyOnWriteArrayList();
-        eventListener = new SensorEventListener<Object>() {
-            @Override public void onEvent(SensorEvent<Object> event) {
-                events.add(event);
-            }
-        };
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testReplacesFailedMember() throws Exception {
-        final DynamicCluster cluster = 
app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, 
EntitySpec.create(TestEntity.class))
-                .configure(DynamicCluster.INITIAL_SIZE, 3));
-        app.start(ImmutableList.<Location>of(loc));
-
-        ServiceReplacer policy = new ServiceReplacer(new 
ConfigBag().configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED));
-        cluster.addPolicy(policy);
-
-        final Set<Entity> initialMembers = 
ImmutableSet.copyOf(cluster.getMembers());
-        final TestEntity e1 = (TestEntity) Iterables.get(initialMembers, 1);
-        
-        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(cluster.getMembers()), initialMembers);
-                Set<Entity> removedMembers = Sets.difference(initialMembers, 
ImmutableSet.copyOf(cluster.getMembers()));
-                assertEquals(removedMembers, ImmutableSet.of(e1));
-                assertEquals(newMembers.size(), 1);
-                
assertEquals(((TestEntity)Iterables.getOnlyElement(newMembers)).getCallHistory(),
 ImmutableList.of("start"));
-                assertEquals(e1.getCallHistory(), ImmutableList.of("start", 
"stop"));
-                assertFalse(Entities.isManaged(e1));
-            }});
-    }
-
-    @Test(invocationCount=100)
-    public void testSetsOnFireWhenFailToReplaceMemberManyTimes() throws 
Exception {
-        testSetsOnFireWhenFailToReplaceMember();
-    }
-    
-    // fails the startup of the replacement entity (but not the original). 
-    @Test
-    public void testSetsOnFireWhenFailToReplaceMember() throws Exception {
-        app.subscribe(null, ServiceReplacer.ENTITY_REPLACEMENT_FAILED, 
eventListener);
-        
-        final DynamicCluster cluster = 
app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, 
EntitySpec.create(FailingEntity.class)
-                        .configure(FailingEntity.FAIL_ON_START_CONDITION, 
predicateOnlyTrueForCallAtOrAfter(2)))
-                .configure(DynamicCluster.INITIAL_SIZE, 1)
-                .configure(DynamicCluster.QUARANTINE_FAILED_ENTITIES, true)
-                
.configure(ComputeServiceIndicatorsFromChildrenAndMembers.UP_QUORUM_CHECK, 
QuorumCheck.QuorumChecks.alwaysTrue())
-                
.configure(ComputeServiceIndicatorsFromChildrenAndMembers.RUNNING_QUORUM_CHECK, 
QuorumCheck.QuorumChecks.alwaysTrue()));
-        app.start(ImmutableList.<Location>of(loc));
-        
-        // should not be on fire
-        
Assert.assertNotEquals(cluster.getAttribute(Attributes.SERVICE_STATE_ACTUAL), 
Lifecycle.ON_FIRE);
-        // and should eventually be running
-        EntityTestUtils.assertAttributeEqualsEventually(cluster, 
Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        
-        log.info("started "+app+" for "+JavaClassNames.niceClassAndMethod());
-        
-        ServiceReplacer policy = new ServiceReplacer(new 
ConfigBag().configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED));
-        cluster.addPolicy(policy);
-        
-        final Set<Entity> initialMembers = 
ImmutableSet.copyOf(cluster.getMembers());
-        final TestEntity e1 = (TestEntity) Iterables.get(initialMembers, 0);
-        
-        e1.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e1, "simulate 
failure"));
-
-        // Expect cluster to go on-fire when fails to start replacement
-        // Note that we've set up-quorum and running-quorum to be "alwaysTrue" 
so that we don't get a transient onFire
-        // when the failed node fails to start (but before it has been removed 
from the group to be put in quarantine).
-        EntityTestUtils.assertAttributeEqualsEventually(cluster, 
Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
-
-        // Expect to have the second failed entity still kicking around as 
proof (in quarantine)
-        // The cluster should NOT go on fire until after the 2nd failure
-        Iterable<Entity> members = 
Iterables.filter(managementContext.getEntityManager().getEntities(), 
Predicates.instanceOf(FailingEntity.class));
-        assertEquals(Iterables.size(members), 2);
-
-        // e2 failed to start, so it won't have called stop on e1
-        TestEntity e2 = (TestEntity) 
Iterables.getOnlyElement(Sets.difference(ImmutableSet.copyOf(members), 
initialMembers));
-        assertEquals(e1.getCallHistory(), ImmutableList.of("start"), 
"e1.history="+e1.getCallHistory());
-        assertEquals(e2.getCallHistory(), ImmutableList.of("start"), 
"e2.history="+e2.getCallHistory());
-
-        // And will have received notification event about it
-        assertEventuallyHasEntityReplacementFailedEvent(cluster);
-    }
-    
-    @Test(groups="Integration") // has a 1 second wait
-    public void testDoesNotOnFireWhenFailToReplaceMember() throws Exception {
-        app.subscribe(null, ServiceReplacer.ENTITY_REPLACEMENT_FAILED, 
eventListener);
-        
-        final DynamicCluster cluster = 
app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, 
EntitySpec.create(FailingEntity.class)
-                        .configure(FailingEntity.FAIL_ON_START_CONDITION, 
predicateOnlyTrueForCallAtOrAfter(2)))
-                .configure(DynamicCluster.INITIAL_SIZE, 1)
-                .configure(DynamicCluster.QUARANTINE_FAILED_ENTITIES, true));
-        app.start(ImmutableList.<Location>of(loc));
-        
-        ServiceReplacer policy = new ServiceReplacer(new ConfigBag()
-                .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED)
-                .configure(ServiceReplacer.SET_ON_FIRE_ON_FAILURE, false));
-        cluster.addPolicy(policy);
-        
-        final Set<Entity> initialMembers = 
ImmutableSet.copyOf(cluster.getMembers());
-        final TestEntity e1 = (TestEntity) Iterables.get(initialMembers, 0);
-        
-        e1.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e1, "simulate 
failure"));
-
-        // Configured to not mark cluster as on fire
-        Asserts.succeedsContinually(new Runnable() {
-            @Override public void run() {
-                
assertNotEquals(cluster.getAttribute(Attributes.SERVICE_STATE_ACTUAL), 
Lifecycle.ON_FIRE);
-            }});
-        
-        // And will have received notification event about it
-        assertEventuallyHasEntityReplacementFailedEvent(cluster);
-    }
-
-    @Test(groups="Integration")  // 1s wait
-    public void testStopFailureOfOldEntityDoesNotSetClusterOnFire() throws 
Exception {
-        app.subscribe(null, ServiceReplacer.ENTITY_REPLACEMENT_FAILED, 
eventListener);
-        
-        final DynamicCluster cluster = 
app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, 
EntitySpec.create(FailingEntity.class)
-                        .configure(FailingEntity.FAIL_ON_STOP_CONDITION, 
predicateOnlyTrueForCallAt(1)))
-                .configure(DynamicCluster.INITIAL_SIZE, 2));
-        app.start(ImmutableList.<Location>of(loc));
-        
-        cluster.addPolicy(PolicySpec.create(ServiceReplacer.class)
-                .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED));
-        
-        final Set<Entity> initialMembers = 
ImmutableSet.copyOf(cluster.getMembers());
-        final TestEntity e1 = (TestEntity) Iterables.get(initialMembers, 0);
-        
-        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(cluster.getMembers()), initialMembers);
-                Set<Entity> removedMembers = Sets.difference(initialMembers, 
ImmutableSet.copyOf(cluster.getMembers()));
-                assertEquals(removedMembers, ImmutableSet.of(e1));
-                assertEquals(newMembers.size(), 1);
-                
assertEquals(((TestEntity)Iterables.getOnlyElement(newMembers)).getCallHistory(),
 ImmutableList.of("start"));
-                assertEquals(e1.getCallHistory(), ImmutableList.of("start", 
"stop"));
-                assertFalse(Entities.isManaged(e1));
-            }});
-
-        // Failure to stop the failed member should not cause "on-fire" of 
cluster
-        Asserts.succeedsContinually(new Runnable() {
-            @Override public void run() {
-                
assertNotEquals(cluster.getAttribute(Attributes.SERVICE_STATE_ACTUAL), 
Lifecycle.ON_FIRE);
-            }});
-    }
-
-    /**
-     * If we keep on getting failure reports, never managing to replace the 
failed node, then don't keep trying
-     * (i.e. avoid infinite loop).
-     * 
-     * TODO This code + configuration needs some work; it's not testing quite 
the scenarios that I
-     * was thinking of!
-     * I saw problem where a node failed, and the replacements failed, and we 
ended up trying thousands of times.
-     * (describing this scenario is made more complex by me having temporarily 
disabled the cluster from 
-     * removing failed members, for debugging purposes!)
-     * Imagine these two scenarios:
-     * <ol>
-     *   <li>Entity fails during call to start().
-     *       Here, the cluster removes it as a member (either unmanages it or 
puts it in quarantine)
-     *       So the ENTITY_FAILED is ignored because the entity is not a 
member at that point.
-     *   <li>Entity returns from start(), but quickly goes to service-down.
-     *       Here we'll keep trying to replace that entity. Depending how long 
that takes, we'll either 
-     *       enter a horrible infinite loop, or we'll just provision a huge 
number of VMs over a long 
-     *       time period.
-     *       Unfortunately this scenario is not catered for in the code yet.
-     * </ol>
-     */
-    @Test(groups="Integration") // because takes 1.2 seconds
-    public void testAbandonsReplacementAfterNumFailures() throws Exception {
-        app.subscribe(null, ServiceReplacer.ENTITY_REPLACEMENT_FAILED, 
eventListener);
-        
-        final DynamicCluster cluster = 
app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, 
EntitySpec.create(FailingEntity.class)
-                        .configure(FailingEntity.FAIL_ON_START_CONDITION, 
predicateOnlyTrueForCallAtOrAfter(11)))
-                .configure(DynamicCluster.INITIAL_SIZE, 10)
-                .configure(DynamicCluster.QUARANTINE_FAILED_ENTITIES, true));
-        app.start(ImmutableList.<Location>of(loc));
-        
-        ServiceReplacer policy = new ServiceReplacer(new ConfigBag()
-                .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED)
-                .configure(ServiceReplacer.FAIL_ON_NUM_RECURRING_FAILURES, 3));
-        cluster.addPolicy(policy);
-
-        final Set<Entity> initialMembers = 
ImmutableSet.copyOf(cluster.getMembers());
-        for (int i = 0; i < 5; i++) {
-            final int counter = i+1;
-            EntityInternal entity = (EntityInternal) 
Iterables.get(initialMembers, i);
-            entity.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(entity, 
"simulate failure"));
-            if (i <= 3) {
-                Asserts.succeedsEventually(new Runnable() {
-                    @Override public void run() {
-                        Set<FailingEntity> all = 
ImmutableSet.copyOf(Iterables.filter(managementContext.getEntityManager().getEntities(),
 FailingEntity.class));
-                        Set<FailingEntity> replacements = Sets.difference(all, 
initialMembers);
-                        Set<?> replacementMembers = 
Sets.intersection(ImmutableSet.of(cluster.getMembers()), replacements);
-                        assertTrue(replacementMembers.isEmpty());
-                        assertEquals(replacements.size(), counter);
-                    }});
-            } else {
-                Asserts.succeedsContinually(new Runnable() {
-                    @Override public void run() {
-                        Set<FailingEntity> all = 
ImmutableSet.copyOf(Iterables.filter(managementContext.getEntityManager().getEntities(),
 FailingEntity.class));
-                        Set<FailingEntity> replacements = Sets.difference(all, 
initialMembers);
-                        assertEquals(replacements.size(), 4);
-                    }});
-            }
-        }
-    }
-
-
-    private Predicate<Object> predicateOnlyTrueForCallAt(final int callNumber) 
{
-        return predicateOnlyTrueForCallRange(callNumber, callNumber);
-    }
-
-    private Predicate<Object> predicateOnlyTrueForCallAtOrAfter(final int 
callLowerNumber) {
-        return predicateOnlyTrueForCallRange(callLowerNumber, 
Integer.MAX_VALUE);
-    }
-    
-    private Predicate<Object> predicateOnlyTrueForCallRange(final int 
callLowerNumber, final int callUpperNumber) {
-        return new Predicate<Object>() {
-            private final AtomicInteger counter = new AtomicInteger(0);
-            @Override public boolean apply(Object input) {
-                int num = counter.incrementAndGet();
-                return num >= callLowerNumber && num <= callUpperNumber;
-            }
-        };
-    }
-
-    private void assertEventuallyHasEntityReplacementFailedEvent(final Entity 
expectedCluster) {
-        Asserts.succeedsEventually(new Runnable() {
-            @Override public void run() {
-                assertEquals(Iterables.getOnlyElement(events).getSensor(), 
ServiceReplacer.ENTITY_REPLACEMENT_FAILED, "events="+events);
-                assertEquals(Iterables.getOnlyElement(events).getSource(), 
expectedCluster, "events="+events);
-                
assertEquals(((FailureDescriptor)Iterables.getOnlyElement(events).getValue()).getComponent(),
 expectedCluster, "events="+events);
-            }});
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/ha/ServiceRestarterTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ServiceRestarterTest.java 
b/policy/src/test/java/brooklyn/policy/ha/ServiceRestarterTest.java
deleted file mode 100644
index 81cff78..0000000
--- a/policy/src/test/java/brooklyn/policy/ha/ServiceRestarterTest.java
+++ /dev/null
@@ -1,190 +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.assertNotEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-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.core.util.config.ConfigBag;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.apache.brooklyn.test.entity.TestEntity;
-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.trait.FailingEntity;
-import brooklyn.policy.ha.HASensors.FailureDescriptor;
-import brooklyn.test.Asserts;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-public class ServiceRestarterTest {
-
-    private static final int TIMEOUT_MS = 10*1000;
-
-    private ManagementContext managementContext;
-    private TestApplication app;
-    private TestEntity e1;
-    private ServiceRestarter policy;
-    private SensorEventListener<Object> eventListener;
-    private List<SensorEvent<?>> events;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = new LocalManagementContextForTests();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, 
managementContext);
-        e1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        events = Lists.newCopyOnWriteArrayList();
-        eventListener = new SensorEventListener<Object>() {
-            @Override public void onEvent(SensorEvent<Object> event) {
-                events.add(event);
-            }
-        };
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testRestartsOnFailure() throws Exception {
-        policy = new ServiceRestarter(new 
ConfigBag().configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED));
-        e1.addPolicy(policy);
-        
-        e1.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e1, "simulate 
failure"));
-        
-        Asserts.succeedsEventually(new Runnable() {
-            @Override public void run() {
-                assertEquals(e1.getCallHistory(), ImmutableList.of("restart"));
-            }});
-    }
-    
-    @Test(groups="Integration") // Has a 1 second wait
-    public void testDoesNotRestartsWhenHealthy() throws Exception {
-        policy = new ServiceRestarter(new 
ConfigBag().configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED));
-        e1.addPolicy(policy);
-        
-        e1.emit(HASensors.ENTITY_RECOVERED, new FailureDescriptor(e1, "not a 
failure"));
-        
-        Asserts.succeedsContinually(new Runnable() {
-            @Override public void run() {
-                assertEquals(e1.getCallHistory(), ImmutableList.of());
-            }});
-    }
-    
-    @Test
-    public void testEmitsFailureEventWhenRestarterFails() throws Exception {
-        final FailingEntity e2 = 
app.createAndManageChild(EntitySpec.create(FailingEntity.class)
-                .configure(FailingEntity.FAIL_ON_RESTART, true));
-        app.subscribe(e2, ServiceRestarter.ENTITY_RESTART_FAILED, 
eventListener);
-
-        policy = new ServiceRestarter(new 
ConfigBag().configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED));
-        e2.addPolicy(policy);
-
-        e2.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e2, "simulate 
failure"));
-        
-        Asserts.succeedsEventually(new Runnable() {
-            @Override public void run() {
-                assertEquals(Iterables.getOnlyElement(events).getSensor(), 
ServiceRestarter.ENTITY_RESTART_FAILED, "events="+events);
-                assertEquals(Iterables.getOnlyElement(events).getSource(), e2, 
"events="+events);
-                
assertEquals(((FailureDescriptor)Iterables.getOnlyElement(events).getValue()).getComponent(),
 e2, "events="+events);
-            }});
-        
-        assertEquals(e2.getAttribute(Attributes.SERVICE_STATE_ACTUAL), 
Lifecycle.ON_FIRE);
-    }
-    
-    @Test
-    public void testDoesNotSetOnFireOnFailure() throws Exception {
-        final FailingEntity e2 = 
app.createAndManageChild(EntitySpec.create(FailingEntity.class)
-                .configure(FailingEntity.FAIL_ON_RESTART, true));
-        app.subscribe(e2, ServiceRestarter.ENTITY_RESTART_FAILED, 
eventListener);
-
-        policy = new ServiceRestarter(new ConfigBag()
-                .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED)
-                .configure(ServiceRestarter.SET_ON_FIRE_ON_FAILURE, false));
-        e2.addPolicy(policy);
-
-        e2.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e2, "simulate 
failure"));
-        
-        Asserts.succeedsContinually(new Runnable() {
-            @Override public void run() {
-                
assertNotEquals(e2.getAttribute(Attributes.SERVICE_STATE_ACTUAL), 
Lifecycle.ON_FIRE);
-            }});
-    }
-    
-    // Previously RestarterPolicy called entity.restart inside the 
event-listener thread.
-    // That caused all other events for that entity's subscriptions to be 
queued until that
-    // entity's single event handler thread was free again.
-    @Test
-    public void testRestartDoesNotBlockOtherSubscriptions() throws Exception {
-        final CountDownLatch inRestartLatch = new CountDownLatch(1);
-        final CountDownLatch continueRestartLatch = new CountDownLatch(1);
-        
-        final FailingEntity e2 = 
app.createAndManageChild(EntitySpec.create(FailingEntity.class)
-                .configure(FailingEntity.FAIL_ON_RESTART, true)
-                .configure(FailingEntity.EXEC_ON_FAILURE, new Function<Object, 
Void>() {
-                    @Override public Void apply(Object input) {
-                        inRestartLatch.countDown();
-                        try {
-                            continueRestartLatch.await();
-                        } catch (InterruptedException e) {
-                            throw Exceptions.propagate(e);
-                        }
-                        return null;
-                    }}));
-        
-        e2.addPolicy(PolicySpec.create(ServiceRestarter.class)
-                .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, 
HASensors.ENTITY_FAILED));
-        e2.subscribe(e2, TestEntity.SEQUENCE, eventListener);
-
-        // Cause failure, and wait for entity.restart to be blocking
-        e2.emit(HASensors.ENTITY_FAILED, new FailureDescriptor(e1, "simulate 
failure"));
-        assertTrue(inRestartLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        
-        // Expect other notifications to continue to get through
-        e2.setAttribute(TestEntity.SEQUENCE, 1);
-        Asserts.succeedsEventually(new Runnable() {
-            @Override public void run() {
-                assertEquals(Iterables.getOnlyElement(events).getValue(), 1);
-            }});
-
-        // Allow restart to finish
-        continueRestartLatch.countDown();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
----------------------------------------------------------------------
diff --git 
a/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
 
b/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
deleted file mode 100644
index 68db44c..0000000
--- 
a/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
+++ /dev/null
@@ -1,253 +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.loadbalancing;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.Group;
-import org.apache.brooklyn.api.entity.basic.EntityLocal;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.event.AttributeSensor;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.DynamicGroup;
-import brooklyn.entity.basic.Entities;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.basic.SimulatedLocation;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.time.Time;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-public class AbstractLoadBalancingPolicyTest {
-    
-    private static final Logger LOG = 
LoggerFactory.getLogger(AbstractLoadBalancingPolicyTest.class);
-    
-    protected static final long TIMEOUT_MS = 10*1000;
-    protected static final long SHORT_WAIT_MS = 250;
-    
-    protected static final long CONTAINER_STARTUP_DELAY_MS = 100;
-    
-    public static final AttributeSensor<Integer> TEST_METRIC =
-        Sensors.newIntegerSensor("test.metric", "Dummy workrate for test 
entities");
-    
-    public static final ConfigKey<Double> LOW_THRESHOLD_CONFIG_KEY = new 
BasicConfigKey<Double>(Double.class, TEST_METRIC.getName()+".threshold.low", 
"desc", 0.0);
-    public static final ConfigKey<Double> HIGH_THRESHOLD_CONFIG_KEY = new 
BasicConfigKey<Double>(Double.class, TEST_METRIC.getName()+".threshold.high", 
"desc", 0.0);
-    
-    protected TestApplication app;
-    protected SimulatedLocation loc;
-    protected BalanceableWorkerPool pool;
-    protected DefaultBalanceablePoolModel<Entity, Entity> model;
-    protected LoadBalancingPolicy policy;
-    protected Group containerGroup;
-    protected Group itemGroup;
-    protected Random random = new Random();
-    
-    @BeforeMethod(alwaysRun=true)
-    public void before() {
-        LOG.debug("In AbstractLoadBalancingPolicyTest.before()");
-        
-        MockItemEntityImpl.totalMoveCount.set(0);
-        MockItemEntityImpl.lastMoveTime.set(0);
-        
-        loc = new SimulatedLocation(MutableMap.of("name", "loc"));
-        
-        model = new DefaultBalanceablePoolModel<Entity, Entity>("pool-model");
-        
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        containerGroup = 
app.createAndManageChild(EntitySpec.create(DynamicGroup.class)
-                .displayName("containerGroup")
-                .configure(DynamicGroup.ENTITY_FILTER, 
Predicates.instanceOf(MockContainerEntity.class)));
-        itemGroup = 
app.createAndManageChild(EntitySpec.create(DynamicGroup.class)
-                .displayName("itemGroup")
-                .configure(DynamicGroup.ENTITY_FILTER, 
Predicates.instanceOf(MockItemEntity.class)));
-        pool = 
app.createAndManageChild(EntitySpec.create(BalanceableWorkerPool.class));
-        pool.setContents(containerGroup, itemGroup);
-        policy = new 
LoadBalancingPolicy(MutableMap.of("minPeriodBetweenExecs", 1), TEST_METRIC, 
model);
-        pool.addPolicy(policy);
-        app.start(ImmutableList.of(loc));
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void after() {
-        if (policy != null) policy.destroy();
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-    
-    // Using this utility, as it gives more info about the workrates of all 
containers rather than just the one that differs    
-    protected void assertWorkrates(Collection<MockContainerEntity> containers, 
Collection<Double> expectedC, double precision) {
-        Iterable<Double> actual = Iterables.transform(containers, new 
Function<MockContainerEntity, Double>() {
-            public Double apply(MockContainerEntity input) {
-                return getContainerWorkrate(input);
-            }});
-        
-        List<Double> expected = Lists.newArrayList(expectedC);
-        String errMsg = "actual="+actual+"; expected="+expected;
-        assertEquals(containers.size(), expected.size(), errMsg);
-        for (int i = 0; i < containers.size(); i++) {
-            assertEquals(Iterables.get(actual, i), expected.get(i), precision, 
errMsg);
-        }
-    }
-    
-    protected void assertWorkratesEventually(Collection<MockContainerEntity> 
containers, Iterable<? extends Movable> items, Collection<Double> expected) {
-        assertWorkratesEventually(containers, items, expected, 0d);
-    }
-
-    /**
-     * Asserts that the given container have the given expected workrates (by 
querying the containers directly).
-     * Accepts an accuracy of "precision" for each container's workrate.
-     */
-    protected void assertWorkratesEventually(final 
Collection<MockContainerEntity> containers, final Iterable<? extends Movable> 
items, final Collection<Double> expected, final double precision) {
-        try {
-            Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), 
new Runnable() {
-                public void run() {
-                    assertWorkrates(containers, expected, precision);
-                }});
-        } catch (AssertionError e) {
-            String errMsg = e.getMessage()+"; 
"+verboseDumpToString(containers, items);
-            throw new RuntimeException(errMsg, e);
-        }
-    }
-
-    // Using this utility, as it gives more info about the workrates of all 
containers rather than just the one that differs    
-    protected void assertWorkratesContinually(List<MockContainerEntity> 
containers, Iterable<? extends Movable> items, List<Double> expected) {
-        assertWorkratesContinually(containers, items, expected, 0d);
-    }
-
-    /**
-     * Asserts that the given containers have the given expected workrates (by 
querying the containers directly)
-     * continuously for SHORT_WAIT_MS.
-     * Accepts an accuracy of "precision" for each container's workrate.
-     */
-    protected void assertWorkratesContinually(final List<MockContainerEntity> 
containers, Iterable<? extends Movable> items, final List<Double> expected, 
final double precision) {
-        try {
-            Asserts.succeedsContinually(MutableMap.of("timeout", 
SHORT_WAIT_MS), new Runnable() {
-                public void run() {
-                    assertWorkrates(containers, expected, precision);
-                }});
-        } catch (AssertionError e) {
-            String errMsg = e.getMessage()+"; 
"+verboseDumpToString(containers, items);
-            throw new RuntimeException(errMsg, e);
-        }
-    }
-
-    protected String verboseDumpToString(Iterable<MockContainerEntity> 
containers, Iterable<? extends Movable> items) {
-        Iterable<Double> containerRates = Iterables.transform(containers, new 
Function<MockContainerEntity, Double>() {
-            @Override public Double apply(MockContainerEntity input) {
-                return (double) input.getWorkrate();
-            }});
-        
-        Map<MockContainerEntity, Set<Movable>> itemDistributionByContainer = 
Maps.newLinkedHashMap();
-        for (MockContainerEntity container : containers) {
-            itemDistributionByContainer.put(container, 
container.getBalanceableItems());
-        }
-        
-        Map<Movable, BalanceableContainer<?>> itemDistributionByItem = 
Maps.newLinkedHashMap();
-        for (Movable item : items) {
-            itemDistributionByItem.put(item, 
item.getAttribute(Movable.CONTAINER));
-        }
-
-        String modelItemDistribution = model.itemDistributionToString();
-        return "containers="+containers+"; containerRates="+containerRates
-                +"; itemDistributionByContainer="+itemDistributionByContainer
-                +"; itemDistributionByItem="+itemDistributionByItem
-                +"; model="+modelItemDistribution
-                +"; totalMoves="+MockItemEntityImpl.totalMoveCount
-                +"; 
lastMoveTime="+Time.makeDateString(MockItemEntityImpl.lastMoveTime.get());
-    }
-    
-    protected MockContainerEntity newContainer(TestApplication app, String 
name, double lowThreshold, double highThreshold) {
-        return newAsyncContainer(app, name, lowThreshold, highThreshold, 0);
-    }
-    
-    /**
-     * Creates a new container that will take "delay" millis to complete its 
start-up.
-     */
-    protected MockContainerEntity newAsyncContainer(TestApplication app, 
String name, double lowThreshold, double highThreshold, long delay) {
-        MockContainerEntity container = 
app.createAndManageChild(EntitySpec.create(MockContainerEntity.class)
-                .displayName(name)
-                .configure(MockContainerEntity.DELAY, delay)
-                .configure(LOW_THRESHOLD_CONFIG_KEY, lowThreshold)
-                .configure(HIGH_THRESHOLD_CONFIG_KEY, highThreshold));
-        LOG.debug("Managed new container {}", container);
-        container.start(ImmutableList.of(loc));
-        return container;
-    }
-    
-    protected static MockItemEntity newItem(TestApplication app, 
MockContainerEntity container, String name, double workrate) {
-        MockItemEntity item = 
app.createAndManageChild(EntitySpec.create(MockItemEntity.class)
-                .displayName(name));
-        LOG.debug("Managing new item {} on container {}", item, container);
-        item.move(container);
-        ((EntityLocal)item).setAttribute(TEST_METRIC, (int)workrate);
-        return item;
-    }
-    
-    protected static MockItemEntity newLockedItem(TestApplication app, 
MockContainerEntity container, String name, double workrate) {
-        MockItemEntity item = 
app.createAndManageChild(EntitySpec.create(MockItemEntity.class)
-                .displayName(name)
-                .configure(Movable.IMMOVABLE, true));
-        LOG.debug("Managed new item {} on container {}", item, container);
-        item.move(container);
-        ((EntityLocal)item).setAttribute(TEST_METRIC, (int)workrate);
-        return item;
-    }
-    
-    /**
-     * Asks the item directly for its workrate.
-     */
-    protected static double getItemWorkrate(MockItemEntity item) {
-        Object result = item.getAttribute(TEST_METRIC);
-        return (result == null ? 0 : ((Number) result).doubleValue());
-    }
-    
-    /**
-     * Asks the container for its items, and then each of those items directly 
for their workrates; returns the total.
-     */
-    protected static double getContainerWorkrate(MockContainerEntity 
container) {
-        double result = 0.0;
-        Preconditions.checkNotNull(container, "container");
-        for (Movable item : container.getBalanceableItems()) {
-            Preconditions.checkNotNull(item, "item in container");
-            assertEquals(item.getContainerId(), container.getId());
-            result += getItemWorkrate((MockItemEntity)item);
-        }
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
----------------------------------------------------------------------
diff --git 
a/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
 
b/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
deleted file mode 100644
index e744720..0000000
--- 
a/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
+++ /dev/null
@@ -1,133 +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.loadbalancing;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import org.apache.brooklyn.api.entity.Group;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
-import org.apache.brooklyn.test.entity.TestApplication;
-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.AbstractGroup;
-import brooklyn.entity.basic.AbstractGroupImpl;
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.DynamicGroup;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.trait.Resizable;
-import org.apache.brooklyn.location.basic.SimulatedLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-
-public class BalanceableWorkerPoolTest {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(BalanceableWorkerPoolTest.class);
-    
-    protected static final long TIMEOUT_MS = 10*1000;
-    protected static final long SHORT_WAIT_MS = 250;
-    
-    protected static final long CONTAINER_STARTUP_DELAY_MS = 100;
-    
-    protected TestApplication app;
-    protected SimulatedLocation loc;
-    protected BalanceableWorkerPool pool;
-    protected Group containerGroup;
-    protected Group itemGroup;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void before() {
-        loc = new SimulatedLocation(MutableMap.of("name", "loc"));
-        
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
-        containerGroup = 
app.createAndManageChild(EntitySpec.create(DynamicGroup.class)
-                .displayName("containerGroup")
-                .configure(DynamicGroup.ENTITY_FILTER, 
Predicates.instanceOf(MockContainerEntity.class)));
-        itemGroup = 
app.createAndManageChild(EntitySpec.create(DynamicGroup.class)
-                .displayName("itemGroup")
-                .configure(DynamicGroup.ENTITY_FILTER, 
Predicates.instanceOf(MockItemEntity.class)));
-        pool = 
app.createAndManageChild(EntitySpec.create(BalanceableWorkerPool.class));
-        pool.setContents(containerGroup, itemGroup);
-        
-        app.start(ImmutableList.of(loc));
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void after() {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-    
-    @Test
-    public void testDefaultResizeFailsIfContainerGroupNotResizable() throws 
Exception {
-        try {
-            pool.resize(1);
-            fail();
-        } catch (Exception e) {
-            if (Exceptions.getFirstThrowableOfType(e, 
UnsupportedOperationException.class) == null) throw e;
-        }
-    }
-    
-    @Test
-    public void testDefaultResizeCallsResizeOnContainerGroup() {
-        LocallyResizableGroup resizable = 
app.createAndManageChild(EntitySpec.create(LocallyResizableGroup.class));
-        
-        BalanceableWorkerPool pool2 = 
app.createAndManageChild(EntitySpec.create(BalanceableWorkerPool.class));
-        pool2.setContents(resizable, itemGroup);
-        Entities.manage(pool2);
-        
-        pool2.resize(123);
-        assertEquals(resizable.getCurrentSize(), (Integer) 123);
-    }
-    
-    @Test
-    public void testCustomResizableCalledWhenResizing() {
-        LocallyResizableGroup resizable = 
app.createAndManageChild(EntitySpec.create(LocallyResizableGroup.class));
-        
-        pool.setResizable(resizable);
-        
-        pool.resize(123);
-        assertEquals(resizable.getCurrentSize(), (Integer)123);
-    }
-
-    @ImplementedBy(LocallyResizableGroupImpl.class)
-    public static interface LocallyResizableGroup extends AbstractGroup, 
Resizable {
-    }
-    
-    public static class LocallyResizableGroupImpl extends AbstractGroupImpl 
implements LocallyResizableGroup {
-        private int size = 0;
-
-        @Override
-        public Integer resize(Integer newSize) {
-            size = newSize;
-            return size;
-        }
-        @Override
-        public Integer getCurrentSize() {
-            return size;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
----------------------------------------------------------------------
diff --git 
a/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
 
b/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
deleted file mode 100644
index cf47359..0000000
--- 
a/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
+++ /dev/null
@@ -1,189 +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.loadbalancing;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.Group;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-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.DynamicGroup;
-import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.basic.SimulatedLocation;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class ItemsInContainersGroupTest {
-
-    // all tests are 20ms or less, but use a big timeout just in case very 
slow machine!
-    private static final long TIMEOUT_MS = 15000;
-    
-    private TestApplication app;
-    private SimulatedLocation loc;
-    private Group containerGroup;
-    private ItemsInContainersGroup itemGroup;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        loc = new SimulatedLocation(MutableMap.of("name", "loc"));
-        
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
-        containerGroup = 
app.createAndManageChild(EntitySpec.create(DynamicGroup.class)
-                .displayName("containerGroup")
-                .configure(DynamicGroup.ENTITY_FILTER, new Predicate<Entity>() 
{
-                    public boolean apply(Entity input) {
-                        return input instanceof MockContainerEntity && 
-                                
input.getConfig(MockContainerEntity.MOCK_MEMBERSHIP) == "ingroup";
-                    }}));
-        itemGroup = 
app.createAndManageChild(EntitySpec.create(ItemsInContainersGroup.class)
-                .displayName("itemGroup"));
-        itemGroup.setContainers(containerGroup);
-        
-        app.start(ImmutableList.of(loc));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    @Test
-    public void testSimpleMembership() throws Exception {
-        MockContainerEntity containerIn = newContainer(app, "A", "ingroup");
-        MockItemEntity item1 = newItem(app, containerIn, "1");
-        MockItemEntity item2 = newItem(app, containerIn, "2");
-        
-        assertItemsEventually(item1, item2);
-    }
-
-    @Test
-    public void testFilterIsAppliedToItems() throws Exception {
-        itemGroup.stop();
-        Entities.unmanage(itemGroup);
-        
-        itemGroup = 
app.createAndManageChild(EntitySpec.create(ItemsInContainersGroup.class)
-                .displayName("itemGroupWithDispName2")
-                .configure(ItemsInContainersGroup.ITEM_FILTER, new 
Predicate<Entity>() {
-                    public boolean apply(Entity input) {
-                        return "2".equals(input.getDisplayName());
-                    }}));
-        itemGroup.setContainers(containerGroup);
-        
-        MockContainerEntity containerIn = newContainer(app, "A", "ingroup");
-        MockItemEntity item1 = newItem(app, containerIn, "1");
-        MockItemEntity item2 = newItem(app, containerIn, "2");
-        
-        assertItemsEventually(item2); // does not include item1
-    }
-
-    @Test
-    public void testItemsInOtherContainersIgnored() throws Exception {
-        MockContainerEntity containerOut = newContainer(app, "A", "outgroup");
-        MockItemEntity item1 = newItem(app, containerOut, "1");
-        
-        assertItemsEventually();
-    }
-    
-    @Test
-    public void testItemMovedInIsAdded() throws Exception {
-        MockContainerEntity containerIn = newContainer(app, "A", "ingroup");
-        MockContainerEntity containerOut = newContainer(app, "A", "outgroup");
-        MockItemEntity item1 = newItem(app, containerOut, "1");
-        item1.move(containerIn);
-        
-        assertItemsEventually(item1);
-    }
-
-    @Test
-    public void testItemMovedOutIsRemoved() throws Exception {
-        MockContainerEntity containerIn = newContainer(app, "A", "ingroup");
-        MockContainerEntity containerOut = newContainer(app, "A", "outgroup");
-        MockItemEntity item1 = newItem(app, containerIn, "1");
-        assertItemsEventually(item1);
-        
-        item1.move(containerOut);
-        assertItemsEventually();
-    }
-
-    /*
-     * Previously could fail if...
-     * ItemsInContainersGroupImpl listener got notified of Movable.CONTAINER 
after entity was unmanaged
-     * (because being done in concurrent threads).
-     * This called ItemsInContainersGroupImpl.onItemMoved, which called 
addMember to add it back in again.
-     * In AbstractGroup.addMember, we now check if the entity is still 
managed, to 
-     * ensure there is synchronization for concurrent calls to add/remove 
member.
-     */
-    @Test
-    public void testItemUnmanagedIsRemoved() throws Exception {
-        MockContainerEntity containerIn = newContainer(app, "A", "ingroup");
-        MockItemEntity item1 = newItem(app, containerIn, "1");
-        assertItemsEventually(item1);
-        
-        Entities.unmanage(item1);
-        assertItemsEventually();
-    }
-
-    // TODO How to test this? Will it be used?
-    // Adding a new container then adding items to it is tested in many other 
methods.
-    @Test(enabled=false)
-    public void testContainerAddedWillAddItsItems() throws Exception {
-    }
-
-    @Test
-    public void testContainerRemovedWillRemoveItsItems() throws Exception {
-        MockContainerEntity containerA = newContainer(app, "A", "ingroup");
-        MockItemEntity item1 = newItem(app, containerA, "1");
-        assertItemsEventually(item1);
-        
-        Entities.unmanage(containerA);
-        assertItemsEventually();
-    }
-
-    private void assertItemsEventually(final MockItemEntity... expected) {
-        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new 
Runnable() {
-            public void run() {
-                assertEquals(ImmutableSet.copyOf(itemGroup.getMembers()), 
ImmutableSet.copyOf(expected));
-            }});
-    }   
-     
-    private MockContainerEntity newContainer(TestApplication app, String name, 
String membership) {
-        MockContainerEntity container = 
app.createAndManageChild(EntitySpec.create(MockContainerEntity.class)
-                        .displayName(name)
-                        .configure(MockContainerEntity.MOCK_MEMBERSHIP, 
membership));
-        container.start(ImmutableList.of(loc));
-        return container;
-    }
-    
-    private static MockItemEntity newItem(TestApplication app, 
MockContainerEntity container, String name) {
-        MockItemEntity item = 
app.createAndManageChild(EntitySpec.create(MockItemEntity.class)
-                .displayName(name));
-        item.move(container);
-        return item;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingModelTest.java
----------------------------------------------------------------------
diff --git 
a/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingModelTest.java
 
b/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingModelTest.java
deleted file mode 100644
index cae86e7..0000000
--- 
a/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingModelTest.java
+++ /dev/null
@@ -1,115 +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.loadbalancing;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Collections;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class LoadBalancingModelTest {
-
-    private static final double PRECISION = 0.00001;
-    
-    private MockContainerEntity container1 = new MockContainerEntityImpl();
-    private MockContainerEntity container2 = new MockContainerEntityImpl();
-    private MockItemEntity item1 = new MockItemEntityImpl();
-    private MockItemEntity item2 = new MockItemEntityImpl();
-    private MockItemEntity item3 = new MockItemEntityImpl();
-    
-    private DefaultBalanceablePoolModel<MockContainerEntity, MockItemEntity> 
model;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        model = new DefaultBalanceablePoolModel<MockContainerEntity, 
MockItemEntity>("myname");
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        // nothing to tear down; no management context created
-    }
-
-    @Test
-    public void testPoolRatesCorrectlySumContainers() throws Exception {
-        model.onContainerAdded(container1, 10d, 20d);
-        model.onContainerAdded(container2, 11d, 22d);
-        
-        assertEquals(model.getPoolLowThreshold(), 10d+11d, PRECISION);
-        assertEquals(model.getPoolHighThreshold(), 20d+22d, PRECISION);
-    }
-    
-    @Test
-    public void testPoolRatesCorrectlySumItems() throws Exception {
-        model.onContainerAdded(container1, 10d, 20d);
-        model.onItemAdded(item1, container1, true);
-        model.onItemAdded(item2, container1, true);
-        
-        model.onItemWorkrateUpdated(item1, 1d);
-        assertEquals(model.getCurrentPoolWorkrate(), 1d, PRECISION);
-        
-        model.onItemWorkrateUpdated(item2, 2d);
-        assertEquals(model.getCurrentPoolWorkrate(), 1d+2d, PRECISION);
-        
-        model.onItemWorkrateUpdated(item2, 4d);
-        assertEquals(model.getCurrentPoolWorkrate(), 1d+4d, PRECISION);
-        
-        model.onItemRemoved(item1);
-        assertEquals(model.getCurrentPoolWorkrate(), 4d, PRECISION);
-    }
-    
-    @Test
-    public void testWorkrateUpdateAfterItemRemovalIsNotRecorded() throws 
Exception {
-        model.onContainerAdded(container1, 10d, 20d);
-        model.onItemAdded(item1, container1, true);
-        model.onItemRemoved(item1);
-        model.onItemWorkrateUpdated(item1, 123d);
-        
-        assertEquals(model.getCurrentPoolWorkrate(), 0d, PRECISION);
-        assertEquals(model.getContainerWorkrates().get(container1), 0d, 
PRECISION);
-        assertEquals(model.getItemWorkrate(item1), null);
-    }
-    
-    @Test
-    public void testItemMovedWillUpdateContainerWorkrates() throws Exception {
-        model.onContainerAdded(container1, 10d, 20d);
-        model.onContainerAdded(container2, 11d, 21d);
-        model.onItemAdded(item1, container1, false);
-        model.onItemWorkrateUpdated(item1, 123d);
-        
-        model.onItemMoved(item1, container2);
-        
-        assertEquals(model.getItemsForContainer(container1), 
Collections.emptySet());
-        assertEquals(model.getItemsForContainer(container2), 
ImmutableSet.of(item1));
-        assertEquals(model.getItemWorkrate(item1), 123d);
-        assertEquals(model.getTotalWorkrate(container1), 0d);
-        assertEquals(model.getTotalWorkrate(container2), 123d);
-        assertEquals(model.getItemWorkrates(container1), 
Collections.emptyMap());
-        assertEquals(model.getItemWorkrates(container2), 
ImmutableMap.of(item1, 123d));
-        assertEquals(model.getContainerWorkrates(), 
ImmutableMap.of(container1, 0d, container2, 123d));
-        assertEquals(model.getCurrentPoolWorkrate(), 123d);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicyConcurrencyTest.java
----------------------------------------------------------------------
diff --git 
a/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicyConcurrencyTest.java
 
b/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicyConcurrencyTest.java
deleted file mode 100644
index 69d380b..0000000
--- 
a/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicyConcurrencyTest.java
+++ /dev/null
@@ -1,211 +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.loadbalancing;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.entity.basic.EntityLocal;
-import org.apache.brooklyn.test.entity.TestApplication;
-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.Entities;
-
-import com.google.common.collect.Lists;
-
-public class LoadBalancingPolicyConcurrencyTest extends 
AbstractLoadBalancingPolicyTest {
-    
-    private static final Logger LOG = 
LoggerFactory.getLogger(LoadBalancingPolicyConcurrencyTest.class);
-
-    private static final double WORKRATE_JITTER = 2d;
-    private static final int NUM_CONTAINERS = 20;
-    private static final int WORKRATE_UPDATE_PERIOD_MS = 1000;
-    
-    private ScheduledExecutorService scheduledExecutor;
-
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void before() {
-        scheduledExecutor = Executors.newScheduledThreadPool(10);
-        super.before();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    @Override
-    public void after() {
-        if (scheduledExecutor != null) scheduledExecutor.shutdownNow();
-        super.after();
-    }
-    
-    @Test
-    public void testSimplePeriodicWorkrateUpdates() {
-        List<MockItemEntity> items = Lists.newArrayList();
-        List<MockContainerEntity> containers = Lists.newArrayList();
-        
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            containers.add(newContainer(app, "container"+i, 10, 30));
-        }
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            newItemWithPeriodicWorkrates(app, containers.get(0), "item"+i, 20);
-        }
-
-        assertWorkratesEventually(containers, items, 
Collections.nCopies(NUM_CONTAINERS, 20d), WORKRATE_JITTER);
-    }
-    
-    @Test
-    public void testConcurrentlyAddContainers() {
-        final Queue<MockContainerEntity> containers = new 
ConcurrentLinkedQueue<MockContainerEntity>();
-        final List<MockItemEntity> items = Lists.newArrayList();
-        
-        containers.add(newContainer(app, "container-orig", 10, 30));
-        
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            items.add(newItemWithPeriodicWorkrates(app, 
containers.iterator().next(), "item"+i, 20));
-        }
-        for (int i = 0; i < NUM_CONTAINERS-1; i++) {
-            final int index = i;
-            scheduledExecutor.submit(new Callable<Void>() {
-                @Override public Void call() {
-                    containers.add(newContainer(app, "container"+index, 10, 
30));
-                    return null;
-                }});
-        }
-
-        assertWorkratesEventually(containers, items, 
Collections.nCopies(NUM_CONTAINERS, 20d), WORKRATE_JITTER);
-    }
-    
-    @Test
-    public void testConcurrentlyAddItems() {
-        final Queue<MockItemEntity> items = new 
ConcurrentLinkedQueue<MockItemEntity>();
-        final List<MockContainerEntity> containers = Lists.newArrayList();
-        
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            containers.add(newContainer(app, "container"+i, 10, 30));
-        }
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            final int index = i;
-            scheduledExecutor.submit(new Callable<Void>() {
-                @Override public Void call() {
-                    items.add(newItemWithPeriodicWorkrates(app, 
containers.get(0), "item"+index, 20));
-                    return null;
-                }});
-        }
-        assertWorkratesEventually(containers, items, 
Collections.nCopies(NUM_CONTAINERS, 20d), WORKRATE_JITTER);
-    }
-    
-    // TODO Got IndexOutOfBoundsException from containers.last()
-    @Test(groups="WIP", invocationCount=100)
-    public void testConcurrentlyRemoveContainers() {
-        List<MockItemEntity> items = Lists.newArrayList();
-        final List<MockContainerEntity> containers = Lists.newArrayList();
-        
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            containers.add(newContainer(app, "container"+i, 15, 45));
-        }
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            items.add(newItemWithPeriodicWorkrates(app, containers.get(i), 
"item"+i, 20));
-        }
-        
-        final List<MockContainerEntity> containersToStop = 
Lists.newArrayList();
-        for (int i = 0; i < NUM_CONTAINERS/2; i++) {
-            containersToStop.add(containers.remove(0));
-        }
-        for (final MockContainerEntity containerToStop : containersToStop) {
-            scheduledExecutor.submit(new Callable<Void>() {
-                @Override public Void call() {
-                    try {
-                        
containerToStop.offloadAndStop(containers.get(containers.size()-1));
-                        Entities.unmanage(containerToStop);
-                    } catch (Throwable t) {
-                        LOG.error("Error stopping container "+containerToStop, 
t);
-                    }
-                    return null;
-                }});
-        }
-        
-        assertWorkratesEventually(containers, items, 
Collections.nCopies((int)(NUM_CONTAINERS/2), 40d), WORKRATE_JITTER*2);
-    }
-    
-    @Test(groups="WIP")
-    public void testConcurrentlyRemoveItems() {
-        List<MockItemEntity> items = Lists.newArrayList();
-        List<MockContainerEntity> containers = Lists.newArrayList();
-        
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            containers.add(newContainer(app, "container"+i, 15, 45));
-        }
-        for (int i = 0; i < NUM_CONTAINERS*2; i++) {
-            items.add(newItemWithPeriodicWorkrates(app, 
containers.get(i%NUM_CONTAINERS), "item"+i, 20));
-        }
-        // should now have item0 and item{0+NUM_CONTAINERS} on container0, etc
-        
-        for (int i = 0; i < NUM_CONTAINERS; i++) {
-            // not removing consecutive items as that would leave it balanced!
-            int indexToStop = (i < NUM_CONTAINERS/2) ? NUM_CONTAINERS : 0; 
-            final MockItemEntity itemToStop = items.remove(indexToStop);
-            scheduledExecutor.submit(new Callable<Void>() {
-                @Override public Void call() {
-                    try {
-                        itemToStop.stop();
-                        Entities.unmanage(itemToStop);
-                    } catch (Throwable t) {
-                        LOG.error("Error stopping item "+itemToStop, t);
-                    }
-                    return null;
-                }});
-        }
-        
-        assertWorkratesEventually(containers, items, 
Collections.nCopies(NUM_CONTAINERS, 20d), WORKRATE_JITTER);
-    }
-    
-    protected MockItemEntity newItemWithPeriodicWorkrates(TestApplication app, 
MockContainerEntity container, String name, double workrate) {
-        MockItemEntity item = newItem(app, container, name, workrate);
-        scheduleItemWorkrateUpdates(item, workrate, WORKRATE_JITTER);
-        return item;
-    }
-    
-    private void scheduleItemWorkrateUpdates(final MockItemEntity item, final 
double workrate, final double jitter) {
-        final AtomicReference<Future<?>> futureRef = new 
AtomicReference<Future<?>>();
-        Future<?> future = scheduledExecutor.scheduleAtFixedRate(
-                new Runnable() {
-                    @Override public void run() {
-                        if (item.isStopped() && futureRef.get() != null) {
-                            futureRef.get().cancel(true);
-                            return;
-                        }
-                        double jitteredWorkrate = workrate + 
(random.nextDouble()*jitter*2 - jitter);
-                        ((EntityLocal)item).setAttribute(TEST_METRIC, (int) 
Math.max(0, jitteredWorkrate));
-                    }
-                },
-                0, WORKRATE_UPDATE_PERIOD_MS, TimeUnit.MILLISECONDS);
-        futureRef.set(future);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d30ff597/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicySoakTest.java
----------------------------------------------------------------------
diff --git 
a/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicySoakTest.java
 
b/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicySoakTest.java
deleted file mode 100644
index 1bb8dc4..0000000
--- 
a/policy/src/test/java/brooklyn/policy/loadbalancing/LoadBalancingPolicySoakTest.java
+++ /dev/null
@@ -1,273 +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.loadbalancing;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.basic.EntityLocal;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-public class LoadBalancingPolicySoakTest extends 
AbstractLoadBalancingPolicyTest {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(LoadBalancingPolicySoakTest.class);
-    
-    private static final long TIMEOUT_MS = 40*1000;
-    
-    @Test
-    public void testLoadBalancingQuickTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 1;
-        config.numContainers = 5;
-        config.numItems = 5;
-        config.lowThreshold = 200;
-        config.highThreshold = 300;
-        config.totalRate = (int) 
(config.numContainers*(0.95*config.highThreshold));
-    
-        runLoadBalancingSoakTest(config);
-    }
-    
-    @Test
-    public void testLoadBalancingManyItemsQuickTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 1;
-        config.numContainers = 5;
-        config.numItems = 30;
-        config.lowThreshold = 200;
-        config.highThreshold = 300;
-        config.numContainerStopsPerCycle = 1;
-        config.numItemStopsPerCycle = 1;
-        config.totalRate = (int) 
(config.numContainers*(0.95*config.highThreshold));
-    
-        runLoadBalancingSoakTest(config);
-    }
-    
-    @Test(groups={"Integration","Acceptance"}) // acceptance group, because 
it's slow to run many cycles
-    public void testLoadBalancingSoakTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 100;
-        config.numContainers = 5;
-        config.numItems = 5;
-        config.lowThreshold = 200;
-        config.highThreshold = 300;
-        config.totalRate = (int) 
(config.numContainers*(0.95*config.highThreshold));
-    
-        runLoadBalancingSoakTest(config);
-    }
-
-    @Test(groups={"Integration","Acceptance"}) // acceptance group, because 
it's slow to run many cycles
-    public void testLoadBalancingManyItemsSoakTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 100;
-        config.numContainers = 5;
-        config.numItems = 30;
-        config.lowThreshold = 200;
-        config.highThreshold = 300;
-        config.totalRate = (int) 
(config.numContainers*(0.95*config.highThreshold));
-        config.numContainerStopsPerCycle = 3;
-        config.numItemStopsPerCycle = 10;
-        
-        runLoadBalancingSoakTest(config);
-    }
-
-    @Test(groups={"Integration","Acceptance"})
-    public void testLoadBalancingManyManyItemsTest() {
-        RunConfig config = new RunConfig();
-        config.numCycles = 1;
-        config.numContainers = 5;
-        config.numItems = 1000;
-        config.lowThreshold = 2000;
-        config.highThreshold = 3000;
-        config.numContainerStopsPerCycle = 0;
-        config.numItemStopsPerCycle = 0;
-        config.totalRate = (int) 
(config.numContainers*(0.95*config.highThreshold));
-        config.verbose = false;
-        
-        runLoadBalancingSoakTest(config);
-    }
-    
-    private void runLoadBalancingSoakTest(RunConfig config) {
-        final int numCycles = config.numCycles;
-        final int numContainers = config.numContainers;
-        final int numItems = config.numItems;
-        final double lowThreshold = config.lowThreshold;
-        final double highThreshold = config.highThreshold;
-        final int totalRate = config.totalRate;
-        final int numContainerStopsPerCycle = config.numContainerStopsPerCycle;
-        final int numItemStopsPerCycle = config.numItemStopsPerCycle;
-        final boolean verbose = config.verbose;
-        
-        MockItemEntityImpl.totalMoveCount.set(0);
-        
-        final List<MockContainerEntity> containers = new 
ArrayList<MockContainerEntity>();
-        final List<MockItemEntity> items = new ArrayList<MockItemEntity>();
-
-        for (int i = 1; i <= numContainers; i++) {
-            MockContainerEntity container = newContainer(app, "container-"+i, 
lowThreshold, highThreshold);
-            containers.add(container);
-        }
-        for (int i = 1; i <= numItems; i++) {
-            MockItemEntity item = newItem(app, containers.get(0), "item-"+i, 
5);
-            items.add(item);
-        }
-        
-        for (int i = 1; i <= numCycles; i++) {
-            LOG.info(LoadBalancingPolicySoakTest.class.getSimpleName()+": 
cycle "+i);
-            
-            // Stop items, and start others
-            for (int j = 1; j <= numItemStopsPerCycle; j++) {
-                int itemIndex = random.nextInt(numItems);
-                MockItemEntity itemToStop = items.get(itemIndex);
-                itemToStop.stop();
-                LOG.debug("Unmanaging item {}", itemToStop);
-                Entities.unmanage(itemToStop);
-                items.set(itemIndex, newItem(app, containers.get(0), 
"item-"+(itemIndex+1)+"."+i+"."+j, 5));
-            }
-            
-            // Repartition the load across the items
-            final List<Integer> itemRates = randomlyDivideLoad(numItems, 
totalRate, 0, (int)highThreshold);
-            
-            for (int j = 0; j < numItems; j++) {
-                MockItemEntity item = items.get(j);
-                ((EntityLocal)item).setAttribute(MockItemEntity.TEST_METRIC, 
itemRates.get(j));
-            }
-                
-            // Stop containers, and start others
-            for (int j = 1; j <= numContainerStopsPerCycle; j++) {
-                int containerIndex = random.nextInt(numContainers);
-                MockContainerEntity containerToStop = 
containers.get(containerIndex);
-                
containerToStop.offloadAndStop(containers.get((containerIndex+1)%numContainers));
-                LOG.debug("Unmanaging container {}", containerToStop);
-                Entities.unmanage(containerToStop);
-                
-                MockContainerEntity containerToAdd = newContainer(app, 
"container-"+(containerIndex+1)+"."+i+"."+j, lowThreshold, highThreshold);
-                containers.set(containerIndex, containerToAdd);
-            }
-
-            // Assert that the items become balanced again
-            Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), 
new Runnable() {
-                @Override public void run() {
-                    Iterable<Double> containerRates = 
Iterables.transform(containers, new Function<MockContainerEntity, Double>() {
-                        @Override public Double apply(MockContainerEntity 
input) {
-                            return (double) input.getWorkrate();
-                        }});
-                    
-                    String errMsg;
-                    if (verbose) {
-                        errMsg = verboseDumpToString(containers, items)+"; 
itemRates="+itemRates;
-                    } else {
-                        errMsg = containerRates+"; 
totalMoves="+MockItemEntityImpl.totalMoveCount;
-                    }
-                    
-                    // Check that haven't lost any items
-                    // (as observed in one jenkins build failure: 2014-03-18; 
but that could also be 
-                    // explained by errMsg generated in the middle of a move)
-                    List<Entity> itemsFromModel = Lists.newArrayList();
-                    List<Entity> itemsFromContainers = Lists.newArrayList();
-                    for (Entity container : model.getPoolContents()) {
-                        
itemsFromModel.addAll(model.getItemsForContainer(container));
-                    }
-                    for (MockContainerEntity container : containers) {
-                        
itemsFromContainers.addAll(container.getBalanceableItems());
-                    }
-                    Asserts.assertEqualsIgnoringOrder(itemsFromModel, items, 
true, errMsg);
-                    Asserts.assertEqualsIgnoringOrder(itemsFromContainers, 
items, true, errMsg);
-                    
-                    // Check overall container rates are balanced
-                    assertEquals(sum(containerRates), sum(itemRates), errMsg);
-                    for (double containerRate : containerRates) {
-                        assertTrue(containerRate >= lowThreshold, errMsg);
-                        assertTrue(containerRate <= highThreshold, errMsg);
-                    }
-                }});
-        }
-    }
-    
-    private static class RunConfig {
-        int numCycles = 1;
-        int numContainers = 5;
-        int numItems = 5;
-        double lowThreshold = 200;
-        double highThreshold = 300;
-        int totalRate = (int) (5*(0.95*highThreshold));
-        int numContainerStopsPerCycle = 1;
-        int numItemStopsPerCycle = 1;
-        boolean verbose = true;
-    }
-
-    // Testing conveniences.
-    
-    private double sum(Iterable<? extends Number> vals) {
-        double total = 0;;
-        for (Number val : vals) {
-            total += val.doubleValue();
-        }
-        return total;
-    }
-    
-    /**
-     * Distributes a given load across a number of items randomly. The 
variability in load for an item is dictated by the variance,
-     * but the total will always equal totalLoad.
-     * 
-     * The distribution of load is skewed: one side of the list will have 
bigger values than the other.
-     * Which side is skewed will vary, so when balancing a policy will find 
that things have entirely changed.
-     * 
-     * TODO This is not particularly good at distributing load, but it's 
random and skewed enough to force rebalancing.
-     */
-    private List<Integer> randomlyDivideLoad(int numItems, int totalLoad, int 
min, int max) {
-        List<Integer> result = new ArrayList<Integer>(numItems);
-        int totalRemaining = totalLoad;
-        int variance = 3;
-        int skew = 3;
-        
-        for (int i = 0; i < numItems; i++) {
-            int itemsRemaining = numItems-i;
-            int itemFairShare = (totalRemaining/itemsRemaining);
-            double skewFactor = ((double)i/numItems)*2 - 1; // a number 
between -1 and 1, depending how far through the item set we are
-            int itemSkew = (int) (random.nextInt(skew)*skewFactor);
-            int itemLoad = itemFairShare + 
(random.nextInt(variance*2)-variance) + itemSkew;
-            itemLoad = Math.max(min, itemLoad);
-            itemLoad = Math.min(totalRemaining, itemLoad);
-            itemLoad = Math.min(max, itemLoad);
-            result.add(itemLoad);
-            totalRemaining -= itemLoad;
-        }
-
-        if (random.nextBoolean()) Collections.reverse(result);
-        
-        assertTrue(sum(result) <= totalLoad, "totalLoad="+totalLoad+"; 
result="+result);
-        
-        return result;
-    }
-}

Reply via email to