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 2022/08/21 17:23:40 UTC

[brooklyn-server] 04/07: predicate tidy-up and dsl test

This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 379f9184b6eb9840fb90e575e2e80b9c0cd0c432
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Fri Aug 19 14:59:12 2022 +0100

    predicate tidy-up and dsl test
---
 .../brooklyn/spi/dsl/DslPredicateYamlTest.java     | 120 +++++++++++++++++++++
 .../util/core/predicates/DslPredicates.java        |  29 ++---
 .../brooklyn/core/test/entity/TestEntity.java      |   2 +
 .../core/predicates/DslPredicateEntityTest.java    |   4 +-
 4 files changed, 142 insertions(+), 13 deletions(-)

diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslPredicateYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslPredicateYamlTest.java
new file mode 100644
index 0000000000..4688964004
--- /dev/null
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslPredicateYamlTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2016 The Apache Software Foundation.
+ *
+ * Licensed 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.camp.brooklyn.spi.dsl;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslTestObjects.DslTestCallable;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslTestObjects.DslTestSupplierWrapper;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslTestObjects.TestDslSupplier;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslTestObjects.TestDslSupplierValue;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.custom.UserSuppliedPackageType;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.Dumper;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.entity.group.DynamicCluster;
+import org.apache.brooklyn.entity.stock.BasicApplication;
+import org.apache.brooklyn.entity.stock.BasicEntity;
+import org.apache.brooklyn.entity.stock.BasicStartable;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.core.predicates.DslPredicates;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.ExecutionException;
+
+import static org.testng.Assert.assertEquals;
+
+public class DslPredicateYamlTest extends AbstractYamlTest {
+
+    @Test
+    public void testDslConfigSimple() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.config:",
+                "    "+TestEntity.CONF_STRING.getName()+": x",
+                "    test.confPredicate:",
+                "      config: "+TestEntity.CONF_STRING.getName(),
+                "      equals: y");
+        DslPredicates.DslPredicate predicate = app.config().get(TestEntity.CONF_PREDICATE);
+        Asserts.assertFalse( predicate.apply(app) );
+        app.config().set(TestEntity.CONF_STRING, "y");
+        Asserts.assertTrue( predicate.apply(app) );
+    }
+
+    @Test
+    public void testDslTags() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.tags:",
+                "  - tag1",
+                "  - color: blue");
+
+        DslPredicates.DslPredicate predicate = TypeCoercions.coerce(MutableMap.of("tag", "tag1"), DslPredicates.DslPredicate.class);
+        Asserts.assertTrue( predicate.apply(app) );
+
+        predicate = TypeCoercions.coerce(MutableMap.of("tag", "tag2"), DslPredicates.DslPredicate.class);
+        Asserts.assertFalse( predicate.apply(app) );
+
+        predicate = TypeCoercions.coerce(MutableMap.of("tag", MutableMap.of("key", "color", "equals", "blue")), DslPredicates.DslPredicate.class);
+        Asserts.assertTrue( predicate.apply(app) );
+
+        predicate = TypeCoercions.coerce(MutableMap.of("tag", MutableMap.of("key", "color", "equals", "red")), DslPredicates.DslPredicate.class);
+        Asserts.assertFalse( predicate.apply(app) );
+    }
+
+    @Test
+    public void testDslConfigContainingDsl() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.config:",
+                "    "+TestEntity.CONF_STRING.getName()+": x",
+                "    expected: x",
+                "    test.confPredicate:",
+                "      config: "+TestEntity.CONF_STRING.getName(),
+                "      equals: $brooklyn:config(\"expected\")");
+        DslPredicates.DslPredicate predicate = app.config().get(TestEntity.CONF_PREDICATE);
+        Asserts.assertTrue( predicate.apply(app) );
+
+        app.config().set(TestEntity.CONF_STRING, "y");
+        Asserts.assertFalse( predicate.apply(app) );
+
+        // nested DSL is resolved when predicate is _retrieved_, not when predicate is applied
+        // this is simpler and more efficient, although it might be surprising
+        app.config().set(ConfigKeys.newStringConfigKey("expected"), "y");
+        Asserts.assertFalse( predicate.apply(app) );
+
+        // per above, if we re-retrieve the predicate it should work fine
+        predicate = app.config().get(TestEntity.CONF_PREDICATE);
+        Asserts.assertTrue( predicate.apply(app) );
+    }
+
+}
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/predicates/DslPredicates.java b/core/src/main/java/org/apache/brooklyn/util/core/predicates/DslPredicates.java
index 4756bd50a2..5d4ff03a39 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/predicates/DslPredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/predicates/DslPredicates.java
@@ -56,6 +56,8 @@ import org.apache.brooklyn.util.guava.SerializablePredicate;
 import org.apache.brooklyn.util.javalang.Boxing;
 import org.apache.brooklyn.util.text.NaturalOrderComparator;
 import org.apache.brooklyn.util.text.WildcardGlobs;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nullable;
 import java.io.IOException;
