You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/11/22 00:25:42 UTC

[1/2] incubator-brooklyn git commit: Added utility class `TestFrameworkAssertions` to address comments from #999

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 10e9a3c7c -> 15faad338


Added utility class `TestFrameworkAssertions` to address comments from #999

TestFrameworkAssertions is a common class used by [TestSensor,TestHttpCall] instead of each entity having its own assertions

Changes to TestHttpCall
Added new config key `applyAssertionTo` possible values [body,status]

Changes to [TestSensor,TestHttpCall] blueprint
  Previous::
  assert:
    isEqualTo: SomeValue
  Now::
  assert:
  - isEqualTo: SomeValue

Currently Supported assertions [isNull,notNull,isEqualTo,equalTo,equals,matches,contains]


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/c129f064
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/c129f064
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/c129f064

Branch: refs/heads/master
Commit: c129f06441615eb75e64316c37915ba88135bed4
Parents: 295cf63
Author: Mark McKenna <m4...@gmail.com>
Authored: Wed Nov 11 18:06:55 2015 +0000
Committer: Mark McKenna <m4...@gmail.com>
Committed: Thu Nov 19 12:03:02 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/test/framework/BaseTest.java       |   8 +-
 .../test/framework/TestFrameworkAssertions.java | 160 +++++++++++++++++++
 .../brooklyn/test/framework/TestHttpCall.java   |  16 ++
 .../test/framework/TestHttpCallImpl.java        |  72 ++++-----
 .../brooklyn/test/framework/TestSensorImpl.java |  73 ++-------
 .../framework/TestFrameworkAssertionsTest.java  | 135 ++++++++++++++++
 .../test/framework/TestHttpCallTest.java        | 121 ++++++++++++++
 .../brooklyn/test/framework/TestSensorTest.java |  48 +++---
 .../example-catalog-test.bom                    |   2 +-
 .../nginx-test-examples.yml                     |  21 +--
 .../testhttpcall-examples.yml                   |  27 ++--
 .../tomcat-test-examples.yml                    |   8 +-
 12 files changed, 544 insertions(+), 147 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java
index 7fd70ef..f458018 100644
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/BaseTest.java
@@ -18,13 +18,15 @@
  */
 package org.apache.brooklyn.test.framework;
 
