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 2016/02/01 18:48:48 UTC

[02/50] brooklyn-server git commit: HttpLatencyDetector: cleanup

HttpLatencyDetector: cleanup

- Some minor cleanup, following Alex's commits for HttpLatencyDetector


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

Branch: refs/heads/0.5.0
Commit: 9714edc3d5381b827c0f5019d1c974c8c473718b
Parents: d2ed034
Author: Aled Sage <al...@gmail.com>
Authored: Thu Mar 28 09:30:45 2013 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Fri Mar 29 09:41:06 2013 +0000

----------------------------------------------------------------------
 .../java/brooklyn/event/feed/http/HttpFeed.java |  3 +-
 .../brooklyn/event/feed/http/HttpPolls.java     |  8 +--
 .../util/javalang/AtomicReferences.java         |  4 +-
 .../java/brooklyn/util/javalang/Providers.java  | 50 -------------
 .../java/brooklyn/util/math/MathFunctions.java  |  4 +-
 core/src/main/java/brooklyn/util/net/Urls.java  | 34 +++++++--
 .../brooklyn/event/feed/http/HttpFeedTest.java  | 19 +++--
 .../brooklyn/enricher/HttpLatencyDetector.java  | 62 ++++++++--------
 .../src/main/java/brooklyn/test/Asserts.java    | 66 ++++++++++++++++-
 .../main/java/brooklyn/test/TestUtils.groovy    | 74 ++++++++++----------
 10 files changed, 183 insertions(+), 141 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java b/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
index 0c1806d..5872921 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
@@ -35,7 +35,6 @@ import brooklyn.event.feed.AttributePollHandler;
 import brooklyn.event.feed.DelegatingPollHandler;
 import brooklyn.event.feed.Poller;
 import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.net.Urls;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Supplier;
