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 2015/08/20 00:54:18 UTC
[30/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
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));
- }
-
-}