-import com.google.common.collect.Maps;
+import com.google.common.reflect.TypeToken;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.util.time.Duration;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
@@ -46,7 +48,9 @@ public interface BaseTest extends Entity, Startable {
     /**
      * The assertions to be made
      */
-    ConfigKey<Map> ASSERTIONS = ConfigKeys.newConfigKey(Map.class, "assert", "Assertions to be evaluated", Maps.newHashMap());
+    ConfigKey<List<Map<String, Object>>> ASSERTIONS = ConfigKeys.newConfigKey(
+            new TypeToken<List<Map<String, Object>>>() {},
+            "assert", "Assertions to be evaluated", new ArrayList<Map<String, Object>>());
 
     /**
      * THe duration to wait

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestFrameworkAssertions.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestFrameworkAssertions.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestFrameworkAssertions.java
new file mode 100644
index 0000000..9851ca2
--- /dev/null
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestFrameworkAssertions.java
@@ -0,0 +1,160 @@
+/*
+ * 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.test.framework;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Utility class to evaluate test-framework assertions
+ *
+ * @author m4rkmckenna on 11/11/2015.
+ */
+public class TestFrameworkAssertions {
+    private static final Logger LOG = LoggerFactory.getLogger(TestFrameworkAssertions.class);
+
+    private TestFrameworkAssertions() {
+    }
+
+    /**
+     * Evaluates all assertions against dataSupplier
+     *
+     * @param dataSupplier
+     * @param flags
+     * @param assertions
+     */
+    public static void checkAssertions(final Supplier<String> dataSupplier, final Map flags, final List<Map<String, Object>> assertions) {
+        //Iterate through assert array
+        for (final Map<String, Object> assertionsMap : assertions) {
+            checkAssertions(dataSupplier, flags, assertionsMap);
+        }
+    }
+
+    /**
+     * Evaluates all assertions against dataSupplier
+     *
+     * @param dataSupplier
+     * @param flags
+     * @param assertionsMap
+     */
+    public static void checkAssertions(final Supplier<String> dataSupplier, final Map flags, final Map<String, Object> assertionsMap) {
+        for (final Map.Entry<String, Object> assertion : assertionsMap.entrySet()) {
+            final Maybe<Predicate<String>> optionalPredicate = getPredicate(assertion.getKey(), assertion.getValue());
+            Asserts.succeedsEventually(flags, new PredicateChecker(dataSupplier, optionalPredicate.get()));
+        }
+    }
+
+    /**
+     * Returns the predicate associated with the predicateKey if one exists
+     *
+     * @param predicateKey
+     * @param predicateTarget
+     * @return {@link Maybe} of {@Link Predicate}
+     */
+    public static Maybe<Predicate<String>> getPredicate(final String predicateKey, final Object predicateTarget) {
+        if (StringUtils.equalsIgnoreCase("isNull", predicateKey)) {
+            return Maybe.of(Predicates.<String>isNull());
+        } else if (StringUtils.equalsIgnoreCase("notNull", predicateKey)) {
+            return Maybe.of(Predicates.<String>notNull());
+        } else if (StringUtils.equalsIgnoreCase("isEqualTo", predicateKey)
+                || StringUtils.equalsIgnoreCase("equalTo", predicateKey)
+                || StringUtils.equalsIgnoreCase("equals", predicateKey)) {
+            return Maybe.of(Predicates.equalTo(TypeCoercions.coerce(predicateTarget.toString(), String.class)));
+        } else if (StringUtils.equalsIgnoreCase("matches", predicateKey)) {
+            return Maybe.of(buildMatchesPredicate(TypeCoercions.coerce(predicateTarget, String.class)));
+        } else if (StringUtils.equalsIgnoreCase("contains", predicateKey)) {
+            return Maybe.of(buildContainsPredicate(TypeCoercions.coerce(predicateTarget, String.class)));
+        }
+        return Maybe.absent(String.format("No predicate found with signature [%s]", predicateKey));
+    }
+
+    /**
+     * Builds a predicate that checks if a string contains the supplied value
+     *
+     * @param predicateTarget
+     * @return {@link Predicate}
+     */
+    private static Predicate<String> buildContainsPredicate(final String predicateTarget) {
+        return new Predicate<String>() {
+
+            @Override
+            public boolean apply(@Nullable final String input) {
+                return StringUtils.contains(input, predicateTarget);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("TestFrameworkAssertions.contains(%s)", predicateTarget);
+            }
+        };
+    }
+
+    /**
+     * Builds a predicate that checks if a string matches the supplied pattern
+     *
+     * @param predicateTarget The pattern to check
+     * @return {@link Predicate}
+     */
+    private static Predicate<String> buildMatchesPredicate(final String predicateTarget) {
+        final Pattern pattern = Pattern.compile(predicateTarget);
+        return new Predicate<String>() {
+            public boolean apply(final String input) {
+                return (input != null) && pattern.matcher(input.toString()).matches();
+            }
+
+            @Override
+            public String toString() {
+                return String.format("TestFrameworkAssertions.matches(%s)", predicateTarget);
+            }
+        };
+    }
+
+    /**
+     * Runnable that will be passed to {@link Asserts#succeedsEventually}
+     */
+    private static class PredicateChecker implements Runnable {
+        private final Supplier<String> dataSupplier;
+        private final Predicate<String> predicate;
+
+        public PredicateChecker(final Supplier<String> dataSupplier, final Predicate<String> predicate) {
+            this.dataSupplier = dataSupplier;
+            this.predicate = predicate;
+        }
+
+        @Override
+        public void run() {
+            final String value = dataSupplier.get();
+            LOG.debug("Evaluating predicate [{}] with value [{}]", predicate.toString(), value);
+            Asserts.assertEquals(predicate.apply(value), true);
+            LOG.debug("Evaluation of predicate [{}] with value [{}] ... PASSED", predicate.toString(), value);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCall.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCall.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCall.java
index f1e51f6..c9faeb1 100644
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCall.java
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCall.java
@@ -34,4 +34,20 @@ public interface TestHttpCall extends BaseTest {
     @SetFromFlag(nullable = false)
     ConfigKey<String> TARGET_URL = ConfigKeys.newStringConfigKey("url", "URL to test");
 
+    ConfigKey<HttpAssertionTarget> ASSERTION_TARGET = ConfigKeys.newConfigKey(HttpAssertionTarget.class, "applyAssertionTo", "The HTTP field to apply the assertion to [body,status]", HttpAssertionTarget.body);
+
+    enum HttpAssertionTarget {
+        body("body"), status("status");
+        private final String httpAssertionTarget;
+
+        HttpAssertionTarget(final String httpAssertionTarget) {
+            this.httpAssertionTarget = httpAssertionTarget;
+        }
+
+        @Override
+        public String toString() {
+            return httpAssertionTarget;
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCallImpl.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCallImpl.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCallImpl.java
index 66e24da..028161c 100644
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCallImpl.java
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestHttpCallImpl.java
@@ -18,23 +18,22 @@
  */
 package org.apache.brooklyn.test.framework;
 
-import com.google.api.client.util.Objects;
+import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.http.HttpTool;
 import org.apache.brooklyn.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 
-import static org.apache.brooklyn.util.http.HttpAsserts.*;
-
 /**
  * {@inheritDoc}
  */
@@ -51,10 +50,12 @@ public class TestHttpCallImpl extends AbstractTest implements TestHttpCall {
         }
         ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
         final String url = getConfig(TARGET_URL);
-        final Map assertions = getConfig(ASSERTIONS);
+        final List<Map<String, Object>> assertions = getConfig(ASSERTIONS);
         final Duration timeout = getConfig(TIMEOUT);
+        final HttpAssertionTarget httpAssertionTarget = getConfig(ASSERTION_TARGET);
         try {
-            checkAssertions(url, ImmutableMap.of("timeout", timeout), assertions);
+            TestFrameworkAssertions.checkAssertions(buildDataSupplier(httpAssertionTarget, url),
+                    ImmutableMap.of("timeout", timeout), assertions);
             sensors().set(SERVICE_UP, true);
             ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
         } catch (Throwable t) {
@@ -65,42 +66,31 @@ public class TestHttpCallImpl extends AbstractTest implements TestHttpCall {
         }
     }
 
-    /**
-     * Tests HTTP Request reponse matches assertions
-     * <p>
-     * Supported keys in the <code>assertions</code> {@link Map} include:
-     * <ul>
-     * <li>string - simple string match
-     * <li>regex - uses {@link java.lang.String#matches(String)}, if the url returns a multi-line response you should
-     * use the embedded dotall flag expression <code>(?s)</code> in your regex.
-     * <li>status - HTTP status code
-     * </ul>
-     * Wraps the {@link org.apache.brooklyn.util.http.HttpAsserts} immediate assertion methods.
-     * <p>
-     * See the test/resources directory for examples.
-     *
-     * @param url        The target URL to be tested
-     * @param flags      Passed to {@link org.apache.brooklyn.util.http.HttpAsserts#assertContentEventuallyContainsText(Map, String, String, String...)},
-     *                   {@link org.apache.brooklyn.util.http.HttpAsserts#assertContentEventuallyMatches(Map, String, String)},
-     *                   {@link org.apache.brooklyn.util.http.HttpAsserts#assertHttpStatusCodeEventuallyEquals(Map, String, int)}
-     * @param assertions The map of assertions
-     */
-    private void checkAssertions(final String url, final Map<String, ?> flags, final Map<?, ?> assertions) {
+    private Supplier<String> buildDataSupplier(final HttpAssertionTarget httpAssertionTarget, final String url) {
+
+        switch (httpAssertionTarget) {
+            case body:
+                return new Supplier<String>() {
+                    @Override
+                    public String get() {
+                        return HttpTool.getContent(url);
+                    }
+                };
+            case status:
+                return new Supplier<String>() {
+                    @Override
+                    public String get() {
+                        try {
+                            return String.valueOf(HttpTool.getHttpStatusCode(url));
+                        } catch (Exception e) {
+                            LOG.error("HTTP call to [{}] failed due to [{}] ... returning Status code [0 - Unreachable]", url, e.getMessage());
+                            return "0";
+                        }
 
-        for (final Map.Entry<?, ?> entry : assertions.entrySet()) {
-            if (Objects.equal(entry.getKey(), "regex")) {
-                LOG.info("Testing if url [{}] matches regex [{}]",
-                        new Object[]{url, entry.getValue()});
-                assertContentEventuallyMatches(flags, url, TypeCoercions.coerce(entry.getValue(), String.class));
-            } else if (Objects.equal(entry.getKey(), "bodyContains")) {
-                LOG.debug("Testing if url [{}] contains string [{}]",
-                        new Object[]{url, entry.getValue()});
-                assertContentEventuallyContainsText(flags, url, TypeCoercions.coerce(entry.getValue(), String.class));
-            } else if (Objects.equal(entry.getKey(), "status")) {
-                LOG.debug("Testing if url [{}] returns status code [{}]",
-                        new Object[]{url, entry.getValue()});
-                assertHttpStatusCodeEventuallyEquals(flags, url, TypeCoercions.coerce(entry.getValue(), Integer.class));
-            }
+                    }
+                };
+            default:
+                throw new RuntimeException("Unable to build a data supplier to target assertion [" + httpAssertionTarget + "]");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
index c2d6169..0f7760a 100644
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/TestSensorImpl.java
@@ -20,14 +20,15 @@ package org.apache.brooklyn.test.framework;
 
 import com.google.api.client.util.Objects;
 import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
 import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.util.core.flags.ClassCoercionException;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.time.Duration;
@@ -35,10 +36,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
-import java.util.regex.Pattern;
-
-import static org.apache.brooklyn.core.entity.EntityAsserts.assertAttributeEventually;
 
 /**
  * {@inheritDoc}
@@ -58,10 +57,21 @@ public class TestSensorImpl extends AbstractTest implements TestSensor {
         final Entity target = resolveTarget();
         final String sensor = getConfig(SENSOR_NAME);
         final Duration timeout = getConfig(TIMEOUT);
-        final Map assertions = getConfig(ASSERTIONS);
+        final List<Map<String, Object>> assertions = getConfig(ASSERTIONS);
         try {
-            checkAssertions(target, Sensors.newSensor(Object.class, sensor), ImmutableMap.of("timeout", timeout),
-                    assertions);
+            TestFrameworkAssertions.checkAssertions(new Supplier<String>() {
+                @Override
+                public String get() {
+                    final Object sensorValue = target.sensors().get(Sensors.newSensor(Object.class, sensor));
+                    try {
+                        return TypeCoercions.coerce(sensorValue, String.class);
+                    } catch (ClassCoercionException cce) {
+                        LOG.debug("Could mot coerce sensor value to a string ... invoking toString() instead");
+                        return (sensorValue != null) ? sensorValue.toString() : null;
+                    }
+                }
+            }, ImmutableMap.of("timeout", timeout), assertions);
+
             sensors().set(SERVICE_UP, true);
             ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
         } catch (Throwable t) {
@@ -72,25 +82,6 @@ public class TestSensorImpl extends AbstractTest implements TestSensor {
         }
     }
 
-    /**
-     * Tests sensor values match assertions
-     *
-     * @param target     The {@link Entity} that has the sensor under test
-     * @param sensor     The sensor to test
-     * @param flags      Passed to {@link org.apache.brooklyn.core.entity.EntityAsserts#assertAttributeEventually(Map, Entity, AttributeSensor, Predicate)}
-     * @param assertions The map of assertions
-     */
-    private void checkAssertions(final Entity target, final AttributeSensor<Object> sensor, final Map<?, ?> flags, final Map<?, ?> assertions) {
-        for (final Map.Entry<?, ?> entry : assertions.entrySet()) {
-            if (Objects.equal(entry.getKey(), "equals")) {
-                assertAttributeEventually(flags, target, sensor, isEqualTo(entry.getValue()));
-            } else if (Objects.equal(entry.getKey(), "regex")) {
-                assertAttributeEventually(flags, target, sensor, regexMatches(entry.getValue()));
-            } else if (Objects.equal(entry.getKey(), "isNull")) {
-                assertAttributeEventually(flags, target, sensor, isNull(entry.getValue()));
-            }
-        }
-    }
 
     /**
      * {@inheritDoc}
@@ -122,34 +113,4 @@ public class TestSensorImpl extends AbstractTest implements TestSensor {
             }
         };
     }
-
-    /**
-     * Predicate to check if a sensor matches a regex pattern
-     *
-     * @param patternValue
-     * @return
-     */
-    private Predicate<Object> regexMatches(final Object patternValue) {
-        final Pattern pattern = Pattern.compile(TypeCoercions.coerce(patternValue, String.class));
-        return new Predicate<Object>() {
-            public boolean apply(final Object input) {
-                return (input != null) && pattern.matcher(input.toString()).matches();
-            }
-        };
-    }
-
-    /**
-     * Predicate to check if a sensor value is null
-     *
-     * @param isNullValue
-     * @return
-     */
-    private Predicate<Object> isNull(final Object isNullValue) {
-        return new Predicate<Object>() {
-            public boolean apply(final Object input) {
-                return (input == null) == TypeCoercions.coerce(isNullValue, Boolean.class);
-            }
-        };
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestFrameworkAssertionsTest.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestFrameworkAssertionsTest.java b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestFrameworkAssertionsTest.java
new file mode 100644
index 0000000..eb39735
--- /dev/null
+++ b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestFrameworkAssertionsTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.test.framework;
+
+import com.google.common.base.Supplier;
+import org.apache.brooklyn.util.text.Identifiers;
+import org.apache.brooklyn.util.time.Duration;
+import org.python.google.common.collect.ImmutableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author m4rkmckenna on 11/11/2015.
+ */
+public class TestFrameworkAssertionsTest {
+    private static final Logger LOG = LoggerFactory.getLogger(TestFrameworkAssertionsTest.class);
+
+    @BeforeMethod
+    public void setup() {
+
+    }
+
+    @DataProvider
+    public Object[][] positiveTestsDP() {
+        return new Object[][]{
+                {"some-sensor-value", Arrays.asList(ImmutableMap.of("isEqualTo", "some-sensor-value"))},
+                {"some-sensor-value", Arrays.asList(ImmutableMap.of("equals", "some-sensor-value"))},
+                {"some-regex-value-to-match", Arrays.asList(ImmutableMap.of("matches", "some.*match", "isEqualTo", "some-regex-value-to-match"))},
+                {null, Arrays.asList(ImmutableMap.of("isNUll", ""))},
+                {"some-non-null-value", Arrays.asList(ImmutableMap.of("notNull", ""))},
+                {"<html><body><h1>Im a H1 tag!</h1></body></html>", Arrays.asList(ImmutableMap.of("contains", "Im a H1 tag!"))},
+                {"{\"a\":\"b\",\"c\":\"d\",\"e\":123,\"g\":false}", Arrays.asList(ImmutableMap.of("contains", "false"))}
+        };
+    }
+
+    @Test(dataProvider = "positiveTestsDP")
+    public void positiveTest(final String data, final List<Map<String, Object>> assertions) {
+        final Supplier<String> supplier = new Supplier<String>() {
+            @Override
+            public String get() {
+                LOG.info("Supplier invoked for data [{}]", data);
+                return data;
+            }
+        };
+        TestFrameworkAssertions.checkAssertions(supplier, ImmutableMap.of("timeout", new Duration(2L, TimeUnit.SECONDS)), assertions);
+    }
+
+    @DataProvider
+    public Object[][] negativeTestsDP() {
+        return new Object[][]{
+                {"some-sensor-value", Arrays.asList(ImmutableMap.of("isEqualTo", Identifiers.makeRandomId(8)))},
+                {"some-sensor-value", Arrays.asList(ImmutableMap.of("equals", Identifiers.makeRandomId(8)))},
+                {"some-regex-value-to-match", Arrays.asList(ImmutableMap.of("matches", "some.*not-match", "isEqualTo", "oink"))},
+                {null, Arrays.asList(ImmutableMap.of("notNull", ""))},
+                {"some-non-null-value", Arrays.asList(ImmutableMap.of("isNull", ""))},
+                {"<html><body><h1>Im a H1 tag!</h1></body></html>", Arrays.asList(ImmutableMap.of("contains", "quack"))},
+                {"{\"a\":\"b\",\"c\":\"d\",\"e\":123,\"g\":false}", Arrays.asList(ImmutableMap.of("contains", "moo"))}
+        };
+    }
+
+    @Test(dataProvider = "negativeTestsDP")
+    public void negativeTests(final String data, final List<Map<String, Object>> assertions) {
+        final Supplier<String> supplier = new Supplier<String>() {
+            @Override
+            public String get() {
+                LOG.info("Supplier invoked for data [{}]", data);
+                return data;
+            }
+        };
+        boolean assertionErrorCaught = false;
+        try {
+            TestFrameworkAssertions.checkAssertions(supplier, ImmutableMap.of("timeout", new Duration(2L, TimeUnit.SECONDS)), assertions);
+        } catch (AssertionError e) {
+            assertionErrorCaught = true;
+            assertThat(e).hasMessage("expected [true] but found [false]");
+        } finally {
+            assertThat(assertionErrorCaught).isTrue().as("An assertion error should have been thrown");
+        }
+
+    }
+
+    @Test
+    public void testUnknownAssertion() {
+        final String randomId = Identifiers.makeRandomId(8);
+        final Map<String, Object> assertions = new HashMap<>();
+        assertions.put(randomId, randomId);
+
+        final Supplier<String> supplier = new Supplier<String>() {
+            @Override
+            public String get() {
+                LOG.info("Supplier invoked for data [{}]", randomId);
+                return randomId;
+            }
+        };
+        boolean illegalStateExceptionThrown = false;
+        try {
+            TestFrameworkAssertions.checkAssertions(supplier, ImmutableMap.of("timeout", new Duration(2L, TimeUnit.SECONDS)), assertions);
+        } catch (Exception e) {
+            assertThat(e).isInstanceOf(IllegalStateException.class);
+            assertThat(e).hasMessage("No predicate found with signature [" + randomId + "]");
+            illegalStateExceptionThrown = true;
+        } finally {
+            assertThat(illegalStateExceptionThrown).isTrue().as("An illegal state exception should have been thrown");
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestHttpCallTest.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestHttpCallTest.java b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestHttpCallTest.java
new file mode 100644
index 0000000..ffa4001
--- /dev/null
+++ b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestHttpCallTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.test.framework;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.test.http.TestHttpRequestHandler;
+import org.apache.brooklyn.test.http.TestHttpServer;
+import org.apache.brooklyn.util.text.Identifiers;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author m4rkmckenna on 12/11/2015.
+ */
+public class TestHttpCallTest {
+
+
+    private TestHttpServer server;
+    private TestApplication app;
+    private ManagementContext managementContext;
+    private LocalhostMachineProvisioningLocation loc;
+    private String testId;
+
+    @BeforeMethod
+    public void setup() {
+        testId = Identifiers.makeRandomId(8);
+        server = new TestHttpServer()
+                .handler("/201", new TestHttpRequestHandler()
+                        .response("Created - " + testId)
+                        .code(201))
+                .handler("/204", new TestHttpRequestHandler().code(204))
+                .handler("/index.html", new TestHttpRequestHandler()
+                        .response("<html><body><h1>Im a H1 tag!</h1></body></html>")
+                        .code(200))
+                .handler("/body.json", new TestHttpRequestHandler()
+                        .response("{\"a\":\"b\",\"c\":\"d\",\"e\":123,\"g\":false}")
+                        .code(200 + Identifiers.randomInt(99)))
+                .start();
+        app = TestApplication.Factory.newManagedInstanceForTests();
+        managementContext = app.getManagementContext();
+        loc = managementContext.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class)
+                .configure("name", testId));
+    }
+
+
+    @Test
+    public void testHttpBodyAssertions() {
+        app.createAndManageChild(EntitySpec.create(TestHttpCall.class)
+                .configure(TestHttpCall.TARGET_URL, server.getUrl() + "/201")
+                .configure(TestHttpCall.TIMEOUT, new Duration(10L, TimeUnit.SECONDS))
+                .configure(TestSensor.ASSERTIONS, newAssertion("isEqualTo", "Created - " + testId)));
+        app.createAndManageChild(EntitySpec.create(TestHttpCall.class)
+                .configure(TestHttpCall.TARGET_URL, server.getUrl() + "/204")
+                .configure(TestHttpCall.TIMEOUT, new Duration(10L, TimeUnit.SECONDS))
+                .configure(TestSensor.ASSERTIONS, newAssertion("isEqualTo", "")));
+        app.createAndManageChild(EntitySpec.create(TestHttpCall.class)
+                .configure(TestHttpCall.TARGET_URL, server.getUrl() + "/index.html")
+                .configure(TestHttpCall.TIMEOUT, new Duration(10L, TimeUnit.SECONDS))
+                .configure(TestSensor.ASSERTIONS, newAssertion("contains", "Im a H1 tag!")));
+        app.createAndManageChild(EntitySpec.create(TestHttpCall.class)
+                .configure(TestHttpCall.TARGET_URL, server.getUrl() + "/body.json")
+                .configure(TestHttpCall.TIMEOUT, new Duration(10L, TimeUnit.SECONDS))
+                .configure(TestSensor.ASSERTIONS, newAssertion("matches", ".*123.*")));
+        app.start(ImmutableList.of(loc));
+    }
+
+    @Test
+    public void testHttpStatusAssertions() {
+        app.createAndManageChild(EntitySpec.create(TestHttpCall.class)
+                .configure(TestHttpCall.TARGET_URL, server.getUrl() + "/201")
+                .configure(TestHttpCall.TIMEOUT, new Duration(10L, TimeUnit.SECONDS))
+                .configure(TestHttpCall.ASSERTION_TARGET, TestHttpCall.HttpAssertionTarget.status)
+                .configure(TestSensor.ASSERTIONS, newAssertion("notNull", "")));
+        app.createAndManageChild(EntitySpec.create(TestHttpCall.class)
+                .configure(TestHttpCall.TARGET_URL, server.getUrl() + "/204")
+                .configure(TestHttpCall.TIMEOUT, new Duration(10L, TimeUnit.SECONDS))
+                .configure(TestHttpCall.ASSERTION_TARGET, TestHttpCall.HttpAssertionTarget.status)
+                .configure(TestSensor.ASSERTIONS, newAssertion("isEqualTo", "204")));
+        app.createAndManageChild(EntitySpec.create(TestHttpCall.class)
+                .configure(TestHttpCall.TARGET_URL, server.getUrl() + "/body.json")
+                .configure(TestHttpCall.TIMEOUT, new Duration(10L, TimeUnit.SECONDS))
+                .configure(TestHttpCall.ASSERTION_TARGET, TestHttpCall.HttpAssertionTarget.status)
+                .configure(TestSensor.ASSERTIONS, newAssertion("matches", "2[0-9][0-9]")));
+        app.start(ImmutableList.of(loc));
+    }
+
+    private List<Map<String, Object>> newAssertion(final String assertionKey, final Object assertionValue) {
+        final List<Map<String, Object>> result = new ArrayList<>();
+        result.add(ImmutableMap.of(assertionKey, assertionValue));
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestSensorTest.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestSensorTest.java b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestSensorTest.java
index ecb1c31..83634fa 100644
--- a/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestSensorTest.java
+++ b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/TestSensorTest.java
@@ -37,6 +37,10 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 import static org.assertj.core.api.Assertions.assertThat;
 
 /**
@@ -73,12 +77,12 @@ public class TestSensorTest {
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, BOOLEAN_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("equals", true)));
+                .configure(TestSensor.ASSERTIONS, newAssertion("equals", true)));
         //Add Sensor Test for STRING sensor
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("equals", testId)));
+                .configure(TestSensor.ASSERTIONS, newAssertion("equals", testId)));
 
         //Set BOOLEAN Sensor to true
         app.sensors().set(BOOLEAN_SENSOR, Boolean.TRUE);
@@ -98,7 +102,7 @@ public class TestSensorTest {
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, BOOLEAN_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("equals", true)));
+                .configure(TestSensor.ASSERTIONS, newAssertion("equals", true)));
 
         //Set BOOLEAN Sensor to false
         app.sensors().set(BOOLEAN_SENSOR, Boolean.FALSE);
@@ -122,7 +126,7 @@ public class TestSensorTest {
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, BOOLEAN_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("equals", false)));
+                .configure(TestSensor.ASSERTIONS, newAssertion("equals", false)));
 
         try {
             app.start(ImmutableList.of(loc));
@@ -141,12 +145,12 @@ public class TestSensorTest {
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, BOOLEAN_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("isNull", true)));
+                .configure(TestSensor.ASSERTIONS, newAssertion("isNull", "")));
         //Add Sensor Test for STRING sensor
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("isNull", false)));
+                .configure(TestSensor.ASSERTIONS, newAssertion("notNUll", "")));
 
         //Set STRING sensor to random string
         app.sensors().set(STRING_SENSOR, testId);
@@ -163,7 +167,7 @@ public class TestSensorTest {
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("isNull", true)));
+                .configure(TestSensor.ASSERTIONS, newAssertion("isNull", "true")));
 
         //Set STRING sensor to random string
         app.sensors().set(STRING_SENSOR, testId);
@@ -182,7 +186,7 @@ public class TestSensorTest {
     }
 
     @Test
-    public void testAssertRegex() {
+    public void testAssertMatches() {
         final long time = System.currentTimeMillis();
         final String sensorValue = String.format("%s%s%s", Identifiers.makeRandomId(8), time, Identifiers.makeRandomId(8));
 
@@ -190,11 +194,11 @@ public class TestSensorTest {
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("regex", String.format(".*%s.*", time))));
+                .configure(TestSensor.ASSERTIONS, newAssertion("matches", String.format(".*%s.*", time))));
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, BOOLEAN_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("regex", "true")));
+                .configure(TestSensor.ASSERTIONS, newAssertion("matches", "true")));
 
         //Set STRING sensor
         app.sensors().set(STRING_SENSOR, sensorValue);
@@ -205,7 +209,7 @@ public class TestSensorTest {
     }
 
     @Test
-    public void testAssertRegexFail() {
+    public void testAssertmatchesFail() {
         boolean sensorTestFail = false;
         final String sensorValue = String.format("%s%s%s", Identifiers.makeRandomId(8), System.currentTimeMillis(), Identifiers.makeRandomId(8));
 
@@ -213,12 +217,10 @@ public class TestSensorTest {
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("regex", String.format(".*%s.*", Identifiers.makeRandomId(8)))));
+                .configure(TestSensor.ASSERTIONS, newAssertion("matches", String.format(".*%s.*", Identifiers.makeRandomId(8)))));
 
         //Set STRING sensor
         app.sensors().set(STRING_SENSOR, sensorValue);
-
-
         try {
             app.start(ImmutableList.of(loc));
         } catch (final PropagatedRuntimeException pre) {
@@ -226,18 +228,18 @@ public class TestSensorTest {
             assertThat(assertionError).isNotNull().as("An assertion error should have been thrown");
             sensorTestFail = true;
         } finally {
-            assertThat(sensorTestFail).isTrue().as("regex assert should have failed");
+            assertThat(sensorTestFail).isTrue().as("matches assert should have failed");
         }
     }
 
     @Test
-    public void testAssertRegexOnNullSensor() {
+    public void testAssertmatchesOnNullSensor() {
         boolean sensorTestFail = false;
         //Add Sensor Test for STRING sensor
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("regex", String.format(".*%s.*", Identifiers.makeRandomId(8)))));
+                .configure(TestSensor.ASSERTIONS, newAssertion("matches", String.format(".*%s.*", Identifiers.makeRandomId(8)))));
 
         try {
             app.start(ImmutableList.of(loc));
@@ -246,18 +248,18 @@ public class TestSensorTest {
             assertThat(assertionError).isNotNull().as("An assertion error should have been thrown");
             sensorTestFail = true;
         } finally {
-            assertThat(sensorTestFail).isTrue().as("regex assert should have failed");
+            assertThat(sensorTestFail).isTrue().as("matches assert should have failed");
         }
     }
 
 
     @Test
-    public void testAssertRegexOnNonStringSensor() {
+    public void testAssertMatchesOnNonStringSensor() {
         //Add Sensor Test for OBJECT sensor
         app.createAndManageChild(EntitySpec.create(TestSensor.class)
                 .configure(TestSensor.TARGET_ENTITY, app)
                 .configure(TestSensor.SENSOR_NAME, OBJECT_SENSOR.getName())
-                .configure(TestSensor.ASSERTIONS, ImmutableMap.of("regex", ".*TestObject.*id=.*")));
+                .configure(TestSensor.ASSERTIONS, newAssertion("matches", ".*TestObject.*id=.*")));
 
         app.sensors().set(OBJECT_SENSOR, new TestObject());
 
@@ -265,6 +267,12 @@ public class TestSensorTest {
 
     }
 
+    private List<Map<String, Object>> newAssertion(final String assertionKey, final Object assertionValue) {
+        final List<Map<String, Object>> result = new ArrayList<>();
+        result.add(ImmutableMap.<String, Object>of(assertionKey, assertionValue));
+        return result;
+    }
+
 
     class TestObject {
         private final String id;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/test/resources/test-framework-examples/example-catalog-test.bom
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/resources/test-framework-examples/example-catalog-test.bom b/usage/test-framework/src/test/resources/test-framework-examples/example-catalog-test.bom
index fae0f60..65f2673 100644
--- a/usage/test-framework/src/test/resources/test-framework-examples/example-catalog-test.bom
+++ b/usage/test-framework/src/test/resources/test-framework-examples/example-catalog-test.bom
@@ -37,4 +37,4 @@ brooklyn.catalog:
         sensor: service.isUp
         timeout: 10m
         assert:
-          equals: true
\ No newline at end of file
+        - equals: true
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/test/resources/test-framework-examples/nginx-test-examples.yml
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/resources/test-framework-examples/nginx-test-examples.yml b/usage/test-framework/src/test/resources/test-framework-examples/nginx-test-examples.yml
index 6cb7d2d..ff01082 100644
--- a/usage/test-framework/src/test/resources/test-framework-examples/nginx-test-examples.yml
+++ b/usage/test-framework/src/test/resources/test-framework-examples/nginx-test-examples.yml
@@ -34,7 +34,8 @@ services:
   - type: org.apache.brooklyn.test.framework.TestSensor
     target: $brooklyn:component("nginx1")
     sensor: service.isUp
-    equals: true
+    assert:
+    - equals: true
     timeout: 5m
   - type: org.apache.brooklyn.test.framework.TestEffector
     target: $brooklyn:component("nginx1")
@@ -43,7 +44,7 @@ services:
     target: $brooklyn:component("nginx1")
     sensor: service.isUp
     assert:
-      equals: false
+    - equals: false
 ...
 
 ---
@@ -58,13 +59,15 @@ services:
     id: nginx1
   - type: org.apache.brooklyn.test.framework.TestSensor
     sensor: service.isUp
-    equals: true
+    assert:
+    - equals: true
     timeout: 5m
   - type: org.apache.brooklyn.test.framework.TestEffector
     effector: stop
   - type: org.apache.brooklyn.test.framework.TestSensor
     sensor: service.isUp
-    equals: false
+    assert:
+    - equals: false
 
 
 
@@ -82,7 +85,7 @@ services:
     sensor: service.isUp
     timeout: 5m
     assert:
-      equals: true
+    - equals: true
   - type: org.apache.brooklyn.test.framework.TestEffector
     target: $brooklyn:component("nginx1")
     effector: stop
@@ -90,8 +93,8 @@ services:
     target: $brooklyn:component("nginx1")
     sensor: service.isUp
     assert:
-      equals: false
-      regex: .*
+    - isEqualTo: false
+    - matches: .*
 ...
 
 ---
@@ -105,12 +108,12 @@ services:
   sensor: service.isUp
   timeout: 5m
   assert:
-    equals: true
+  - equals: true
 - type: org.apache.brooklyn.test.framework.TestSensor
   name: Test Regex
   target: $brooklyn:component("nginx1")
   sensor: service.isUp
   timeout: 5m
   assert:
-    regex: .*
+  - matches: .*
 ...
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/test/resources/test-framework-examples/testhttpcall-examples.yml
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/resources/test-framework-examples/testhttpcall-examples.yml b/usage/test-framework/src/test/resources/test-framework-examples/testhttpcall-examples.yml
index 2b7a871..738f787 100644
--- a/usage/test-framework/src/test/resources/test-framework-examples/testhttpcall-examples.yml
+++ b/usage/test-framework/src/test/resources/test-framework-examples/testhttpcall-examples.yml
@@ -29,22 +29,26 @@ services:
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: Status Code 200
     url: $brooklyn:component("tomcat").attributeWhenReady("webapp.url")
+    applyAssertionTo: status
     assert:
-      status: 200
+    - equalTo: 200
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: Status Code 404
     url: $brooklyn:formatString("%s/invalidpath/", component("tomcat").attributeWhenReady("webapp.url"))
     timeout: 10s
+    applyAssertionTo: status
     assert:
       status: 404
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: String match
     url: $brooklyn:component("tomcat").attributeWhenReady("webapp.url")
+    applyAssertionTo: body
     assert:
-      bodyContains: Sample Brooklyn Deployed
+    - contains: Sample Brooklyn Deployed
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: Regex match
     url: $brooklyn:component("tomcat").attributeWhenReady("webapp.url")
+    applyAssertionTo: body
     # the regex assert uses java.lang.String under the hood so if the url is expected to returns
     # a multi-line response you should use the embedded dotall flag expression `(?s)` in your regex.
     # See: http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
@@ -65,13 +69,15 @@ services:
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: / Status Code 200
     url: $brooklyn:component("tomcat").attributeWhenReady("webapp.url")
+    applyAssertionTo: status
     assert:
-      status: 200
+    - isEqualTo: 200
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: /newcontext Status Code 404
     url: $brooklyn:formatString("%s/newcontext/", component("tomcat").attributeWhenReady("webapp.url"))
+    applyAssertionTo: status
     assert:
-      status: 404
+    - equalTo: 404
   - type: org.apache.brooklyn.test.framework.TestEffector
     name: Deploy WAR in /newcontext
     target: $brooklyn:component("tomcat")
@@ -84,8 +90,9 @@ services:
     url: $brooklyn:formatString("%s/newcontext/", component("tomcat").attributeWhenReady("webapp.url"))
     # Give Tomcat time to make the newly deployed War accessible
     timeout: 10s
+    applyAssertionTo: status
     assert:
-      status: 200
+    - equals: 200
 ...
 
 ---
@@ -110,7 +117,7 @@ services:
     url: $brooklyn:formatString("%s/newcontext/", component("tomcat").attributeWhenReady("webapp.url"))
     timeout: 10s
     assert:
-      regex: "(?s).*illustrate(\\s)*how(\\s)*web(\\s)*applications.*"
+    - matches: "(?s).*illustrate(\\s)*how(\\s)*web(\\s)*applications.*"
   - type: org.apache.brooklyn.test.framework.TestEffector
     name: Deploy WAR in /newcontext2
     target: $brooklyn:component("tomcat")
@@ -123,14 +130,12 @@ services:
     url: $brooklyn:formatString("%s/newcontext2/", component("tomcat").attributeWhenReady("webapp.url"))
     timeout: 10s
     assert:
-      bodyContains: Sample Brooklyn Deployed
-    assert:
-      status: 404
+    - contains: Sample Brooklyn Deployed
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: String match
     url: $brooklyn:component("tomcat").attributeWhenReady("webapp.url")
     assert:
-      bodyContains: Sample Brooklyn Deployed
+    - contains: Sample Brooklyn Deployed
   - type: org.apache.brooklyn.test.framework.TestHttpCall
     name: Regex match
     url: $brooklyn:component("tomcat").attributeWhenReady("webapp.url")
@@ -138,5 +143,5 @@ services:
     # a multi-line response you should use the embedded dotall flag expression `(?s)` in your regex.
     # See: http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
     assert:
-      regex: "(?s).*illustrate(\\s)*how(\\s)*web(\\s)*applications.*"
+    - matches: "(?s).*illustrate(\\s)*how(\\s)*web(\\s)*applications.*"
 ...
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c129f064/usage/test-framework/src/test/resources/test-framework-examples/tomcat-test-examples.yml
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/resources/test-framework-examples/tomcat-test-examples.yml b/usage/test-framework/src/test/resources/test-framework-examples/tomcat-test-examples.yml
index a971355..0a843e7 100644
--- a/usage/test-framework/src/test/resources/test-framework-examples/tomcat-test-examples.yml
+++ b/usage/test-framework/src/test/resources/test-framework-examples/tomcat-test-examples.yml
@@ -32,7 +32,7 @@ services:
   target: $brooklyn:component("tomcat")
   sensor: service.isUp
   assert:
-    equals: true
+  - equals: true
   timeout: 10m
 ...
 
@@ -54,10 +54,4 @@ services:
       params:
         url: https://tomcat.apache.org/tomcat-6.0-doc/appdev/sample/sample.war
         targetName: sample1
-#    - type: org.apache.brooklyn.test.framework.TestSensor
-#      target: $brooklyn:component("tomcat")
-#      sensor: webapp.deployedWars
-#      assert:
-#        regex: .*sample1.*
-#      timeout: 1m
 ...
\ No newline at end of file


[2/2] incubator-brooklyn git commit: This closes #1049

Posted by ha...@apache.org.
This closes #1049


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/15faad33
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/15faad33
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/15faad33

Branch: refs/heads/master
Commit: 15faad33862149aa85d4d7a8935d16b061d1bb01
Parents: 10e9a3c c129f06
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Sat Nov 21 18:12:35 2015 -0500
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Sat Nov 21 18:12:35 2015 -0500

----------------------------------------------------------------------
 .../brooklyn/test/framework/BaseTest.java       |   8 +-
 .../test/framework/TestFrameworkAssertions.java | 160 +++++++++++++++++++
 .../brooklyn/test/framework/TestHttpCall.java   |  16 ++
 .../test/framework/TestHttpCallImpl.java        |  72 ++++-----
 .../brooklyn/test/framework/TestSensorImpl.java |  73 ++-------
 .../framework/TestFrameworkAssertionsTest.java  | 135 ++++++++++++++++
 .../test/framework/TestHttpCallTest.java        | 121 ++++++++++++++
 .../brooklyn/test/framework/TestSensorTest.java |  48 +++---
 .../example-catalog-test.bom                    |   2 +-
 .../nginx-test-examples.yml                     |  21 +--
 .../testhttpcall-examples.yml                   |  27 ++--
 .../tomcat-test-examples.yml                    |   8 +-
 12 files changed, 544 insertions(+), 147 deletions(-)
----------------------------------------------------------------------