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 <[email protected]> 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 + }
