brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject [1/6] brooklyn-server git commit: PR #390: incorporate review comments
Date Wed, 02 Nov 2016 10:06:22 GMT
Repository: brooklyn-server
Updated Branches:
  refs/heads/master c4cc0d1bd -> 4fab5b1a8


PR #390: incorporate review comments

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

Branch: refs/heads/master
Commit: cee60cc84510aebb548cecc9c2a3e65e96635406
Parents: 1cd2a09
Author: Aled Sage <aled.sage@gmail.com>
Authored: Tue Nov 1 11:05:45 2016 +0000
Committer: Aled Sage <aled.sage@gmail.com>
Committed: Tue Nov 1 11:06:02 2016 +0000

----------------------------------------------------------------------
 .../spi/dsl/methods/BrooklynDslCommon.java      | 40 +++++--------
 .../brooklyn/spi/dsl/methods/DslComponent.java  | 23 +++++--
 .../brooklyn/camp/brooklyn/dsl/DslTest.java     | 63 ++++++++++++--------
 .../util/core/task/ImmediateSupplier.java       |  2 +-
 .../brooklyn/util/core/task/ValueResolver.java  |  7 +--
 .../core/entity/EntitySubscriptionTest.java     | 19 +++++-
 .../util/core/task/ValueResolverTest.java       | 45 +++++++++++++-
 7 files changed, 137 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/cee60cc8/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
