You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/08/20 00:53:54 UTC

[06/36] incubator-brooklyn git commit: Rename o.a.b.effector.core to o.a.b.core.effector

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java
new file mode 100644
index 0000000..76dcdba
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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 org.apache.brooklyn.core.effector;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.annotation.EffectorParam;
+import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.BasicTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+/**
+ * Test the operation of the {@link Effector} implementations.
+ *
+ * TODO clarify test purpose
+ */
+public class EffectorSayHiTest extends BrooklynAppUnitTestSupport {
+    
+    //TODO test edge/error conditions
+    //(missing parameters, wrong number of params, etc)
+
+    private static final Logger log = LoggerFactory.getLogger(EffectorSayHiTest.class);
+
+    private MyEntity e;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        e = app.createAndManageChild(EntitySpec.create(MyEntity.class));
+    }
+
+    @Test
+    public void testFindEffectorMetaData() {
+        assertEquals("sayHi1", e.SAY_HI_1.getName());
+        assertEquals("says hello", e.SAY_HI_1.getDescription());
+        
+        assertEquals(ImmutableList.of("name", "greeting"), getParameterNames(e.SAY_HI_1));
+        assertEquals(MutableMap.of("name", null, "greeting", "what to say"), getParameterDescriptions(e.SAY_HI_1));
+    }
+
+    @Test
+    public void testFindTraitEffectors() {
+        assertEquals(ImmutableList.of("locations"), getParameterNames(Startable.START));
+    }
+
+    @Test
+    public void testInvokeEffectors1() throws Exception {
+        assertEquals("hi Bob", e.sayHi1("Bob", "hi"));
+
+        assertEquals("hi Bob", e.SAY_HI_1.call(e, ImmutableMap.of("name", "Bob", "greeting", "hi")) );
+        assertEquals("hi Bob", e.invoke(e.SAY_HI_1, ImmutableMap.of("name", "Bob", "greeting", "hi")).get() );
+        
+        // and with default greeting param value
+        assertEquals("hi Bob", e.SAY_HI_1.call(e, ImmutableMap.of("name", "Bob", "greeting", "hi")) );
+        assertEquals("hello Bob", e.invoke(e.SAY_HI_1, ImmutableMap.of("name", "Bob")).get() );
+    }
+
+    @Test
+    public void testCanRetrieveTaskForEffector() {
+        e.sayHi1("Bob", "hi");
+
+        Set<Task<?>> tasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+                BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
+        assertEquals(tasks.size(), 1);
+        assertTrue(tasks.iterator().next().getDescription().contains("sayHi1"));
+    }
+
+    @Test
+    public void testDelegatedNestedEffectorNotRepresentedAsTask() {
+        e.delegateSayHi1("Bob", "hi");
+
+        Set<Task<?>> tasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+                BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
+        assertEquals(tasks.size(), 1);
+        assertTrue(tasks.iterator().next().getDescription().contains("delegateSayHi1"));
+        assertFalse(tasks.iterator().next().getDescription().contains("sayHi1"));
+    }
+
+    @Test
+    public void testCanExcludeNonEffectorTasks() throws Exception {
+        ExecutionContext executionContext = mgmt.getExecutionContext(e);
+        executionContext.submit(new BasicTask<Void>(new Runnable() { public void run() {} }));
+
+        Set<Task<?>> effectTasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+                BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
+        assertEquals(effectTasks.size(), 0);
+    }
+
+    public interface CanSayHi {
+        static MethodEffector<String> SAY_HI_1 = new MethodEffector<String>(CanSayHi.class, "sayHi1");
+        static MethodEffector<String> DELEGATE_SAY_HI_1 = new MethodEffector<String>(CanSayHi.class, "delegateSayHi1");
+    
+        @org.apache.brooklyn.core.annotation.Effector(description="says hello")
+        public String sayHi1(
+            @EffectorParam(name="name") String name,
+            @EffectorParam(name="greeting", defaultValue="hello", description="what to say") String greeting);
+        
+        @org.apache.brooklyn.core.annotation.Effector(description="delegate says hello")
+        public String delegateSayHi1(
+            @EffectorParam(name="name") String name,
+            @EffectorParam(name="greeting") String greeting);
+    }
+
+    @ImplementedBy(MyEntityImpl.class)
+    public interface MyEntity extends Entity, CanSayHi {
+    }
+    
+    public static class MyEntityImpl extends AbstractEntity implements MyEntity {
+        @Override
+        public String sayHi1(String name, String greeting) {
+            return greeting+" "+name;
+        }
+        @Override
+        public String delegateSayHi1(String name, String greeting) {
+            return sayHi1(name, greeting);
+        }
+    }
+    
+    private List<String> getParameterNames(Effector<?> effector) {
+        return ImmutableList.copyOf(getParameterDescriptions(effector).keySet());
+    }
+    
+    private Map<String, String> getParameterDescriptions(Effector<?> effector) {
+        Map<String,String> result = Maps.newLinkedHashMap();
+        for (ParameterType<?> parameter : effector.getParameters()) {
+            result.put(parameter.getName(), parameter.getDescription());
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java
new file mode 100644
index 0000000..3e79aa9
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java
@@ -0,0 +1,437 @@
+/*
+ * 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 org.apache.brooklyn.core.effector;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.HasTaskChildren;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.EffectorWithBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.TaskBuilder;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class EffectorTaskTest extends BrooklynAppUnitTestSupport {
+
+    // ----------- syntax 1 -- effector with body in a class
+    
+    public static final Effector<Integer> DOUBLE_1 = Effectors.effector(Integer.class, "double")
+            .description("doubles the given number")
+            .parameter(Integer.class, "numberToDouble")
+            .impl(new EffectorBody<Integer>() {
+                @Override
+                public Integer call(ConfigBag parameters) {
+                    // do a sanity check
+                    Assert.assertNotNull(entity());
+                    
+                    // finally double the input
+                    return 2*(Integer)parameters.getStringKey("numberToDouble");
+                }
+            })
+            .build();
+
+    public static class DoublingEntity extends AbstractEntity {
+        public static final Effector<Integer> DOUBLE = EffectorTaskTest.DOUBLE_1;
+    }
+
+    @Test
+    public void testSyntaxOneDouble1() throws Exception {
+        // just use "dynamic" support of effector
+        Assert.assertEquals(app.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+    
+    @Test
+    public void testSyntaxOneTaggedCorrectly() throws Exception {
+        Task<Integer> t = app.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3));
+        t.get();
+        checkTags(t, app, DOUBLE_1, false);
+    }
+    
+    @Test
+    // also assert it works when the effector is defined on an entity
+    public void testSimpleEffectorOnEntity() throws Exception {
+        Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
+        
+        Assert.assertEquals(doubler.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+
+    @Test
+    // also assert it works when an abstract effector name is passed in to the entity
+    public void testSimpleEffectorNameMatching() throws Exception {
+        Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
+        
+        Assert.assertEquals(doubler.invoke(Effectors.effector(Integer.class, "double").buildAbstract(), MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+
+
+    // ----------- syntax 2 -- effector with body built with fluent API
+    
+    public static EffectorTaskFactory<Integer> times(final EffectorTaskFactory<Integer> x, final int y) {
+        return new EffectorTaskFactory<Integer>() {
+            @Override
+            public Task<Integer> newTask(final Entity entity, final Effector<Integer> effector, final ConfigBag parameters) {
+                return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() { 
+                    return DynamicTasks.get( x.newTask(entity, effector, parameters) )*y; 
+                } }).build();
+            }
+        };
+    }
+
+    public static final Effector<Integer> DOUBLE_2 = Effectors.effector(Integer.class, "double")
+            .description("doubles the given number")
+            .parameter(Integer.class, "numberToDouble")
+            .impl(times(EffectorTasks.parameter(Integer.class, "numberToDouble"), 2))
+            .build();
+
+    @Test
+    public void testSyntaxTwoDouble2() throws Exception {
+        Assert.assertEquals(app.invoke(DOUBLE_2, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+
+    @Test
+    public void testEffectorImplTaggedCorrectly() throws Exception {
+        Task<Integer> t = app.invoke(DOUBLE_2, MutableMap.of("numberToDouble", 3));
+        t.get();
+        checkTags(t, app, DOUBLE_2, true);
+    }
+
+    public static final Effector<Integer> DOUBLE_CALL_ABSTRACT = Effectors.effector(Integer.class, "double_call")
+        .description("doubles the given number")
+        .parameter(Integer.class, "numberToDouble")
+        .buildAbstract();
+    public static final Effector<Integer> DOUBLE_CALL = Effectors.effector(DOUBLE_CALL_ABSTRACT)
+        .impl(new EffectorBody<Integer>() {
+            @Override
+            public Integer call(ConfigBag parameters) {
+                final Entity parent = entity();
+                final Entity child = Iterables.getOnlyElement(entity().getChildren());
+                
+                final Effector<Integer> DOUBLE_CHECK_ABSTRACT = Effectors.effector(Integer.class, "double_check")
+                    .description("doubles the given number and checks tags, assuming double exists as an effector here")
+                    .parameter(Integer.class, "numberToDouble")
+                    .buildAbstract();
+                Effector<Integer> DOUBLE_CHECK = Effectors.effector(DOUBLE_CHECK_ABSTRACT)
+                    .impl(new EffectorBody<Integer>() {
+                        @Override
+                        public Integer call(ConfigBag parameters) {
+                            Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, null, false));
+                            Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_CHECK_ABSTRACT, false));
+                            Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_1, false));
+                            Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, true));
+                            Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, false));
+                            Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_CALL_ABSTRACT, true));
+                            Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_1, true));
+                            
+                            return entity().invoke(DOUBLE_1, parameters.getAllConfig()).getUnchecked();
+                        }
+                    }).build();
+
+                return child.invoke(DOUBLE_CHECK, parameters.getAllConfig()).getUnchecked();
+            }
+        }).build();
+
+
+    @Test
+    // also assert it works when the effector is defined on an entity
+    public void testNestedEffectorTag() throws Exception {
+        app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
+        Assert.assertEquals(app.invoke(DOUBLE_CALL, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+
+
+    private void checkTags(Task<Integer> t, Entity entity, Effector<?> eff, boolean shouldHaveChild) {
+        Assert.assertEquals(BrooklynTaskTags.getContextEntity(t), app);
+        Assert.assertTrue(t.getTags().contains(BrooklynTaskTags.EFFECTOR_TAG), "missing effector tag; had: "+t.getTags());
+        Assert.assertTrue(t.getDescription().contains(eff.getName()), "description missing effector name: "+t.getDescription());
+        Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(t, entity, eff, false));
+        Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(t, null, null, false));
+        Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(t, entity, Startable.START, false));
+        
+        if (shouldHaveChild) {
+            Task<?> subtask = ((HasTaskChildren)t).getChildren().iterator().next();
+            Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(subtask, entity, eff, false));
+            Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(subtask, null, null, false));
+        }
+    }
+
+    // TEST parameter task missing
+    
+    // ----------------- syntax for more complex -- an effector using subtasks
+    
+    public static Task<Integer> add(final int x, final int y) {
+        return TaskBuilder.<Integer>builder().name("add").body(new Callable<Integer>() { public Integer call() { return x+y; } }).build();
+    }
+
+    public static Task<Integer> add(final Task<Integer> x, final int y) {
+        return TaskBuilder.<Integer>builder().name("add").body(new Callable<Integer>() { public Integer call() { return DynamicTasks.get(x)+y; } }).build();
+    }
+
+    public static Task<Integer> addBasic(final Task<Integer> x, final int y) {
+        return TaskBuilder.<Integer>builder().name("add (not dynamic)").dynamic(false).body(new Callable<Integer>() { public Integer call() {
+            Preconditions.checkState(x.isSubmitted()); 
+            return x.getUnchecked()+y; 
+        } }).build();
+    }
+
+    public static Task<Integer> times(final int x, final int y) {
+        return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() { return x*y; } }).build();
+    }
+
+    public static Task<Integer> times(final Task<Integer> x, final int y) {
+        return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() { return DynamicTasks.get(x)*y; } }).build();
+    }
+    
+    public static final Effector<Integer> TWO_X_PLUS_ONE = Effectors.effector(Integer.class, "twoXPlusOne")
+            .description("doubles the given number and adds one")
+            .parameter(Integer.class, "numberToStartWith")
+            .impl(new EffectorBody<Integer>() {
+                public Integer call(ConfigBag parameters) {
+                    int input = (Integer)parameters.getStringKey("numberToStartWith");
+                    queue( add(times(input, 2), 1) );
+                    return last(Integer.class);
+                }
+            })
+            .build();
+
+    public static final Effector<Integer> TWO_X_PLUS_ONE_BASIC = Effectors.effector(Integer.class, "twoXPlusOne_Basic")
+            .description("doubles the given number and adds one, as a basic task")
+            .parameter(Integer.class, "numberToStartWith")
+            .impl(new EffectorBody<Integer>() {
+                public Integer call(ConfigBag parameters) {
+                    int input = (Integer)parameters.getStringKey("numberToStartWith");
+                    // note the subtasks must be queued explicitly with a basic task
+                    // (but with the DynamicSequentialTask they can be resolved by the task itself; see above)
+                    Task<Integer> product = queue(times(input, 2));
+                    queue( addBasic(product, 1) );
+                    return last(Integer.class);
+                }
+            })
+            .build();
+
+    // TODO a chaining style approach
+    
+    public static class Txp1Entity extends AbstractEntity {
+        public static final Effector<Integer> TWO_X_P_1 = EffectorTaskTest.TWO_X_PLUS_ONE;
+    }
+
+    /** the composed effector should allow us to inspect its children */
+    @Test
+    public void testComposedEffector() throws Exception {
+        Entity txp1 = app.createAndManageChild(EntitySpec.create(Entity.class, Txp1Entity.class));
+        
+        Task<Integer> e = txp1.invoke(TWO_X_PLUS_ONE, MutableMap.of("numberToStartWith", 3));
+        Assert.assertTrue(e instanceof DynamicSequentialTask);
+        Assert.assertEquals(e.get(), (Integer)7);
+        Assert.assertEquals( Iterables.size( ((HasTaskChildren)e).getChildren() ), 1);
+        Task<?> child = ((HasTaskChildren)e).getChildren().iterator().next();
+        Assert.assertEquals( Iterables.size( ((HasTaskChildren)child).getChildren() ), 1);
+    }
+
+    /** the composed effector should allow us to inspect its children */
+    @Test
+    public void testComposedEffectorBasic() throws Exception {
+        Entity txp1 = app.createAndManageChild(EntitySpec.create(Entity.class, Txp1Entity.class));
+        
+        Task<Integer> e = txp1.invoke(TWO_X_PLUS_ONE_BASIC, MutableMap.of("numberToStartWith", 3));
+        Assert.assertTrue(e instanceof DynamicSequentialTask);
+        Assert.assertEquals(e.get(), (Integer)7);
+        Assert.assertEquals( Iterables.size( ((HasTaskChildren)e).getChildren() ), 2);
+    }
+
+    // --------- defining 
+    
+    @Test
+    public void testEffectorWithBodyWorksEvenIfNotOnEntity() throws Exception {
+        Entity doubler = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        
+        Assert.assertEquals(doubler.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+
+    public static final Effector<Integer> DOUBLE_BODYLESS = Effectors.effector(Integer.class, "double")
+            .description("doubles the given number")
+            .parameter(Integer.class, "numberToDouble")
+            .buildAbstract();
+    
+    @Test
+    public void testEffectorWithoutBodyFails() throws Exception {
+        Entity doubler = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        
+        boolean failed = false;
+        try {
+            doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3));
+        } catch (Exception e) {
+            failed = true;
+        }
+        if (!failed) Assert.fail("doubling should have failed because it had no body");
+    }
+
+    @Test
+    public void testEffectorBodyAdded() throws Exception {
+        EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        
+        // not yet present
+        Assert.assertNull( doubler.getEffector("double") );
+        
+        // add it
+        doubler.getMutableEntityType().addEffector(DOUBLE_BODYLESS, new EffectorBody<Integer>() {
+            @Override
+            public Integer call(ConfigBag parameters) {
+                int input = (Integer)parameters.getStringKey("numberToDouble");
+                return queue(times(input, 2)).getUnchecked();            
+            }
+        });
+        // now it is present
+        Assert.assertNotNull( doubler.getEffector("double") );
+        
+        Assert.assertEquals(doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+
+    @Test
+    public void testEffectorBodyAddedImplicitlyButBodylessSignatureInvoked() throws Exception {
+        EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        
+        // add it
+        doubler.getMutableEntityType().addEffector(DOUBLE_1);
+
+        // invoke it, but using something with equivalent name (and signature -- though only name is used currently)
+        // ensures that the call picks up the body by looking in the actual entity
+        Assert.assertEquals(doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+    }
+ 
+    @Test(dependsOnMethods={"testEffectorBodyAdded"})
+    public void testEntityNotPermanentlyChanged() throws Exception {
+        EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        // ensures that independent creations of the class previously modified do not have this effector 
+        Assert.assertNull( doubler.getEffector("double") );
+   }
+    
+    // --- overriding by using statics ---------
+
+    public static class BadDoublingEntity extends DoublingEntity {
+        public static final Effector<Integer> DOUBLE = Effectors.effector(DoublingEntity.DOUBLE).
+                impl( ((EffectorWithBody<Integer>)TWO_X_PLUS_ONE).getBody() ).build();
+    }
+
+    @Test
+    // also assert it works when the entity is defined on an entity
+    public void testOverriddenEffectorOnEntity() throws Exception {
+        Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, BadDoublingEntity.class));
+        
+        Assert.assertEquals(doubler.invoke(DoublingEntity.DOUBLE, MutableMap.of("numberToDouble", 3, "numberToStartWith", 3)).get(), (Integer)7);
+    }
+    
+    public static final Effector<Void> DUMMY = Effectors.effector(Void.class, "dummy")
+            .impl(new EffectorBody<Void>() {
+                @Override
+                public Void call(ConfigBag parameters) {
+                    return null;
+                }
+            })
+            .build();
+    
+    public static final Effector<Void> STALL = Effectors.effector(Void.class, "stall")
+            .parameter(AtomicBoolean.class, "lock")
+            .impl(new EffectorBody<Void>() {
+                @Override
+                public Void call(ConfigBag parameters) {
+                    AtomicBoolean lock = (AtomicBoolean)parameters.getStringKey("lock");
+                    synchronized(lock) {
+                        if (!lock.get()) {
+                            try {
+                                lock.wait();
+                            } catch (InterruptedException e) {
+                                Exceptions.propagate(e);
+                            }
+                        }
+                    }
+                    return null;
+                }
+            })
+            .build();
+
+    public static final Effector<Void> CONTEXT = Effectors.effector(Void.class, "stall_caller")
+            .parameter(AtomicBoolean.class, "lock")
+            .impl(new EffectorBody<Void>() {
+                @Override
+                public Void call(ConfigBag parameters) {
+                    Entity child = Iterables.getOnlyElement(entity().getChildren());
+                    AtomicBoolean lock = new AtomicBoolean();
+                    Task<Void> dummyTask = null;
+
+                    try {
+                        // Queue a (DST secondary) task which waits until notified, so that tasks queued later will get blocked
+                        queue(Effectors.invocation(entity(), STALL, ImmutableMap.of("lock", lock)));
+    
+                        // Start a new task - submitted directly to child's ExecutionContext, as well as added as a
+                        // DST secondary of the current effector.
+                        dummyTask = child.invoke(DUMMY, ImmutableMap.<String, Object>of());
+                        dummyTask.getUnchecked();
+
+                        // Execution completed in the child's ExecutionContext, but still queued as a secondary.
+                        // Destroy the child entity so that no subsequent tasks can be executed in its context.
+                        Entities.destroy(child);
+                    } finally {
+                        // Let STALL complete
+                        synchronized(lock) {
+                            lock.set(true);
+                            lock.notifyAll();
+                        }
+                        // At this point DUMMY will be unblocked and the DST will try to execute it as a secondary.
+                        // Submission will be ignored because DUMMY already executed.
+                        // If it's not ignored then submission will fail because entity is already unmanaged.
+                    }
+                    return null;
+                }
+            })
+            .build();
+    
+
+    @Test
+    public void testNestedEffectorExecutedAsSecondaryTask() throws Exception {
+        app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        Task<Void> effTask = app.invoke(CONTEXT, ImmutableMap.<String, Object>of());
+        effTask.get();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java
new file mode 100644
index 0000000..fce676a
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java
@@ -0,0 +1,265 @@
+/*
+ * 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 org.apache.brooklyn.core.effector.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasksTest;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.commons.io.FileUtils;
+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 org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+import com.google.common.io.Files;
+
+public class SshEffectorTasksTest {
+
+    private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
+    
+    TestApplication app;
+    ManagementContext mgmt;
+    SshMachineLocation host;
+    File tempDir;
+    
+    boolean failureExpected;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setup() throws Exception {
+        app = TestApplication.Factory.newManagedInstanceForTests();
+        mgmt = app.getManagementContext();
+        
+        LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+        host = lhc.obtain();
+        app.start(Arrays.asList(host));
+        clearExpectedFailure();
+        tempDir = Files.createTempDir();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        mgmt = null;
+        FileUtils.deleteDirectory(tempDir);
+        checkExpectedFailure();
+    }
+
+    protected void checkExpectedFailure() {
+        if (failureExpected) {
+            clearExpectedFailure();
+            Assert.fail("Test should have thrown an exception but it did not.");
+        }
+    }
+    
+    protected void clearExpectedFailure() {
+        failureExpected = false;
+    }
+
+    protected void setExpectingFailure() {
+        failureExpected = true;
+    }
+    
+    public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
+        return Entities.submit(app, taskFactory);
+    }
+    
+    // ------------------- basic ssh
+    
+    @Test(groups="Integration")
+    public void testSshEchoHello() {
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
+        Assert.assertFalse(t.isDone());
+        Assert.assertEquals(t.get(), (Integer)0);
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        Assert.assertEquals(t.getStdout().trim(), "hello world");
+    }
+
+    @Test(groups="Integration")
+    public void testSshPut() throws IOException {
+        String fn = Urls.mergePaths(tempDir.getPath(), "f1");
+        SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
+        t.block();
+        Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
+        // and make sure this doesn't throw
+        Assert.assertTrue(t.isDone());
+        Assert.assertTrue(t.isSuccessful());
+        Assert.assertEquals(t.get(), null);
+        Assert.assertEquals(t.getExitCode(), (Integer)0);
+    }
+
+    @Test(groups="Integration")
+    public void testSshFetch() throws IOException {
+        String fn = Urls.mergePaths(tempDir.getPath(), "f2");
+        FileUtils.write(new File(fn), "hello fetched world");
+        
+        SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
+        t.block();
+        
+        Assert.assertTrue(t.isDone());
+        Assert.assertEquals(t.get(), "hello fetched world");
+    }
+
+    // ----------------- pid stuff
+    
+    @Test(groups="Integration")
+    public void testNonRunningPid() {
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
+        Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
+        Assert.assertNotEquals(t.getExitCode(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
+        Assert.assertFalse(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testNonRunningPidRequired() {
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+        }
+        checkExpectedFailure();
+    }
+
+    public static Integer getMyPid() {
+        try {
+            java.lang.management.RuntimeMXBean runtime = 
+                    java.lang.management.ManagementFactory.getRuntimeMXBean();
+            java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
+            jvm.setAccessible(true);
+//            sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+            Object mgmt = jvm.get(runtime);
+            java.lang.reflect.Method pid_method =  
+                    mgmt.getClass().getDeclaredMethod("getProcessId");
+            pid_method.setAccessible(true);
+
+            return (Integer) pid_method.invoke(mgmt);
+        } catch (Exception e) {
+            throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
+        }
+    }
+
+    @Test(groups="Integration")
+    public void testRunningPid() {
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
+        Assert.assertTrue(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testRunningPidFromFile() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
+        Assert.assertTrue(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailure() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( "99999".getBytes(), f );
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)1);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)1);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)2);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnSuccess() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+        
+        t.getTask().getUnchecked();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
+        
+        t.getTask().getUnchecked();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
index 885eb45..fb9276c 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
@@ -24,10 +24,10 @@ import static org.testng.Assert.assertFalse;
 import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.effector.EffectorTaskTest;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.EffectorTaskTest;
 import org.apache.brooklyn.entity.stock.BasicEntity;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
index c01c5c9..cead05a 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
@@ -47,13 +47,13 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.core.effector.MethodEffector;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
 import org.apache.brooklyn.core.test.entity.TestEntity;
 import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.effector.core.MethodEffector;
 import org.apache.brooklyn.sensor.core.BasicSensorEvent;
 import org.apache.brooklyn.sensor.core.Sensors;
 import org.apache.brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
index 9d14868..a217514 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.annotation.Effector;
 import org.apache.brooklyn.core.annotation.EffectorParam;
 import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
 import org.apache.brooklyn.entity.group.AbstractGroup;
 import org.apache.brooklyn.sensor.core.BasicSensor;
 import org.apache.brooklyn.sensor.core.Sensors;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
index f648419..1d50609 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
@@ -42,6 +42,7 @@ import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemDtoAbstract;
 import org.apache.brooklyn.core.catalog.internal.CatalogTestUtils;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.effector.Effectors;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
@@ -50,7 +51,6 @@ import org.apache.brooklyn.core.objs.proxy.InternalEntityFactory;
 import org.apache.brooklyn.core.objs.proxy.InternalPolicyFactory;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.effector.core.Effectors;
 import org.apache.brooklyn.test.support.TestResourceUnavailableException;
 import org.apache.brooklyn.util.core.osgi.Osgis;
 import org.apache.brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
index c25dd0e..3b9bbfb 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
@@ -29,10 +29,10 @@ import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.stream.Streams;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
index 2106f18..8c185a0 100644
--- a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
+++ b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
@@ -36,11 +36,11 @@ import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.config.ListConfigKey;
 import org.apache.brooklyn.core.config.MapConfigKey;
 import org.apache.brooklyn.core.config.SetConfigKey;
+import org.apache.brooklyn.core.effector.MethodEffector;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.effector.core.MethodEffector;
 import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
 import org.apache.brooklyn.sensor.core.Sensors;
 import org.apache.brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java
deleted file mode 100644
index 786fe69..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java
+++ /dev/null
@@ -1,183 +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 org.apache.brooklyn.effector.core;
-
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.HasTaskChildren;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.trait.FailingEntity;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.location.SimulatedLocation;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.test.TestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-
-public class EffectorBasicTest extends BrooklynAppUnitTestSupport {
-
-    private static final Logger log = LoggerFactory.getLogger(EffectorBasicTest.class);
-    
-    // NB: more tests of effectors in EffectorSayHiTest and EffectorConcatenateTest
-    // as well as EntityConfigMapUsageTest and others
-
-    private List<SimulatedLocation> locs;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        locs = ImmutableList.of(new SimulatedLocation());
-    }
-    
-    @Test
-    public void testInvokeEffectorStart() {
-        app.start(locs);
-        TestUtils.assertSetsEqual(locs, app.getLocations());
-        // TODO above does not get registered as a task
-    }
-
-    @Test
-    public void testInvokeEffectorStartWithMap() {
-        app.invoke(Startable.START, MutableMap.of("locations", locs)).getUnchecked();
-        TestUtils.assertSetsEqual(locs, app.getLocations());
-    }
-
-    @Test
-    public void testInvokeEffectorStartWithArgs() {
-        Entities.invokeEffectorWithArgs((EntityLocal)app, app, Startable.START, locs).getUnchecked();
-        TestUtils.assertSetsEqual(locs, app.getLocations());
-    }
-
-    @Test
-    public void testInvokeEffectorStartWithTwoEntities() {
-        TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        app.start(locs);
-        TestUtils.assertSetsEqual(locs, app.getLocations());
-        TestUtils.assertSetsEqual(locs, entity.getLocations());
-        TestUtils.assertSetsEqual(locs, entity2.getLocations());
-    }
-    
-    @Test
-    public void testInvokeEffectorTaskHasTag() {
-        Task<Void> starting = app.invoke(Startable.START, MutableMap.of("locations", locs));
-//        log.info("TAGS: "+starting.getTags());
-        Assert.assertTrue(starting.getTags().contains(ManagementContextInternal.EFFECTOR_TAG));
-    }
-
-    // check various failure situations
-    
-    private FailingEntity createFailingEntity() {
-        FailingEntity entity = app.createAndManageChild(EntitySpec.create(FailingEntity.class)
-            .configure(FailingEntity.FAIL_ON_START, true));
-        return entity;
-    }
-
-    // uncaught failures are propagates
-    
-    @Test
-    public void testInvokeEffectorStartFailing_Method() {
-        FailingEntity entity = createFailingEntity();
-        assertStartMethodFails(entity);
-    }
-
-    @Test
-    public void testInvokeEffectorStartFailing_EntityInvoke() {
-        FailingEntity entity = createFailingEntity();
-        assertTaskFails( entity.invoke(Startable.START, MutableMap.of("locations", locs)) );
-    }
-     
-    @Test
-    public void testInvokeEffectorStartFailing_EntitiesInvoke() {
-        FailingEntity entity = createFailingEntity();
-        
-        assertTaskFails( Entities.invokeEffectorWithArgs(entity, entity, Startable.START, locs) );
-    }
-
-    // caught failures are NOT propagated!
-    
-    @Test
-    public void testInvokeEffectorStartFailing_MethodInDynamicTask() {
-        Task<Void> task = app.getExecutionContext().submit(Tasks.<Void>builder().dynamic(true).body(new Callable<Void>() {
-            @Override public Void call() throws Exception {
-                testInvokeEffectorStartFailing_Method();
-                return null;
-            }
-        }).build());
-        
-        assertTaskSucceeds(task);
-        assertTaskHasFailedChild(task);
-    }
-
-    @Test
-    public void testInvokeEffectorStartFailing_MethodInTask() {
-        Task<Void> task = app.getExecutionContext().submit(Tasks.<Void>builder().dynamic(false).body(new Callable<Void>() {
-            @Override public Void call() throws Exception {
-                testInvokeEffectorStartFailing_Method();
-                return null;
-            }
-        }).build());
-        
-        assertTaskSucceeds(task);
-    }
-
-    private void assertTaskSucceeds(Task<Void> task) {
-        task.getUnchecked();
-        Assert.assertFalse(task.isError());
-    }
-
-    private void assertTaskHasFailedChild(Task<Void> task) {
-        Assert.assertTrue(Tasks.failed( ((HasTaskChildren)task).getChildren() ).iterator().hasNext());
-    }
-        
-    private void assertStartMethodFails(FailingEntity entity) {
-        try {
-            entity.start(locs);
-            Assert.fail("Should have failed");
-        } catch (Exception e) {
-            // expected
-        }
-    }
-     
-    protected void assertTaskFails(Task<?> t) {
-        try {
-            t.get();
-            Assert.fail("Should have failed");
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            // expected
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java
deleted file mode 100644
index 9372e41..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java
+++ /dev/null
@@ -1,241 +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 org.apache.brooklyn.effector.core;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ExecutionManager;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.annotation.Effector;
-import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
-import org.apache.brooklyn.effector.core.MethodEffector;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.BasicExecutionContext;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class EffectorConcatenateTest {
-
-    
-    private static final Logger log = LoggerFactory.getLogger(EffectorConcatenateTest.class);
-    private static final long TIMEOUT = 10*1000;
-    
-    public static class MyEntityImpl extends AbstractEntity {
-
-        public static MethodEffector<String> CONCATENATE = new MethodEffector<String>(MyEntityImpl.class, "concatenate");
-        public static MethodEffector<Void> WAIT_A_BIT = new MethodEffector<Void>(MyEntityImpl.class, "waitabit");
-        public static MethodEffector<Void> SPAWN_CHILD = new MethodEffector<Void>(MyEntityImpl.class, "spawnchild");
-
-        public MyEntityImpl() {
-            super();
-        }
-        public MyEntityImpl(Entity parent) {
-            super(parent);
-        }
-
-        /** The "current task" representing the effector currently executing */
-        AtomicReference<Task<?>> waitingTask = new AtomicReference<Task<?>>();
-        
-        /** latch is .countDown'ed by the effector at the beginning of the "waiting" point */
-        CountDownLatch nowWaitingLatch = new CountDownLatch(1);
-        
-        /** latch is await'ed on by the effector when it is in the "waiting" point */
-        CountDownLatch continueFromWaitingLatch = new CountDownLatch(1);
-        
-        @Effector(description="sample effector concatenating strings")
-        public String concatenate(@EffectorParam(name="first", description="first argument") String first,
-                @EffectorParam(name="second", description="2nd arg") String second) throws Exception {
-            return first+second;
-        }
-        
-        @Effector(description="sample effector doing some waiting")
-        public void waitabit() throws Exception {
-            waitingTask.set(Tasks.current());
-            
-            Tasks.setExtraStatusDetails("waitabit extra status details");
-            
-            Tasks.withBlockingDetails("waitabit.blocking", new Callable<Void>() {
-                    public Void call() throws Exception {
-                        nowWaitingLatch.countDown();
-                        if (!continueFromWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
-                            fail("took too long to be told to continue");
-                        }
-                        return null;
-                    }});
-        }
-        
-        @Effector(description="sample effector that spawns a child task that waits a bit")
-        public void spawnchild() throws Exception {
-            // spawn a child, then wait
-            BasicExecutionContext.getCurrentExecutionContext().submit(
-                    MutableMap.of("displayName", "SpawnedChildName"),
-                    new Callable<Void>() {
-                        public Void call() throws Exception {
-                            log.info("beginning spawned child response "+Tasks.current()+", with tags "+Tasks.current().getTags());
-                            Tasks.setBlockingDetails("spawned child blocking details");
-                            nowWaitingLatch.countDown();
-                            if (!continueFromWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
-                                fail("took too long to be told to continue");
-                            }
-                            return null;
-                        }});
-        }
-    }
-            
-    private TestApplication app;
-    private MyEntityImpl e;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        app = new TestApplicationImpl();
-        e = new MyEntityImpl(app);
-        Entities.startManagement(app);
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-    
-    @Test
-    public void testCanInvokeEffector() throws Exception {
-        // invocation map syntax
-        Task<String> task = e.invoke(MyEntityImpl.CONCATENATE, ImmutableMap.of("first", "a", "second", "b"));
-        assertEquals(task.get(TIMEOUT, TimeUnit.MILLISECONDS), "ab");
-
-        // method syntax
-        assertEquals("xy", e.concatenate("x", "y"));
-    }
-    
-    @Test
-    public void testReportsTaskDetails() throws Exception {
-        final AtomicReference<String> result = new AtomicReference<String>();
-
-        Thread bg = new Thread(new Runnable() {
-            public void run() {
-                try {
-                    // Expect "wait a bit" to tell us it's blocking 
-                    if (!e.nowWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
-                        result.set("took too long for waitabit to be waiting");
-                        return;
-                    }
-
-                    // Expect "wait a bit" to have retrieved and set its task
-                    try {
-                        Task<?> t = e.waitingTask.get();
-                        String status = t.getStatusDetail(true);
-                        log.info("waitabit task says:\n"+status);
-                        if (!status.contains("waitabit extra status details")) {
-                            result.set("Status not in expected format: doesn't contain extra status details phrase 'My extra status details'\n"+status);
-                            return;
-                        }
-                        if (!status.startsWith("waitabit.blocking")) {
-                            result.set("Status not in expected format: doesn't start with blocking details 'waitabit.blocking'\n"+status);
-                            return;
-                        }
-                    } finally {
-                        e.continueFromWaitingLatch.countDown();
-                    }
-                } catch (Throwable t) {
-                    log.warn("Failure: "+t, t);
-                    result.set("Failure: "+t);
-                }
-            }});
-        bg.start();
-    
-        e.invoke(MyEntityImpl.WAIT_A_BIT, ImmutableMap.<String,Object>of())
-                .get(TIMEOUT, TimeUnit.MILLISECONDS);
-        
-        bg.join(TIMEOUT*2);
-        assertFalse(bg.isAlive());
-        
-        String problem = result.get();
-        if (problem!=null) fail(problem);
-    }
-    
-    @Test
-    public void testReportsSpawnedTaskDetails() throws Exception {
-        final AtomicReference<String> result = new AtomicReference<String>();
-
-        Thread bg = new Thread(new Runnable() {
-            public void run() {
-                try {
-                    // Expect "spawned child" to tell us it's blocking 
-                    if (!e.nowWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
-                        result.set("took too long for spawnchild's sub-task to be waiting");
-                        return;
-                    }
-
-                    // Expect spawned task to be have been tagged with entity
-                    ExecutionManager em = e.getManagementContext().getExecutionManager();
-                    Task<?> subtask = Iterables.find(BrooklynTaskTags.getTasksInEntityContext(em, e), new Predicate<Task<?>>() {
-                        public boolean apply(Task<?> input) {
-                            return "SpawnedChildName".equals(input.getDisplayName());
-                        }
-                    });
-                    
-                    // Expect spawned task to haev correct "blocking details"
-                    try {
-                        String status = subtask.getStatusDetail(true);
-                        log.info("subtask task says:\n"+status);
-                        if (!status.contains("spawned child blocking details")) {
-                            result.set("Status not in expected format: doesn't contain blocking details phrase 'spawned child blocking details'\n"+status);
-                            return;
-                        }
-                    } finally {
-                        e.continueFromWaitingLatch.countDown();
-                    }
-                } catch (Throwable t) {
-                    log.warn("Failure: "+t, t);
-                    result.set("Failure: "+t);
-                }
-            }});
-        bg.start();
-    
-        e.invoke(MyEntityImpl.SPAWN_CHILD, ImmutableMap.<String,Object>of())
-                .get(TIMEOUT, TimeUnit.MILLISECONDS);
-        
-        bg.join(TIMEOUT*2);
-        assertFalse(bg.isAlive());
-        
-        String problem = result.get();
-        if (problem!=null) fail(problem);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java
deleted file mode 100644
index b8b6bf4..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java
+++ /dev/null
@@ -1,166 +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 org.apache.brooklyn.effector.core;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.effector.core.BasicParameterType;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.MethodEffector;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Test the operation of the {@link Effector} implementations.
- *
- * TODO clarify test purpose
- */
-public class EffectorMetadataTest extends BrooklynAppUnitTestSupport {
-    
-    private MyAnnotatedEntity e1;
-    private MyOverridingEntity e2;
-
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        e1 = app.createAndManageChild(EntitySpec.create(MyAnnotatedEntity.class));
-        e2 = app.createAndManageChild(EntitySpec.create(MyOverridingEntity.class));
-    }
-
-    @Test
-    public void testEffectorMetaDataFromAnnotationsWithConstant() {
-        Effector<?> effector = EffectorUtils.findEffectorDeclared(e1, "effWithNewAnnotation").get();
-        Assert.assertTrue(Effectors.sameSignature(effector, MyAnnotatedEntity.EFF_WITH_NEW_ANNOTATION));
-        assertEquals(effector.getName(), "effWithNewAnnotation");
-        assertEquals(effector.getDescription(), "my effector description");
-        assertEquals(effector.getReturnType(), String.class);
-        assertParametersEqual(
-                effector.getParameters(), 
-                ImmutableList.<ParameterType<?>>of(
-                        new BasicParameterType<String>("param1", String.class, "my param description", "my default val")));
-    }
-
-    @Test
-    public void testEffectorMetaDataFromAnnotationsWithoutConstant() {
-        Effector<?> effector = EffectorUtils.findEffectorDeclared(e1, "effWithAnnotationButNoConstant").get();
-        assertEquals(effector.getName(), "effWithAnnotationButNoConstant");
-        assertEquals(effector.getDescription(), "my effector description");
-        assertEquals(effector.getReturnType(), String.class);
-        assertParametersEqual(
-                effector.getParameters(), 
-                ImmutableList.<ParameterType<?>>of(
-                        new BasicParameterType<String>("param1", String.class, "my param description", "my default val")));
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Test
-    public void testEffectorMetaDataFromOverriddenMethod() {
-        // Overridden with new annotations
-        Effector<?> startEffector = EffectorUtils.findEffectorDeclared(e2, "start").get();
-        assertEquals(startEffector.getName(), "start");
-        assertEquals(startEffector.getDescription(), "My overridden start description");
-        assertEquals(startEffector.getReturnType(), void.class);
-        assertParametersEqual(
-                startEffector.getParameters(), 
-                ImmutableList.<ParameterType<?>>of(
-                        new BasicParameterType<Collection>("locations", Collection.class, "my overridden param description", null)));
-    }
-
-    private void assertParametersEqual(List<ParameterType<?>> actuals, List<ParameterType<?>> expecteds) {
-        assertEquals(actuals.size(), expecteds.size(), "actual="+actuals);
-        for (int i = 0; i < actuals.size(); i++) {
-            ParameterType<?> actual = actuals.get(i);
-            ParameterType<?> expected = expecteds.get(i);
-            assertParameterEqual(actual, expected);
-        }
-    }
-    
-    private void assertParameterEqual(ParameterType<?> actual, ParameterType<?> expected) {
-        assertEquals(actual.getName(), expected.getName(), "actual="+actual);
-        assertEquals(actual.getDescription(), expected.getDescription(), "actual="+actual);
-        assertEquals(actual.getParameterClass(), expected.getParameterClass(), "actual="+actual);
-        assertEquals(actual.getParameterClassName(), expected.getParameterClassName(), "actual="+actual);
-    }
-
-    @ImplementedBy(MyAnnotatedEntityImpl.class)
-    public interface MyAnnotatedEntity extends Entity {
-        static MethodEffector<String> EFF_WITH_NEW_ANNOTATION = new MethodEffector<String>(MyAnnotatedEntity.class, "effWithNewAnnotation");
-
-        @org.apache.brooklyn.core.annotation.Effector(description="my effector description")
-        public String effWithNewAnnotation(
-                @EffectorParam(name="param1", defaultValue="my default val", description="my param description") String param1);
-        
-        @org.apache.brooklyn.core.annotation.Effector(description="my effector description")
-        public String effWithAnnotationButNoConstant(
-                @EffectorParam(name="param1", defaultValue="my default val", description="my param description") String param1);
-    }
-    
-    public static class MyAnnotatedEntityImpl extends AbstractEntity implements MyAnnotatedEntity {
-        @Override
-        public String effWithNewAnnotation(String param1) {
-            return param1;
-        }
-
-        @Override
-        public String effWithAnnotationButNoConstant(String param1) {
-            return param1;
-        }
-    }
-    
-    @ImplementedBy(MyOverridingEntityImpl.class)
-    public interface MyOverridingEntity extends Entity, Startable {
-        org.apache.brooklyn.api.effector.Effector<Void> START = Effectors.effector(Startable.START)
-            .description("My overridden start description")
-            .parameter(Collection.class, "locations", "my overridden param description")
-            .build();
-    }
-
-    public static class MyOverridingEntityImpl extends AbstractEntity implements MyOverridingEntity {
-
-        @Override
-        public void restart() {
-        }
-
-        @Override
-        public void start(Collection<? extends Location> locations2) {
-        }
-
-        @Override
-        public void stop() {
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy
deleted file mode 100644
index ec5c442..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy
+++ /dev/null
@@ -1,179 +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 org.apache.brooklyn.effector.core
-
-import static org.testng.Assert.*
-
-import org.apache.brooklyn.api.effector.Effector
-import org.apache.brooklyn.api.entity.Entity
-import org.apache.brooklyn.api.entity.EntitySpec
-import org.apache.brooklyn.api.entity.ImplementedBy
-import org.apache.brooklyn.api.mgmt.ManagementContext
-import org.apache.brooklyn.api.mgmt.Task
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.mgmt.internal.EffectorUtils
-import org.apache.brooklyn.core.test.entity.TestApplication
-import org.apache.brooklyn.core.annotation.EffectorParam
-import org.apache.brooklyn.core.entity.AbstractEntity
-import org.apache.brooklyn.core.entity.Entities
-import org.apache.brooklyn.core.entity.trait.Startable
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.AfterMethod
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-/**
- * Test the operation of the {@link Effector} implementations.
- *
- * TODO clarify test purpose
- */
-public class EffectorSayHiGroovyTest {
-    private static final Logger log = LoggerFactory.getLogger(EffectorSayHiTest.class);
-
-    private TestApplication app;
-    private MyEntity e;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        e = app.createAndManageChild(EntitySpec.create(MyEntity.class));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    @Test
-    public void testFindEffectors() {
-        assertEquals("sayHi1", e.SAY_HI_1.getName());
-        assertEquals(["name", "greeting"], e.SAY_HI_1.getParameters()[0..1]*.getName());
-        assertEquals("says hello", e.SAY_HI_1.getDescription());
-
-		assertEquals("sayHi1", e.SAY_HI_1_ALT.getName());
-		assertEquals(["name", "greeting"], e.SAY_HI_1_ALT.getParameters()[0..1]*.getName());
-		assertEquals("says hello", e.SAY_HI_1_ALT.getDescription());
-
-		assertEquals("sayHi2", e.SAY_HI_2.getName());
-		assertEquals(["name", "greeting"], e.SAY_HI_2.getParameters()[0..1]*.getName());
-		assertEquals("says hello", e.SAY_HI_2.getDescription());
-    }
-
-    @Test
-    public void testFindTraitEffectors() {
-        assertEquals("locations", Startable.START.getParameters()[0].getName());
-    }
-
-    @Test
-    public void testInvokeEffectorMethod1BypassInterception() {
-        String name = "sayHi1"
-        def args = ["Bob", "hello"] as Object[]
-
-        //try the alt syntax recommended from web
-        def metaMethod = e.metaClass.getMetaMethod(name, args)
-        if (metaMethod==null)
-            throw new IllegalArgumentException("Invalid arguments (no method found) for method $name: "+args);
-        assertEquals("hello Bob", metaMethod.invoke(e, args))
-    }
-
-    @Test
-    public void testInvokeEffectorMethod2BypassInterception() {
-        String name = "sayHi2"
-        def args = ["Bob", "hello"] as Object[]
-        assertEquals("hello Bob", e.metaClass.invokeMethod(e, name, args))
-    }
-
-    @Test
-    public void testInvokeEffectors1() {
-        assertEquals("hi Bob", e.sayHi1("Bob", "hi"))
-
-        assertEquals("hello Bob", e.SAY_HI_1.call(e, [name:"Bob"]) )
-        assertEquals("hello Bob", e.invoke(e.SAY_HI_1, [name:"Bob"]).get() );
-
-		assertEquals("hello Bob", e.SAY_HI_1_ALT.call(e, [name:"Bob"]) )
-    }
-
-    @Test
-    public void testInvokeEffectors2() {
-        assertEquals("hi Bob", e.sayHi2("Bob", "hi"))
-
-        assertEquals("hello Bob", e.SAY_HI_2.call(e, [name:"Bob"]) )
-        assertEquals("hello Bob", e.invoke(e.SAY_HI_2, [name:"Bob"]).get() );
-        
-    }
-
-    @Test
-    public void testCanRetrieveTaskForEffector() {
-        e.sayHi2("Bob", "hi")
-
-        ManagementContext managementContext = e.getManagementContext()
-
-        Set<Task> tasks = managementContext.getExecutionManager().getTasksWithAllTags([
-            BrooklynTaskTags.tagForContextEntity(e),"EFFECTOR"])
-        assertEquals(tasks.size(), 1)
-        assertTrue(tasks.iterator().next().getDescription().contains("sayHi2"))
-    }
-}
-public interface CanSayHi {
-	//prefer following simple groovy syntax
-	static Effector<String> SAY_HI_1 = new MethodEffector<String>(CanSayHi.&sayHi1);
-	//slightly longer-winded pojo also supported
-	static Effector<String> SAY_HI_1_ALT = new MethodEffector<String>(CanSayHi.class, "sayHi1");
-
-	@org.apache.brooklyn.core.annotation.Effector(description="says hello")
-	public String sayHi1(
-		@EffectorParam(name="name") String name,
-		@EffectorParam(name="greeting", defaultValue="hello", description="what to say") String greeting);
-
-	//finally there is a way to provide a class/closure if needed or preferred for some odd reason
-	static Effector<String> SAY_HI_2 =
-
-		//groovy 1.8.2 balks at runtime during getCallSiteArray (bug 5122) if we use anonymous inner class
-//	  new ExplicitEffector<CanSayHi,String>(
-//			"sayHi2", String.class, [
-//					[ "name", String.class, "person to say hi to" ] as BasicParameterType<String>,
-//					[ "greeting", String.class, "what to say as greeting", "hello" ] as BasicParameterType<String>
-//				],
-//			"says hello to a person") {
-//		public String invokeEffector(CanSayHi e, Map m) {
-//			e.sayHi2(m)
-//		}
-//	};
-	//following is a workaround, not greatly enamoured of it... but MethodEffector is generally preferred anyway
-		ExplicitEffector.create("sayHi2", String.class, [
-					new BasicParameterType<String>("name", String.class, "person to say hi to"),
-					new BasicParameterType<String>("greeting", String.class, "what to say as greeting", "hello")
-				],
-			"says hello", { e, m ->
-                def args = EffectorUtils.prepareArgsForEffector(SAY_HI_2, m);
-                e.sayHi2(args[0], args[1]) })
-
-	public String sayHi2(String name, String greeting);
-
-}
-
-@ImplementedBy(MyEntityImpl.class)
-public interface MyEntity extends Entity, CanSayHi {
-}
-
-public class MyEntityImpl extends AbstractEntity implements MyEntity {
-    public String sayHi1(String name, String greeting) { "$greeting $name" }
-	public String sayHi2(String name, String greeting) { "$greeting $name" }
-}