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:54:10 UTC

[22/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to o.a.b.feed and o.a.b.core.feed

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java
new file mode 100644
index 0000000..9cf568b
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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.feed.shell;
+
+import static org.testng.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.function.FunctionFeedTest;
+import org.apache.brooklyn.feed.shell.ShellFeed;
+import org.apache.brooklyn.feed.shell.ShellFeedIntegrationTest;
+import org.apache.brooklyn.feed.shell.ShellPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
+import org.apache.brooklyn.feed.ssh.SshValueFunctions;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.stream.Streams;
+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 com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class ShellFeedIntegrationTest extends BrooklynAppUnitTestSupport {
+
+    private static final Logger log = LoggerFactory.getLogger(ShellFeedIntegrationTest.class);
+    
+    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+    final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("anInt", "");
+    final static AttributeSensor<Long> SENSOR_LONG = Sensors.newLongSensor("aLong", "");
+
+    private LocalhostMachineProvisioningLocation loc;
+    private EntityLocal entity;
+    private ShellFeed feed;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        loc = new LocalhostMachineProvisioningLocation();
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        app.start(ImmutableList.of(loc));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    @Override
+    public void tearDown() throws Exception {
+        if (feed != null) feed.stop();
+        super.tearDown();
+        if (loc != null) Streams.closeQuietly(loc);
+    }
+    
+    @Test(groups="Integration")
+    public void testReturnsShellExitStatus() throws Exception {
+        feed = ShellFeed.builder()
+                .entity(entity)
+                .poll(new ShellPollConfig<Integer>(SENSOR_INT)
+                        .command("exit 123")
+                        .onFailure(SshValueFunctions.exitStatus()))
+                .build();
+
+        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 123);
+    }
+    
+    @Test(groups="Integration")
+    public void testFeedDeDupe() throws Exception {
+        testReturnsShellExitStatus();
+        entity.addFeed(feed);
+        log.info("Feed 0 is: "+feed);
+        
+        testReturnsShellExitStatus();
+        log.info("Feed 1 is: "+feed);
+        entity.addFeed(feed);
+                
+        FeedSupport feeds = ((EntityInternal)entity).feeds();
+        Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
+    }
+    
+    // TODO timeout no longer supported; would be nice to have a generic task-timeout feature,
+    // now that the underlying impl uses SystemProcessTaskFactory
+    @Test(enabled=false, groups={"Integration", "WIP"})
+    public void testShellTimesOut() throws Exception {
+        feed = ShellFeed.builder()
+                .entity(entity)
+                .poll(new ShellPollConfig<String>(SENSOR_STRING)
+                        .command("sleep 10")
+                        .timeout(1, TimeUnit.MILLISECONDS)
+                        .onException(new FunctionFeedTest.ToStringFunction()))
+                .build();
+
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                String val = entity.getAttribute(SENSOR_STRING);
+                assertTrue(val != null && val.contains("timed out after 1ms"), "val=" + val);
+            }});
+    }
+    
+    @Test(groups="Integration")
+    public void testShellUsesEnv() throws Exception {
+        feed = ShellFeed.builder()
+                .entity(entity)
+                .poll(new ShellPollConfig<String>(SENSOR_STRING)
+                        .env(ImmutableMap.of("MYENV", "MYVAL"))
+                        .command("echo hello $MYENV")
+                        .onSuccess(SshValueFunctions.stdout()))
+                .build();
+        
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                String val = entity.getAttribute(SENSOR_STRING);
+                assertTrue(val != null && val.contains("hello MYVAL"), "val="+val);
+            }});
+    }
+    
+    @Test(groups="Integration")
+    public void testReturnsShellStdout() throws Exception {
+        feed = ShellFeed.builder()
+                .entity(entity)
+                .poll(new ShellPollConfig<String>(SENSOR_STRING)
+                        .command("echo hello")
+                        .onSuccess(SshValueFunctions.stdout()))
+                .build();
+        
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                String val = entity.getAttribute(SENSOR_STRING);
+                assertTrue(val != null && val.contains("hello"), "val="+val);
+            }});
+    }
+
+    @Test(groups="Integration")
+    public void testReturnsShellStderr() throws Exception {
+        final String cmd = "thiscommanddoesnotexist";
+        
+        feed = ShellFeed.builder()
+                .entity(entity)
+                .poll(new ShellPollConfig<String>(SENSOR_STRING)
+                        .command(cmd)
+                        .onFailure(SshValueFunctions.stderr()))
+                .build();
+        
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                String val = entity.getAttribute(SENSOR_STRING);
+                assertTrue(val != null && val.contains(cmd), "val="+val);
+            }});
+    }
+    
+    @Test(groups="Integration")
+    public void testFailsOnNonZero() throws Exception {
+        feed = ShellFeed.builder()
+                .entity(entity)
+                .poll(new ShellPollConfig<String>(SENSOR_STRING)
+                        .command("exit 123")
+                        .onSuccess(new Function<SshPollValue, String>() {
+                            @Override
+                            public String apply(SshPollValue input) {
+                                return "Exit status (on success) " + input.getExitStatus();
+                            }})
+                        .onFailure(new Function<SshPollValue, String>() {
+                            @Override
+                            public String apply(SshPollValue input) {
+                                return "Exit status (on failure) " + input.getExitStatus();
+                            }}))
+                .build();
+        
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                String val = entity.getAttribute(SENSOR_STRING);
+                assertTrue(val != null && val.contains("Exit status (on failure) 123"), "val="+val);
+            }});
+    }
+    
+    // Example in ShellFeed javadoc
+    @Test(groups="Integration")
+    public void testDiskUsage() throws Exception {
+        feed = ShellFeed.builder()
+                .entity(entity)
+                .poll(new ShellPollConfig<Long>(SENSOR_LONG)
+                        .command("df -P | tail -1")
+                        .onSuccess(new Function<SshPollValue, Long>() {
+                            public Long apply(SshPollValue input) {
+                                String[] parts = input.getStdout().split("[ \\t]+");
+                                System.out.println("input="+input+"; parts="+Arrays.toString(parts));
+                                return Long.parseLong(parts[2]);
+                            }}))
+                .build();
+        
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                Long val = entity.getAttribute(SENSOR_LONG);
+                assertTrue(val != null && val >= 0, "val="+val);
+            }});
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java
new file mode 100644
index 0000000..fa8e2df
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.feed.ssh;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+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.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshFeedIntegrationTest;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
+import org.apache.brooklyn.feed.ssh.SshValueFunctions;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.text.StringFunctions;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+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.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+
+public class SshFeedIntegrationTest extends BrooklynAppUnitTestSupport {
+
+    private static final Logger log = LoggerFactory.getLogger(SshFeedIntegrationTest.class);
+    
+    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+    final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
+
+    private LocalhostMachineProvisioningLocation loc;
+    private SshMachineLocation machine;
+    private EntityLocal entity;
+    private SshFeed feed;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        loc = app.newLocalhostProvisioningLocation();
+        machine = loc.obtain();
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        app.start(ImmutableList.of(loc));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    @Override
+    public void tearDown() throws Exception {
+        if (feed != null) feed.stop();
+        super.tearDown();
+        if (loc != null) Streams.closeQuietly(loc);
+    }
+    
+    /** this is one of the most common pattern */
+    @Test(groups="Integration")
+    public void testReturnsSshStdoutAndInfersMachine() throws Exception {
+        final TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+            // inject the machine location, because the app was started with a provisioning location
+            // and TestEntity doesn't provision
+            .location(machine));
+        
+        feed = SshFeed.builder()
+                .entity(entity2)
+                .poll(new SshPollConfig<String>(SENSOR_STRING)
+                        .command("echo hello")
+                        .onSuccess(SshValueFunctions.stdout()))
+                .build();
+        
+        EntityTestUtils.assertAttributeEventuallyNonNull(entity2, SENSOR_STRING);
+        String val = entity2.getAttribute(SENSOR_STRING);
+        Assert.assertTrue(val.contains("hello"), "val="+val);
+        Assert.assertEquals(val.trim(), "hello");
+    }
+
+    @Test(groups="Integration")
+    public void testFeedDeDupe() throws Exception {
+        testReturnsSshStdoutAndInfersMachine();
+        entity.addFeed(feed);
+        log.info("Feed 0 is: "+feed);
+        
+        testReturnsSshStdoutAndInfersMachine();
+        log.info("Feed 1 is: "+feed);
+        entity.addFeed(feed);
+                
+        FeedSupport feeds = ((EntityInternal)entity).feeds();
+        Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
+    }
+    
+    @Test(groups="Integration")
+    public void testReturnsSshExitStatus() throws Exception {
+        feed = SshFeed.builder()
+                .entity(entity)
+                .machine(machine)
+                .poll(new SshPollConfig<Integer>(SENSOR_INT)
+                        .command("exit 123")
+                        .checkSuccess(Predicates.alwaysTrue())
+                        .onSuccess(SshValueFunctions.exitStatus()))
+                .build();
+
+        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 123);
+    }
+    
+    @Test(groups="Integration")
+    public void testReturnsSshStdout() throws Exception {
+        feed = SshFeed.builder()
+                .entity(entity)
+                .machine(machine)
+                .poll(new SshPollConfig<String>(SENSOR_STRING)
+                        .command("echo hello")
+                        .onSuccess(SshValueFunctions.stdout()))
+                .build();
+        
+        EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING, 
+            Predicates.compose(Predicates.equalTo("hello"), StringFunctions.trim()));
+    }
+
+    @Test(groups="Integration")
+    public void testReturnsSshStderr() throws Exception {
+        final String cmd = "thiscommanddoesnotexist";
+        
+        feed = SshFeed.builder()
+                .entity(entity)
+                .machine(machine)
+                .poll(new SshPollConfig<String>(SENSOR_STRING)
+                        .command(cmd)
+                        .onFailure(SshValueFunctions.stderr()))
+                .build();
+        
+        EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING, StringPredicates.containsLiteral(cmd));
+    }
+    
+    @Test(groups="Integration")
+    public void testFailsOnNonZero() throws Exception {
+        feed = SshFeed.builder()
+                .entity(entity)
+                .machine(machine)
+                .poll(new SshPollConfig<String>(SENSOR_STRING)
+                        .command("exit 123")
+                        .onFailure(new Function<SshPollValue, String>() {
+                            @Override
+                            public String apply(SshPollValue input) {
+                                return "Exit status " + input.getExitStatus();
+                            }}))
+                .build();
+        
+        EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING, StringPredicates.containsLiteral("Exit status 123"));
+    }
+    
+    @Test(groups="Integration")
+    public void testAddedEarly() throws Exception {
+        final TestEntity entity2 = app.addChild(EntitySpec.create(TestEntity.class)
+            .location(machine)
+            .addInitializer(new EntityInitializer() {
+                @Override
+                public void apply(EntityLocal entity) {
+                    SshFeed.builder()
+                        .entity(entity)
+                        .onlyIfServiceUp()
+                        .poll(new SshPollConfig<String>(SENSOR_STRING)
+                            .command("echo hello")
+                            .onSuccess(SshValueFunctions.stdout()))
+                        .build();
+                }
+            }));
+        Time.sleep(Duration.seconds(2));
+        // would be nice to hook in and assert no errors
+        Assert.assertEquals(entity2.getAttribute(SENSOR_STRING), null);
+        Entities.manage(entity2);
+        Time.sleep(Duration.seconds(2));
+        Assert.assertEquals(entity2.getAttribute(SENSOR_STRING), null);
+        entity2.setAttribute(Attributes.SERVICE_UP, true);
+    
+        EntityTestUtils.assertAttributeEventually(entity2, SENSOR_STRING, StringPredicates.containsLiteral("hello"));
+    }
+
+    
+    @Test(groups="Integration")
+    public void testDynamicEnvAndCommandSupplier() throws Exception {
+        final TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
+        
+        final AtomicInteger count = new AtomicInteger();
+        Supplier<Map<String, String>> envSupplier = new Supplier<Map<String,String>>() {
+            @Override
+            public Map<String, String> get() {
+                return MutableMap.of("COUNT", ""+count.incrementAndGet());
+            }
+        };
+        Supplier<String> cmdSupplier = new Supplier<String>() {
+            @Override
+            public String get() {
+                return "echo count-"+count.incrementAndGet()+"-$COUNT";
+            }
+        };
+        
+        feed = SshFeed.builder()
+                .entity(entity2)
+                .poll(new SshPollConfig<String>(SENSOR_STRING)
+                        .env(envSupplier)
+                        .command(cmdSupplier)
+                        .onSuccess(SshValueFunctions.stdout()))
+                .build();
+        
+        EntityTestUtils.assertAttributeEventuallyNonNull(entity2, SENSOR_STRING);        
+        final String val1 = assertDifferentOneInOutput(entity2);
+        
+        EntityTestUtils.assertAttributeEventually(entity2, SENSOR_STRING, Predicates.not(Predicates.equalTo(val1)));        
+        final String val2 = assertDifferentOneInOutput(entity2);
+        log.info("vals from dynamic sensors are: "+val1.trim()+" and "+val2.trim());
+    }
+
+    private String assertDifferentOneInOutput(final TestEntity entity2) {
+        String val = entity2.getAttribute(SENSOR_STRING);
+        Assert.assertTrue(val.startsWith("count"), "val="+val);
+        try {
+            String[] fields = val.trim().split("-");
+            int field1 = Integer.parseInt(fields[1]); 
+            int field2 = Integer.parseInt(fields[2]);
+            Assert.assertEquals(Math.abs(field2-field1), 1, "expected difference of 1");
+        } catch (Throwable t) {
+            Exceptions.propagateIfFatal(t);
+            Assert.fail("Wrong output from sensor, got '"+val.trim()+"', giving error: "+t);
+        }
+        return val;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
new file mode 100644
index 0000000..421fff4
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.feed.windows;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * WindowsPerformanceCounterFeed Live Test.
+ * <p>
+ * This test is currently disabled. To run, you must configure a location named {@code WindowsLiveTest}
+ * or adapt the {@link #LOCATION_SPEC} below.
+ * <p>
+ * The location must provide Windows nodes that are running an SSH server on port 22. The login credentials must
+ * be either be auto-detectable or configured in brooklyn.properties in the usual fashion.
+ * <p>
+ * Here is an example configuration from brooklyn.properties for a pre-configured Windows VM
+ * running an SSH server with public key authentication:
+ * <pre>
+ * {@code brooklyn.location.named.WindowsLiveTest=byon:(hosts="ec2-xx-xxx-xxx-xx.eu-west-1.compute.amazonaws.com")
+ * brooklyn.location.named.WindowsLiveTest.user=Administrator
+ * brooklyn.location.named.WindowsLiveTest.privateKeyFile = ~/.ssh/id_rsa
+ * brooklyn.location.named.WindowsLiveTest.publicKeyFile = ~/.ssh/id_rsa.pub
+ * }</pre>
+ * The location must by {@code byon} or another primitive type. Unfortunately, it's not possible to
+ * use a jclouds location, as adding a dependency on brooklyn-locations-jclouds would cause a
+ * cyclic dependency.
+ */
+public class WindowsPerformanceCounterFeedLiveTest extends BrooklynAppLiveTestSupport {
+
+    final static AttributeSensor<Double> CPU_IDLE_TIME = Sensors.newDoubleSensor("cpu.idleTime", "");
+    final static AttributeSensor<Integer> TELEPHONE_LINES = Sensors.newIntegerSensor("telephone.lines", "");
+
+    private static final String LOCATION_SPEC = "named:WindowsLiveTest";
+
+    private Location loc;
+    private EntityLocal entity;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+        
+        Map<String,?> allFlags = MutableMap.<String,Object>builder()
+                .put("tags", ImmutableList.of(getClass().getName()))
+                .build();
+        MachineProvisioningLocation<? extends MachineLocation> provisioningLocation =
+                (MachineProvisioningLocation<? extends MachineLocation>)
+                        mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
+        loc = provisioningLocation.obtain(ImmutableMap.of());
+
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        app.start(ImmutableList.of(loc));
+    }
+
+    @Test(groups={"Live","Disabled"}, enabled=false)
+    public void testRetrievesPerformanceCounters() throws Exception {
+        // We can be pretty sure that a Windows instance in the cloud will have zero telephone lines...
+        entity.setAttribute(TELEPHONE_LINES, 42);
+        WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
+                .entity(entity)
+                .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
+                .addSensor("\\Telephony\\Lines", TELEPHONE_LINES)
+                .build();
+        try {
+            EntityTestUtils.assertAttributeEqualsEventually(entity, TELEPHONE_LINES, 0);
+        } finally {
+            feed.stop();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
new file mode 100644
index 0000000..3f4862b
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.feed.windows;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterPollConfig;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class WindowsPerformanceCounterFeedTest extends BrooklynAppUnitTestSupport {
+
+    private Location loc;
+    private EntityLocal entity;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        loc = new LocalhostMachineProvisioningLocation();
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        app.start(ImmutableList.of(loc));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeedTest.class);
+
+    @Test
+    public void testIteratorWithSingleValue() {
+        Iterator<?> iterator = new WindowsPerformanceCounterFeed
+                .PerfCounterValueIterator("\"10/14/2013 15:28:24.406\",\"0.000000\"");
+        assertTrue(iterator.hasNext());
+        assertEquals(iterator.next(), "0.000000");
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testIteratorWithMultipleValues() {
+        Iterator<?> iterator = new WindowsPerformanceCounterFeed
+                .PerfCounterValueIterator("\"10/14/2013 15:35:50.582\",\"8803.000000\",\"405622.000000\"");
+        assertTrue(iterator.hasNext());
+        assertEquals(iterator.next(), "8803.000000");
+        assertTrue(iterator.hasNext());
+        assertEquals(iterator.next(), "405622.000000");
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testSendPerfCountersToSensors() {
+        AttributeSensor<String> stringSensor = Sensors.newStringSensor("foo.bar");
+        AttributeSensor<Integer> integerSensor = Sensors.newIntegerSensor("bar.baz");
+        AttributeSensor<Double> doubleSensor = Sensors.newDoubleSensor("baz.quux");
+
+        Collection<WindowsPerformanceCounterPollConfig<?>> polls = ImmutableSet.<WindowsPerformanceCounterPollConfig<?>>of(
+                new WindowsPerformanceCounterPollConfig(stringSensor).performanceCounterName("\\processor information(_total)\\% processor time"),
+                new WindowsPerformanceCounterPollConfig(integerSensor).performanceCounterName("\\integer.sensor"),
+                new WindowsPerformanceCounterPollConfig(doubleSensor).performanceCounterName("\\double\\sensor\\with\\multiple\\sub\\paths")
+        );
+
+        WindowsPerformanceCounterFeed.SendPerfCountersToSensors sendPerfCountersToSensors = new WindowsPerformanceCounterFeed.SendPerfCountersToSensors(entity, polls);
+
+        assertNull(entity.getAttribute(stringSensor));
+
+        StringBuilder responseBuilder = new StringBuilder();
+        // NOTE: This builds the response in a different order to which they are passed to the SendPerfCountersToSensors constructor
+        // this tests that the values are applied correctly even if the (possibly non-deterministic) order in which
+        // they are returned by the Get-Counter scriptlet is different
+        addMockResponse(responseBuilder, "\\\\machine.name\\double\\sensor\\with\\multiple\\sub\\paths", "3.1415926");
+        addMockResponse(responseBuilder, "\\\\win-lge7uj2blau\\processor information(_total)\\% processor time", "99.9");
+        addMockResponse(responseBuilder, "\\\\machine.name\\integer.sensor", "15");
+
+        sendPerfCountersToSensors.onSuccess(new WinRmToolResponse(responseBuilder.toString(), "", 0));
+
+        EntityTestUtils.assertAttributeEquals(entity, stringSensor, "99.9");
+        EntityTestUtils.assertAttributeEquals(entity, integerSensor, 15);
+        EntityTestUtils.assertAttributeEquals(entity, doubleSensor, 3.1415926);
+    }
+
+    private void addMockResponse(StringBuilder responseBuilder, String path, String value) {
+        responseBuilder.append(path);
+        responseBuilder.append(Strings.repeat(" ", 200 - (path.length() + value.length())));
+        responseBuilder.append(value);
+        responseBuilder.append("\r\n");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
deleted file mode 100644
index b82aecf..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
+++ /dev/null
@@ -1,70 +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.sensor.feed;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class ConfigToAttributesTest {
-
-    private ManagementContextInternal managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = new LocalManagementContext();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testApplyTemplatedConfigWithEntity() {
-        TestApplication app = managementContext.getEntityManager().createEntity(EntitySpec.create(TestApplication.class)
-                .configure(TestEntity.CONF_NAME, "myval"));
-        Entities.startManagement(app, managementContext);
-        
-        BasicAttributeSensorAndConfigKey<String> key = new TemplatedStringAttributeSensorAndConfigKey("mykey", "my descr", "${config['test.confName']!'notfound'}");
-        String val = ConfigToAttributes.apply(app, key);
-        assertEquals(app.getAttribute(key), val);
-        assertEquals(val, "myval");
-
-    }
-    
-    @Test
-    public void testApplyTemplatedConfigWithManagementContext() {
-        managementContext.getBrooklynProperties().put(TestEntity.CONF_NAME, "myglobalval");
-        BasicAttributeSensorAndConfigKey<String> key = new TemplatedStringAttributeSensorAndConfigKey("mykey", "my descr", "${config['test.confName']!'notfound'}");
-        String val = ConfigToAttributes.transform(managementContext, key);
-        assertEquals(val, "myglobalval");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java
deleted file mode 100644
index 3f9c29b..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java
+++ /dev/null
@@ -1,108 +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.sensor.feed;
-
-import static org.testng.Assert.assertTrue;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.PollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class PollerTest extends BrooklynAppUnitTestSupport {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PollerTest.class);
-
-    private TestEntity entity;
-    private Poller<Integer> poller;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        poller = new Poller<Integer>(entity, false);
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    @Override
-    public void tearDown() throws Exception {
-        if (poller != null) poller.stop();
-        super.tearDown();
-    }
-    
-    @Test(groups={"Integration", "WIP"}) // because takes > 1 second
-    public void testPollingSubTaskFailsOnceKeepsGoing() throws Exception {
-        final AtomicInteger counter = new AtomicInteger();
-        poller.scheduleAtFixedRate(
-                new Callable<Integer>() {
-                    @Override public Integer call() throws Exception {
-                        int result = counter.incrementAndGet();
-                        if (result % 2 == 0) {
-                            DynamicTasks.queue("in-poll", new Runnable() {
-                                public void run() {
-                                    throw new IllegalStateException("Simulating error in sub-task for poll");
-                                }});
-                        }
-                        return result;
-                    }
-                },
-                new PollHandler<Integer>() {
-                    @Override public boolean checkSuccess(Integer val) {
-                        return true;
-                    }
-                    @Override public void onSuccess(Integer val) {
-                        
-                    }
-                    @Override public void onFailure(Integer val) {
-                    }
-                    @Override
-                    public void onException(Exception exception) {
-                        LOG.info("Exception in test poller", exception);
-                    }
-                    @Override public String getDescription() {
-                        return "mypollhandler";
-                    }
-                }, 
-                new Duration(10, TimeUnit.MILLISECONDS));
-        poller.start();
-        
-        Asserts.succeedsContinually(MutableMap.of("timeout", 2*1000, "period", 500), new Runnable() {
-            int oldCounter = -1;
-            @Override public void run() {
-                assertTrue(counter.get() > oldCounter);
-                oldCounter = counter.get();
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
deleted file mode 100644
index 71b44b8..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
+++ /dev/null
@@ -1,315 +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.sensor.feed.function;
-
-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.Callable;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Feed;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeedTest;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-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 com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicates;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.Callables;
-
-public class FunctionFeedTest extends BrooklynAppUnitTestSupport {
-
-    private static final Logger log = LoggerFactory.getLogger(FunctionFeedTest.class);
-    
-    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
-    final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
-
-    private Location loc;
-    private EntityLocal entity;
-    private FunctionFeed feed;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        loc = new LocalhostMachineProvisioningLocation();
-        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        app.start(ImmutableList.of(loc));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    @Override
-    public void tearDown() throws Exception {
-        if (feed != null) feed.stop();
-        super.tearDown();
-    }
-    
-    @Test
-    public void testPollsFunctionRepeatedlyToSetAttribute() throws Exception {
-        feed = FunctionFeed.builder()
-                .entity(entity)
-                .poll(new FunctionPollConfig<Integer,Integer>(SENSOR_INT)
-                        .period(1)
-                        .callable(new IncrementingCallable())
-                        //.onSuccess((Function<Object,Integer>)(Function)Functions.identity()))
-                        )
-                .build();
-        
-        Asserts.succeedsEventually(new Runnable() {
-            @Override
-            public void run() {
-                Integer val = entity.getAttribute(SENSOR_INT);
-                assertTrue(val != null && val > 2, "val=" + val);
-            }
-        });
-    }
-    
-    @Test
-    public void testFeedDeDupe() throws Exception {
-        testPollsFunctionRepeatedlyToSetAttribute();
-        entity.addFeed(feed);
-        log.info("Feed 0 is: "+feed);
-        Feed feed0 = feed;
-        
-        testPollsFunctionRepeatedlyToSetAttribute();
-        entity.addFeed(feed);
-        log.info("Feed 1 is: "+feed);
-        Feed feed1 = feed;
-        Assert.assertFalse(feed1==feed0);
-
-        FeedSupport feeds = ((EntityInternal)entity).feeds();
-        Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
-
-        // a couple extra checks, compared to the de-dupe test in other *FeedTest classes
-        Feed feedAdded = Iterables.getOnlyElement(feeds.getFeeds());
-        Assert.assertTrue(feedAdded==feed1);
-        Assert.assertFalse(feedAdded==feed0);
-    }
-    
-    @Test
-    public void testFeedDeDupeIgnoresSameObject() throws Exception {
-        testPollsFunctionRepeatedlyToSetAttribute();
-        entity.addFeed(feed);
-        assertFeedIsPolling();
-        entity.addFeed(feed);
-        assertFeedIsPollingContinuously();
-    }
-
-    @Test
-    public void testCallsOnSuccessWithResultOfCallable() throws Exception {
-        feed = FunctionFeed.builder()
-                .entity(entity)
-                .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
-                        .period(1)
-                        .callable(Callables.returning(123))
-                        .onSuccess(new AddOneFunction()))
-                .build();
-
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 124);
-    }
-    
-    @Test
-    public void testCallsOnExceptionWithExceptionFromCallable() throws Exception {
-        final String errMsg = "my err msg";
-        
-        feed = FunctionFeed.builder()
-                .entity(entity)
-                .poll(new FunctionPollConfig<Object, String>(SENSOR_STRING)
-                        .period(1)
-                        .callable(new ExceptionCallable(errMsg))
-                        .onException(new ToStringFunction()))
-                .build();
-
-        Asserts.succeedsEventually(new Runnable() {
-            @Override
-            public void run() {
-                String val = entity.getAttribute(SENSOR_STRING);
-                assertTrue(val != null && val.contains(errMsg), "val=" + val);
-            }
-        });
-    }
-
-    @Test
-    public void testCallsOnFailureWithResultOfCallable() throws Exception {
-        feed = FunctionFeed.builder()
-                .entity(entity)
-                .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
-                        .period(1)
-                        .callable(Callables.returning(1))
-                        .checkSuccess(Predicates.alwaysFalse())
-                        .onSuccess(new AddOneFunction())
-                        .onFailure(Functions.constant(-1)))
-                .build();
-
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, -1);
-    }
-
-    @Test
-    public void testCallsOnExceptionWhenCheckSuccessIsFalseButNoFailureHandler() throws Exception {
-        feed = FunctionFeed.builder()
-                .entity(entity)
-                .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
-                        .period(1)
-                        .callable(Callables.returning(1))
-                        .checkSuccess(Predicates.alwaysFalse())
-                        .onSuccess(new AddOneFunction())
-                        .onException(Functions.constant(-1)))
-                .build();
-
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, -1);
-    }
-    
-    @Test
-    public void testSharesFunctionWhenMultiplePostProcessors() throws Exception {
-        final IncrementingCallable incrementingCallable = new IncrementingCallable();
-        final List<Integer> ints = new CopyOnWriteArrayList<Integer>();
-        final List<String> strings = new CopyOnWriteArrayList<String>();
-        
-        entity.subscribe(entity, SENSOR_INT, new SensorEventListener<Integer>() {
-                @Override public void onEvent(SensorEvent<Integer> event) {
-                    ints.add(event.getValue());
-                }});
-        entity.subscribe(entity, SENSOR_STRING, new SensorEventListener<String>() {
-                @Override public void onEvent(SensorEvent<String> event) {
-                    strings.add(event.getValue());
-                }});
-        
-        feed = FunctionFeed.builder()
-                .entity(entity)
-                .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
-                        .period(10)
-                        .callable(incrementingCallable))
-                .poll(new FunctionPollConfig<Integer, String>(SENSOR_STRING)
-                        .period(10)
-                        .callable(incrementingCallable)
-                        .onSuccess(new ToStringFunction()))
-                .build();
-
-        Asserts.succeedsEventually(new Runnable() {
-            @Override
-            public void run() {
-                assertEquals(ints.subList(0, 2), ImmutableList.of(0, 1));
-                assertTrue(strings.size()>=2, "wrong strings list: "+strings);
-                assertEquals(strings.subList(0, 2), ImmutableList.of("0", "1"), "wrong strings list: "+strings);
-            }});
-    }
-    
-    @Test
-    @SuppressWarnings("unused")
-    public void testFunctionPollConfigBuilding() throws Exception {
-        FunctionPollConfig<Integer, Integer> typeFromCallable = FunctionPollConfig.forSensor(SENSOR_INT)
-                .period(1)
-                .callable(Callables.returning(1))
-                .onSuccess(Functions.constant(-1));
-
-        FunctionPollConfig<Integer, Integer> typeFromSupplier = FunctionPollConfig.forSensor(SENSOR_INT)
-                .period(1)
-                .supplier(Suppliers.ofInstance(1))
-                .onSuccess(Functions.constant(-1));
-
-        FunctionPollConfig<Integer, Integer> usingConstructor = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
-                .period(1)
-                .supplier(Suppliers.ofInstance(1))
-                .onSuccess(Functions.constant(-1));
-
-        FunctionPollConfig<Integer, Integer> usingConstructorWithFailureOrException = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
-                .period(1)
-                .supplier(Suppliers.ofInstance(1))
-                .onFailureOrException(Functions.<Integer>constant(null));
-    }
-    
-    
-    private void assertFeedIsPolling() {
-        final Integer val = entity.getAttribute(SENSOR_INT);
-        Asserts.succeedsEventually(new Runnable() {
-            @Override
-            public void run() {
-                assertNotEquals(val, entity.getAttribute(SENSOR_INT));
-            }
-        });
-    }
-    
-    private void assertFeedIsPollingContinuously() {
-        Asserts.succeedsContinually(new Runnable() {
-            @Override
-            public void run() {
-                assertFeedIsPolling();
-            }
-        });
-    }
-
-    private static class IncrementingCallable implements Callable<Integer> {
-        private final AtomicInteger next = new AtomicInteger(0);
-        
-        @Override public Integer call() {
-            return next.getAndIncrement();
-        }
-    }
-    
-    private static class AddOneFunction implements Function<Integer, Integer> {
-        @Override public Integer apply(@Nullable Integer input) {
-            return (input != null) ? (input + 1) : null;
-        }
-    }
-    
-    private static class ExceptionCallable implements Callable<Void> {
-        private final String msg;
-        ExceptionCallable(String msg) {
-            this.msg = msg;
-        }
-        @Override public Void call() {
-            throw new RuntimeException(msg);
-        }
-    }
-    
-    public static class ToStringFunction implements Function<Object, String> {
-        @Override public String apply(@Nullable Object input) {
-            return (input != null) ? (input.toString()) : null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
deleted file mode 100644
index 475490b..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
+++ /dev/null
@@ -1,160 +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.sensor.feed.http;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.net.URI;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.HttpService;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
-
-public class HttpFeedIntegrationTest extends BrooklynAppUnitTestSupport {
-
-    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
-    final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
-
-    private HttpService httpService;
-
-    private Location loc;
-    private EntityLocal entity;
-    private HttpFeed feed;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        loc = new LocalhostMachineProvisioningLocation();
-        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        app.start(ImmutableList.of(loc));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    @Override
-    public void tearDown() throws Exception {
-        if (feed != null) feed.stop();
-        if (httpService != null) httpService.shutdown();
-        super.tearDown();
-    }
-
-    @Test(groups = {"Integration"})
-    public void testPollsAndParsesHttpGetResponseWithSsl() throws Exception {
-        httpService = new HttpService(PortRanges.fromString("9000+"), true).start();
-        URI baseUrl = new URI(httpService.getUrl());
-
-        assertEquals(baseUrl.getScheme(), "https", "baseUrl="+baseUrl);
-        
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUri(baseUrl)
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode()))
-                .poll(new HttpPollConfig<String>(SENSOR_STRING)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction()))
-                .build();
-        
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 200);
-        Asserts.succeedsEventually(new Runnable() {
-            public void run() {
-                String val = entity.getAttribute(SENSOR_STRING);
-                assertTrue(val != null && val.contains("Hello, World"), "val="+val);
-            }});
-    }
-
-    @Test(groups = {"Integration"})
-    public void testPollsAndParsesHttpGetResponseWithBasicAuthentication() throws Exception {
-        final String username = "brooklyn";
-        final String password = "hunter2";
-        httpService = new HttpService(PortRanges.fromString("9000+"))
-                .basicAuthentication(username, password)
-                .start();
-        URI baseUrl = new URI(httpService.getUrl());
-        assertEquals(baseUrl.getScheme(), "http", "baseUrl="+baseUrl);
-
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUri(baseUrl)
-                .credentials(username, password)
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode()))
-                .poll(new HttpPollConfig<String>(SENSOR_STRING)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction()))
-                .build();
-
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 200);
-        Asserts.succeedsEventually(new Runnable() {
-            public void run() {
-                String val = entity.getAttribute(SENSOR_STRING);
-                assertTrue(val != null && val.contains("Hello, World"), "val="+val);
-            }});
-    }
-
-    @Test(groups = {"Integration"})
-    public void testPollWithInvalidCredentialsFails() throws Exception {
-        httpService = new HttpService(PortRanges.fromString("9000+"))
-                .basicAuthentication("brooklyn", "hunter2")
-                .start();
-
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUri(httpService.getUrl())
-                .credentials("brooklyn", "9876543210")
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode())
-                        .onFailure(HttpValueFunctions.responseCode()))
-                .poll(new HttpPollConfig<String>(SENSOR_STRING)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction())
-                        .onException(Functions.constant("Failed!")))
-                .build();
-
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 401);
-        Asserts.succeedsEventually(new Runnable() {
-            public void run() {
-                String val = entity.getAttribute(SENSOR_STRING);
-                assertTrue(val != null && val.equals("Failed!"), "val=" + val);
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
deleted file mode 100644
index f04c855..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
+++ /dev/null
@@ -1,392 +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.sensor.feed.http;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.net.URL;
-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.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityFunctions;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.FeedConfig;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.BetterMockWebServer;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.net.Networking;
-import org.apache.brooklyn.util.time.Duration;
-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 com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.mockwebserver.MockResponse;
-import com.google.mockwebserver.SocketPolicy;
-
-public class HttpFeedTest extends BrooklynAppUnitTestSupport {
-
-    private static final Logger log = LoggerFactory.getLogger(HttpFeedTest.class);
-    
-    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
-    final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor( "aLong", "");
-
-    private static final long TIMEOUT_MS = 10*1000;
-    
-    private BetterMockWebServer server;
-    private URL baseUrl;
-    
-    private Location loc;
-    private EntityLocal entity;
-    private HttpFeed feed;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        server = BetterMockWebServer.newInstanceLocalhost();
-        for (int i = 0; i < 100; i++) {
-            server.enqueue(new MockResponse().setResponseCode(200).addHeader("content-type: application/json").setBody("{\"foo\":\"myfoo\"}"));
-        }
-        server.play();
-        baseUrl = server.getUrl("/");
-
-        loc = app.newLocalhostProvisioningLocation();
-        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        app.start(ImmutableList.of(loc));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    @Override
-    public void tearDown() throws Exception {
-        if (feed != null) feed.stop();
-        if (server != null) server.shutdown();
-        feed = null;
-        super.tearDown();
-    }
-    
-    @Test
-    public void testPollsAndParsesHttpGetResponse() throws Exception {
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(baseUrl)
-                .poll(HttpPollConfig.forSensor(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode()))
-                .poll(HttpPollConfig.forSensor(SENSOR_STRING)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction()))
-                .build();
-        
-        assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
-        assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
-    }
-    
-    @Test
-    public void testFeedDeDupe() throws Exception {
-        testPollsAndParsesHttpGetResponse();
-        entity.addFeed(feed);
-        log.info("Feed 0 is: "+feed);
-        
-        testPollsAndParsesHttpGetResponse();
-        log.info("Feed 1 is: "+feed);
-        entity.addFeed(feed);
-                
-        FeedSupport feeds = ((EntityInternal)entity).feeds();
-        Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
-    }
-    
-    @Test
-    public void testSetsConnectionTimeout() throws Exception {
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(baseUrl)
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .connectionTimeout(Duration.TEN_SECONDS)
-                        .socketTimeout(Duration.TEN_SECONDS)
-                        .onSuccess(HttpValueFunctions.responseCode()))
-                .build();
-        
-        assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
-    }
-    
-    // TODO How to cause the other end to just freeze (similar to aws-ec2 when securityGroup port is not open)?
-    @Test
-    public void testSetsConnectionTimeoutWhenServerDisconnects() throws Exception {
-        if (server != null) server.shutdown();
-        server = BetterMockWebServer.newInstanceLocalhost();
-        for (int i = 0; i < 100; i++) {
-            server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START));
-        }
-        server.play();
-        baseUrl = server.getUrl("/");
-
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(baseUrl)
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .connectionTimeout(Duration.TEN_SECONDS)
-                        .socketTimeout(Duration.TEN_SECONDS)
-                        .onSuccess(HttpValueFunctions.responseCode())
-                        .onException(Functions.constant(-1)))
-                .build();
-        
-        assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
-    }
-    
-    
-    @Test
-    public void testPollsAndParsesHttpPostResponse() throws Exception {
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(baseUrl)
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .method("post")
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode()))
-                .poll(new HttpPollConfig<String>(SENSOR_STRING)
-                        .method("post")
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction()))
-                .build();
-        
-        assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
-        assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
-    }
-
-    @Test
-    public void testUsesFailureHandlerOn4xx() throws Exception {
-        server = BetterMockWebServer.newInstanceLocalhost();
-        for (int i = 0; i < 100; i++) {
-            server.enqueue(new MockResponse()
-                    .setResponseCode(401)
-                    .setBody("Unauthorised"));
-        }
-        server.play();
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(server.getUrl("/"))
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode())
-                        .onFailure(HttpValueFunctions.responseCode()))
-                .poll(new HttpPollConfig<String>(SENSOR_STRING)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction())
-                        .onFailure(Functions.constant("Failed")))
-                .build();
-
-        assertSensorEventually(SENSOR_INT, 401, TIMEOUT_MS);
-        assertSensorEventually(SENSOR_STRING, "Failed", TIMEOUT_MS);
-
-        server.shutdown();
-    }
-
-    @Test
-    public void testUsesExceptionHandlerOn4xxAndNoFailureHandler() throws Exception {
-        server = BetterMockWebServer.newInstanceLocalhost();
-        for (int i = 0; i < 100; i++) {
-            server.enqueue(new MockResponse()
-                    .setResponseCode(401)
-                    .setBody("Unauthorised"));
-        }
-        server.play();
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(server.getUrl("/"))
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode())
-                        .onException(Functions.constant(-1)))
-                .build();
-
-        assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
-
-        server.shutdown();
-    }
-
-    @Test(groups="Integration")
-    // marked integration as it takes a wee while
-    public void testSuspendResume() throws Exception {
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(baseUrl)
-                .poll(new HttpPollConfig<Integer>(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode()))
-                .poll(new HttpPollConfig<String>(SENSOR_STRING)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction()))
-                .build();
-        assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
-        feed.suspend();
-        final int countWhenSuspended = server.getRequestCount();
-        
-        Thread.sleep(500);
-        if (server.getRequestCount() > countWhenSuspended+1)
-            Assert.fail("Request count continued to increment while feed was suspended, from "+countWhenSuspended+" to "+server.getRequestCount());
-        
-        feed.resume();
-        Asserts.succeedsEventually(new Runnable() {
-            public void run() {
-                assertTrue(server.getRequestCount() > countWhenSuspended + 1,
-                        "Request count failed to increment when feed was resumed, from " + countWhenSuspended + ", still at " + server.getRequestCount());
-            }
-        });
-    }
-
-    @Test(groups="Integration")
-    // marked integration as it takes a wee while
-    public void testStartSuspended() throws Exception {
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(baseUrl)
-                .poll(HttpPollConfig.forSensor(SENSOR_INT)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.responseCode()))
-                .poll(HttpPollConfig.forSensor(SENSOR_STRING)
-                        .period(100)
-                        .onSuccess(HttpValueFunctions.stringContentsFunction()))
-                .suspended()
-                .build();
-        Asserts.continually(MutableMap.of("timeout", 500),
-                Entities.attributeSupplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(null));
-        int countWhenSuspended = server.getRequestCount();
-        feed.resume();
-        Asserts.eventually(Entities.attributeSupplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(200));
-        if (server.getRequestCount() <= countWhenSuspended)
-            Assert.fail("Request count failed to increment when feed was resumed, from "+countWhenSuspended+", still at "+server.getRequestCount());
-        log.info("RUN: "+countWhenSuspended+" - "+server.getRequestCount());
-    }
-
-
-    @Test
-    public void testPollsAndParsesHttpErrorResponseLocal() throws Exception {
-        int unboundPort = Networking.nextAvailablePort(10000);
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUri("http://localhost:" + unboundPort + "/path/should/not/exist")
-                .poll(new HttpPollConfig<String>(SENSOR_STRING)
-                        .onSuccess(Functions.constant("success"))
-                        .onFailure(Functions.constant("failure"))
-                        .onException(Functions.constant("error")))
-                .build();
-        
-        assertSensorEventually(SENSOR_STRING, "error", TIMEOUT_MS);
-    }
-
-    @Test
-    public void testPollsMulti() throws Exception {
-        newMultiFeed(baseUrl);
-        assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
-        assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
-    }
-
-    // because takes a wee while
-    @SuppressWarnings("rawtypes")
-    @Test(groups="Integration")
-    public void testPollsMultiClearsOnSubsequentFailure() throws Exception {
-        server = BetterMockWebServer.newInstanceLocalhost();
-        for (int i = 0; i < 10; i++) {
-            server.enqueue(new MockResponse()
-                    .setResponseCode(200)
-                    .setBody("Hello World"));
-        }
-        for (int i = 0; i < 10; i++) {
-            server.enqueue(new MockResponse()
-                    .setResponseCode(401)
-                    .setBody("Unauthorised"));
-        }
-        server.play();
-
-        newMultiFeed(server.getUrl("/"));
-        
-        assertSensorEventually(SENSOR_INT, 200, TIMEOUT_MS);
-        assertSensorEventually(SENSOR_STRING, "Hello World", TIMEOUT_MS);
-        
-        assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
-        assertSensorEventually(SENSOR_STRING, null, TIMEOUT_MS);
-        
-        List<String> attrs = Lists.transform(MutableList.copyOf( ((EntityInternal)entity).getAllAttributes().keySet() ),
-            new Function<AttributeSensor,String>() {
-                @Override public String apply(AttributeSensor input) { return input.getName(); } });
-        Assert.assertTrue(!attrs.contains(SENSOR_STRING.getName()), "attrs contained "+SENSOR_STRING);
-        Assert.assertTrue(!attrs.contains(FeedConfig.NO_SENSOR.getName()), "attrs contained "+FeedConfig.NO_SENSOR);
-        
-        server.shutdown();
-    }
-
-    private void newMultiFeed(URL baseUrl) {
-        feed = HttpFeed.builder()
-                .entity(entity)
-                .baseUrl(baseUrl)
-                
-                .poll(HttpPollConfig.forMultiple()
-                    .onSuccess(new Function<HttpToolResponse,Void>() {
-                        public Void apply(HttpToolResponse response) {
-                            entity.setAttribute(SENSOR_INT, response.getResponseCode());
-                            if (response.getResponseCode()==200)
-                                entity.setAttribute(SENSOR_STRING, response.getContentAsString());
-                            return null;
-                        }
-                    })
-                    .onFailureOrException(Functionals.function(EntityFunctions.settingSensorsConstant(entity, MutableMap.<AttributeSensor<?>,Object>of(
-                        SENSOR_INT, -1, 
-                        SENSOR_STRING, PollConfig.REMOVE))))
-                .period(100))
-                .build();
-    }
-    
-
-    private <T> void assertSensorEventually(final AttributeSensor<T> sensor, final T expectedVal, long timeout) {
-        Asserts.succeedsEventually(ImmutableMap.of("timeout", timeout), new Callable<Void>() {
-            public Void call() {
-                assertEquals(entity.getAttribute(sensor), expectedVal);
-                return null;
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java
deleted file mode 100644
index 2afcae8..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java
+++ /dev/null
@@ -1,94 +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.sensor.feed.http;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-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.gson.JsonElement;
-import com.google.gson.JsonPrimitive;
-
-public class HttpValueFunctionsTest {
-
-    private int responseCode = 200;
-    private long fullLatency = 1000;
-    private String headerName = "my_header";
-    private String headerVal = "my_header_val";
-    private String bodyKey = "mykey";
-    private String bodyVal = "myvalue";
-    private String body = "{"+bodyKey+":"+bodyVal+"}";
-    private long now;
-    private HttpToolResponse response;
-    
-    @BeforeMethod
-    public void setUp() throws Exception {
-        now = System.currentTimeMillis();
-        response = new HttpToolResponse(responseCode, ImmutableMap.of(headerName, ImmutableList.of(headerVal)), 
-                body.getBytes(), now-fullLatency, fullLatency / 2, fullLatency);
-    }
-    
-    @Test
-    public void testResponseCode() throws Exception {
-        assertEquals(HttpValueFunctions.responseCode().apply(response), Integer.valueOf(responseCode));
-    }
-
-    @Test
-    public void testContainsHeader() throws Exception {
-        assertTrue(HttpValueFunctions.containsHeader(headerName).apply(response));
-        assertFalse(HttpValueFunctions.containsHeader("wrong_header").apply(response));
-    }
-    
-    @Test
-    public void testStringContents() throws Exception {
-        assertEquals(HttpValueFunctions.stringContentsFunction().apply(response), body);
-    }
-
-    @Test
-    public void testJsonContents() throws Exception {
-        JsonElement json = HttpValueFunctions.jsonContents().apply(response);
-        assertTrue(json.isJsonObject());
-        assertEquals(json.getAsJsonObject().entrySet(), ImmutableMap.of(bodyKey, new JsonPrimitive(bodyVal)).entrySet());
-    }
-
-    @Test
-    public void testJsonContentsGettingElement() throws Exception {
-        assertEquals(HttpValueFunctions.jsonContents(bodyKey, String.class).apply(response), bodyVal);
-    }
-
-    @Test(expectedExceptions=NoSuchElementException.class)
-    public void testJsonContentsGettingMissingElement() throws Exception {
-        assertNull(HttpValueFunctions.jsonContents("wrongkey", String.class).apply(response));
-    }
-
-    @Test
-    public void testLatency() throws Exception {
-        assertEquals(HttpValueFunctions.latency().apply(response), Long.valueOf(fullLatency));
-    }
-}