@@ -128,7 +127,7 @@ public class HttpFeed extends AbstractFeed {
             return this;
         }
         public Builder baseUrl(URL val) {
-            return baseUri(Urls.URI_FROM_STRING.apply(val.toString()));
+            return baseUri(URI.create(val.toString()));
         }
         public Builder baseUri(String val) {
             return baseUri(URI.create(val));

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/core/src/main/java/brooklyn/event/feed/http/HttpPolls.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/HttpPolls.java b/core/src/main/java/brooklyn/event/feed/http/HttpPolls.java
index 009b459..e434b93 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpPolls.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpPolls.java
@@ -14,15 +14,13 @@ public class HttpPolls {
     public static HttpPollValue executeSimpleGet(URI uri) {
         DefaultHttpClient httpClient = new DefaultHttpClient();
         HttpGet httpGet = new HttpGet(uri);
-        HttpResponse httpResponse = null;
         try {
+            long startTime = System.currentTimeMillis();
+            HttpResponse httpResponse = httpClient.execute(httpGet);
             try {
-                long startTime = System.currentTimeMillis();
-                httpResponse = httpClient.execute(httpGet);
                 return new HttpPollValue(httpResponse, startTime);
             } finally {
-                if (httpResponse!=null)
-                    EntityUtils.consume(httpResponse.getEntity());
+                EntityUtils.consume(httpResponse.getEntity());
             }
         } catch (Exception e) {
             throw Exceptions.propagate(e);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/core/src/main/java/brooklyn/util/javalang/AtomicReferences.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/javalang/AtomicReferences.java b/core/src/main/java/brooklyn/util/javalang/AtomicReferences.java
index 0555de9..fb03d91 100644
--- a/core/src/main/java/brooklyn/util/javalang/AtomicReferences.java
+++ b/core/src/main/java/brooklyn/util/javalang/AtomicReferences.java
@@ -22,8 +22,8 @@ public class AtomicReferences {
     public static <T> Supplier<T> supplier(final AtomicReference<T> ref) {
         Preconditions.checkNotNull(ref);
         return new Supplier<T>() {
-            public T get() { return ref.get(); }
+            @Override public T get() { return ref.get(); }
+            @Override public String toString() { return "AtomicRefSupplier"; }
         };
     }
-
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/core/src/main/java/brooklyn/util/javalang/Providers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/javalang/Providers.java b/core/src/main/java/brooklyn/util/javalang/Providers.java
deleted file mode 100644
index aa3f13c..0000000
--- a/core/src/main/java/brooklyn/util/javalang/Providers.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package brooklyn.util.javalang;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-
-public class Providers {
-
-//    public static <T> Provider<T> constant(T value) {
-//        return new ConstantProvider<T>(value);
-//    }
-//    
-//    public static class ConstantProvider<T> implements Provider<T> {
-//        final T value;
-//        public ConstantProvider(T value) { this.value = value; }
-//        @Override public T get() { return value; }
-//        @Override public int hashCode() { return Objects.hashCode(value); }
-//        @Override public boolean equals(Object other) { 
-//            if (!(other instanceof ConstantProvider)) return false;
-//            return Objects.equal(value, ((ConstantProvider<?>)other).value); 
-//        }
-//    }
-// 
-//    public static <T> AtomicProvider<T> atomic(AtomicReference<T> ref) {
-//        return new AtomicProvider<T>(ref);
-//    }
-//
-//    public static class AtomicProvider<T> implements Provider<T> {
-//        final AtomicReference<T> ref;
-//        public AtomicProvider(AtomicReference<T> ref) { this.ref = ref; }
-//        @Override public T get() { return ref.get(); }
-//        public AtomicReference<T> getReference() { return ref; }
-//        @Override public int hashCode() { return Objects.hashCode(ref); }
-//        @Override public boolean equals(Object other) { 
-//            if (!(other instanceof AtomicProvider)) return false;
-//            return Objects.equal(ref, ((AtomicProvider<?>)other).ref); 
-//        }
-//    }
-//
-//    public static <A,B> Provider<B> transform(final Provider<A> val, final Function<A,B> f) {
-//        return new Provider<B>() {
-//            @Override
-//            public B get() {
-//                return f.apply(val.get());
-//            }
-//        };
-//    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/core/src/main/java/brooklyn/util/math/MathFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/math/MathFunctions.java b/core/src/main/java/brooklyn/util/math/MathFunctions.java
index f682400..9128e96 100644
--- a/core/src/main/java/brooklyn/util/math/MathFunctions.java
+++ b/core/src/main/java/brooklyn/util/math/MathFunctions.java
@@ -6,11 +6,11 @@ import com.google.common.base.Function;
 
 public class MathFunctions {
 
-    public static Function<Number,Double> divide(final Number n, final double divisor) {
+    public static Function<Number,Double> divide(final double divisor) {
         return new Function<Number, Double>() {
             public Double apply(@Nullable Number input) {
                 if (input==null) return null;
-                return n.doubleValue() / divisor;
+                return input.doubleValue() / divisor;
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/core/src/main/java/brooklyn/util/net/Urls.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/net/Urls.java b/core/src/main/java/brooklyn/util/net/Urls.java
index 98d4eb6..aa8f088 100644
--- a/core/src/main/java/brooklyn/util/net/Urls.java
+++ b/core/src/main/java/brooklyn/util/net/Urls.java
@@ -12,13 +12,35 @@ import com.google.common.base.Throwables;
 
 public class Urls {
 
-    public static final Function<String,URI> URI_FROM_STRING = new Function<String,URI>() {
-        public URI apply(String input) { return toUri(input); } 
-    };
+    public static Function<String,URI> stringToUriFunction() {
+        return StringToUri.INSTANCE;
+    }
+    
+    public static Function<String,URL> stringToUrlFunction() {
+        return StringToUrl.INSTANCE;
+    }
+    
+    private static enum StringToUri implements Function<String,URI> {
+        INSTANCE;
+        @Override public URI apply(@Nullable String input) {
+            return toUri(input);
+        }
+        @Override
+        public String toString() {
+            return "StringToUri";
+        }
+    }
 
-    public static final Function<String,URL> URL_FROM_STRING = new Function<String,URL>() {
-        public URL apply(String input) { return toUrl(input); } 
-    };
+    private static enum StringToUrl implements Function<String,URL> {
+        INSTANCE;
+        @Override public URL apply(@Nullable String input) {
+            return toUrl(input);
+        }
+        @Override
+        public String toString() {
+            return "StringToUrl";
+        }
+    }
 
     /** creates a URL, preserving null and propagating exceptions *unchecked* */
     public static final URL toUrl(@Nullable String url) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java b/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
index 6b49b3c..a3dd3f1 100644
--- a/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
@@ -2,6 +2,7 @@ package brooklyn.event.feed.http;
 
 import static brooklyn.test.TestUtils.executeUntilSucceeds;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 
 import java.net.URL;
 import java.util.concurrent.Callable;
@@ -21,6 +22,7 @@ import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.location.Location;
 import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.test.Asserts;
 import brooklyn.test.TestUtils;
 import brooklyn.test.entity.TestApplication;
 import brooklyn.test.entity.TestEntity;
@@ -124,14 +126,19 @@ public class HttpFeedTest {
                 .build();
         assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
         feed.suspend();
-        int countWhenSuspended = server.getRequestCount();
+        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();
-        Thread.sleep(500);
-        if (server.getRequestCount() <= countWhenSuspended+1)
-            Assert.fail("Request count failed to increment when feed was resumed, from "+countWhenSuspended+", still at "+server.getRequestCount());        
+        TestUtils.executeUntilSucceeds(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")
@@ -148,11 +155,11 @@ public class HttpFeedTest {
                         .onSuccess(HttpValueFunctions.stringContentsFunction()))
                 .suspended()
                 .build();
-        TestUtils.assertContinuallyFromJava(MutableMap.of("timeout", 500),
+        Asserts.continually(MutableMap.of("timeout", 500),
                 Entities.supplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(null));
         int countWhenSuspended = server.getRequestCount();
         feed.resume();
-        TestUtils.assertEventually(Entities.supplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(200));
+        Asserts.eventually(Entities.supplier(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());

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java b/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java
index b8c12e7..24d6f1a 100644
--- a/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java
+++ b/policy/src/main/java/brooklyn/enricher/HttpLatencyDetector.java
@@ -53,15 +53,33 @@ public class HttpLatencyDetector extends AbstractEnricher {
                     "Request latency over time window, in seconds");
 
     HttpFeed httpFeed = null;
-    long periodMillis = 1000;
+    final long periodMillis;
     
-    boolean requireServiceUp = true; 
-    AtomicBoolean serviceUp = new AtomicBoolean(false);
+    final boolean requireServiceUp; 
+    final AtomicBoolean serviceUp = new AtomicBoolean(false);
     
-    AttributeSensor<String> urlSensor;
-    Function<String,String> urlPostProcessing = Functions.identity();
-    AtomicReference<String> url = new AtomicReference<String>(null);
-    TimeDuration rollupPeriod = LATENCY_WINDOW_DEFAULT_PERIOD;
+    final AttributeSensor<String> urlSensor;
+    final Function<String,String> urlPostProcessing;
+    final AtomicReference<String> url = new AtomicReference<String>(null);
+    final TimeDuration rollupWindowSize;
+    
+    protected HttpLatencyDetector(Builder builder) {
+        this.periodMillis = builder.periodMillis;
+        this.requireServiceUp = builder.requireServiceUp;
+        
+        if (builder.urlSensor != null) {
+            this.urlSensor = builder.urlSensor;
+            this.urlPostProcessing = builder.urlPostProcessing;
+            if (builder.url != null)
+                throw new IllegalStateException("Cannot set URL and UrlSensor");
+        } else {
+            this.url.set(builder.url);
+            this.urlSensor = null;
+            this.urlPostProcessing = null;
+        }
+
+        this.rollupWindowSize = builder.rollupWindowSize;
+    }
     
     @Override
     public void setEntity(EntityLocal entity) {
@@ -81,7 +99,7 @@ public class HttpLatencyDetector extends AbstractEnricher {
         httpFeed = HttpFeed.builder()
                 .entity(entity)
                 .period(periodMillis)
-                .baseUri(Suppliers.compose(Urls.URI_FROM_STRING, AtomicReferences.supplier(url)))
+                .baseUri(Suppliers.compose(Urls.stringToUriFunction(), AtomicReferences.supplier(url)))
                 .poll(new HttpPollConfig<Double>(REQUEST_LATENCY_IN_SECONDS_MOST_RECENT)
                         .onSuccess(MathFunctions.divide(HttpValueFunctions.latency(), 1000.0d))
                         .onError(Functions.constant((Double)null)))
@@ -116,10 +134,10 @@ public class HttpLatencyDetector extends AbstractEnricher {
     }
 
     protected void activateAdditionalEnrichers(EntityLocal entity) {
-        if (rollupPeriod!=null) {
+        if (rollupWindowSize!=null) {
             entity.addEnricher(new RollingTimeWindowMeanEnricher<Double>(entity,
                 REQUEST_LATENCY_IN_SECONDS_MOST_RECENT, REQUEST_LATENCY_IN_SECONDS_IN_WINDOW,
-                rollupPeriod.toMilliseconds()));
+                rollupWindowSize.toMilliseconds()));
         }
     }
 
@@ -148,11 +166,11 @@ public class HttpLatencyDetector extends AbstractEnricher {
     }
     
     public static class Builder {
-        Boolean requireServiceUp;
-        Long periodMillis;
+        boolean requireServiceUp = true;
+        long periodMillis = 1000;
         String url;
         AttributeSensor<String> urlSensor;
-        Function<String, String> urlPostProcessing;
+        Function<String, String> urlPostProcessing = Functions.identity();
         TimeDuration rollupWindowSize = LATENCY_WINDOW_DEFAULT_PERIOD;
         
         /** indicates that the HttpLatencyDetector should not require "service up";
@@ -204,23 +222,7 @@ public class HttpLatencyDetector extends AbstractEnricher {
         /** returns the detector. note that callers should then add this to the entity,
          * typically using {@link Entity#addEnricher(brooklyn.policy.Enricher)} */
         public HttpLatencyDetector build() {
-            HttpLatencyDetector result = new HttpLatencyDetector();
-            
-            if (periodMillis!=null) result.periodMillis = periodMillis;
-            if (requireServiceUp!=null) result.requireServiceUp = requireServiceUp;
-            
-            if (urlSensor!=null) {
-                result.urlSensor = urlSensor;
-                if (urlPostProcessing!=null) result.urlPostProcessing = urlPostProcessing;
-                if (url!=null)
-                    throw new IllegalStateException("Cannot set URL and UrlSensor");
-            } else {
-                result.url.set(url);
-            }
-
-            result.rollupPeriod = rollupWindowSize;
-            
-            return result;
+            return new HttpLatencyDetector(this);
         }
     }
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/usage/test-support/src/main/java/brooklyn/test/Asserts.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/brooklyn/test/Asserts.java b/usage/test-support/src/main/java/brooklyn/test/Asserts.java
index 6cc6d9a..c5a4283 100644
--- a/usage/test-support/src/main/java/brooklyn/test/Asserts.java
+++ b/usage/test-support/src/main/java/brooklyn/test/Asserts.java
@@ -1,17 +1,79 @@
 package brooklyn.test;
 
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import groovy.time.TimeDuration;
+
+import java.util.Map;
+
+import com.google.common.annotations.Beta;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
 
+@Beta
 public class Asserts {
 
     public static <T> void eventually(Supplier<? extends T> supplier, Predicate<T> predicate) {
-        TestUtils.assertEventually(supplier, predicate);
+        eventually(ImmutableMap.<String,Object>of(), supplier, predicate);
+    }
+    
+    public static <T> void eventually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate) {
+        eventually(flags, supplier, predicate, (String)null);
+    }
+    
+    public static <T> void eventually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
+        TimeDuration timeout = TestUtils.toTimeDuration(flags.get("timeout"), new TimeDuration(0,0,1,0));
+        TimeDuration period = TestUtils.toTimeDuration(flags.get("period"), new TimeDuration(0,0,0,10));
+        long periodMs = period.toMilliseconds();
+        long startTime = System.currentTimeMillis();
+        long expireTime = startTime+timeout.toMilliseconds();
+        
+        boolean first = true;
+        T supplied = supplier.get();
+        while (first || System.currentTimeMillis() <= expireTime) {
+            supplied = supplier.get();
+            if (predicate.apply(supplied)) {
+                return;
+            }
+            first = false;
+            if (periodMs > 0) sleep(periodMs);
+        }
+        fail("supplied="+supplied+"; predicate="+predicate+(errMsg!=null?"; "+errMsg:""));
     }
     
     // TODO improve here -- these methods aren't very useful without timeouts
     public static <T> void continually(Supplier<? extends T> supplier, Predicate<T> predicate) {
-        TestUtils.assertContinuallyFromJava(supplier, predicate);
+        continually(ImmutableMap.<String,Object>of(), supplier, predicate);
     }
 
+    public static <T> void continually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate) {
+        continually(flags, supplier, predicate, (String)null);
+    }
+
+    public static <T> void continually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
+        TimeDuration duration = TestUtils.toTimeDuration(flags.get("timeout"), new TimeDuration(0,0,1,0));
+        TimeDuration period = TestUtils.toTimeDuration(flags.get("period"), new TimeDuration(0,0,0,10));
+        long periodMs = period.toMilliseconds();
+        long startTime = System.currentTimeMillis();
+        long expireTime = startTime+duration.toMilliseconds();
+        
+        boolean first = true;
+        while (first || System.currentTimeMillis() <= expireTime) {
+            assertTrue(predicate.apply(supplier.get()), "supplied="+supplier.get()+"; predicate="+predicate+(errMsg!=null?"; "+errMsg:""));
+            if (periodMs > 0) sleep(periodMs);
+            first = false;
+        }
+    }
+
+    private static void sleep(long periodMs) {
+        if (periodMs > 0) {
+            try {
+                Thread.sleep(periodMs);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                throw new RuntimeException(e);
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/9714edc3/usage/test-support/src/main/java/brooklyn/test/TestUtils.groovy
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/brooklyn/test/TestUtils.groovy b/usage/test-support/src/main/java/brooklyn/test/TestUtils.groovy
index 7aee3e5..54fc516 100644
--- a/usage/test-support/src/main/java/brooklyn/test/TestUtils.groovy
+++ b/usage/test-support/src/main/java/brooklyn/test/TestUtils.groovy
@@ -21,6 +21,8 @@ import com.google.common.collect.Iterables
 
 /**
  * Helper functions for tests of Tomcat, JBoss and others.
+ * 
+ * Note that methods will migrate from here to {@link Asserts} in future releases.
  */
 public class TestUtils {
     private static final Logger log = LoggerFactory.getLogger(TestUtils.class)
@@ -77,31 +79,22 @@ public class TestUtils {
         return HttpTestUtils.connectToUrl(url);
     }
     
-    // TODO see also Java variant: Asserts.eventually()
     // calling groovy from java doesn't cope with generics here; stripping them from here :-(
     //      <T> void assertEventually(Map flags=[:], Supplier<? extends T> supplier, Predicate<T> predicate)
+    /**
+     * @deprecated since 0.5; use {@link Asserts.eventually(Map, Supplier, Predicate)}
+     */
+    @Deprecated
     public static void assertEventually(Map flags=[:], Supplier supplier, Predicate predicate) {
-        assertEventually(flags, supplier, predicate, (String)null);
+        Asserts.eventually(flags, supplier, predicate);
     }
     
+    /**
+     * @deprecated since 0.5; use {@link Asserts.eventually(Map, Supplier, Predicate, String)}
+     */
+    @Deprecated
     public static <T> void assertEventually(Map flags=[:], Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
-        TimeDuration timeout = toTimeDuration(flags.timeout) ?: new TimeDuration(0,0,1,0)
-        TimeDuration period = toTimeDuration(flags.period) ?: new TimeDuration(0,0,0,10)
-        long periodMs = period.toMilliseconds()
-        long startTime = System.currentTimeMillis()
-        long expireTime = startTime+timeout.toMilliseconds()
-        
-        boolean first = true;
-        T supplied = supplier.get();
-        while (first || System.currentTimeMillis() <= expireTime) {
-            supplied = supplier.get();
-            if (predicate.apply(supplied)) {
-                return;
-            }
-            first = false;
-            if (periodMs > 0) sleep(periodMs);
-        }
-        fail("supplied="+supplied+"; predicate="+predicate+(errMsg!=null?"; "+errMsg:""));
+        Asserts.eventually(flags, supplier, predicate, errMsg);
     }
     
     public static void assertEventually(Map flags=[:], Callable c) {
@@ -255,33 +248,38 @@ public class TestUtils {
         }
     }
     
-    // FIXME When calling from java, the generics declared in groovy messing things up! 
+    /**
+     * @deprecated since 0.5; use {@link Asserts.continually(Map, Supplier, Predicate)}
+     */
+    @Deprecated
+    // FIXME When calling from java, the generics declared in groovy messing things up!
     public static void assertContinuallyFromJava(Map flags=[:], Supplier<?> supplier, Predicate<?> predicate) {
-        assertContinually(flags, supplier, predicate, (String)null);
+        Asserts.continually(flags, supplier, predicate);
     }
     
+    /**
+     * @deprecated since 0.5; use {@link Asserts.continually(Map, Supplier, Predicate)}
+     */
+    @Deprecated
     public static <T> void assertContinually(Map flags=[:], Supplier<? extends T> supplier, Predicate<T> predicate) {
-        assertContinually(flags, supplier, predicate, (String)null);
+        Asserts.continually(flags, supplier, predicate, (String)null);
     }
 
+    /**
+     * @deprecated since 0.5; use {@link Asserts.continually(Map, Supplier, Predicate, String)}
+     */
+    @Deprecated
     public static <T> void assertContinually(Map flags=[:], Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg, long durationMs) {
         flags.put("duration", toTimeDuration(durationMs));
-        assertContinually(flags, supplier, predicate, errMsg);
+        Asserts.continually(flags, supplier, predicate, errMsg);
     }
     
+    /**
+     * @deprecated since 0.5; use {@link Asserts.continually(Map, Supplier, Predicate, String)}
+     */
+    @Deprecated
     public static <T> void assertContinually(Map flags=[:], Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
-        TimeDuration duration = toTimeDuration(flags.timeout) ?: new TimeDuration(0,0,1,0)
-        TimeDuration period = toTimeDuration(flags.period) ?: new TimeDuration(0,0,0,10)
-        long periodMs = period.toMilliseconds()
-        long startTime = System.currentTimeMillis()
-        long expireTime = startTime+duration.toMilliseconds()
-        
-        boolean first = true;
-        while (first || System.currentTimeMillis() <= expireTime) {
-            assertTrue(predicate.apply(supplier.get()), "supplied="+supplier.get()+"; predicate="+predicate+(errMsg!=null?"; "+errMsg:""));
-            if (periodMs > 0) sleep(periodMs);
-            first = false;
-        }
+        Asserts.continually(flags, supplier, predicate, errMsg);
     }
     
     public static class BooleanWithMessage {
@@ -306,8 +304,12 @@ public class TestUtils {
     }
 
     public static TimeDuration toTimeDuration(Object duration) {
+        return toTimeDuration(duration, null);
+    }
+            
+    public static TimeDuration toTimeDuration(Object duration, TimeDuration defaultVal) {
         if (duration == null) {
-            return null
+            return defaultVal;
         } else if (duration instanceof TimeDuration) {
             return (TimeDuration) duration
         } else if (duration instanceof Number) {