You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2016/07/04 13:04:35 UTC

[2/3] brooklyn-server git commit: Adds TargetableTestComponent.targetResolutionTimeout

Adds TargetableTestComponent.targetResolutionTimeout

If no entity with the given id yet exists, then wait for this timeout
for it to exist (defaults to zero, in which case fail immediately
like it did before)

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

Branch: refs/heads/master
Commit: de12a4e8a77f7d2bfe1027ed08d6e1e0efb2ce39
Parents: ce1192f
Author: Aled Sage <al...@gmail.com>
Authored: Thu Jun 30 13:16:57 2016 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Jul 4 12:27:53 2016 +0100

----------------------------------------------------------------------
 .../test/framework/TargetableTestComponent.java | 11 +++
 .../framework/TargetableTestComponentImpl.java  | 47 +++++++---
 .../framework/TargetableTestComponentTest.java  | 96 ++++++++++++++++++++
 3 files changed, 140 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/de12a4e8/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponent.java
----------------------------------------------------------------------
diff --git a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponent.java b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponent.java
index 8ae44ad..67daff6 100644
--- a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponent.java
+++ b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponent.java
@@ -20,9 +20,11 @@ package org.apache.brooklyn.test.framework;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.ImplementedBy;
+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.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.util.time.Duration;
 
 /**
  * Entity that can target another entity for the purpouse of testing
@@ -43,6 +45,15 @@ public interface TargetableTestComponent extends Entity, Startable {
     AttributeSensorAndConfigKey<String, String> TARGET_ID = ConfigKeys.newStringSensorAndConfigKey("targetId", "Id of the entity under test");
 
     /**
+     * The duration to wait for an entity with the given targetId to exist, before throwing an exception.
+     */
+    ConfigKey<Duration> TARGET_RESOLUTION_TIMEOUT = ConfigKeys.newConfigKey(
+            Duration.class, 
+            "targetResolutionTimeout", 
+            "Time to wait for targetId to exist (defaults to zero, i.e. must exist immediately)",
+            Duration.ZERO);
+
+    /**
      * Get the target of the test.
      *
      * @return The target.

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/de12a4e8/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponentImpl.java
----------------------------------------------------------------------
diff --git a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponentImpl.java b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponentImpl.java
index 5b133bd..326e3ea 100644
--- a/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponentImpl.java
+++ b/test-framework/src/main/java/org/apache/brooklyn/test/framework/TargetableTestComponentImpl.java
@@ -18,10 +18,8 @@
  */
 package org.apache.brooklyn.test.framework;
 
-import java.util.concurrent.ExecutionException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.mgmt.ExecutionContext;
@@ -30,6 +28,10 @@ import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.repeat.Repeater;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Class that can resolve the target for a test component
@@ -62,22 +64,39 @@ public abstract class TargetableTestComponentImpl extends AbstractEntity impleme
         return target;
     }
 
