http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java new file mode 100644 index 0000000..dbc84ed --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java @@ -0,0 +1,556 @@ +/* + * 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.enricher.stock; + +import java.util.Collection; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.location.LocationSpec; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.location.SimulatedLocation; +import org.apache.brooklyn.core.sensor.BasicAttributeSensor; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.enricher.stock.Enrichers; +import org.apache.brooklyn.entity.group.BasicGroup; +import org.apache.brooklyn.test.EntityTestUtils; +import org.apache.brooklyn.util.collections.MutableMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class CustomAggregatingEnricherTest extends BrooklynAppUnitTestSupport { + + public static final Logger log = LoggerFactory.getLogger(CustomAggregatingEnricherTest.class); + + private static final long TIMEOUT_MS = 10*1000; + private static final long SHORT_WAIT_MS = 50; + + TestEntity entity; + SimulatedLocation loc; + + AttributeSensor<Integer> intSensor; + AttributeSensor<Double> doubleSensor; + AttributeSensor<Integer> target; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor"); + doubleSensor = new BasicAttributeSensor<Double>(Double.class, "double sensor"); + target = new BasicAttributeSensor<Integer>(Integer.class, "target sensor"); + loc = mgmt.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class)); + app.start(ImmutableList.of(loc)); + } + + @Test + public void testSummingEnricherWithNoProducersDefaultsToNull() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromChildren() + .build()); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null); + } + + @Test + public void testSummingEnricherWithNoProducers() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromChildren() + .defaultValueForUnreportedSensors(11) + .valueToReportIfNoSensors(40) + .build()); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 40); + } + + @Test + public void testSummingEnricherWhenNoSensorValuesYet() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromHardcodedProducers(ImmutableList.of(entity)) + .defaultValueForUnreportedSensors(11) + .valueToReportIfNoSensors(40) + .build()); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 11); + } + + @Test + public void testSummingEnricherWhenNoSensorValuesYetDefaultsToNull() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromHardcodedProducers(ImmutableList.of(entity)) + .build()); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null); + } + + @Test + public void testSummingEnricherWithNoValues() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromHardcodedProducers(ImmutableList.of(entity)) + .build()); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null); + } + + @Test + public void testSummingEnricherWithOneValue() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromHardcodedProducers(ImmutableList.of(entity)) + .build()); + + entity.setAttribute(intSensor, 1); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + } + + @Test + public void testSummingEnricherWhenNullSensorValue() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromHardcodedProducers(ImmutableList.of(entity)) + .build()); + + entity.setAttribute(intSensor, null); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null); + } + + @Test + public void testSummingEnricherWhenDefaultValueForUnreportedSensors() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromHardcodedProducers(ImmutableList.of(entity)) + .defaultValueForUnreportedSensors(3) + .valueToReportIfNoSensors(5) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3); + + entity.setAttribute(intSensor, null); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, 3); + + entity.setAttribute(intSensor, 1); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + + entity.setAttribute(intSensor, 7); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 7); + } + + @Test + public void testMultipleProducersSum() { + TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3)) + .build()); + + producer3.setAttribute(intSensor, 1); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + + producer1.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3); + + producer2.setAttribute(intSensor, 4); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 7); + } + + @Test + public void testAveragingEnricherWhenNoAndNullSensorValues() { + TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(doubleSensor) + .computingAverage() + .fromHardcodedProducers(ImmutableList.of(producer1)) + .build()); + + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null); + + producer1.setAttribute(intSensor, null); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null); + } + + @Test + public void testAveragingEnricherWhenDefaultValueForUnreportedSensors() { + TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(doubleSensor) + .computingAverage() + .fromHardcodedProducers(ImmutableList.of(producer1)) + .defaultValueForUnreportedSensors(3) + .valueToReportIfNoSensors(5) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d); + + producer1.setAttribute(intSensor, null); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, 3d); + + producer1.setAttribute(intSensor, 4); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 4d); + } + + @Test + public void testAveragingEnricherWhenNoSensors() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(doubleSensor) + .computingAverage() + .fromChildren() + .defaultValueForUnreportedSensors(3) + .valueToReportIfNoSensors(5) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 5d); + } + + @Test + public void testAveragingEnricherWhenNoProducersDefaultsToNull() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(doubleSensor) + .computingAverage() + .fromChildren() + .build()); + + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null); + } + + @Test + public void testMultipleProducersAverage() { + TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(doubleSensor) + .computingAverage() + .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3)) + .build()); + + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null); + + producer1.setAttribute(intSensor, 3); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d); + + producer2.setAttribute(intSensor, 1); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 2d); + + producer3.setAttribute(intSensor, 5); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d); + + producer2.setAttribute(intSensor, 4); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 4d); + } + + @Test + public void testMultipleProducersAverageDefaultingZero() { + TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(doubleSensor) + .computingAverage() + .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3)) + .defaultValueForUnreportedSensors(0) + .valueToReportIfNoSensors(0) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 0d); + + producer1.setAttribute(intSensor, 3); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 1d); + + producer2.setAttribute(intSensor, 3); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 2d); + + producer3.setAttribute(intSensor, 3); + EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d); + } + + @Test + public void testAggregatesNewMembersOfGroup() { + BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class)); + TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + log.debug("created {} and the entities it will contain {} {}", new Object[] {group, p1, p2}); + + group.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromMembers() + .defaultValueForUnreportedSensors(0) + .valueToReportIfNoSensors(0) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(group, target, 0); + + group.addMember(p1); + p1.setAttribute(intSensor, 1); + EntityTestUtils.assertAttributeEqualsEventually(group, target, 1); + + group.addMember(p2); + p2.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(group, target, 3); + + group.removeMember(p2); + EntityTestUtils.assertAttributeEqualsEventually(group, target, 1); + } + + @Test(groups = "Integration", invocationCount=50) + public void testAggregatesGroupMembersFiftyTimes() { + testAggregatesNewMembersOfGroup(); + } + + @Test + public void testAggregatesExistingMembersOfGroup() { + BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class)); + TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group)); + TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group)); + group.addMember(p1); + group.addMember(p2); + p1.setAttribute(intSensor, 1); + Entities.manage(group); + + group.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromMembers() + .build()); + + + EntityTestUtils.assertAttributeEqualsEventually(group, target, 1); + + p2.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(group, target, 3); + + group.removeMember(p2); + EntityTestUtils.assertAttributeEqualsEventually(group, target, 1); + } + + @Test + public void testAggregatesMembersOfProducer() { + BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class)); + TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group)); + TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group)); + group.addMember(p1); + group.addMember(p2); + p1.setAttribute(intSensor, 1); + Entities.manage(group); + + app.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .from(group) + .fromMembers() + .build()); + + + EntityTestUtils.assertAttributeEqualsEventually(app, target, 1); + + p2.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(app, target, 3); + + group.removeMember(p2); + EntityTestUtils.assertAttributeEqualsEventually(app, target, 1); + } + + @Test + public void testAppliesFilterWhenAggregatingMembersOfGroup() { + BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class)); + TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity p3 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + group.addMember(p1); + group.addMember(p2); + p1.setAttribute(intSensor, 1); + p2.setAttribute(intSensor, 2); + p3.setAttribute(intSensor, 4); + + group.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromMembers() + .entityFilter(Predicates.equalTo((Entity)p1)) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(group, target, 1); + + group.addMember(p3); + EntityTestUtils.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), group, target, 1); + } + + @Test + public void testAggregatesNewChidren() { + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromChildren() + .defaultValueForUnreportedSensors(0) + .valueToReportIfNoSensors(0) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 0); + + TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + p1.setAttribute(intSensor, 1); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + + TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + p2.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3); + + Entities.unmanage(p2); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + } + + @Test + public void testAggregatesExistingChildren() { + TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + p1.setAttribute(intSensor, 1); + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromChildren() + .build()); + + + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + + p2.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3); + + Entities.unmanage(p2); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + } + + @Test + public void testAggregatesChildrenOfProducer() { + TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + p1.setAttribute(intSensor, 1); + + app.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .from(entity) + .fromChildren() + .build()); + + + EntityTestUtils.assertAttributeEqualsEventually(app, target, 1); + + p2.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(app, target, 3); + + Entities.unmanage(p2); + EntityTestUtils.assertAttributeEqualsEventually(app, target, 1); + } + + @Test + public void testAppliesFilterWhenAggregatingChildrenOfGroup() { + TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + p1.setAttribute(intSensor, 1); + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computingSum() + .fromChildren() + .entityFilter(Predicates.equalTo((Entity)p1)) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + + TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class)); + p2.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), entity, target, 1); + } + + @Test + public void testCustomAggregatingFunction() { + TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + Function<Collection<Integer>,Integer> aggregator = new Function<Collection<Integer>, Integer>() { + public Integer apply(Collection<Integer> input) { + int result = 1; + for (Integer in : input) result += in*in; + return result; + } + }; + + entity.addEnricher(Enrichers.builder() + .aggregating(intSensor) + .publishing(target) + .computing(aggregator) + .fromHardcodedProducers(ImmutableList.of(producer1)) + .defaultValueForUnreportedSensors(0) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1); + + // Event by producer + producer1.setAttribute(intSensor, 2); + EntityTestUtils.assertAttributeEqualsEventually(entity, target, 5); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java new file mode 100644 index 0000000..e5c48fa --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java @@ -0,0 +1,501 @@ +/* + * 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.enricher.stock; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.Enricher; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.entity.EntityAdjuncts; +import org.apache.brooklyn.core.entity.RecordingSensorEventListener; +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.enricher.stock.Enrichers; +import org.apache.brooklyn.entity.group.BasicGroup; +import org.apache.brooklyn.test.Asserts; +import org.apache.brooklyn.test.EntityTestUtils; +import org.apache.brooklyn.util.collections.CollectionFunctionals; +import org.apache.brooklyn.util.collections.MutableList; +import org.apache.brooklyn.util.collections.MutableMap; +import org.apache.brooklyn.util.collections.MutableSet; +import org.apache.brooklyn.util.guava.Functionals; +import org.apache.brooklyn.util.text.StringFunctions; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.reflect.TypeToken; + +@SuppressWarnings("serial") +public class EnrichersTest extends BrooklynAppUnitTestSupport { + + public static final AttributeSensor<Integer> NUM1 = Sensors.newIntegerSensor("test.num1"); + public static final AttributeSensor<Integer> NUM2 = Sensors.newIntegerSensor("test.num2"); + public static final AttributeSensor<Integer> NUM3 = Sensors.newIntegerSensor("test.num3"); + public static final AttributeSensor<String> STR1 = Sensors.newStringSensor("test.str1"); + public static final AttributeSensor<String> STR2 = Sensors.newStringSensor("test.str2"); + public static final AttributeSensor<Set<Object>> SET1 = Sensors.newSensor(new TypeToken<Set<Object>>() {}, "test.set1", "set1 descr"); + public static final AttributeSensor<Long> LONG1 = Sensors.newLongSensor("test.long1"); + public static final AttributeSensor<Map<String,String>> MAP1 = Sensors.newSensor(new TypeToken<Map<String,String>>() {}, "test.map1", "map1 descr"); + @SuppressWarnings("rawtypes") + public static final AttributeSensor<Map> MAP2 = Sensors.newSensor(Map.class, "test.map2"); + + private TestEntity entity; + private TestEntity entity2; + private BasicGroup group; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + group = app.createAndManageChild(EntitySpec.create(BasicGroup.class)); + } + + @SuppressWarnings("unchecked") + @Test + public void testAdding() { + Enricher enr = entity.addEnricher(Enrichers.builder() + .combining(NUM1, NUM2) + .publishing(NUM3) + .computingSum() + .build()); + + Assert.assertEquals(EntityAdjuncts.getNonSystemEnrichers(entity), ImmutableList.of(enr)); + + entity.setAttribute(NUM1, 2); + entity.setAttribute(NUM2, 3); + EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 5); + } + + @SuppressWarnings("unchecked") + @Test + public void testCombiningWithCustomFunction() { + entity.addEnricher(Enrichers.builder() + .combining(NUM1, NUM2) + .publishing(NUM3) + .computing(Functions.constant(1)) + .build()); + + entity.setAttribute(NUM1, 2); + entity.setAttribute(NUM2, 3); + EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 1); + } + + @SuppressWarnings("unchecked") + @Test(groups="Integration") // because takes a second + public void testCombiningRespectsUnchanged() { + entity.addEnricher(Enrichers.builder() + .combining(NUM1, NUM2) + .<Object>publishing(NUM3) + .computing(new Function<Iterable<Integer>, Object>() { + @Override public Object apply(Iterable<Integer> input) { + if (input != null && Iterables.contains(input, 123)) { + return Enrichers.sum(input, 0, 0, new TypeToken<Integer>(){}); + } else { + return Entities.UNCHANGED; + } + }}) + .build()); + + entity.setAttribute(NUM1, 123); + entity.setAttribute(NUM2, 3); + EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 126); + + entity.setAttribute(NUM1, 2); + EntityTestUtils.assertAttributeEqualsContinually(entity, NUM3, 126); + } + + @Test + public void testFromEntity() { + entity.addEnricher(Enrichers.builder() + .transforming(NUM1) + .publishing(NUM1) + .computing(Functions.<Integer>identity()) + .from(entity2) + .build()); + + entity2.setAttribute(NUM1, 2); + EntityTestUtils.assertAttributeEqualsEventually(entity, NUM1, 2); + } + + @Test + public void testTransforming() { + entity.addEnricher(Enrichers.builder() + .transforming(STR1) + .publishing(STR2) + .computing(StringFunctions.append("mysuffix")) + .build()); + + entity.setAttribute(STR1, "myval"); + EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myvalmysuffix"); + } + + @Test + public void testTransformingCastsResult() { + entity.addEnricher(Enrichers.builder() + .transforming(NUM1) + .publishing(LONG1) + .computing(Functions.constant(Long.valueOf(1))) + .build()); + + entity.setAttribute(NUM1, 123); + EntityTestUtils.assertAttributeEqualsEventually(entity, LONG1, Long.valueOf(1)); + } + + @Test + public void testTransformingFromEvent() { + entity.addEnricher(Enrichers.builder() + .transforming(STR1) + .publishing(STR2) + .computingFromEvent(new Function<SensorEvent<String>, String>() { + @Override public String apply(SensorEvent<String> input) { + return input.getValue() + "mysuffix"; + }}) + .build()); + + entity.setAttribute(STR1, "myval"); + EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myvalmysuffix"); + } + + @Test(groups="Integration") // because takes a second + public void testTransformingRespectsUnchangedButWillRepublish() { + RecordingSensorEventListener<String> record = new RecordingSensorEventListener<>(); + app.getManagementContext().getSubscriptionManager().subscribe(entity, STR2, record); + + entity.addEnricher(Enrichers.builder() + .transforming(STR1) + .<Object>publishing(STR2) + .computing(new Function<String, Object>() { + @Override public Object apply(String input) { + return ("ignoredval".equals(input)) ? Entities.UNCHANGED : input; + }}) + .build()); + Asserts.assertThat(record.getEvents(), CollectionFunctionals.sizeEquals(0)); + + entity.setAttribute(STR1, "myval"); + Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(1)); + EntityTestUtils.assertAttributeEquals(entity, STR2, "myval"); + + entity.setAttribute(STR1, "ignoredval"); + EntityTestUtils.assertAttributeEqualsContinually(entity, STR2, "myval"); + + entity.setAttribute(STR1, "myval2"); + Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(2)); + EntityTestUtils.assertAttributeEquals(entity, STR2, "myval2"); + + entity.setAttribute(STR1, "myval2"); + entity.setAttribute(STR1, "myval2"); + entity.setAttribute(STR1, "myval3"); + Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(5)); + } + + public void testTransformingSuppressDuplicates() { + RecordingSensorEventListener<String> record = new RecordingSensorEventListener<>(); + app.getManagementContext().getSubscriptionManager().subscribe(entity, STR2, record); + + entity.addEnricher(Enrichers.builder() + .transforming(STR1) + .publishing(STR2) + .computing(Functions.<String>identity()) + .suppressDuplicates(true) + .build()); + + entity.setAttribute(STR1, "myval"); + Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(1)); + EntityTestUtils.assertAttributeEquals(entity, STR2, "myval"); + + entity.setAttribute(STR1, "myval2"); + entity.setAttribute(STR1, "myval2"); + entity.setAttribute(STR1, "myval3"); + EntityTestUtils.assertAttributeEqualsContinually(entity, STR2, "myval3"); + Asserts.assertThat(record.getEvents(), CollectionFunctionals.sizeEquals(3)); + } + + @Test + public void testPropagating() { + entity.addEnricher(Enrichers.builder() + .propagating(ImmutableList.of(STR1)) + .from(entity2) + .build()); + + entity2.setAttribute(STR1, "myval"); + EntityTestUtils.assertAttributeEqualsEventually(entity, STR1, "myval"); + + entity2.setAttribute(STR1, null); + EntityTestUtils.assertAttributeEqualsEventually(entity, STR1, null); + } + + @Test + public void testPropagatingAndRenaming() { + entity.addEnricher(Enrichers.builder() + .propagating(ImmutableMap.of(STR1, STR2)) + .from(entity2) + .build()); + + entity2.setAttribute(STR1, "myval"); + EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myval"); + } + + // FIXME What is default? members? children? fail? + @Test + public void testAggregatingGroupSum() { + TestEntity child1 = group.addChild(EntitySpec.create(TestEntity.class)); + Entities.manage(child1); + group.addMember(entity); + group.addMember(entity2); + group.addEnricher(Enrichers.builder() + .aggregating(NUM1) + .publishing(NUM2) + .fromMembers() + .computingSum() + .build()); + + child1.setAttribute(NUM1, 1); + entity.setAttribute(NUM1, 2); + entity2.setAttribute(NUM1, 3); + EntityTestUtils.assertAttributeEqualsEventually(group, NUM2, 5); + } + + @Test + public void testAggregatingChildrenSum() { + group.addMember(entity); + TestEntity child1 = group.addChild(EntitySpec.create(TestEntity.class)); + Entities.manage(child1); + TestEntity child2 = group.addChild(EntitySpec.create(TestEntity.class)); + Entities.manage(child2); + group.addEnricher(Enrichers.builder() + .aggregating(NUM1) + .publishing(NUM2) + .fromChildren() + .computingSum() + .build()); + + entity.setAttribute(NUM1, 1); + child1.setAttribute(NUM1, 2); + child2.setAttribute(NUM1, 3); + EntityTestUtils.assertAttributeEqualsEventually(group, NUM2, 5); + } + + @Test + public void testAggregatingExcludingBlankString() { + group.addMember(entity); + group.addMember(entity2); + group.addEnricher(Enrichers.builder() + .aggregating(STR1) + .publishing(SET1) + .fromMembers() + .excludingBlank() + .computing(new Function<Collection<?>, Set<Object>>() { + @Override public Set<Object> apply(Collection<?> input) { + // accept null values, so don't use ImmutableSet + return (input == null) ? ImmutableSet.<Object>of() : MutableSet.<Object>copyOf(input); + }}) + .build()); + + entity.setAttribute(STR1, "1"); + entity2.setAttribute(STR1, "2"); + EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("1", "2")); + + entity.setAttribute(STR1, "3"); + entity2.setAttribute(STR1, null); + EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("3")); + + entity.setAttribute(STR1, ""); + entity2.setAttribute(STR1, "4"); + EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("4")); + } + + @Test + public void testAggregatingExcludingNull() { + group.addMember(entity); + group.addEnricher(Enrichers.builder() + .aggregating(NUM1) + .publishing(SET1) + .fromMembers() + .excludingBlank() + .computing(new Function<Collection<?>, Set<Object>>() { + @Override public Set<Object> apply(Collection<?> input) { + // accept null values, so don't use ImmutableSet + return (input == null) ? ImmutableSet.<Object>of() : MutableSet.<Object>copyOf(input); + }}) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of()); + + entity.setAttribute(NUM1, 1); + EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of(1)); + + entity.setAttribute(NUM1, null); + EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of()); + + entity.setAttribute(NUM1, 2); + EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of(2)); + } + + @Test + public void testAggregatingCastsResult() { + group.addMember(entity); + group.addEnricher(Enrichers.builder() + .aggregating(NUM1) + .publishing(LONG1) + .fromMembers() + .computing(Functions.constant(Long.valueOf(1))) + .build()); + + entity.setAttribute(NUM1, 123); + EntityTestUtils.assertAttributeEqualsEventually(group, LONG1, Long.valueOf(1)); + } + + @Test(groups="Integration") // because takes a second + public void testAggregatingRespectsUnchanged() { + group.addMember(entity); + group.addEnricher(Enrichers.builder() + .aggregating(NUM1) + .<Object>publishing(LONG1) + .fromMembers() + .computing(new Function<Iterable<Integer>, Object>() { + @Override public Object apply(Iterable<Integer> input) { + if (input != null && Iterables.contains(input, 123)) { + return Enrichers.sum(input, 0, 0, new TypeToken<Integer>(){}); + } else { + return Entities.UNCHANGED; + } + }}) + .build()); + + entity.setAttribute(NUM1, 123); + EntityTestUtils.assertAttributeEqualsEventually(group, LONG1, Long.valueOf(123)); + + entity.setAttribute(NUM1, 987654); + EntityTestUtils.assertAttributeEqualsContinually(group, LONG1, Long.valueOf(123)); + } + @Test + public void testUpdatingMap1() { + entity.addEnricher(Enrichers.builder() + .updatingMap(MAP1) + .from(LONG1) + .computing(Functionals.ifEquals(-1L).value("-1 is not allowed")) + .build()); + + doUpdatingMapChecks(MAP1); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testUpdatingMap2() { + entity.addEnricher(Enrichers.builder() + .updatingMap((AttributeSensor)MAP2) + .from(LONG1) + .computing(Functionals.ifEquals(-1L).value("-1 is not allowed")) + .build()); + + doUpdatingMapChecks(MAP2); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected void doUpdatingMapChecks(AttributeSensor mapSensor) { + EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of()); + + entity.setAttribute(LONG1, -1L); + EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of( + LONG1.getName(), "-1 is not allowed")); + + entity.setAttribute(LONG1, 1L); + EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of()); + } + + private static AttributeSensor<Object> LIST_SENSOR = Sensors.newSensor(Object.class, "sensor.list"); + + @Test + public void testJoinerDefault() { + entity.addEnricher(Enrichers.builder() + .joining(LIST_SENSOR) + .publishing(TestEntity.NAME) + .build()); + // null values ignored, and it quotes + entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "\"b").append(null)); + EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "\"a\",\"\\\"b\""); + + // empty list causes "" + entity.setAttribute(LIST_SENSOR, MutableList.<String>of().append(null)); + EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, ""); + + // null causes null + entity.setAttribute(LIST_SENSOR, null); + EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null); + } + + @Test + public void testJoinerUnquoted() { + entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "\"b", "ccc").append(null)); + entity.addEnricher(Enrichers.builder() + .joining(LIST_SENSOR) + .publishing(TestEntity.NAME) + .minimum(1) + .maximum(2) + .separator(":") + .quote(false) + .build()); + // in this case, it should be immediately available upon adding the enricher + EntityTestUtils.assertAttributeEquals(entity, TestEntity.NAME, "a:\"b"); + + // empty list causes null here, because below the minimum + entity.setAttribute(LIST_SENSOR, MutableList.<String>of().append(null)); + EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null); + } + + @Test + public void testJoinerMinMax() { + entity.addEnricher(Enrichers.builder() + .joining(LIST_SENSOR) + .publishing(TestEntity.NAME) + .minimum(2) + .maximum(4) + .quote(false) + .build()); + // null values ignored, and it quotes + entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "b")); + EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "a,b"); + + // empty list causes "" + entity.setAttribute(LIST_SENSOR, MutableList.<String>of("x")); + EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null); + + // null causes null + entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "b", "c", "d", "e")); + EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "a,b,c,d"); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java new file mode 100644 index 0000000..a52e2ee --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java @@ -0,0 +1,108 @@ +/* + * 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.enricher.stock; + +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.api.sensor.SensorEventListener; +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.enricher.stock.SensorPropagatingEnricher; +import org.apache.brooklyn.test.Asserts; +import org.apache.brooklyn.test.EntityTestUtils; +import org.apache.brooklyn.util.collections.MutableMap; +import org.apache.brooklyn.util.javalang.AtomicReferences; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableMap; + +public class SensorPropagatingEnricherDeprecatedTest extends BrooklynAppUnitTestSupport { + + private TestEntity entity; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + } + + @Test + public void testPropagatesSpecificSensor() { + app.addEnricher(SensorPropagatingEnricher.newInstanceListeningTo(entity, TestEntity.NAME)); + + // name propagated + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + + // sequence not propagated + entity.setAttribute(TestEntity.SEQUENCE, 2); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null); + } + + @Test + public void testPropagatesAllSensors() { + app.addEnricher(SensorPropagatingEnricher.newInstanceListeningToAllSensors(entity)); + + // all attributes propagated + entity.setAttribute(TestEntity.NAME, "foo"); + entity.setAttribute(TestEntity.SEQUENCE, 2); + + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2); + + // notification-sensor propagated + final AtomicReference<Integer> notif = new AtomicReference<Integer>(); + app.subscribe(app, TestEntity.MY_NOTIF, new SensorEventListener<Integer>() { + @Override public void onEvent(SensorEvent<Integer> event) { + notif.set(event.getValue()); + }}); + entity.emit(TestEntity.MY_NOTIF, 7); + Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo(7)); + } + + @Test + public void testPropagatesAllBut() { + app.addEnricher(SensorPropagatingEnricher.newInstanceListeningToAllSensorsBut(entity, TestEntity.SEQUENCE)) ; + + // name propagated + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + + // sequence not propagated + entity.setAttribute(TestEntity.SEQUENCE, 2); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null); + } + + @Test + public void testPropagatingAsDifferentSensor() { + final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", ""); + app.addEnricher(SensorPropagatingEnricher.newInstanceRenaming(entity, ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE))); + + // name propagated as different attribute + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java new file mode 100644 index 0000000..c660df1 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java @@ -0,0 +1,218 @@ +/* + * 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.enricher.stock; + +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.EnricherSpec; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.api.sensor.SensorEventListener; +import org.apache.brooklyn.core.sensor.BasicNotificationSensor; +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.enricher.stock.Enrichers; +import org.apache.brooklyn.enricher.stock.Propagator; +import org.apache.brooklyn.test.Asserts; +import org.apache.brooklyn.test.EntityTestUtils; +import org.apache.brooklyn.util.collections.MutableMap; +import org.apache.brooklyn.util.exceptions.Exceptions; +import org.apache.brooklyn.util.javalang.AtomicReferences; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class SensorPropagatingEnricherTest extends BrooklynAppUnitTestSupport { + + private TestEntity entity; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + } + + @Test + public void testPropagatesSpecificSensor() { + app.addEnricher(Enrichers.builder() + .propagating(TestEntity.NAME) + .from(entity) + .build()); + + // name propagated + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + + // sequence not propagated + entity.setAttribute(TestEntity.SEQUENCE, 2); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null); + } + + @Test + public void testPropagatesCurrentValue() { + entity.setAttribute(TestEntity.NAME, "foo"); + + app.addEnricher(Enrichers.builder() + .propagating(TestEntity.NAME) + .from(entity) + .build()); + + // name propagated + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + } + + @Test + public void testPropagatesAllStaticSensors() { + app.addEnricher(Enrichers.builder() + .propagatingAll() + .from(entity) + .build()); + + // all attributes propagated + entity.setAttribute(TestEntity.NAME, "foo"); + entity.setAttribute(TestEntity.SEQUENCE, 2); + + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2); + + // notification-sensor propagated + final AtomicReference<Integer> notif = new AtomicReference<Integer>(); + app.subscribe(app, TestEntity.MY_NOTIF, new SensorEventListener<Integer>() { + @Override public void onEvent(SensorEvent<Integer> event) { + notif.set(event.getValue()); + }}); + entity.emit(TestEntity.MY_NOTIF, 7); + Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo(7)); + } + + @Test + public void testPropagatesAllSensorsIncludesDynamicallyAdded() { + AttributeSensor<String> dynamicAttribute = Sensors.newStringSensor("test.dynamicsensor.strattrib"); + BasicNotificationSensor<String> dynamicNotificationSensor = new BasicNotificationSensor(String.class, "test.dynamicsensor.strnotif"); + + app.addEnricher(Enrichers.builder() + .propagatingAll() + .from(entity) + .build()); + + entity.setAttribute(dynamicAttribute, "foo"); + + EntityTestUtils.assertAttributeEqualsEventually(app, dynamicAttribute, "foo"); + + // notification-sensor propagated + final AtomicReference<String> notif = new AtomicReference<String>(); + app.subscribe(app, dynamicNotificationSensor, new SensorEventListener<String>() { + @Override public void onEvent(SensorEvent<String> event) { + notif.set(event.getValue()); + }}); + entity.emit(dynamicNotificationSensor, "mynotifval"); + Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo("mynotifval")); + } + + @Test + public void testPropagatesAllBut() { + app.addEnricher(Enrichers.builder() + .propagatingAllBut(TestEntity.SEQUENCE) + .from(entity) + .build()); + + // name propagated + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + + // sequence not propagated + entity.setAttribute(TestEntity.SEQUENCE, 2); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null); + } + + @Test + public void testPropagatingAsDifferentSensor() { + final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", ""); + + app.addEnricher(Enrichers.builder() + .propagating(ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE)) + .from(entity) + .build()); + + // name propagated as different attribute + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo"); + } + + @Test + public void testEnricherSpecPropagatesSpecificSensor() throws Exception { + app.addEnricher(EnricherSpec.create(Propagator.class) + .configure(MutableMap.builder() + .putIfNotNull(Propagator.PRODUCER, entity) + .putIfNotNull(Propagator.PROPAGATING, ImmutableList.of(TestEntity.NAME)) + .build())); + + // name propagated + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo"); + + // sequence not propagated + entity.setAttribute(TestEntity.SEQUENCE, 2); + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null); + } + + @Test + public void testEnricherSpecPropagatesSpecificSensorAndMapsOthers() throws Exception { + final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", ""); + + app.addEnricher(EnricherSpec.create(Propagator.class) + .configure(MutableMap.builder() + .putIfNotNull(Propagator.PRODUCER, entity) + .putIfNotNull(Propagator.SENSOR_MAPPING, ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE)) + .putIfNotNull(Propagator.PROPAGATING, ImmutableList.of(TestEntity.SEQUENCE)) + .build())); + + // name propagated as alternative sensor + entity.setAttribute(TestEntity.NAME, "foo"); + EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo"); + + // sequence also propagated + entity.setAttribute(TestEntity.SEQUENCE, 2); + EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2); + + // name not propagated as original sensor + EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.NAME, null); + } + + @Test + public void testEnricherSpecThrowsOnPropagatesAndPropagatesAllSet() throws Exception { + try { + app.addEnricher(EnricherSpec.create(Propagator.class) + .configure(MutableMap.builder() + .put(Propagator.PRODUCER, entity) + .put(Propagator.PROPAGATING, ImmutableList.of(TestEntity.NAME)) + .put(Propagator.PROPAGATING_ALL, true) + .build())); + } catch (Exception e) { + IllegalStateException ise = Exceptions.getFirstThrowableOfType(e, IllegalStateException.class); + if (ise == null) throw e; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy new file mode 100644 index 0000000..d1f264d --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy @@ -0,0 +1,83 @@ +/* + * 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.enricher.stock + +import java.util.concurrent.Callable + +import org.apache.brooklyn.api.entity.EntitySpec +import org.apache.brooklyn.api.sensor.AttributeSensor +import org.apache.brooklyn.core.test.entity.TestApplication +import org.apache.brooklyn.core.test.entity.TestEntity +import org.apache.brooklyn.enricher.stock.SensorTransformingEnricher; +import org.apache.brooklyn.core.entity.Entities +import org.apache.brooklyn.core.location.SimulatedLocation +import org.apache.brooklyn.core.sensor.BasicAttributeSensor +import org.apache.brooklyn.test.TestUtils +import org.apache.brooklyn.util.collections.MutableMap +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.testng.Assert +import org.testng.annotations.AfterMethod +import org.testng.annotations.BeforeMethod +import org.testng.annotations.Test + +public class TransformingEnricherDeprecatedTest { + + public static final Logger log = LoggerFactory.getLogger(TransformingEnricherDeprecatedTest.class); + + private static final long TIMEOUT_MS = 10*1000; +// private static final long SHORT_WAIT_MS = 250; + + TestApplication app; + TestEntity producer; + AttributeSensor<Integer> intSensorA; + AttributeSensor<Long> target; + + @BeforeMethod() + public void before() { + app = TestApplication.Factory.newManagedInstanceForTests(); + producer = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + intSensorA = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a"); + target = new BasicAttributeSensor<Long>(Long.class, "long.sensor.target"); + + app.start(Arrays.asList(new SimulatedLocation())); + } + + @AfterMethod(alwaysRun=true) + public void after() { + if (app!=null) Entities.destroyAll(app.getManagementContext()); + } + + @Test + public void testTransformingEnricher() throws InterruptedException { + final SensorTransformingEnricher e1 = new SensorTransformingEnricher<Integer,Long>(intSensorA, target, + { 2*it }); + + producer.setAttribute(intSensorA, 3); + //ensure previous values get picked up + producer.addEnricher(e1); + + TestUtils.assertEventually(MutableMap.of("timeout", TIMEOUT_MS), + new Callable<Object>() { public Object call() { + Assert.assertEquals(producer.getAttribute(target), (Long)((long)6)); + return null; + }}); + + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java new file mode 100644 index 0000000..ee8fc9e --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java @@ -0,0 +1,71 @@ +/* + * 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.enricher.stock; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.core.location.SimulatedLocation; +import org.apache.brooklyn.core.sensor.BasicAttributeSensor; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.enricher.stock.Enrichers; +import org.apache.brooklyn.test.EntityTestUtils; +import org.apache.brooklyn.util.math.MathFunctions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; + +public class TransformingEnricherTest extends BrooklynAppUnitTestSupport { + + public static final Logger log = LoggerFactory.getLogger(TransformingEnricherTest.class); + + TestEntity producer; + AttributeSensor<Integer> intSensorA; + AttributeSensor<Long> target; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + producer = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + intSensorA = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a"); + target = new BasicAttributeSensor<Long>(Long.class, "long.sensor.target"); + + app.start(ImmutableList.of(new SimulatedLocation())); + } + + @Test + public void testTransformingEnricher() throws Exception { + //ensure previous values get picked up + producer.setAttribute(intSensorA, 3); + + producer.addEnricher(Enrichers.builder() + .transforming(intSensorA) + //.computing(MathFunctions.times(2)) // TODO calling it before "publishing" means it doesn't check return type! + .publishing(target) + .computing((Function)MathFunctions.times(2)) // TODO doesn't match strongly typed int->long + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(producer, target, 6L); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java new file mode 100644 index 0000000..af683ac --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java @@ -0,0 +1,179 @@ +/* + * 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.enricher.stock; + +import static org.testng.Assert.assertEquals; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.SubscriptionContext; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.EnricherSpec; +import org.apache.brooklyn.core.entity.AbstractApplication; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.sensor.BasicAttributeSensor; +import org.apache.brooklyn.core.sensor.BasicSensorEvent; +import org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher; +import org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher; +import org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher.ConfidenceQualifiedNumber; +import org.apache.brooklyn.entity.stock.BasicEntity; +import org.apache.brooklyn.util.time.Duration; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class YamlRollingTimeWindowMeanEnricherTest { + + AbstractApplication app; + + BasicEntity producer; + + AttributeSensor<Integer> intSensor; + AttributeSensor<Double> avgSensor, deltaSensor; + + Duration timePeriod = Duration.ONE_SECOND; + + YamlTimeWeightedDeltaEnricher<Double> delta; + YamlRollingTimeWindowMeanEnricher<Double> averager; + + ConfidenceQualifiedNumber average; + SubscriptionContext subscription; + + @SuppressWarnings("unchecked") + @BeforeMethod + public void before() { + app = new AbstractApplication() {}; + Entities.startManagement(app); + producer = app.addChild(EntitySpec.create(BasicEntity.class)); + + intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor"); + deltaSensor = new BasicAttributeSensor<Double>(Double.class, "delta sensor"); + avgSensor = new BasicAttributeSensor<Double>(Double.class, "avg sensor"); + + delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class) + .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer) + .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor) + .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor)); + + averager = producer.addEnricher(EnricherSpec.create(YamlRollingTimeWindowMeanEnricher.class) + .configure(YamlRollingTimeWindowMeanEnricher.PRODUCER, producer) + .configure(YamlRollingTimeWindowMeanEnricher.SOURCE_SENSOR, deltaSensor) + .configure(YamlRollingTimeWindowMeanEnricher.TARGET_SENSOR, avgSensor) + .configure(YamlRollingTimeWindowMeanEnricher.WINDOW_DURATION, timePeriod)); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + if (app != null) Entities.destroyAll(app.getManagementContext()); + } + + @Test + public void testDefaultAverageWhenEmpty() { + ConfidenceQualifiedNumber average = averager.getAverage(0, 0); + assertEquals(average.value, 0d); + assertEquals(average.confidence, 0.0d); + } + + protected BasicSensorEvent<Integer> newIntSensorEvent(int value, long timestamp) { + return new BasicSensorEvent<Integer>(intSensor, producer, value, timestamp); + } + protected BasicSensorEvent<Double> newDeltaSensorEvent(double value, long timestamp) { + return new BasicSensorEvent<Double>(deltaSensor, producer, value, timestamp); + } + + @Test + public void testNoRecentValuesAverage() { + averager.onEvent(newDeltaSensorEvent(10, 0)); + average = averager.getAverage(timePeriod.toMilliseconds()+1000, 0); + assertEquals(average.value, 10d); + assertEquals(average.confidence, 0d); + } + + @Test + public void testNoRecentValuesUsesLastForAverage() { + averager.onEvent(newDeltaSensorEvent(10, 0)); + averager.onEvent(newDeltaSensorEvent(20, 10)); + average = averager.getAverage(timePeriod.toMilliseconds()+1000, 0); + assertEquals(average.value, 20d); + assertEquals(average.confidence, 0d); + } + + @Test + public void testSingleValueTimeAverage() { + averager.onEvent(newDeltaSensorEvent(10, 1000)); + average = averager.getAverage(1000, 0); + assertEquals(average.confidence, 0d); + } + + @Test + public void testTwoValueAverageForPeriod() { + averager.onEvent(newDeltaSensorEvent(10, 1000)); + averager.onEvent(newDeltaSensorEvent(10, 2000)); + average = averager.getAverage(2000, 0); + assertEquals(average.value, 10 /1d); + assertEquals(average.confidence, 1d); + } + + @Test + public void testMonospacedAverage() { + averager.onEvent(newDeltaSensorEvent(10, 1000)); + averager.onEvent(newDeltaSensorEvent(20, 1250)); + averager.onEvent(newDeltaSensorEvent(30, 1500)); + averager.onEvent(newDeltaSensorEvent(40, 1750)); + averager.onEvent(newDeltaSensorEvent(50, 2000)); + average = averager.getAverage(2000, 0); + assertEquals(average.value, (20+30+40+50)/4d); + assertEquals(average.confidence, 1d); + } + + @Test + public void testWeightedAverage() { + averager.onEvent(newDeltaSensorEvent(10, 1000)); + averager.onEvent(newDeltaSensorEvent(20, 1100)); + averager.onEvent(newDeltaSensorEvent(30, 1300)); + averager.onEvent(newDeltaSensorEvent(40, 1600)); + averager.onEvent(newDeltaSensorEvent(50, 2000)); + + average = averager.getAverage(2000, 0); + assertEquals(average.value, (20*0.1d)+(30*0.2d)+(40*0.3d)+(50*0.4d)); + assertEquals(average.confidence, 1d); + } + + @Test + public void testConfidenceDecay() { + averager.onEvent(newDeltaSensorEvent(10, 1000)); + averager.onEvent(newDeltaSensorEvent(20, 1250)); + averager.onEvent(newDeltaSensorEvent(30, 1500)); + averager.onEvent(newDeltaSensorEvent(40, 1750)); + averager.onEvent(newDeltaSensorEvent(50, 2000)); + + average = averager.getAverage(2250, 0); + assertEquals(average.value, (30+40+50)/3d); + assertEquals(average.confidence, 0.75d); + average = averager.getAverage(2500, 0); + assertEquals(average.value, (40+50)/2d); + assertEquals(average.confidence, 0.5d); + average = averager.getAverage(2750, 0); + assertEquals(average.value, 50d); + assertEquals(average.confidence, 0.25d); + average = averager.getAverage(3000, 0); + assertEquals(average.value, 50d); + assertEquals(average.confidence, 0d); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java new file mode 100644 index 0000000..41b75a7 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java @@ -0,0 +1,107 @@ +/* + * 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.enricher.stock; + +import static org.testng.Assert.assertEquals; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.SubscriptionContext; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.EnricherSpec; +import org.apache.brooklyn.core.entity.AbstractApplication; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.sensor.BasicAttributeSensor; +import org.apache.brooklyn.core.sensor.BasicSensorEvent; +import org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher; +import org.apache.brooklyn.entity.stock.BasicEntity; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class YamlTimeWeightedDeltaEnricherTest { + + AbstractApplication app; + + BasicEntity producer; + + AttributeSensor<Integer> intSensor; + AttributeSensor<Double> avgSensor, deltaSensor; + SubscriptionContext subscription; + + @BeforeMethod + public void before() { + app = new AbstractApplication() {}; + Entities.startManagement(app); + producer = app.addChild(EntitySpec.create(BasicEntity.class)); + + intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor"); + deltaSensor = new BasicAttributeSensor<Double>(Double.class, "delta sensor"); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + if (app != null) Entities.destroyAll(app.getManagementContext()); + } + + @Test + public void testMonospaceTimeWeightedDeltaEnricher() { + @SuppressWarnings("unchecked") + YamlTimeWeightedDeltaEnricher<Integer> delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class) + .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer) + .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor) + .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor)); + + delta.onEvent(newIntSensorEvent(0, 0)); + assertEquals(producer.getAttribute(deltaSensor), null); + delta.onEvent(newIntSensorEvent(0, 1000)); + assertEquals(producer.getAttribute(deltaSensor), 0d); + delta.onEvent(newIntSensorEvent(1, 2000)); + assertEquals(producer.getAttribute(deltaSensor), 1d); + delta.onEvent(newIntSensorEvent(3, 3000)); + assertEquals(producer.getAttribute(deltaSensor), 2d); + delta.onEvent(newIntSensorEvent(8, 4000)); + assertEquals(producer.getAttribute(deltaSensor), 5d); + } + + protected BasicSensorEvent<Integer> newIntSensorEvent(int value, long timestamp) { + return new BasicSensorEvent<Integer>(intSensor, producer, value, timestamp); + } + + @Test + public void testVariableTimeWeightedDeltaEnricher() { + @SuppressWarnings("unchecked") + YamlTimeWeightedDeltaEnricher<Integer> delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class) + .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer) + .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor) + .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor)); + + delta.onEvent(newIntSensorEvent(0, 0)); + delta.onEvent(newIntSensorEvent(0, 2000)); + assertEquals(producer.getAttribute(deltaSensor), 0d); + delta.onEvent(newIntSensorEvent(3, 5000)); + assertEquals(producer.getAttribute(deltaSensor), 1d); + delta.onEvent(newIntSensorEvent(7, 7000)); + assertEquals(producer.getAttribute(deltaSensor), 2d); + delta.onEvent(newIntSensorEvent(12, 7500)); + assertEquals(producer.getAttribute(deltaSensor), 10d); + delta.onEvent(newIntSensorEvent(15, 9500)); + assertEquals(producer.getAttribute(deltaSensor), 1.5d); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java deleted file mode 100644 index 04c183f..0000000 --- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.sensor.enricher; - -import static org.testng.Assert.assertEquals; - -import java.util.Map; - -import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.api.sensor.Enricher; -import org.apache.brooklyn.api.sensor.EnricherSpec; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.apache.brooklyn.core.entity.BrooklynConfigKeys; -import org.apache.brooklyn.core.entity.factory.ApplicationBuilder; -import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; -import org.apache.brooklyn.core.test.entity.TestApplication; -import org.apache.brooklyn.core.test.entity.TestApplicationNoEnrichersImpl; -import org.apache.brooklyn.sensor.enricher.AbstractEnricher; -import org.apache.brooklyn.util.collections.MutableSet; -import org.apache.brooklyn.util.core.flags.SetFromFlag; -import org.testng.Assert; -import org.testng.annotations.Test; - -import com.google.common.collect.Iterables; - -/** - * Test that enricher can be created and accessed, by construction and by spec - */ -public class BasicEnricherTest extends BrooklynAppUnitTestSupport { - - // TODO These tests are a copy of BasicPolicyTest, which is a code smell. - // However, the src/main/java code does not contain as much duplication. - - protected void setUpApp() { - EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class, TestApplicationNoEnrichersImpl.class) - .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution()); - app = ApplicationBuilder.newManagedApp(appSpec, mgmt); - } - - public static class MyEnricher extends AbstractEnricher { - @SetFromFlag("intKey") - public static final BasicConfigKey<Integer> INT_KEY = new BasicConfigKey<Integer>(Integer.class, "bkey", "b key"); - - @SetFromFlag("strKey") - public static final ConfigKey<String> STR_KEY = new BasicConfigKey<String>(String.class, "akey", "a key"); - public static final ConfigKey<Integer> INT_KEY_WITH_DEFAULT = new BasicConfigKey<Integer>(Integer.class, "ckey", "c key", 1); - public static final ConfigKey<String> STR_KEY_WITH_DEFAULT = new BasicConfigKey<String>(String.class, "strKey", "str key", "str key default"); - - MyEnricher(Map<?,?> flags) { - super(flags); - } - - public MyEnricher() { - super(); - } - } - - @Test - public void testAddInstance() throws Exception { - MyEnricher enricher = new MyEnricher(); - enricher.setDisplayName("Bob"); - enricher.config().set(MyEnricher.STR_KEY, "aval"); - enricher.config().set(MyEnricher.INT_KEY, 2); - app.addEnricher(enricher); - - assertEquals(enricher.getDisplayName(), "Bob"); - assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval"); - assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2); - } - - @Test - public void testAddSpec() throws Exception { - MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class) - .displayName("Bob") - .configure(MyEnricher.STR_KEY, "aval").configure(MyEnricher.INT_KEY, 2)); - - assertEquals(enricher.getDisplayName(), "Bob"); - assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval"); - assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2); - } - - @Test - public void testTagsFromSpec() throws Exception { - MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x")); - - assertEquals(enricher.tags().getTags(), MutableSet.of("x", 99)); - assertEquals(enricher.getUniqueTag(), "x"); - } - - @Test - public void testSameUniqueTagEnricherNotAddedTwice() throws Exception { - app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x")); - app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(94).uniqueTag("x")); - - assertEquals(app.getEnrichers().size(), 1); - // the more recent one should dominate - Enricher enricher = Iterables.getOnlyElement(app.getEnrichers()); - Assert.assertTrue(enricher.tags().containsTag(94)); - Assert.assertFalse(enricher.tags().containsTag(99)); - } - -}