@@ -66,10 +68,11 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.BiFunction;
 import java.util.function.Function;
-import java.util.function.Supplier;
 
 public class DslPredicates {
 
+    private static final Logger LOG = LoggerFactory.getLogger(DslPredicates.class);
+
     static AtomicBoolean initialized = new AtomicBoolean(false);
     public static void init() {
         if (initialized.getAndSet(true)) return;
@@ -210,16 +213,18 @@ public class DslPredicates {
             int checksDefined = 0;
             int checksApplicable = 0;
             int checksPassed = 0;
-            public <T> void check(T test, java.util.function.Predicate<T> check) {
+
+            public <T> void checkTest(T test, java.util.function.Predicate<T> predicateForTest) {
                 if (test!=null) {
                     checksDefined++;
                     checksApplicable++;
-                    if (check.test(test)) checksPassed++;
+                    if (predicateForTest.test(test)) checksPassed++;
                 }
             }
+
             public <T> void check(T test, Maybe<Object> value, java.util.function.BiPredicate<T,Object> check) {
                 if (value.isPresent()) {
-                    check(test, t -> check.test(t, value.get()));
+                    checkTest(test, t -> check.test(t, value.get()));
                 } else {
                     if (test!=null) {
                         checksDefined++;
@@ -297,7 +302,7 @@ public class DslPredicates {
         }
 
         public void applyToResolved(Maybe<Object> result, CheckCounts checker) {
-            checker.check(implicitEquals, result, (test,value) -> {
+            checker.check(implicitEquals, result, (test, value) -> {
                 if ((!(test instanceof BrooklynObject) && value instanceof BrooklynObject) ||
                         (!(test instanceof Iterable) && value instanceof Iterable)) {
                     throw new IllegalStateException("Implicit string used for equality check comparing "+test+" with "+value+", which is probably not what was meant. Use explicit 'equals: ...' syntax for this case.");
@@ -305,8 +310,8 @@ public class DslPredicates {
                 return DslPredicates.coercedEqual(test, value);
             });
             checker.check(equals, result, DslPredicates::coercedEqual);
-            checker.check(regex, result, (test,value) -> asStringTestOrFalse(value, v -> v.matches(test)));
-            checker.check(glob, result, (test,value) -> asStringTestOrFalse(value, v -> WildcardGlobs.isGlobMatched(test, v)));
+            checker.check(regex, result, (test, value) -> asStringTestOrFalse(value, v -> v.matches(test)));
+            checker.check(glob, result, (test, value) -> asStringTestOrFalse(value, v -> WildcardGlobs.isGlobMatched(test, v)));
 
             checker.check(inRange, result, (test,value) ->
                 // current Range only supports Integer, but this code will support any
@@ -328,9 +333,9 @@ public class DslPredicates {
                 return false;
             });
 
-            checker.check(check, test -> nestedPredicateCheck(check, result));
-            checker.check(any, test -> test.stream().anyMatch(p -> nestedPredicateCheck(p, result)));
-            checker.check(all, test -> test.stream().allMatch(p -> nestedPredicateCheck(p, result)));
+            checker.checkTest(check, test -> nestedPredicateCheck(check, result));
+            checker.checkTest(any, test -> test.stream().anyMatch(p -> nestedPredicateCheck(p, result)));
+            checker.checkTest(all, test -> test.stream().allMatch(p -> nestedPredicateCheck(p, result)));
 
             checker.check(javaInstanceOf, result, (test, value) -> {
                 Entity ent = null;
@@ -346,11 +351,11 @@ public class DslPredicates {
 
                 return tt.get().isSupertypeOf(value.getClass());
             });
-            checker.check(javaTypeName, (test) -> nestedPredicateCheck(test, result.map(v -> v.getClass().getName())));
+            checker.checkTest(javaTypeName, (test) -> nestedPredicateCheck(test, result.map(v -> v.getClass().getName())));
         }
 
         protected void checkWhen(WhenPresencePredicate when, Maybe<Object> result, CheckCounts checker) {
-            checker.check(when, test -> {
+            checker.checkTest(when, test -> {
                 switch (test) {
                     case PRESENT: return result.isPresent();
                     case PRESENT_NON_NULL: return result.isPresentAndNonNull();
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
index 072a5218b0..e1dede1f15 100644
--- a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
+++ b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
@@ -45,6 +45,7 @@ import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
 import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.apache.brooklyn.util.core.predicates.DslPredicates;
 import org.apache.brooklyn.util.time.Duration;
 
 import com.google.common.collect.ImmutableList;
@@ -74,6 +75,7 @@ public interface TestEntity extends Entity, Startable, EntityLocal, EntityIntern
     public static final SetConfigKey<String> CONF_SET_THING = new SetConfigKey<String>(String.class, "test.confSetThing", "Configuration key that's a set thing");
     public static final SetConfigKey<Object> CONF_SET_OBJ_THING = new SetConfigKey<Object>(Object.class, "test.confSetObjThing", "Configuration key that's a set thing, of objects");
     public static final BasicConfigKey<Object> CONF_OBJECT = new BasicConfigKey<Object>(Object.class, "test.confObject", "Configuration key that's an object");
+    public static final BasicConfigKey<DslPredicates.DslPredicate> CONF_PREDICATE = new BasicConfigKey<DslPredicates.DslPredicate>(DslPredicates.DslPredicate.class, "test.confPredicate", "Configuration key that's a predicate/filter");
     public static final ConfigKey<Integer> CONF_INTEGER = ConfigKeys.newConfigKey(Integer.class, "test.confInteger", "Configuration key, an integer");
     public static final ConfigKey<Double> CONF_DOUBLE = ConfigKeys.newConfigKey(Double.class, "test.confDouble", "Configuration key, a double");
     public static final ConfigKey<EntitySpec<? extends Entity>> CHILD_SPEC = ConfigKeys.newConfigKey(new TypeToken<EntitySpec<? extends Entity>>() {}, "test.childSpec", "Spec to be used for creating children");
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/predicates/DslPredicateEntityTest.java b/core/src/test/java/org/apache/brooklyn/util/core/predicates/DslPredicateEntityTest.java
index 2465003544..431f8c589f 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/predicates/DslPredicateEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/predicates/DslPredicateEntityTest.java
@@ -87,7 +87,7 @@ public class DslPredicateEntityTest extends BrooklynAppUnitTestSupport {
         Asserts.assertFalse(p.test(app));
     }
 
-    // TODO would be nice to add tag, location tests -- but manual checking has confirmed they work
+    // ----- some weird stuff -----
 
     @Test
     // would be nice to support all the EntityPredicates with the new mechanism; but coercion works well enough in practice,
@@ -133,4 +133,6 @@ public class DslPredicateEntityTest extends BrooklynAppUnitTestSupport {
     }
 
 
+    // note: tags, config, dsl values, etc are tested in camp project DslPredicateYamlTest
+
 }