-    private static Entity getTargetById(ExecutionContext executionContext, Entity entity) {
-        String targetId = entity.getConfig(TARGET_ID);
-
+    private static Entity getTargetById(final ExecutionContext executionContext, final Entity entity) {
+        final String targetId = entity.getConfig(TARGET_ID);
+        Duration resolutionTimeout = entity.getConfig(TARGET_RESOLUTION_TIMEOUT);
+        
         if(targetId == null){
             return null;
         }
 
-        final Task<Entity> targetLookup = new DslComponent(targetId).newTask();
-        Entity target = null;
+        final AtomicReference<Entity> result = new AtomicReference<>();
+        final DslComponent dslComponent = new DslComponent(targetId);
+        Callable<Boolean> resolver = new Callable<Boolean>() {
+            @Override public Boolean call() throws Exception {
+                Task<Entity> task = dslComponent.newTask();
+                result.set(Tasks.resolveValue(task, Entity.class, executionContext, "Finding entity " + targetId));
+                return true;
+            }
+        };
         try {
-            target = Tasks.resolveValue(targetLookup, Entity.class, executionContext, "Finding entity " + targetId);
-            LOG.debug("Found target by id {}", targetId);
-        } catch (final ExecutionException | InterruptedException e) {
+            if (resolutionTimeout == null || resolutionTimeout.toMilliseconds() <= 0) {
+                resolver.call();
+            } else {
+                Repeater.create("find entity "+targetId)
+                        .backoffTo(resolutionTimeout.multiply(0.1))
+                        .limitTimeTo(resolutionTimeout)
+                        .rethrowException()
+                        .until(resolver)
+                        .runRequiringTrue();
+            }
+            LOG.debug("Found target {} by id {}", result.get(), targetId);
+            return result.get();
+        } catch (Exception e) {
             LOG.error("Error finding target {}", targetId);
-            Exceptions.propagate(e);
+            throw Exceptions.propagate(e);
         }
-        return target;
     }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/de12a4e8/test-framework/src/test/java/org/apache/brooklyn/test/framework/TargetableTestComponentTest.java
----------------------------------------------------------------------
diff --git a/test-framework/src/test/java/org/apache/brooklyn/test/framework/TargetableTestComponentTest.java b/test-framework/src/test/java/org/apache/brooklyn/test/framework/TargetableTestComponentTest.java
new file mode 100644
index 0000000..dec0be7
--- /dev/null
+++ b/test-framework/src/test/java/org/apache/brooklyn/test/framework/TargetableTestComponentTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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 java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class TargetableTestComponentTest extends BrooklynAppUnitTestSupport {
+
+    private static final AttributeSensor<String> STRING_SENSOR = Sensors.newStringSensor("string-sensor");
+
+    @Test
+    public void testTargetEntity() {
+        app.sensors().set(STRING_SENSOR, "myval");
+
+        app.addChild(EntitySpec.create(TestSensor.class)
+                .configure(TestSensor.TARGET_ENTITY, app)
+                .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
+                .configure(TestSensor.ASSERTIONS, ImmutableList.of(ImmutableMap.of("equals", "myval"))));
+
+        app.start(ImmutableList.<Location>of());
+    }
+    
+    @Test
+    public void testTargetEntityById() {
+        TestEntity target = app.addChild(EntitySpec.create(TestEntity.class)
+                .configure(BrooklynCampConstants.PLAN_ID, "myTargetId"));
+        target.sensors().set(STRING_SENSOR, "myval");
+
+        app.addChild(EntitySpec.create(TestSensor.class)
+                .configure(TestSensor.TARGET_ID, "myTargetId")
+                .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
+                .configure(TestSensor.ASSERTIONS, ImmutableList.of(ImmutableMap.of("equals", "myval"))));
+
+        app.start(ImmutableList.<Location>of());
+    }
+    
+    @Test
+    public void testTargetEntityByIdWithDelayedEntityCreation() {
+        final Duration entityCreationDelay = Duration.millis(250);
+        final Duration overheadDuration = Duration.seconds(10);
+        ExecutorService executor = Executors.newCachedThreadPool();
+        
+        try {
+            executor.submit(new Runnable() {
+                @Override public void run() {
+                    Time.sleep(entityCreationDelay);
+                    TestEntity target = app.addChild(EntitySpec.create(TestEntity.class)
+                            .configure(BrooklynCampConstants.PLAN_ID, "myTargetId"));
+                    target.sensors().set(STRING_SENSOR, "myval");
+                }});
+    
+            app.addChild(EntitySpec.create(TestSensor.class)
+                    .configure(TestSensor.TARGET_ID, "myTargetId")
+                    .configure(TestSensor.TARGET_RESOLUTION_TIMEOUT, Duration.of(entityCreationDelay).add(overheadDuration))
+                    .configure(TestSensor.SENSOR_NAME, STRING_SENSOR.getName())
+                    .configure(TestSensor.ASSERTIONS, ImmutableList.of(ImmutableMap.of("equals", "myval"))));
+
+            
+            app.start(ImmutableList.<Location>of());
+            
+        } finally {
+            executor.shutdownNow();
+        }
+    }
+}