index d92bf46..f508db9 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
@@ -414,17 +414,7 @@ public class BrooklynDslCommon {
 
         @Override
         public Maybe<Object> getImmediately() {
-            Class<?> type = this.type;
-            if (type == null) {
-                EntityInternal entity = entity();
-                try {
-                    type = new ClassLoaderUtils(BrooklynDslCommon.class, entity).loadClass(typeName);
-                } catch (ClassNotFoundException e) {
-                    throw Exceptions.propagate(e);
-                }
-            }
-            final Class<?> clazz = type;
-
+            final Class<?> clazz = getOrLoadType();
             final ExecutionContext executionContext = ((EntityInternal)entity()).getExecutionContext();
 
             // Marker exception that one of our component-parts cannot yet be resolved -

@@ -465,17 +455,7 @@ public class BrooklynDslCommon {
         
         @Override
         public Task<Object> newTask() {
-            Class<?> type = this.type;
-            if (type == null) {
-                EntityInternal entity = entity();
-                try {
-                    type = new ClassLoaderUtils(BrooklynDslCommon.class, entity).loadClass(typeName);
-                } catch (ClassNotFoundException e) {
-                    throw Exceptions.propagate(e);
-                }
-            }
-            final Class<?> clazz = type;
-
+            final Class<?> clazz = getOrLoadType();
             final ExecutionContext executionContext = ((EntityInternal)entity()).getExecutionContext();
             
             final Function<Object, Object> resolver = new Function<Object, Object>()
{
@@ -508,6 +488,19 @@ public class BrooklynDslCommon {
                     .build();
         }
 
+        protected Class<?> getOrLoadType() {
+            Class<?> type = this.type;
+            if (type == null) {
+                EntityInternal entity = entity();
+                try {
+                    type = new ClassLoaderUtils(BrooklynDslCommon.class, entity).loadClass(typeName);
+                } catch (ClassNotFoundException e) {
+                    throw Exceptions.propagate(e);
+                }
+            }
+            return type;
+        }
+        
         public static <T> T create(Class<T> type, List<?> constructorArgs,
Map<String,?> fields, Map<String,?> config) {
             try {
                 T bean = Reflections.invokeConstructorFromArgs(type, constructorArgs.toArray()).get();
@@ -603,8 +596,7 @@ public class BrooklynDslCommon {
                 .body(new Callable<Object>() {
                     @Override
                     public Object call() throws Exception {
-                        ManagementContextInternal managementContext = DslExternal.managementContext();
-                        return managementContext.getExternalConfigProviderRegistry().getConfig(providerName,
key);
+                        return getImmediately().get();
                     }
                 })
                 .build();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/cee60cc8/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
index b134450..cded853 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
@@ -88,7 +88,7 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity>
{
     }
 
     // ---------------------------
-    
+
     @Override
     public final Maybe<Entity> getImmediately() {
         try {
@@ -236,7 +236,11 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity>
{
 
         @Override
         public Maybe<Object> getImmediately() {
-            return Maybe.<Object>of(component.get().getId());
+            Maybe<Entity> targetEntityMaybe = component.getImmediately();
+            if (targetEntityMaybe.isAbsent()) return Maybe.absent("Target entity not available");
+            Entity targetEntity = targetEntityMaybe.get();
+
+            return Maybe.<Object>of(targetEntity.getId());
         }
         
         @Override
@@ -277,7 +281,10 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity>
{
 
         @Override
         public final Maybe<Object> getImmediately() {
-            Entity targetEntity = component.getImmediately().get();
+            Maybe<Entity> targetEntityMaybe = component.getImmediately();
+            if (targetEntityMaybe.isAbsent()) return Maybe.absent("Target entity not available");
+            Entity targetEntity = targetEntityMaybe.get();
+
             AttributeSensor<?> targetSensor = (AttributeSensor<?>) targetEntity.getEntityType().getSensor(sensorName);
             if (targetSensor == null) {
                 targetSensor = Sensors.newSensor(Object.class, sensorName);
@@ -331,7 +338,10 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity>
{
 
         @Override
         public final Maybe<Object> getImmediately() {
-            Entity targetEntity = component.get();
+            Maybe<Entity> targetEntityMaybe = component.getImmediately();
+            if (targetEntityMaybe.isAbsent()) return Maybe.absent("Target entity not available");
+            Entity targetEntity = targetEntityMaybe.get();
+            
             return Maybe.of(targetEntity.getConfig(ConfigKeys.newConfigKey(Object.class,
keyName)));
         }
 
@@ -394,7 +404,10 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity>
{
             if (si instanceof Sensor) {
                 return Maybe.<Sensor<?>>of((Sensor<?>)si);
             } else if (si instanceof String) {
-                Entity targetEntity = component.get();
+                Maybe<Entity> targetEntityMaybe = component.getImmediately();
+                if (targetEntityMaybe.isAbsent()) return Maybe.absent("Target entity not
available");
+                Entity targetEntity = targetEntityMaybe.get();
+
                 Sensor<?> result = null;
                 if (targetEntity!=null) {
                     result = targetEntity.getEntityType().getSensor((String)si);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/cee60cc8/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/dsl/DslTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/dsl/DslTest.java
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/dsl/DslTest.java
index d27e6c2..8db3720 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/dsl/DslTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/dsl/DslTest.java
@@ -48,6 +48,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.ListenableScheduledFuture;
 import com.google.common.util.concurrent.ListeningScheduledExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
@@ -79,7 +80,7 @@ public class DslTest extends BrooklynAppUnitTestSupport {
     @Test
     public void testAttributeWhenReadyEmptyDoesNotBlock() throws Exception {
         BrooklynDslDeferredSupplier<?> dsl = BrooklynDslCommon.attributeWhenReady(TestApplication.MY_ATTRIBUTE.getName());
-        Maybe<?> actualValue = execDslRealRealyQuick(dsl, TestApplication.MY_ATTRIBUTE.getType(),
app);
+        Maybe<?> actualValue = execDslRealRealQuick(dsl, TestApplication.MY_ATTRIBUTE.getType(),
app);
         assertTrue(actualValue.isAbsent());
     }
 
@@ -100,7 +101,7 @@ public class DslTest extends BrooklynAppUnitTestSupport {
     public void testAttributeWhenReadyBlocksUntilReady() throws Exception {
         // Fewer iterations, because there is a sleep each time
         BrooklynDslDeferredSupplier<?> dsl = BrooklynDslCommon.attributeWhenReady(TestEntity.NAME.getName());
-        new AttributeWhenReadyTestWorker(app, TestEntity.NAME, dsl).eventually(true).resolverIterations(2).run();
+        new AttributeWhenReadyTestWorker(app, TestEntity.NAME, dsl).satisfiedAsynchronously(true).resolverIterations(2).run();
     }
 
     @Test(groups="Integration")
@@ -165,7 +166,7 @@ public class DslTest extends BrooklynAppUnitTestSupport {
         protected final Class<?> type;
         protected EntitySpec<TestEntity> childSpec = EntitySpec.create(TestEntity.class);
         protected int resolverIterations = MANY_RESOLVER_ITERATIONS;
-        protected boolean eventually = false;
+        protected boolean satisfiedAsynchronously = false;
         private boolean wrapInTaskForImmediately = true;
         
         public DslTestWorker(TestApplication parent, BrooklynDslDeferredSupplier<?>
dsl, Class<?> type) {
@@ -179,8 +180,8 @@ public class DslTest extends BrooklynAppUnitTestSupport {
             return this;
         }
         
-        public DslTestWorker eventually(boolean val) {
-            eventually = val;
+        public DslTestWorker satisfiedAsynchronously(boolean val) {
+            satisfiedAsynchronously = val;
             return this;
         }
         
@@ -191,13 +192,10 @@ public class DslTest extends BrooklynAppUnitTestSupport {
         
         @Override
         public void run() {
-            TestEntity entity = parent.addChild(childSpec);
-            for (int i = 0; i < resolverIterations; i++) {
-                preResolve(entity);
-                Maybe<?> eventualValue = execDslEventually(dsl, type, entity, Duration.FIVE_SECONDS);//FIXME
ONE_MINUTE);
-                postResolve(entity, eventualValue);
-
-                if (!eventually) {
+            try {
+                TestEntity entity = parent.addChild(childSpec);
+                for (int i = 0; i < resolverIterations; i++) {
+                    // Call dsl.getImmediately()
                     preResolve(entity);
                     Maybe<?> immediateValue;
                     try {
@@ -205,21 +203,29 @@ public class DslTest extends BrooklynAppUnitTestSupport {
                     } catch (Exception e) {
                         throw Exceptions.propagate(e);
                     }
-                    postResolve(entity, immediateValue);
+                    postResolve(entity, immediateValue, true);
+                    
+                    // Call dsl.get()
+                    preResolve(entity);
+                    Maybe<?> eventualValue = execDslEventually(dsl, type, entity, Duration.ONE_MINUTE);
+                    postResolve(entity, eventualValue, false);
                 }
+            } catch (Exception e) {
+                Exceptions.propagate(e);
             }
         }
 
-        protected void preResolve(TestEntity entity) {
+        protected void preResolve(TestEntity entity) throws Exception {
         }
 
-        protected void postResolve(TestEntity entity, Maybe<?> actualValue) {
+        protected void postResolve(TestEntity entity, Maybe<?> actualValue, boolean
isImmediate) throws Exception {
         }
     }
 
     private class AttributeWhenReadyTestWorker extends DslTestWorker {
         private AttributeSensor<String> sensor;
         private String expectedValue;
+        private ListenableScheduledFuture<?> future;
 
         public AttributeWhenReadyTestWorker(TestApplication parent, AttributeSensor<String>
sensor, BrooklynDslDeferredSupplier<?> dsl) {
             super(parent, dsl, sensor.getType());
@@ -234,21 +240,28 @@ public class DslTest extends BrooklynAppUnitTestSupport {
                     entity.sensors().set(sensor, expectedValue);
                 }
             };
-            if (eventually) {
-                executor.schedule(job, random.nextInt(20), TimeUnit.MILLISECONDS);
+            if (satisfiedAsynchronously) {
+                future = executor.schedule(job, random.nextInt(20), TimeUnit.MILLISECONDS);
             } else {
                 job.run();
             }
         }
 
         @Override
-        protected void postResolve(TestEntity entity, Maybe<?> actualValue) {
-            assertEquals(actualValue.get(), expectedValue);
+        protected void postResolve(TestEntity entity, Maybe<?> actualValue, boolean
isImmediate) throws Exception {
+            if (satisfiedAsynchronously && isImmediate) {
+                // We accept a maybe.absent if we called getImmediately when satisfiedAsynchronously
+                assertTrue(actualValue.isAbsent() || expectedValue.equals(actualValue.get()),
"actual="+actualValue+"; expected="+expectedValue);
+            } else {
+                assertEquals(actualValue.get(), expectedValue);
+            }
             
-            if (eventually) {
-                // Reset sensor - otherwise if run in a loop the old value will be picked
up, before our execute sets the new value
-                entity.sensors().set(sensor, null);
+            if (future != null) {
+                future.get(Asserts.DEFAULT_LONG_TIMEOUT.toMilliseconds(), TimeUnit.MILLISECONDS);
+                future = null;
             }
+            // Reset sensor - otherwise if run in a loop the old value will be picked up,
before our execute sets the new value
+            entity.sensors().set(sensor, null);
         }
 
     }
@@ -263,7 +276,7 @@ public class DslTest extends BrooklynAppUnitTestSupport {
         }
 
         @Override
-        protected void postResolve(TestEntity entity, Maybe<?> actualValue) {
+        protected void postResolve(TestEntity entity, Maybe<?> actualValue, boolean
isImmediate) {
             assertEquals(actualValue.get(), entity);
         }
 
@@ -275,7 +288,7 @@ public class DslTest extends BrooklynAppUnitTestSupport {
         }
 
         @Override
-        protected void postResolve(TestEntity entity, Maybe<?> actualValue) {
+        protected void postResolve(TestEntity entity, Maybe<?> actualValue, boolean
isImmediate) {
             assertEquals(actualValue.get(), parent);
         }
     }
@@ -304,7 +317,7 @@ public class DslTest extends BrooklynAppUnitTestSupport {
         }
     }
     
-    static Maybe<?> execDslRealRealyQuick(BrooklynDslDeferredSupplier<?> dsl,
Class<?> type, Entity context) {
+    static Maybe<?> execDslRealRealQuick(BrooklynDslDeferredSupplier<?> dsl,
Class<?> type, Entity context) {
         return execDslEventually(dsl, type, context, ValueResolver.REAL_REAL_QUICK_WAIT);
     }
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/cee60cc8/core/src/main/java/org/apache/brooklyn/util/core/task/ImmediateSupplier.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ImmediateSupplier.java
b/core/src/main/java/org/apache/brooklyn/util/core/task/ImmediateSupplier.java
index 03a1da6..ac0aae4 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ImmediateSupplier.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ImmediateSupplier.java
@@ -30,7 +30,7 @@ public interface ImmediateSupplier<T> {
      * Indicates that we are unable to get the value immediately, because that is not supported
      * (e.g. because the supplier is composed of sub-tasks that do not support {@link ImmediateSupplier}.
 
      */
-    public static class ImmediateUnsupportedException extends RuntimeException {
+    public static class ImmediateUnsupportedException extends UnsupportedOperationException
{
         private static final long serialVersionUID = -7942339715007942797L;
         
         public ImmediateUnsupportedException(String message) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/cee60cc8/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
index 10fd665..4c3cbe2 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
@@ -379,12 +379,9 @@ public class ValueResolver<T> implements DeferredSupplier<T>
{
                             .tagIfNotNull(BrooklynTaskTags.getTargetOrContextEntityTag(Tasks.current()));
                     if (isTransientTask) tb.tag(BrooklynTaskTags.TRANSIENT_TASK_TAG);
                     
+                    // Note that immediate resolution is handled by using ImmediateSupplier
(using an instanceof check), 
+                    // so that it executes in the current thread instead of using task execution.
                     Task<Object> vt = exec.submit(tb.build());
-                    // TODO to handle immediate resolution, it would be nice to be able to
submit 
-                    // so it executes in the current thread,
-                    // or put a marker in the target thread or task while it is running that
the task 
-                    // should never wait on anything other than another value being resolved

-                    // (though either could recurse infinitely) 
                     Maybe<Object> vm = Durations.get(vt, timer);
                     vt.cancel(true);
                     if (vm.isAbsent()) return (Maybe<T>)vm;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/cee60cc8/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
index a16576c..ea91f36 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.core.test.policy.TestEnricher;
 import org.apache.brooklyn.core.test.policy.TestPolicy;
 import org.apache.brooklyn.entity.group.BasicGroup;
 import org.apache.brooklyn.test.Asserts;
+import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -76,6 +77,23 @@ public class EntitySubscriptionTest extends BrooklynAppUnitTestSupport
{
         app.start(ImmutableList.of(loc));
     }
     
+    @AfterMethod(alwaysRun=true)
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            super.tearDown();
+        } finally {
+            loc = null;
+            entity = null;
+            observedEntity = null;
+            observedChildEntity = null;
+            observedGroup = null;
+            observedMemberEntity = null;
+            otherEntity = null;
+            listener = null;
+        }
+    }
+    
     @Test
     public void testSubscriptionReceivesEvents() {
         entity.subscriptions().subscribe(observedEntity, TestEntity.SEQUENCE, listener);
@@ -298,7 +316,6 @@ public class EntitySubscriptionTest extends BrooklynAppUnitTestSupport
{
         entity.subscriptions().subscribeToChildren(observedEntity, TestEntity.SEQUENCE, listener);
         observedChildEntity.sensors().set(TestEntity.SEQUENCE, 123);
         assertListenerCalledOnceWithContextEntityEventually(listener, entity);
-        listener.clearEvents();
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/cee60cc8/core/src/test/java/org/apache/brooklyn/util/core/task/ValueResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/task/ValueResolverTest.java
b/core/src/test/java/org/apache/brooklyn/util/core/task/ValueResolverTest.java
index 43cd0ba..b13d2b5 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/task/ValueResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/task/ValueResolverTest.java
@@ -59,13 +59,56 @@ public class ValueResolverTest extends BrooklynAppUnitTestSupport {
         Assert.assertEquals(result.get(), "foo");
     }
 
-    public void testNoExecutionContextOnCompleted() {
+    public void testCompletedTaskReturnsResultImmediately() {
+        // Call ValueResolver.getMaybe() from this thread, which has no execution context.
+        // However, the task has already been submitted and we have waited for it to complete.
+        // Therefore the ValueResolver can simply check for task.isDone() and return its
result immediately.
         Task<String> t = newSleepTask(Duration.ZERO, "foo");
         app.getExecutionContext().submit(t).getUnchecked();
         Maybe<String> result = Tasks.resolving(t).as(String.class).timeout(Duration.ZERO).getMaybe();
         Assert.assertEquals(result.get(), "foo");
     }
 
+    public void testUnsubmittedTaskWhenNoExecutionContextFails() {
+        // ValueResolver.getMaybe() is called with no execution context. Therefore it will
not execute the task.
+        Task<String> t = newSleepTask(Duration.ZERO, "foo");
+        Maybe<String> result = Tasks.resolving(t).as(String.class).timeout(Duration.ZERO).getMaybe();
+        
+        Assert.assertTrue(result.isAbsent(), "result="+result);
+        Exception exception = ((Maybe.Absent<?>)result).getException();
+        Assert.assertTrue(exception.toString().contains("no execution context available"),
"exception="+exception);
+    }
+
+    public void testUnsubmittedTaskWithExecutionContextExecutesAndReturns() {
+        // ValueResolver.getMaybe() is called in app's execution context. Therefore it will
execute the task.
+        final Task<String> t = newSleepTask(Duration.ZERO, "foo");
+        
+        Maybe<String>  result = app.getExecutionContext()
+                .submit(new Callable<Maybe<String> >() {
+                    public Maybe<String>  call() throws Exception {
+                        return Tasks.resolving(t).as(String.class).timeout(Asserts.DEFAULT_LONG_TIMEOUT).getMaybe();
+                    }})
+                .getUnchecked();
+        
+        Assert.assertEquals(result.get(), "foo");
+    }
+
+    public void testUnsubmittedTaskWithExecutionContextExecutesAndTimesOut() {
+        // ValueResolver.getMaybe() is called in app's execution context. Therefore it will
execute the task.
+        final Task<String> t = newSleepTask(Duration.ONE_MINUTE, "foo");
+        
+        Maybe<String>  result = app.getExecutionContext()
+                .submit(new Callable<Maybe<String> >() {
+                    public Maybe<String>  call() throws Exception {
+                        return Tasks.resolving(t).as(String.class).timeout(Duration.ZERO).getMaybe();
+                    }})
+                .getUnchecked();
+        
+        Assert.assertTrue(result.isAbsent(), "result="+result);
+        Exception exception = ((Maybe.Absent<?>)result).getException();
+        Assert.assertTrue(exception.toString().contains("not completed when immediate completion
requested"), "exception="+exception);
+    }
+
     public void testSwallowError() {
         ValueResolver<String> result = Tasks.resolving(newThrowTask(Duration.ZERO)).as(String.class).context(app).swallowExceptions();
         assertMaybeIsAbsent(result);


Mime
View raw message