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/01/30 04:38:46 UTC
[21/29] incubator-brooklyn git commit: fix failing (time sensitive)
test
fix failing (time sensitive) test
and improve the "Asserts.eventually" routines which that used,
adding a new simpler eventuallyOnNotify(...) and having it used elsewhere.
also add convenience methods for CountdownTimer so its usage is more readable.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/dc0ca058
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/dc0ca058
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/dc0ca058
Branch: refs/heads/master
Commit: dc0ca058d848e1231cf4c05a603b8a74fd179903
Parents: 9d5ba14
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jan 29 23:30:07 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Sat Jan 30 00:26:17 2016 +0000
----------------------------------------------------------------------
.../core/task/DynamicSequentialTaskTest.java | 32 +---
.../software/base/SoftwareProcessImpl.java | 2 +-
.../AutoScalerPolicyNoMoreMachinesTest.java | 17 +-
.../SystemServiceEnricherTest.java | 4 +-
.../org/apache/brooklyn/test/WebAppMonitor.java | 2 +-
.../java/org/apache/brooklyn/test/Asserts.java | 183 +++++++++++++++----
.../brooklyn/util/time/CountdownTimer.java | 23 ++-
.../brooklyn/util/time/CountdownTimerTest.java | 7 +
8 files changed, 190 insertions(+), 80 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/core/src/test/java/org/apache/brooklyn/util/core/task/DynamicSequentialTaskTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/test/java/org/apache/brooklyn/util/core/task/DynamicSequentialTaskTest.java b/brooklyn-server/core/src/test/java/org/apache/brooklyn/util/core/task/DynamicSequentialTaskTest.java
index 763c067..c5664a6 100644
--- a/brooklyn-server/core/src/test/java/org/apache/brooklyn/util/core/task/DynamicSequentialTaskTest.java
+++ b/brooklyn-server/core/src/test/java/org/apache/brooklyn/util/core/task/DynamicSequentialTaskTest.java
@@ -26,7 +26,6 @@ import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import org.apache.brooklyn.api.mgmt.HasTaskChildren;
import org.apache.brooklyn.api.mgmt.Task;
@@ -39,7 +38,6 @@ import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.task.TaskInternal.TaskCancellationMode;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.math.MathPredicates;
-import org.apache.brooklyn.util.time.CountdownTimer;
import org.apache.brooklyn.util.time.Duration;
import org.apache.brooklyn.util.time.Time;
import org.slf4j.Logger;
@@ -64,7 +62,7 @@ public class DynamicSequentialTaskTest {
private static final Logger log = LoggerFactory.getLogger(DynamicSequentialTaskTest.class);
public static final Duration TIMEOUT = Duration.TEN_SECONDS;
- public static final Duration TINY_TIME = Duration.millis(20);
+ public static final Duration TINY_TIME = Duration.millis(1);
BasicExecutionManager em;
BasicExecutionContext ec;
@@ -246,6 +244,8 @@ public class DynamicSequentialTaskTest {
@Test
public void testCancellationModeAndSubmitted() throws Exception {
+ // seems actually to be the logging which causes this to take ~50ms ?
+
doTestCancellationModeAndSubmitted(true, TaskCancellationMode.DO_NOT_INTERRUPT, false, false);
doTestCancellationModeAndSubmitted(true, TaskCancellationMode.INTERRUPT_TASK_AND_ALL_SUBMITTED_TASKS, true, true);
@@ -317,27 +317,14 @@ public class DynamicSequentialTaskTest {
@Override public Number get() { return t1.getEndTimeUtc(); }},
MathPredicates.<Number>greaterThanOrEqual(0));
} else {
- Time.sleep(Duration.millis(5));
+ Time.sleep(TINY_TIME);
Assert.assertFalse(t1.isCancelled());
Assert.assertFalse(t1.isDone());
}
}
protected void waitForMessages(Predicate<? super List<String>> predicate, Duration timeout) throws Exception {
- long endtime = System.currentTimeMillis() + timeout.toMilliseconds();
- synchronized (messages) {
- while (true) {
- if (predicate.apply(messages)) {
- return;
- }
- long waittime = endtime - System.currentTimeMillis();
- if (waittime > 0) {
- messages.wait(waittime);
- } else {
- throw new TimeoutException("Timeout after "+timeout+"; messages="+messages+"; predicate="+predicate);
- }
- }
- }
+ Asserts.eventuallyOnNotify(messages, predicate, timeout);
}
protected Task<String> monitorableTask(final String id) {
@@ -373,14 +360,7 @@ public class DynamicSequentialTaskTest {
monitorableJobSemaphoreMap.get(id).release();
}
protected void waitForMessage(final String id) {
- CountdownTimer timer = CountdownTimer.newInstanceStarted(TIMEOUT);
- synchronized (messages) {
- while (!timer.isExpired()) {
- if (messages.contains(id)) return;
- timer.waitOnForExpiryUnchecked(messages);
- }
- }
- Assert.fail("Did not see message "+id);
+ Asserts.eventuallyOnNotify(messages, CollectionFunctionals.contains(id), TIMEOUT);
}
protected void releaseAndWaitForMonitorableJob(final String id) {
releaseMonitorableJob(id);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java b/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
index c62cc3d..ace4ebe 100644
--- a/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
+++ b/brooklyn-server/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
@@ -548,7 +548,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
boolean isRunningResult = false;
long delay = 100;
Exception firstFailure = null;
- while (!isRunningResult && !timer.isExpired()) {
+ while (!isRunningResult && timer.isNotExpired()) {
Time.sleep(delay);
try {
isRunningResult = driver.isRunning();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/autoscaling/AutoScalerPolicyNoMoreMachinesTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/autoscaling/AutoScalerPolicyNoMoreMachinesTest.java b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/autoscaling/AutoScalerPolicyNoMoreMachinesTest.java
index 77175d2..e3dfb12 100644
--- a/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/autoscaling/AutoScalerPolicyNoMoreMachinesTest.java
+++ b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/autoscaling/AutoScalerPolicyNoMoreMachinesTest.java
@@ -38,6 +38,7 @@ import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -75,12 +76,14 @@ public class AutoScalerPolicyNoMoreMachinesTest extends BrooklynAppUnitTestSuppo
entitiesAdded = Sets.newLinkedHashSet();
entitiesRemoved = Sets.newLinkedHashSet();
mgmt.addEntitySetListener(new CollectionChangeListener<Entity>() {
- @Override public void onItemAdded(Entity item) {
- entitiesAdded.add(item);
- }
- @Override public void onItemRemoved(Entity item) {
- entitiesRemoved.add(item);
- }});
+ @Override public void onItemAdded(Entity item) { addToSetAndNotify(entitiesAdded, item); }
+ @Override public void onItemRemoved(Entity item) { addToSetAndNotify(entitiesRemoved, item); }});
+ }
+ private static <T> void addToSetAndNotify(Set<T> items, T item) {
+ synchronized (items) {
+ items.add(item);
+ items.notifyAll();
+ }
}
@Test
@@ -179,7 +182,7 @@ public class AutoScalerPolicyNoMoreMachinesTest extends BrooklynAppUnitTestSuppo
protected void assertSize(int targetSize, int quarantineSize, final int deletedSize) {
assertSize(targetSize, quarantineSize);
- assertEquals(entitiesRemoved.size(), deletedSize, "removed="+entitiesRemoved);
+ Asserts.eventuallyOnNotify(entitiesRemoved, CollectionFunctionals.sizeEquals(deletedSize));
}
protected void assertSize(int targetSize, int quarantineSize) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
index 10e2e15..70c0da5 100644
--- a/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
+++ b/brooklyn-server/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
@@ -86,10 +86,10 @@ public class SystemServiceEnricherTest extends BrooklynAppLiveTestSupport {
}
private void waitFailed(VanillaSoftwareProcess proc) {
- Asserts.eventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE));
+ Asserts.eventually(Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE), Duration.FIVE_MINUTES);
}
private void waitHealthy(VanillaSoftwareProcess proc) {
- Asserts.eventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING));
+ Asserts.eventually(Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING), Duration.FIVE_MINUTES);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/test-support/src/main/java/org/apache/brooklyn/test/WebAppMonitor.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/test-support/src/main/java/org/apache/brooklyn/test/WebAppMonitor.java b/brooklyn-server/test-support/src/main/java/org/apache/brooklyn/test/WebAppMonitor.java
index d804312..b957a5b 100644
--- a/brooklyn-server/test-support/src/main/java/org/apache/brooklyn/test/WebAppMonitor.java
+++ b/brooklyn-server/test-support/src/main/java/org/apache/brooklyn/test/WebAppMonitor.java
@@ -184,7 +184,7 @@ public class WebAppMonitor implements Runnable {
return this;
}
public WebAppMonitor waitForAtLeastOneAttempt() {
- return waitForAtLeastOneAttempt(Asserts.DEFAULT_TIMEOUT);
+ return waitForAtLeastOneAttempt(Asserts.DEFAULT_LONG_TIMEOUT);
}
public WebAppMonitor waitForAtLeastOneAttempt(Duration timeout) {
Asserts.succeedsEventually(MutableMap.of("timeout", timeout), new Runnable() {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java b/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
index 15aa76e..fac3142 100644
--- a/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
+++ b/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
@@ -37,7 +37,9 @@ import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.javalang.JavaClassNames;
+import org.apache.brooklyn.util.repeat.Repeater;
import org.apache.brooklyn.util.text.StringPredicates;
+import org.apache.brooklyn.util.time.CountdownTimer;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,6 +48,7 @@ import com.google.common.annotations.Beta;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -68,11 +71,24 @@ import com.google.common.collect.Sets;
@Beta
public class Asserts {
- /**
- * The default timeout for assertions - 30s.
- * Alter in individual tests by giving a "timeout" entry in method flags.
+ /**
+ * Timeout for use when something should happen within several seconds,
+ * but there might be network calls or computation so {@link #DEFAULT_SHORT_TIMEOUT} is not applicable.
*/
- public static final Duration DEFAULT_TIMEOUT = Duration.THIRTY_SECONDS;
+ public static final Duration DEFAULT_LONG_TIMEOUT = Duration.THIRTY_SECONDS;
+
+ /**
+ * Timeout for use when waiting for other threads to finish.
+ * <p>
+ * Long enough for parallel execution to catch up,
+ * even on overloaded mediocre test boxes most of the time,
+ * but short enough not to irritate you when your test is failing. */
+ public static final Duration DEFAULT_SHORT_TIMEOUT = Duration.ONE_SECOND;
+
+ /** @deprecated since 0.9.0 use {@link #DEFAULT_LONG_TIMEOUT} */ @Deprecated
+ public static final Duration DEFAULT_TIMEOUT = DEFAULT_LONG_TIMEOUT;
+
+ private static final Duration DEFAULT_SHORT_PERIOD = Repeater.DEFAULT_REAL_QUICK_PERIOD;
private static final Logger log = LoggerFactory.getLogger(Asserts.class);
@@ -730,58 +746,99 @@ public class Asserts {
// --- new routines
+ /** As {@link #eventually(Supplier, Predicate, Duration, Duration, String)} with defaults. */
public static <T> void eventually(Supplier<? extends T> supplier, Predicate<T> predicate) {
- eventually(ImmutableMap.<String,Object>of(), supplier, predicate);
+ eventually(supplier, predicate, null, null, null);
}
+ /** @deprecated since 0.9.0 use {@link #eventually(Supplier, Predicate, Duration, Duration, String)} */ @Deprecated
public static <T> void eventually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate) {
eventually(flags, supplier, predicate, (String)null);
}
-
+ /** @deprecated since 0.9.0 use {@link #eventually(Supplier, Predicate, Duration, Duration, String)} */ @Deprecated
public static <T> void eventually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
- Duration timeout = toDuration(flags.get("timeout"), Duration.ONE_SECOND);
- Duration period = toDuration(flags.get("period"), Duration.millis(10));
- long periodMs = period.toMilliseconds();
- long startTime = System.currentTimeMillis();
- long expireTime = startTime+timeout.toMilliseconds();
+ eventually(supplier, predicate, toDuration(flags.get("timeout"), null), toDuration(flags.get("period"), null), errMsg);
+ }
+
+ /** As {@link #eventually(Supplier, Predicate, Duration, Duration, String)} with default. */
+ public static <T> void eventually(Supplier<? extends T> supplier, Predicate<T> predicate, Duration timeout) {
+ eventually(supplier, predicate, timeout, null, null);
+ }
+
+ /** Asserts that eventually the supplier gives a value accepted by the predicate.
+ * Tests periodically and succeeds as soon as the supplier gives an allowed value.
+ * Other arguments can be null.
+ *
+ * @param supplier supplies the value to test, such as {@link Suppliers#ofInstance(Object)} for a constant
+ * @param predicate the {@link Predicate} to apply to each value given by the supplier
+ * @param timeout how long to wait, default {@link #DEFAULT_SHORT_TIMEOUT}
+ * @param period how often to check, default quite often so you won't notice but letting the CPU do work
+ * @param errMsg an error message to display if not satisfied, in addition to the last-tested supplied value and the predicate
+ */
+ public static <T> void eventually(Supplier<? extends T> supplier, Predicate<T> predicate, Duration timeout, Duration period, String errMsg) {
+ if (timeout==null) timeout = DEFAULT_SHORT_TIMEOUT;
+ if (period==null) period = DEFAULT_SHORT_PERIOD;
+ CountdownTimer timeleft = timeout.countdownTimer();
- boolean first = true;
- T supplied = supplier.get();
- while (first || System.currentTimeMillis() <= expireTime) {
+ T supplied;
+ int count = 0;
+ do {
+ if (count++ > 0) Duration.sleep(period);
supplied = supplier.get();
- if (predicate.apply(supplied)) {
- return;
- }
- first = false;
- if (periodMs > 0) sleep(periodMs);
- }
- fail("supplied="+supplied+"; predicate="+predicate+(errMsg!=null?"; "+errMsg:""));
+ if (predicate.apply(supplied)) return;
+ } while (timeleft.isNotExpired());
+
+ fail("Expected: eventually "+predicate+"; got most recently: "+supplied
+ +" (waited "+timeleft.getDurationElapsed()+", checked "+count+")"
+ +(errMsg!=null?"; "+errMsg:""));
}
- // TODO improve here -- these methods aren't very useful without timeouts
+ /** As {@link #continually(Supplier, Predicate, Duration, Duration, String)} with defaults. */
public static <T> void continually(Supplier<? extends T> supplier, Predicate<T> predicate) {
continually(ImmutableMap.<String,Object>of(), supplier, predicate);
}
+ /** @deprecated since 0.9.0 use {@link #eventually(Supplier, Predicate, Duration, Duration, String)} */ @Deprecated
public static <T> void continually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<? super T> predicate) {
- continually(flags, supplier, predicate, (String)null);
+ continually(flags, supplier, predicate, null);
}
+ /** @deprecated since 0.9.0 use {@link #eventually(Supplier, Predicate, Duration, Duration, String)} */ @Deprecated
public static <T> void continually(Map<String,?> flags, Supplier<? extends T> supplier, Predicate<T> predicate, String errMsg) {
- Duration duration = toDuration(flags.get("timeout"), Duration.ONE_SECOND);
- Duration period = toDuration(flags.get("period"), Duration.millis(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;
- }
+ continually(supplier, predicate, toDuration(flags.get("timeout"), toDuration(flags.get("duration"), null)),
+ toDuration(flags.get("period"), null), null);
}
+ /**
+ * Asserts that continually the supplier gives a value accepted by the predicate.
+ * Tests periodically and fails if the supplier gives a disallowed value.
+ * Other arguments can be null.
+ *
+ * @param supplier supplies the value to test, such as {@link Suppliers#ofInstance(Object)} for a constant
+ * @param predicate the {@link Predicate} to apply to each value given by the supplier
+ * @param duration how long to test for, default {@link #DEFAULT_SHORT_TIMEOUT}
+ * @param period how often to check, default quite often to minimise chance of missing a flashing violation but letting the CPU do work
+ * @param errMsg an error message to display if not satisfied, in addition to the last-tested supplied value and the predicate
+ */
+ public static <T> void continually(Supplier<? extends T> supplier, Predicate<T> predicate, Duration duration, Duration period, String errMsg) {
+ if (duration==null) duration = DEFAULT_SHORT_TIMEOUT;
+ if (period==null) period = DEFAULT_SHORT_PERIOD;
+ CountdownTimer timeleft = duration.countdownTimer();
+
+ T supplied;
+ int count = 0;
+ do {
+ if (count > 0) Duration.sleep(period);
+ supplied = supplier.get();
+ if (!predicate.apply(supplied)) {
+ fail("Expected: continually "+predicate+"; got violation: "+supplied
+ // tell timing if it worked the first time and then failed
+ +(count > 0 ? " (after "+timeleft.getDurationElapsed()+", successfully checked "+count+")" : "")
+ +(errMsg!=null?"; "+errMsg:""));
+ }
+ count++;
+ } while (timeleft.isNotExpired());
+ }
/**
* @see #succeedsContinually(Map, Callable)
@@ -818,6 +875,9 @@ public class Asserts {
}
}
+ // TODO flags are ugly; remove this in favour of something strongly typed,
+ // e.g. extending Repeater and taking the extra semantics.
+ // TODO remove the #succeedsEventually in favour of #eventually (and same for continually)
/**
* Convenience method for cases where we need to test until something is true.
*
@@ -827,7 +887,7 @@ public class Asserts {
* <ul>
* <li>abortOnError (boolean, default true)
* <li>abortOnException - (boolean, default false)
- * <li>timeout - (a Duration or an integer in millis, defaults to {@link Asserts#DEFAULT_TIMEOUT})
+ * <li>timeout - (a Duration or an integer in millis, defaults to {@link Asserts#DEFAULT_LONG_TIMEOUT})
* <li>period - (a Duration or an integer in millis, for fixed retry time; if not set, defaults to exponentially increasing from 1 to 500ms)
* <li>minPeriod - (a Duration or an integer in millis; only used if period not explicitly set; the minimum period when exponentially increasing; defaults to 1ms)
* <li>maxPeriod - (a Duration or an integer in millis; only used if period not explicitly set; the maximum period when exponentially increasing; defaults to 500ms)
@@ -849,7 +909,7 @@ public class Asserts {
boolean logException = get(flags, "logException", true);
// To speed up tests, default is for the period to start small and increase...
- Duration duration = toDuration(flags.get("timeout"), DEFAULT_TIMEOUT);
+ Duration duration = toDuration(flags.get("timeout"), DEFAULT_LONG_TIMEOUT);
Duration fixedPeriod = toDuration(flags.get("period"), null);
Duration minPeriod = (fixedPeriod != null) ? fixedPeriod : toDuration(flags.get("minPeriod"), Duration.millis(1));
Duration maxPeriod = (fixedPeriod != null) ? fixedPeriod : toDuration(flags.get("maxPeriod"), Duration.millis(500));
@@ -915,7 +975,8 @@ public class Asserts {
public static <T> T succeedsContinually(Callable<T> c) {
return succeedsContinually(ImmutableMap.<String,Object>of(), c);
}
-
+
+ // TODO unify with "continually"; see also eventually, some of those options might be useful
public static <T> T succeedsContinually(Map<?,?> flags, Callable<T> job) {
Duration duration = toDuration(flags.get("timeout"), Duration.ONE_SECOND);
Duration period = toDuration(flags.get("period"), Duration.millis(10));
@@ -1240,4 +1301,50 @@ public class Asserts {
throw new RuntimeException(t);
}
+ /** As {@link #eventuallyOnNotify(Object, Supplier, Predicate, Duration, boolean)} with default timeout. */
+ public static <T> void eventuallyOnNotify(Object notifyTarget, Supplier<T> supplier, Predicate<T> predicate) {
+ eventuallyOnNotify(notifyTarget, supplier, predicate, null);
+ }
+
+ /** as {@link #eventually(Supplier, Predicate)} for cases where an object is notified;
+ * more efficient as it waits on the notify target object.
+ * See also the simpler {@link #eventuallyOnNotify(Object, Predicate)} when looking at a collection which is getting notified.
+ * Timeout defaults to {@link #DEFAULT_SHORT_TIMEOUT}.
+ * <p>
+ * This synchronizes on the notify target for the duration of the wait,
+ * including while getting and checking the value, so as not to miss any notification. */
+ public static <T> void eventuallyOnNotify(Object notifyTarget, Supplier<T> supplier, Predicate<T> predicate, Duration timeout) {
+ T supplied = null;
+ if (timeout==null) timeout = DEFAULT_SHORT_TIMEOUT;
+ CountdownTimer remaining = timeout.countdownTimer();
+ int checks = 0;
+ synchronized (notifyTarget) {
+ do {
+ if (checks>0) {
+ remaining.waitOnForExpiryUnchecked(notifyTarget);
+ }
+ supplied = supplier.get();
+ if (predicate.apply(supplied)) return;
+ checks++;
+ } while (remaining.isNotExpired());
+ }
+
+ // should get 2 checks, 1 before and 1 after, if no notifications; if more, tell the user
+ fail("Expected: eventually "+predicate+"; got most recently: "+supplied+
+ " (waited "+remaining.getDurationElapsed()+
+ (checks>2 ? "; notification count "+(checks-2) : "")+
+ ")");
+ }
+
+ /** Convenience for {@link #eventuallyOnNotify(Object, Supplier, Predicate, Duration, boolean)}
+ * when the notify target and the value under test are the same. */
+ public static <T> void eventuallyOnNotify(T object, Predicate<T> predicate, Duration timeout) {
+ eventuallyOnNotify(object, Suppliers.ofInstance(object), predicate, timeout);
+ }
+
+ /** As {@link #eventuallyOnNotify(Object, Predicate, Duration)} with the default duration of {@link #eventuallyOnNotify(Object, Supplier, Predicate)}. */
+ public static <T> void eventuallyOnNotify(T object, Predicate<T> predicate) {
+ eventuallyOnNotify(object, Suppliers.ofInstance(object), predicate, null);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/util/time/CountdownTimer.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/util/time/CountdownTimer.java b/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/util/time/CountdownTimer.java
index 508657d..fea8ee6 100644
--- a/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/util/time/CountdownTimer.java
+++ b/brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/util/time/CountdownTimer.java
@@ -55,7 +55,7 @@ public class CountdownTimer {
return limit;
}
- /** return how long the timer has been running (longer than limit if {@link #isExpired()}) */
+ /** return how long the timer has been running (may be longer than {@link #getLimit()} if {@link #isExpired()}) */
public Duration getDurationElapsed() {
return Duration.nanos(stopwatch.elapsed(TimeUnit.NANOSECONDS));
}
@@ -65,15 +65,28 @@ public class CountdownTimer {
return Duration.millis(limit.toMilliseconds() - stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
- /** true iff the timer has been running for the duration specified at creation time */
+ /** true iff the timer has run for more than the duration specified at creation time */
public boolean isExpired() {
return stopwatch.elapsed(TimeUnit.MILLISECONDS) > limit.toMilliseconds();
}
-
- /** true iff timer is running (even if it is expired) */
- public boolean isRunning() {
+
+ /** true iff {@link #isNotPaused()} and not {@link #isExpired()} */
+ public boolean isLive() {
+ return isNotPaused() && isNotExpired();
+ }
+
+ /** true iff not {@link #isExpired()} */
+ public boolean isNotExpired() {
+ return !isExpired();
+ }
+
+ /** false if started or paused, true otherwise (ie the timer is counting down, even if it is expired) */
+ public boolean isNotPaused() {
return stopwatch.isRunning();
}
+
+ /** @deprecated since 0.9.0 use better named {@link #isNotPaused()} */ @Deprecated
+ public boolean isRunning() { return isNotPaused(); }
// --- constructor methods
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc0ca058/brooklyn-server/utils/common/src/test/java/org/apache/brooklyn/util/time/CountdownTimerTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/utils/common/src/test/java/org/apache/brooklyn/util/time/CountdownTimerTest.java b/brooklyn-server/utils/common/src/test/java/org/apache/brooklyn/util/time/CountdownTimerTest.java
index 5541caa..45995da 100644
--- a/brooklyn-server/utils/common/src/test/java/org/apache/brooklyn/util/time/CountdownTimerTest.java
+++ b/brooklyn-server/utils/common/src/test/java/org/apache/brooklyn/util/time/CountdownTimerTest.java
@@ -50,6 +50,9 @@ public class CountdownTimerTest {
CountdownTimer timer = SIMPLE_DURATION.countdownTimer();
assertFalse(timer.isExpired());
+ assertTrue(timer.isNotExpired());
+ assertTrue(timer.isLive());
+ assertTrue(timer.isNotPaused());
assertTrue(timer.getDurationElapsed().toMilliseconds() <= OVERHEAD_MS, "elapsed="+timer.getDurationElapsed().toMilliseconds());
assertTrue(timer.getDurationRemaining().toMilliseconds() >= TOTAL_TIME_MS - OVERHEAD_MS, "remaining="+timer.getDurationElapsed().toMilliseconds());
@@ -60,6 +63,10 @@ public class CountdownTimerTest {
Time.sleep(Duration.millis(SECOND_SLEEP_TIME_MS));
assertTrue(timer.isExpired());
+ assertFalse(timer.isNotExpired());
+ assertFalse(timer.isLive());
+ assertTrue(timer.isNotPaused());
+
}
public void testNotify() throws InterruptedException {