http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntityConfigTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityConfigTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityConfigTest.java new file mode 100644 index 0000000..2c58f66 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityConfigTest.java @@ -0,0 +1,178 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; +import org.apache.brooklyn.core.entity.AbstractEntity; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.entity.EntityInternal; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.apache.brooklyn.util.core.flags.SetFromFlag; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; + +public class EntityConfigTest { + + private ManagementContext managementContext; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + managementContext = LocalManagementContextForTests.newInstance(); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() { + if (managementContext != null) Entities.destroyAll(managementContext); + } + + @Test + public void testConfigBagContainsMatchesForConfigKeyName() throws Exception { + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure("myentity.myconfig", "myval1") + .configure("myentity.myconfigwithflagname", "myval2")); + + assertEquals(entity.getAllConfig(), ImmutableMap.of(MyEntity.MY_CONFIG, "myval1", MyEntity.MY_CONFIG_WITH_FLAGNAME, "myval2")); + assertEquals(entity.getAllConfigBag().getAllConfig(), ImmutableMap.of("myentity.myconfig", "myval1", "myentity.myconfigwithflagname", "myval2")); + assertEquals(entity.getLocalConfigBag().getAllConfig(), ImmutableMap.of("myentity.myconfig", "myval1", "myentity.myconfigwithflagname", "myval2")); + } + + @Test + public void testConfigBagContainsMatchesForFlagName() throws Exception { + // Prefers flag-name, over config-key's name + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure("myconfigflagname", "myval")); + + assertEquals(entity.getAllConfig(), ImmutableMap.of(MyEntity.MY_CONFIG_WITH_FLAGNAME, "myval")); + assertEquals(entity.getAllConfigBag().getAllConfig(), ImmutableMap.of("myentity.myconfigwithflagname", "myval")); + assertEquals(entity.getLocalConfigBag().getAllConfig(), ImmutableMap.of("myentity.myconfigwithflagname", "myval")); + } + + // TODO Which way round should it be?! + @Test(enabled=false) + public void testPrefersFlagNameOverConfigKeyName() throws Exception { + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure("myconfigflagname", "myval") + .configure("myentity.myconfigwithflagname", "shouldIgnoreAndPreferFlagName")); + + assertEquals(entity.getAllConfig(), ImmutableMap.of(MyEntity.MY_CONFIG_WITH_FLAGNAME, "myval")); + } + + @Test + public void testConfigBagContainsUnmatched() throws Exception { + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure("notThere", "notThereVal")); + + assertEquals(entity.getAllConfig(), ImmutableMap.of(ConfigKeys.newConfigKey(Object.class, "notThere"), "notThereVal")); + assertEquals(entity.getAllConfigBag().getAllConfig(), ImmutableMap.of("notThere", "notThereVal")); + assertEquals(entity.getLocalConfigBag().getAllConfig(), ImmutableMap.of("notThere", "notThereVal")); + } + + @Test + public void testChildConfigBagInheritsUnmatchedAtParent() throws Exception { + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure("mychildentity.myconfig", "myval1") + .configure("mychildconfigflagname", "myval2") + .configure("notThere", "notThereVal")); + + EntityInternal child = managementContext.getEntityManager().createEntity(EntitySpec.create(MyChildEntity.class) + .parent(entity)); + + assertEquals(child.getAllConfig(), ImmutableMap.of(MyChildEntity.MY_CHILD_CONFIG, "myval1", + ConfigKeys.newConfigKey(Object.class, "mychildconfigflagname"), "myval2", + ConfigKeys.newConfigKey(Object.class, "notThere"), "notThereVal")); + assertEquals(child.getAllConfigBag().getAllConfig(), ImmutableMap.of("mychildentity.myconfig", "myval1", "mychildconfigflagname", "myval2", "notThere", "notThereVal")); + assertEquals(child.getLocalConfigBag().getAllConfig(), ImmutableMap.of()); + } + + @Test + public void testChildInheritsFromParent() throws Exception { + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure("myentity.myconfig", "myval1")); + + EntityInternal child = managementContext.getEntityManager().createEntity(EntitySpec.create(MyChildEntity.class) + .parent(entity)); + + assertEquals(child.getAllConfig(), ImmutableMap.of(MyEntity.MY_CONFIG, "myval1")); + assertEquals(child.getAllConfigBag().getAllConfig(), ImmutableMap.of("myentity.myconfig", "myval1")); + assertEquals(child.getLocalConfigBag().getAllConfig(), ImmutableMap.of()); + } + + @Test + public void testChildCanOverrideConfigUsingKeyName() throws Exception { + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure("mychildentity.myconfigwithflagname", "myval") + .configure("notThere", "notThereVal")); + + EntityInternal child = managementContext.getEntityManager().createEntity(EntitySpec.create(MyChildEntity.class) + .parent(entity) + .configure("mychildentity.myconfigwithflagname", "overrideMyval") + .configure("notThere", "overrideNotThereVal")); + + assertEquals(child.getAllConfig(), ImmutableMap.of(MyChildEntity.MY_CHILD_CONFIG_WITH_FLAGNAME, "overrideMyval", + ConfigKeys.newConfigKey(Object.class, "notThere"), "overrideNotThereVal")); + assertEquals(child.getAllConfigBag().getAllConfig(), ImmutableMap.of("mychildentity.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal")); + assertEquals(child.getLocalConfigBag().getAllConfig(), ImmutableMap.of("mychildentity.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal")); + } + + @Test + public void testChildCanOverrideConfigUsingFlagName() throws Exception { + EntityInternal entity = managementContext.getEntityManager().createEntity(EntitySpec.create(MyEntity.class) + .configure(MyChildEntity.MY_CHILD_CONFIG_WITH_FLAGNAME, "myval")); + assertEquals(entity.getAllConfig(), ImmutableMap.of(MyChildEntity.MY_CHILD_CONFIG_WITH_FLAGNAME, "myval")); + + EntityInternal child = managementContext.getEntityManager().createEntity(EntitySpec.create(MyChildEntity.class) + .parent(entity) + .configure("mychildconfigflagname", "overrideMyval")); + + assertEquals(child.getAllConfig(), ImmutableMap.of(MyChildEntity.MY_CHILD_CONFIG_WITH_FLAGNAME, "overrideMyval")); + assertEquals(child.getAllConfigBag().getAllConfig(), ImmutableMap.of("mychildentity.myconfigwithflagname", "overrideMyval")); + assertEquals(child.getLocalConfigBag().getAllConfig(), ImmutableMap.of("mychildentity.myconfigwithflagname", "overrideMyval")); + } + + public static class MyEntity extends AbstractEntity { + public static final ConfigKey<String> MY_CONFIG = ConfigKeys.newStringConfigKey("myentity.myconfig"); + + @SetFromFlag("myconfigflagname") + public static final ConfigKey<String> MY_CONFIG_WITH_FLAGNAME = ConfigKeys.newStringConfigKey("myentity.myconfigwithflagname"); + + @Override + public void init() { + super.init(); + + // Just calling this to prove we can! When config() was changed to return BasicConfigurationSupport, + // it broke because BasicConfigurationSupport was private. + config().getLocalBag(); + } + } + + public static class MyChildEntity extends AbstractEntity { + public static final ConfigKey<String> MY_CHILD_CONFIG = ConfigKeys.newStringConfigKey("mychildentity.myconfig"); + + @SetFromFlag("mychildconfigflagname") + public static final ConfigKey<String> MY_CHILD_CONFIG_WITH_FLAGNAME = ConfigKeys.newStringConfigKey("mychildentity.myconfigwithflagname"); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntityFunctionsTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityFunctionsTest.java new file mode 100644 index 0000000..b120d98 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityFunctionsTest.java @@ -0,0 +1,77 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.core.entity.EntityFunctions; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; + +public class EntityFunctionsTest extends BrooklynAppUnitTestSupport { + + private TestEntity entity; + private Location loc; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("mydisplayname")); + loc = app.getManagementContext().getLocationRegistry().resolve("localhost"); + } + + @Test + public void testAttribute() throws Exception { + entity.setAttribute(TestEntity.NAME, "myname"); + assertEquals(EntityFunctions.attribute(TestEntity.NAME).apply(entity), "myname"); + assertNull(EntityFunctions.attribute(TestEntity.SEQUENCE).apply(entity)); + } + + @Test + public void testConfig() throws Exception { + entity.setConfig(TestEntity.CONF_NAME, "myname"); + assertEquals(EntityFunctions.config(TestEntity.CONF_NAME).apply(entity), "myname"); + assertNull(EntityFunctions.config(TestEntity.CONF_OBJECT).apply(entity)); + } + + @Test + public void testDisplayName() throws Exception { + assertEquals(EntityFunctions.displayName().apply(entity), "mydisplayname"); + } + + @Test + public void testId() throws Exception { + assertEquals(EntityFunctions.id().apply(entity), entity.getId()); + } + + @Test + public void testLocationMatching() throws Exception { + entity.addLocations(ImmutableList.of(loc)); + assertEquals(EntityFunctions.locationMatching(Predicates.alwaysTrue()).apply(entity), loc); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntityLocationsTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityLocationsTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityLocationsTest.java new file mode 100644 index 0000000..3aa68b6 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityLocationsTest.java @@ -0,0 +1,126 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.core.entity.AbstractEntity; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.test.Asserts; +import org.testng.Assert; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +public class EntityLocationsTest extends BrooklynAppUnitTestSupport { + + @Test + public void testDuplicateLocationOnlyAddedOnce() { + Location l = app.newSimulatedLocation(); + app.addLocations(Arrays.asList(l, l)); + app.addLocations(Arrays.asList(l, l)); + Assert.assertEquals(app.getLocations().size(), 1); + } + + @Test + public void testNotifiedOfAddAndRemoveLocations() throws Exception { + final Location l = app.newSimulatedLocation(); + final Location l2 = app.newSimulatedLocation(); + + final RecordingSensorEventListener<Object> addedEvents = new RecordingSensorEventListener<>(); + final RecordingSensorEventListener<Object> removedEvents = new RecordingSensorEventListener<>(); + app.subscribe(app, AbstractEntity.LOCATION_ADDED, addedEvents); + app.subscribe(app, AbstractEntity.LOCATION_REMOVED, removedEvents); + + // Add first location + app.addLocations(ImmutableList.of(l)); + + assertEventValuesEqualsEventually(addedEvents, ImmutableList.of(l)); + assertEventValuesEquals(removedEvents, ImmutableList.of()); + + // Add second location + app.addLocations(ImmutableList.of(l2)); + + assertEventValuesEqualsEventually(addedEvents, ImmutableList.of(l, l2)); + assertEventValuesEquals(removedEvents, ImmutableList.of()); + + // Remove first location + app.removeLocations(ImmutableList.of(l)); + + assertEventValuesEqualsEventually(removedEvents, ImmutableList.of(l)); + assertEventValuesEquals(addedEvents, ImmutableList.of(l, l2)); + + // Remove second location + app.removeLocations(ImmutableList.of(l2)); + + assertEventValuesEqualsEventually(removedEvents, ImmutableList.of(l, l2)); + assertEventValuesEquals(addedEvents, ImmutableList.of(l, l2)); + } + + @Test(groups="Integration") // because takes a second + public void testNotNotifiedDuplicateAddedLocations() throws Exception { + final Location l = app.newSimulatedLocation(); + + final RecordingSensorEventListener<Object> addedEvents = new RecordingSensorEventListener<>(); + final RecordingSensorEventListener<Object> removedEvents = new RecordingSensorEventListener<>(); + app.subscribe(app, AbstractEntity.LOCATION_ADDED, addedEvents); + app.subscribe(app, AbstractEntity.LOCATION_REMOVED, removedEvents); + + // Add first location + app.addLocations(ImmutableList.of(l, l)); + + assertEventValuesEqualsEventually(addedEvents, ImmutableList.of(l)); + assertEventValuesEquals(removedEvents, ImmutableList.of()); + + // Add second location + app.addLocations(ImmutableList.of(l)); + + assertEventValuesEqualsContinually(addedEvents, ImmutableList.of(l)); + assertEventValuesEquals(removedEvents, ImmutableList.of()); + } + + private void assertEventValuesEqualsEventually(final RecordingSensorEventListener<Object> listener, final List<?> expectedVals) { + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEventValuesEquals(listener, expectedVals); + }}); + } + + private void assertEventValuesEqualsContinually(final RecordingSensorEventListener<Object> listener, final List<?> expectedVals) { + Asserts.succeedsContinually(new Runnable() { + @Override public void run() { + assertEventValuesEquals(listener, expectedVals); + }}); + } + + private void assertEventValuesEquals(final RecordingSensorEventListener<Object> listener, final List<?> expectedVals) { + Iterable<SensorEvent<Object>> events = listener.getEvents(); + assertEquals(Iterables.size(events), expectedVals.size(), "events=" + events); + for (int i = 0; i < expectedVals.size(); i++) { + Object expectedVal = expectedVals.get(i); + assertEquals(Iterables.get(events, i).getValue(), expectedVal, "events=" + events); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntityPreManagementTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityPreManagementTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityPreManagementTest.java new file mode 100644 index 0000000..bc7ed14 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityPreManagementTest.java @@ -0,0 +1,146 @@ +/* + * 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.core.entity; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.brooklyn.api.entity.EntityLocal; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.EntityManager; +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.api.sensor.SensorEventListener; +import org.apache.brooklyn.core.entity.Attributes; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.entity.factory.ApplicationBuilder; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.apache.brooklyn.core.test.entity.TestApplication; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.policy.core.AbstractPolicy; +import org.apache.brooklyn.test.TestUtils; +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; + + +@SuppressWarnings({"rawtypes","unchecked"}) +public class EntityPreManagementTest { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(EntityPreManagementTest.class); + + private ManagementContext managementContext; + private EntityManager entityManager; + private TestApplication app; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + managementContext = new LocalManagementContextForTests(); + entityManager = managementContext.getEntityManager(); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + if (managementContext != null) Entities.destroyAll(managementContext); + } + + @Test + public void testSetSensorBeforeManaged() { + TestEntity e = entityManager.createEntity(EntitySpec.create(TestEntity.class)); + + e.setAttribute(Attributes.HOSTNAME, "martian.martian"); + Assert.assertEquals(e.getAttribute(Attributes.HOSTNAME), "martian.martian"); + + Assert.assertFalse(e.getManagementSupport().isManagementContextReal()); + } + + @Test + public void testAddPolicyToEntityBeforeManaged() { + TestEntity e = entityManager.createEntity(EntitySpec.create(TestEntity.class)); + final List events = new ArrayList(); + + e.addPolicy(new AbstractPolicy() { + @Override + public void setEntity(EntityLocal entity) { + super.setEntity(entity); + subscribe(entity, Attributes.HOSTNAME, new SensorEventListener() { + @Override + public void onEvent(SensorEvent event) { + events.add(event); + } + }); + } + }); + + e.setAttribute(Attributes.HOSTNAME, "martian.martian"); + Assert.assertEquals(e.getAttribute(Attributes.HOSTNAME), "martian.martian"); + + if (!events.isEmpty()) Assert.fail("Shouldn't have events yet: "+events); + Assert.assertFalse(e.getManagementSupport().isManagementContextReal()); + + TestApplication app = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext); + e.setParent(app); + Entities.manage(e); + + TestUtils.assertEventually(new Runnable() { + @Override + public void run() { + if (events.isEmpty()) Assert.fail("no events received"); + }}); + Assert.assertEquals(events.size(), 1, "Expected 1 event; got: "+events); + } + + @Test + public void testAddPolicyToApplicationBeforeManaged() { + app = entityManager.createEntity(EntitySpec.create(TestApplication.class)); + final List events = new ArrayList(); + + app.addPolicy(new AbstractPolicy() { + @Override + public void setEntity(EntityLocal entity) { + super.setEntity(entity); + subscribe(entity, Attributes.HOSTNAME, new SensorEventListener() { + @Override + public void onEvent(SensorEvent event) { + events.add(event); + } + }); + } + }); + + app.setAttribute(Attributes.HOSTNAME, "martian.martian"); + Assert.assertEquals(app.getAttribute(Attributes.HOSTNAME), "martian.martian"); + + if (!events.isEmpty()) Assert.fail("Shouldn't have events yet: "+events); + + Entities.startManagement(app, managementContext); + + TestUtils.assertEventually(new Runnable() { + @Override + public void run() { + if (events.isEmpty()) Assert.fail("no events received"); + }}); + Assert.assertEquals(events.size(), 1, "Expected 1 event; got: "+events); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntityPredicatesTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityPredicatesTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityPredicatesTest.java new file mode 100644 index 0000000..dbd2972 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityPredicatesTest.java @@ -0,0 +1,129 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.entity.EntityPredicates; +import org.apache.brooklyn.core.entity.trait.Changeable; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.entity.group.BasicGroup; +import org.apache.brooklyn.util.text.StringPredicates; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; + +public class EntityPredicatesTest extends BrooklynAppUnitTestSupport { + + private TestEntity entity; + private BasicGroup group; + private Location loc; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("mydisplayname")); + group = app.createAndManageChild(EntitySpec.create(BasicGroup.class)); + loc = app.getManagementContext().getLocationRegistry().resolve("localhost"); + } + + @Test + public void testApplicationIdEqualTo() throws Exception { + assertTrue(EntityPredicates.applicationIdEqualTo(app.getId()).apply(entity)); + assertFalse(EntityPredicates.applicationIdEqualTo("wrongid").apply(entity)); + } + + @Test + public void testIdEqualTo() throws Exception { + assertTrue(EntityPredicates.idEqualTo(entity.getId()).apply(entity)); + assertFalse(EntityPredicates.idEqualTo("wrongid").apply(entity)); + } + + @Test + public void testAttributeEqualTo() throws Exception { + entity.setAttribute(TestEntity.NAME, "myname"); + assertTrue(EntityPredicates.attributeEqualTo(TestEntity.NAME, "myname").apply(entity)); + assertFalse(EntityPredicates.attributeEqualTo(TestEntity.NAME, "wrongname").apply(entity)); + } + + @Test + public void testConfigEqualTo() throws Exception { + entity.setConfig(TestEntity.CONF_NAME, "myname"); + assertTrue(EntityPredicates.configEqualTo(TestEntity.CONF_NAME, "myname").apply(entity)); + assertFalse(EntityPredicates.configEqualTo(TestEntity.CONF_NAME, "wrongname").apply(entity)); + } + + @Test + public void testDisplayNameEqualTo() throws Exception { + assertTrue(EntityPredicates.displayNameEqualTo("mydisplayname").apply(entity)); + assertFalse(EntityPredicates.displayNameEqualTo("wrongname").apply(entity)); + } + + @Test + public void testDisplayNameSatisfies() throws Exception { + assertTrue(EntityPredicates.displayNameSatisfies(StringPredicates.matchesRegex("myd.*me")).apply(entity)); + assertFalse(EntityPredicates.applicationIdEqualTo("wrongname").apply(entity)); + } + + @Test + public void testIsChildOf() throws Exception { + assertTrue(EntityPredicates.isChildOf(app).apply(entity)); + assertFalse(EntityPredicates.isChildOf(entity).apply(entity)); + assertFalse(EntityPredicates.isChildOf(entity).apply(app)); + } + + @Test + public void testIsMemberOf() throws Exception { + group.addMember(entity); + assertTrue(EntityPredicates.isMemberOf(group).apply(entity)); + assertFalse(EntityPredicates.isMemberOf(group).apply(app)); + assertFalse(EntityPredicates.isMemberOf(group).apply(group)); + } + + @Test + public void testManaged() throws Exception { + assertTrue(EntityPredicates.isManaged().apply(entity)); + Entities.unmanage(entity); + assertFalse(EntityPredicates.isManaged().apply(entity)); + } + + @Test + public void testWithLocation() throws Exception { + entity.addLocations(ImmutableList.of(loc)); + assertTrue(EntityPredicates.locationsIncludes(loc).apply(entity)); + assertFalse(EntityPredicates.locationsIncludes(loc).apply(app)); + } + + @Test + public void testHasInterfaceMatching() throws Exception { + assertTrue(EntityPredicates.hasInterfaceMatching(".*").apply(entity)); + assertTrue(EntityPredicates.hasInterfaceMatching(".*TestEntity").apply(entity)); + assertFalse(EntityPredicates.hasInterfaceMatching(".*TestEntity").apply(group)); + assertTrue(EntityPredicates.hasInterfaceMatching(Changeable.class.getName()).apply(group)); + assertTrue(EntityPredicates.hasInterfaceMatching(".*C.*able").apply(group)); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntityRegistrationTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityRegistrationTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityRegistrationTest.java new file mode 100644 index 0000000..018b82c --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityRegistrationTest.java @@ -0,0 +1,102 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; + +import java.util.Collection; +import java.util.List; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.api.sensor.SensorEventListener; +import org.apache.brooklyn.core.entity.AbstractEntity; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.test.Asserts; +import org.apache.brooklyn.util.collections.MutableMap; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; + +public class EntityRegistrationTest extends BrooklynAppUnitTestSupport { + + private static final int TIMEOUT_MS = 10*1000; + + private TestEntity entity; + private TestEntity entity2; + + private List<Entity> added; + private List<Entity> removed; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + + added = Lists.newCopyOnWriteArrayList(); + removed = Lists.newCopyOnWriteArrayList(); + + app.subscribe(app, AbstractEntity.CHILD_ADDED, new SensorEventListener<Entity>() { + @Override public void onEvent(SensorEvent<Entity> event) { + added.add(event.getValue()); + }}); + app.subscribe(app, AbstractEntity.CHILD_REMOVED, new SensorEventListener<Entity>() { + @Override public void onEvent(SensorEvent<Entity> event) { + removed.add(event.getValue()); + }}); + } + + @Test + public void testAddAndRemoveChildrenEmitsEvent() { + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + assertCollectionEquals(app.getChildren(), ImmutableList.of(entity)); + assertEqualsEventually(added, ImmutableList.of(entity)); + + entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + assertCollectionEquals(app.getChildren(), ImmutableList.of(entity, entity2)); + assertEqualsEventually(added, ImmutableList.of(entity, entity2)); + + entity.removeChild(entity); + assertCollectionEquals(app.getChildren(), ImmutableList.of(entity2)); + assertEqualsEventually(removed, ImmutableList.of(entity)); + + Entities.unmanage(entity2); + assertCollectionEquals(app.getChildren(), ImmutableList.of()); + assertEqualsEventually(removed, ImmutableList.of(entity, entity2)); + } + + private <T> void assertEqualsEventually(final T actual, final T expected) { + Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() { + @Override public void run() { + assertEquals(actual, expected, "actual="+actual); + }}); + } + + // Ignores order of vals in collection, but asserts each same size and same elements + private <T> void assertCollectionEquals(Collection<?> actual, Collection<?> expected) { + assertEquals(ImmutableSet.copyOf(actual), ImmutableSet.copyOf(expected), "actual="+actual); + assertEquals(actual.size(), expected.size(), "actual="+actual); + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntitySetFromFlagTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySetFromFlagTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySetFromFlagTest.java new file mode 100644 index 0000000..d60c290 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySetFromFlagTest.java @@ -0,0 +1,213 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; + +import java.util.Map; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.location.PortRange; +import org.apache.brooklyn.core.entity.AbstractEntity; +import org.testng.annotations.Test; +import org.apache.brooklyn.location.core.PortRanges; +import org.apache.brooklyn.util.collections.MutableMap; +import org.apache.brooklyn.util.core.flags.SetFromFlag; + +public class EntitySetFromFlagTest { + + @Test + public void testSetFromFlagUsingFieldName() { + MyEntity entity = new MyEntity(MutableMap.of("str1", "myval")); + assertEquals(entity.str1, "myval"); + } + + @Test + public void testSetFromFlagUsingOverridenName() { + MyEntity entity = new MyEntity(MutableMap.of("altStr2", "myval")); + assertEquals(entity.str2, "myval"); + } + + @Test + public void testSetFromFlagWhenNoDefaultIsNull() { + MyEntity entity = new MyEntity(); + assertEquals(entity.str1, null); + } + + @Test + public void testSetFromFlagUsesDefault() { + MyEntity entity = new MyEntity(); + assertEquals(entity.str3, "default str3"); + } + + @Test + public void testSetFromFlagOverridingDefault() { + MyEntity entity = new MyEntity(MutableMap.of("str3", "overridden str3")); + assertEquals(entity.str3, "overridden str3"); + } + + @Test + public void testSetFromFlagCastsPrimitives() { + MyEntity entity = new MyEntity(MutableMap.of("double1", 1f)); + assertEquals(entity.double1, 1d); + } + + @Test + public void testSetFromFlagCastsDefault() { + MyEntity entity = new MyEntity(); + assertEquals(entity.byte1, (byte)1); + assertEquals(entity.short1, (short)2); + assertEquals(entity.int1, 3); + assertEquals(entity.long1, 4l); + assertEquals(entity.float1, 5f); + assertEquals(entity.double1, 6d); + assertEquals(entity.char1, 'a'); + assertEquals(entity.bool1, true); + + assertEquals(entity.byte2, Byte.valueOf((byte)1)); + assertEquals(entity.short2, Short.valueOf((short)2)); + assertEquals(entity.int2, Integer.valueOf(3)); + assertEquals(entity.long2, Long.valueOf(4l)); + assertEquals(entity.float2, Float.valueOf(5f)); + assertEquals(entity.double2, Double.valueOf(6d)); + assertEquals(entity.char2, Character.valueOf('a')); + assertEquals(entity.bool2, Boolean.TRUE); + } + + @Test + public void testSetFromFlagCoercesDefaultToPortRange() { + MyEntity entity = new MyEntity(); + assertEquals(entity.portRange1, PortRanges.fromInteger(1234)); + } + + @Test + public void testSetFromFlagCoercesStringValueToPortRange() { + MyEntity entity = new MyEntity(MutableMap.of("portRange1", "1-3")); + assertEquals(entity.portRange1, new PortRanges.LinearPortRange(1, 3)); + } + + @Test + public void testSetFromFlagCoercesStringValueToInt() { + MyEntity entity = new MyEntity(MutableMap.of("int1", "123")); + assertEquals(entity.int1, 123); + } + + @Test + public void testSetIconUrl() { + MyEntity entity = new MyEntity(MutableMap.of("iconUrl", "/img/myicon.gif")); + assertEquals(entity.getIconUrl(), "/img/myicon.gif"); + } + + @Test(expectedExceptions=IllegalArgumentException.class) + public void testFailsFastOnInvalidCoercion() {; + new MyEntity(MutableMap.of("int1", "thisisnotanint")); + } + + // Fails because configure being called from inside constructor; so field is set after configure called + @Test(enabled=false) + public void testSetFromFlagWithFieldThatIsExplicitySet() { + MyEntity entity = new MyEntity(MutableMap.of("str4", "myval")); + assertEquals(entity.str4, "myval"); + + MyEntity entity2 = new MyEntity(); + assertEquals(entity2.str4, "explicit str4"); + } + + private static class MyEntity extends AbstractEntity { + + @SetFromFlag(defaultVal="1234") + PortRange portRange1; + + @SetFromFlag + String str1; + + @SetFromFlag("altStr2") + String str2; + + @SetFromFlag(defaultVal="default str3") + String str3; + + @SetFromFlag + String str4 = "explicit str4"; + + @SetFromFlag(defaultVal="1") + byte byte1; + + @SetFromFlag(defaultVal="2") + short short1; + + @SetFromFlag(defaultVal="3") + int int1; + + @SetFromFlag(defaultVal="4") + long long1; + + @SetFromFlag(defaultVal="5") + float float1; + + @SetFromFlag(defaultVal="6") + double double1; + + @SetFromFlag(defaultVal="a") + char char1; + + @SetFromFlag(defaultVal="true") + boolean bool1; + + @SetFromFlag(defaultVal="1") + Byte byte2; + + @SetFromFlag(defaultVal="2") + Short short2; + + @SetFromFlag(defaultVal="3") + Integer int2; + + @SetFromFlag(defaultVal="4") + Long long2; + + @SetFromFlag(defaultVal="5") + Float float2; + + @SetFromFlag(defaultVal="6") + Double double2; + + @SetFromFlag(defaultVal="a") + Character char2; + + @SetFromFlag(defaultVal="true") + Boolean bool2; + + MyEntity() { + super(MutableMap.of(), null); + } + + MyEntity(Map flags) { + super(flags, null); + } + + MyEntity(Entity parent) { + super(MutableMap.of(), parent); + } + + MyEntity(Map flags, Entity parent) { + super(flags, parent); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java new file mode 100644 index 0000000..af9eab0 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java @@ -0,0 +1,214 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.api.policy.PolicySpec; +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.config.ConfigKeys; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.core.test.entity.TestEntityImpl; +import org.apache.brooklyn.core.test.entity.TestEntityNoEnrichersImpl; +import org.apache.brooklyn.entity.group.BasicGroup; +import org.apache.brooklyn.policy.core.AbstractPolicy; +import org.apache.brooklyn.sensor.enricher.AbstractEnricher; +import org.apache.brooklyn.test.Asserts; +import org.apache.brooklyn.util.core.flags.SetFromFlag; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.apache.brooklyn.location.core.SimulatedLocation; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +public class EntitySpecTest extends BrooklynAppUnitTestSupport { + + private SimulatedLocation loc; + private TestEntity entity; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + loc = new SimulatedLocation(); + } + + @Test + public void testSetsConfig() throws Exception { + // TODO Test other permutations + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class) + .configure(TestEntity.CONF_NAME, "myname")); + assertEquals(entity.getConfig(TestEntity.CONF_NAME), "myname"); + } + + @Test + public void testAddsChildren() throws Exception { + entity = app.createAndManageChild( EntitySpec.create(TestEntity.class) + .displayName("child") + .child(EntitySpec.create(TestEntity.class) + .displayName("grandchild")) ); + + Entity child = Iterables.getOnlyElement(app.getChildren()); + assertEquals(child, entity); + assertEquals(child.getDisplayName(), "child"); + Entity grandchild = Iterables.getOnlyElement(child.getChildren()); + assertEquals(grandchild.getDisplayName(), "grandchild"); + } + + + @Test + public void testAddsPolicySpec() throws Exception { + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class) + .policy(PolicySpec.create(MyPolicy.class) + .displayName("mypolicyname") + .configure(MyPolicy.CONF1, "myconf1val") + .configure("myfield", "myfieldval"))); + + Policy policy = Iterables.getOnlyElement(entity.getPolicies()); + assertTrue(policy instanceof MyPolicy, "policy="+policy); + assertEquals(policy.getDisplayName(), "mypolicyname"); + assertEquals(policy.getConfig(MyPolicy.CONF1), "myconf1val"); + } + + @Test + public void testAddsPolicy() throws Exception { + MyPolicy policy = new MyPolicy(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class) + .policy(policy)); + + assertEquals(Iterables.getOnlyElement(entity.getPolicies()), policy); + } + + @Test + public void testAddsEnricherSpec() throws Exception { + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class, TestEntityNoEnrichersImpl.class) + .enricher(EnricherSpec.create(MyEnricher.class) + .displayName("myenrichername") + .configure(MyEnricher.CONF1, "myconf1val") + .configure("myfield", "myfieldval"))); + + Enricher enricher = Iterables.getOnlyElement(entity.getEnrichers()); + assertTrue(enricher instanceof MyEnricher, "enricher="+enricher); + assertEquals(enricher.getDisplayName(), "myenrichername"); + assertEquals(enricher.getConfig(MyEnricher.CONF1), "myconf1val"); + } + + @Test + public void testAddsEnricher() throws Exception { + MyEnricher enricher = new MyEnricher(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class, TestEntityNoEnrichersImpl.class) + .enricher(enricher)); + + assertEquals(Iterables.getOnlyElement(entity.getEnrichers()), enricher); + } + + @Test + public void testAddsMembers() throws Exception { + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class) + .member(entity)); + + Asserts.assertEqualsIgnoringOrder(group.getMembers(), ImmutableSet.of(entity)); + Asserts.assertEqualsIgnoringOrder(entity.getGroups(), ImmutableSet.of(group)); + } + + @Test + public void testAddsGroups() throws Exception { + BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class)); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class) + .group(group)); + + Asserts.assertEqualsIgnoringOrder(group.getMembers(), ImmutableSet.of(entity)); + Asserts.assertEqualsIgnoringOrder(entity.getGroups(), ImmutableSet.of(group)); + } + + @Test + public void testCallsConfigureAfterConstruction() throws Exception { + AbstractEntityLegacyTest.MyEntity entity = app.createAndManageChild(EntitySpec.create(AbstractEntityLegacyTest.MyEntity.class)); + + assertEquals(entity.getConfigureCount(), 1); + assertEquals(entity.getConfigureDuringConstructionCount(), 0); + } + + @Test + public void testDisplayNameUsesDefault() throws Exception { + TestEntity entity = app.addChild(EntitySpec.create(TestEntity.class)); + + assertTrue(entity.getDisplayName().startsWith("TestEntity:"+entity.getId().substring(0,4)), "displayName="+entity.getDisplayName()); + } + + @Test + public void testDisplayNameUsesCustom() throws Exception { + TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("entityname")); + + assertEquals(entity.getDisplayName(), "entityname"); + } + + @Test + public void testDisplayNameUsesOverriddenDefault() throws Exception { + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class) + .impl(TestEntityWithDefaultNameImpl.class) + .configure(TestEntityWithDefaultNameImpl.DEFAULT_NAME, "myOverriddenDefaultName")); + assertEquals(entity.getDisplayName(), "myOverriddenDefaultName"); + } + + @Test + public void testDisplayNameUsesCustomWhenOverriddenDefault() throws Exception { + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class) + .impl(TestEntityWithDefaultNameImpl.class) + .configure(TestEntityWithDefaultNameImpl.DEFAULT_NAME, "myOverriddenDefaultName") + .displayName("myEntityName")); + assertEquals(entity.getDisplayName(), "myEntityName"); + } + + public static class TestEntityWithDefaultNameImpl extends TestEntityImpl { + public static final ConfigKey<String> DEFAULT_NAME = ConfigKeys.newStringConfigKey("defaultName"); + + @Override + public void init() { + super.init(); + if (getConfig(DEFAULT_NAME) != null) setDefaultDisplayName(getConfig(DEFAULT_NAME)); + } + } + + public static class MyPolicy extends AbstractPolicy { + public static final BasicConfigKey<String> CONF1 = new BasicConfigKey<String>(String.class, "testpolicy.conf1", "my descr, conf1", "defaultval1"); + public static final BasicConfigKey<Integer> CONF2 = new BasicConfigKey<Integer>(Integer.class, "testpolicy.conf2", "my descr, conf2", 2); + + @SetFromFlag + public String myfield; + } + + public static class MyEnricher extends AbstractEnricher { + public static final BasicConfigKey<String> CONF1 = new BasicConfigKey<String>(String.class, "testenricher.conf1", "my descr, conf1", "defaultval1"); + public static final BasicConfigKey<Integer> CONF2 = new BasicConfigKey<Integer>(Integer.class, "testenricher.conf2", "my descr, conf2", 2); + + @SetFromFlag + public String myfield; + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java new file mode 100644 index 0000000..0abb2fc --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java @@ -0,0 +1,242 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; + +import org.apache.brooklyn.api.entity.EntityLocal; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.SubscriptionHandle; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.test.entity.TestApplication; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.entity.group.BasicGroup; +import org.apache.brooklyn.sensor.core.BasicSensorEvent; +import org.apache.brooklyn.test.Asserts; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.apache.brooklyn.location.core.SimulatedLocation; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +public class EntitySubscriptionTest { + + // TODO Duplication between this and PolicySubscriptionTest + + private SimulatedLocation loc; + private TestApplication app; + private TestEntity entity; + private TestEntity observedEntity; + private BasicGroup observedGroup; + private TestEntity observedChildEntity; + private TestEntity observedMemberEntity; + private TestEntity otherEntity; + private RecordingSensorEventListener<Object> listener; + + @BeforeMethod(alwaysRun=true) + public void setUp() { + app = TestApplication.Factory.newManagedInstanceForTests(); + loc = app.newSimulatedLocation(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + observedEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + observedChildEntity = observedEntity.createAndManageChild(EntitySpec.create(TestEntity.class)); + + observedGroup = app.createAndManageChild(EntitySpec.create(BasicGroup.class)); + observedMemberEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + observedGroup.addMember(observedMemberEntity); + + otherEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + + listener = new RecordingSensorEventListener<>(); + + app.start(ImmutableList.of(loc)); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() { + if (app != null) Entities.destroyAll(app.getManagementContext()); + } + + @Test + public void testSubscriptionReceivesEvents() { + entity.subscribe(observedEntity, TestEntity.SEQUENCE, listener); + entity.subscribe(observedEntity, TestEntity.NAME, listener); + entity.subscribe(observedEntity, TestEntity.MY_NOTIF, listener); + + otherEntity.setAttribute(TestEntity.SEQUENCE, 123); + observedEntity.setAttribute(TestEntity.SEQUENCE, 123); + observedEntity.setAttribute(TestEntity.NAME, "myname"); + observedEntity.emit(TestEntity.MY_NOTIF, 456); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedEntity, 123), + new BasicSensorEvent<String>(TestEntity.NAME, observedEntity, "myname"), + new BasicSensorEvent<Integer>(TestEntity.MY_NOTIF, observedEntity, 456))); + }}); + } + + @Test + public void testSubscriptionToAllReceivesEvents() { + entity.subscribe(null, TestEntity.SEQUENCE, listener); + + observedEntity.setAttribute(TestEntity.SEQUENCE, 123); + otherEntity.setAttribute(TestEntity.SEQUENCE, 456); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedEntity, 123), + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, otherEntity, 456))); + }}); + } + + @Test + public void testSubscribeToChildrenReceivesEvents() { + entity.subscribeToChildren(observedEntity, TestEntity.SEQUENCE, listener); + + observedChildEntity.setAttribute(TestEntity.SEQUENCE, 123); + observedEntity.setAttribute(TestEntity.SEQUENCE, 456); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedChildEntity, 123))); + }}); + } + + @Test + public void testSubscribeToChildrenReceivesEventsForDynamicallyAddedChildren() { + entity.subscribeToChildren(observedEntity, TestEntity.SEQUENCE, listener); + + final TestEntity observedChildEntity2 = observedEntity.createAndManageChild(EntitySpec.create(TestEntity.class)); + observedChildEntity2.setAttribute(TestEntity.SEQUENCE, 123); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedChildEntity2, 123))); + }}); + } + + @Test + public void testSubscribeToMembersReceivesEvents() { + entity.subscribeToMembers(observedGroup, TestEntity.SEQUENCE, listener); + + observedMemberEntity.setAttribute(TestEntity.SEQUENCE, 123); + ((EntityLocal)observedGroup).setAttribute(TestEntity.SEQUENCE, 456); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedMemberEntity, 123))); + }}); + } + + @Test + public void testSubscribeToMembersReceivesEventsForDynamicallyAddedMembers() { + entity.subscribeToMembers(observedGroup, TestEntity.SEQUENCE, listener); + + final TestEntity observedMemberEntity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + observedGroup.addMember(observedMemberEntity2); + observedMemberEntity2.setAttribute(TestEntity.SEQUENCE, 123); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedMemberEntity2, 123))); + }}); + } + + @Test(groups="Integration") + public void testSubscribeToMembersIgnoresEventsForDynamicallyRemovedMembers() { + entity.subscribeToMembers(observedGroup, TestEntity.SEQUENCE, listener); + + observedGroup.removeMember(observedMemberEntity); + + observedMemberEntity.setAttribute(TestEntity.SEQUENCE, 123); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of()); + }}); + } + + @Test + public void testUnsubscribeRemovesAllSubscriptionsForThatEntity() { + entity.subscribe(observedEntity, TestEntity.SEQUENCE, listener); + entity.subscribe(observedEntity, TestEntity.NAME, listener); + entity.subscribe(observedEntity, TestEntity.MY_NOTIF, listener); + entity.subscribe(otherEntity, TestEntity.SEQUENCE, listener); + entity.unsubscribe(observedEntity); + + observedEntity.setAttribute(TestEntity.SEQUENCE, 123); + observedEntity.setAttribute(TestEntity.NAME, "myname"); + observedEntity.emit(TestEntity.MY_NOTIF, 123); + otherEntity.setAttribute(TestEntity.SEQUENCE, 456); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, otherEntity, 456))); + }}); + } + + @Test + public void testUnsubscribeUsingHandleStopsEvents() { + SubscriptionHandle handle1 = entity.subscribe(observedEntity, TestEntity.SEQUENCE, listener); + SubscriptionHandle handle2 = entity.subscribe(observedEntity, TestEntity.NAME, listener); + SubscriptionHandle handle3 = entity.subscribe(otherEntity, TestEntity.SEQUENCE, listener); + + entity.unsubscribe(observedEntity, handle2); + + observedEntity.setAttribute(TestEntity.SEQUENCE, 123); + observedEntity.setAttribute(TestEntity.NAME, "myname"); + otherEntity.setAttribute(TestEntity.SEQUENCE, 456); + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(listener.getEvents(), ImmutableList.of( + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, observedEntity, 123), + new BasicSensorEvent<Integer>(TestEntity.SEQUENCE, otherEntity, 456))); + }}); + } + + @Test + public void testSubscriptionReceivesEventsInOrder() { + final int NUM_EVENTS = 100; + entity.subscribe(observedEntity, TestEntity.MY_NOTIF, listener); + + for (int i = 0; i < NUM_EVENTS; i++) { + observedEntity.emit(TestEntity.MY_NOTIF, i); + } + + Asserts.succeedsEventually(new Runnable() { + @Override public void run() { + assertEquals(Iterables.size(listener.getEvents()), NUM_EVENTS); + for (int i = 0; i < NUM_EVENTS; i++) { + assertEquals(Iterables.get(listener.getEvents(), i).getValue(), i); + } + }}); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntitySuppliersTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySuppliersTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySuppliersTest.java new file mode 100644 index 0000000..1ed5b26 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySuppliersTest.java @@ -0,0 +1,70 @@ +/* + * 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.core.entity; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.api.location.MachineProvisioningLocation; +import org.apache.brooklyn.core.entity.EntitySuppliers; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.apache.brooklyn.location.ssh.SshMachineLocation; + +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class EntitySuppliersTest extends BrooklynAppUnitTestSupport { + + private TestEntity entity; + private Location loc; + private SshMachineLocation machine; + + @BeforeMethod(alwaysRun=true) + @SuppressWarnings("unchecked") + @Override + public void setUp() throws Exception { + super.setUp(); + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("mydisplayname")); + loc = app.getManagementContext().getLocationRegistry().resolve("localhost"); + machine = ((MachineProvisioningLocation<SshMachineLocation>)loc).obtain(ImmutableMap.of()); + } + + @Test + public void testUniqueSshMachineLocation() throws Exception { + entity.addLocations(ImmutableList.of(machine)); + assertEquals(EntitySuppliers.uniqueSshMachineLocation(entity).get(), machine); + } + + @Test + public void testUniqueSshMachineLocationWhenNoLocation() throws Exception { + Supplier<SshMachineLocation> supplier = EntitySuppliers.uniqueSshMachineLocation(entity); + try { + supplier.get(); + fail(); + } catch (IllegalStateException e) { + // expected: success + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java new file mode 100644 index 0000000..c01c5c9 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java @@ -0,0 +1,284 @@ +/* + * 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.core.entity; + +import static org.apache.brooklyn.core.entity.AbstractEntity.CHILD_ADDED; +import static org.apache.brooklyn.core.entity.AbstractEntity.CHILD_REMOVED; +import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_ADDED; +import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_CHANGED; +import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_REMOVED; +import static org.apache.brooklyn.core.entity.AbstractEntity.GROUP_ADDED; +import static org.apache.brooklyn.core.entity.AbstractEntity.GROUP_REMOVED; +import static org.apache.brooklyn.core.entity.AbstractEntity.LOCATION_ADDED; +import static org.apache.brooklyn.core.entity.AbstractEntity.LOCATION_REMOVED; +import static org.apache.brooklyn.core.entity.AbstractEntity.POLICY_ADDED; +import static org.apache.brooklyn.core.entity.AbstractEntity.POLICY_REMOVED; +import static org.apache.brooklyn.core.entity.AbstractEntity.SENSOR_ADDED; +import static org.apache.brooklyn.core.entity.AbstractEntity.SENSOR_REMOVED; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.util.List; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.api.effector.Effector; +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.Sensor; +import org.apache.brooklyn.core.entity.AbstractEntity; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.entity.EntityInternal; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.core.test.entity.TestEntityImpl; +import org.apache.brooklyn.effector.core.MethodEffector; +import org.apache.brooklyn.sensor.core.BasicSensorEvent; +import org.apache.brooklyn.sensor.core.Sensors; +import org.apache.brooklyn.test.Asserts; +import org.apache.brooklyn.util.collections.MutableSet; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +public class EntityTypeTest extends BrooklynAppUnitTestSupport { + private static final AttributeSensor<String> TEST_SENSOR = Sensors.newStringSensor("test.sensor"); + private EntityInternal entity; + private RecordingSensorEventListener<Sensor> listener; + + public final static Set<Sensor<?>> DEFAULT_SENSORS = ImmutableSet.<Sensor<?>>of( + SENSOR_ADDED, SENSOR_REMOVED, + EFFECTOR_ADDED, EFFECTOR_REMOVED, EFFECTOR_CHANGED, + POLICY_ADDED, POLICY_REMOVED, + CHILD_ADDED, CHILD_REMOVED, + LOCATION_ADDED, LOCATION_REMOVED, + GROUP_ADDED, GROUP_REMOVED); + + public static class EmptyEntityForTesting extends AbstractEntity {} + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception{ + super.setUp(); + entity = (EntityInternal) app.createAndManageChild(EntitySpec.create(Entity.class, EmptyEntityForTesting.class)); + listener = new RecordingSensorEventListener<>(); + app.getSubscriptionContext().subscribe(entity, SENSOR_ADDED, listener); + app.getSubscriptionContext().subscribe(entity, SENSOR_REMOVED, listener); + } + + @Test + public void testGetName() throws Exception { + TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + assertEquals(entity2.getEntityType().getName(), TestEntity.class.getCanonicalName()); + } + + @Test + public void testGetSimpleName() throws Exception { + TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + assertEquals(entity2.getEntityType().getSimpleName(), TestEntity.class.getSimpleName()); + } + + @Test + public void testGetEffectors() throws Exception { + TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + Set<Effector<?>> effectors = entity2.getEntityType().getEffectors(); + + class MatchesNamePredicate implements Predicate<Effector<?>> { + private final String name; + public MatchesNamePredicate(String name) { + this.name = name; + } + @Override public boolean apply(@Nullable Effector<?> input) { + return name.equals(input.getName()); + } + }; + + assertNotNull(Iterables.find(effectors, new MatchesNamePredicate("myEffector")), null); + assertNotNull(Iterables.find(effectors, new MatchesNamePredicate("identityEffector")), null); + } + + @Test + public void testGetEffector() throws Exception { + TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + Effector<?> effector = entity2.getEntityType().getEffectorByName("myEffector").get(); + Effector<?> effector2 = entity2.getEntityType().getEffectorByName("identityEffector").get(); + assertEquals(effector.getName(), "myEffector"); + assertTrue(effector.getParameters().isEmpty(), "myEffector should have had no params, but had "+effector.getParameters()); + assertEquals(effector2.getName(), "identityEffector"); + assertEquals(effector2.getParameters().size(), 1, "identityEffector should have had one param, but had "+effector2.getParameters()); + assertEquals(Iterables.getOnlyElement(effector2.getParameters()).getName(), "arg", "identityEffector should have had 'arg' param, but had "+effector2.getParameters()); + } + + @Test + public void testGetEffectorDeprecated() throws Exception { + TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + Effector<?> effector = entity2.getEntityType().getEffectorByName("myEffector").get(); + Effector<?> effector2 = entity2.getEntityType().getEffectorByName("identityEffector").get(); + assertEquals(effector.getName(), "myEffector"); + assertEquals(effector2.getName(), "identityEffector"); + } + + @Test + public void testCustomSimpleName() throws Exception { + class CustomTypeNamedEntity extends AbstractEntity { + private final String typeName; + @SuppressWarnings("deprecation") + CustomTypeNamedEntity(Entity parent, String typeName) { + super(parent); + this.typeName = typeName; + } + @Override protected String getEntityTypeName() { + return typeName; + } + } + + CustomTypeNamedEntity entity2 = new CustomTypeNamedEntity(app, "a.b.with space"); + Entities.manage(entity2); + assertEquals(entity2.getEntityType().getSimpleName(), "with_space"); + + CustomTypeNamedEntity entity3 = new CustomTypeNamedEntity(app, "a.b.with$dollar"); + Entities.manage(entity3); + assertEquals(entity3.getEntityType().getSimpleName(), "with_dollar"); + + CustomTypeNamedEntity entity4 = new CustomTypeNamedEntity(app, "a.nothingafterdot."); + Entities.manage(entity4); + assertEquals(entity4.getEntityType().getSimpleName(), "a.nothingafterdot."); + } + + @Test + public void testGetSensors() throws Exception{ + assertEquals(entity.getEntityType().getSensors(), DEFAULT_SENSORS); + } + + protected <T> void assertEventuallyListenerEventsEqual(final List<T> sensorEvents) { + final RecordingSensorEventListener listener = this.listener; + Asserts.succeedsEventually(new Runnable() { + @Override + public void run() { + assertEquals(listener.getEvents(), sensorEvents); + } + }); + } + + @Test + public void testAddSensors() throws Exception{ + entity.getMutableEntityType().addSensor(TEST_SENSOR); + assertEquals(entity.getEntityType().getSensors(), + ImmutableSet.builder().addAll(DEFAULT_SENSORS).add(TEST_SENSOR).build()); + + assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(SENSOR_ADDED, entity, TEST_SENSOR))); + } + + @Test + public void testAddSensorValueThroughEntity() throws Exception{ + entity.setAttribute(TEST_SENSOR, "abc"); + assertEquals(entity.getEntityType().getSensors(), + ImmutableSet.builder().addAll(DEFAULT_SENSORS).add(TEST_SENSOR).build()); + + assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(SENSOR_ADDED, entity, TEST_SENSOR))); + } + + @Test + public void testRemoveSensorThroughEntity() throws Exception{ + entity.setAttribute(TEST_SENSOR, "abc"); + entity.removeAttribute(TEST_SENSOR); + assertFalse(entity.getEntityType().getSensors().contains(TEST_SENSOR), "sensors="+entity.getEntityType().getSensors()); + assertEquals(entity.getAttribute(TEST_SENSOR), null); + + assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(SENSOR_ADDED, entity, TEST_SENSOR), + BasicSensorEvent.ofUnchecked(SENSOR_REMOVED, entity, TEST_SENSOR))); + } + + @Test + public void testRemoveSensor() throws Exception { + entity.getMutableEntityType().removeSensor(SENSOR_ADDED); + assertEquals(entity.getEntityType().getSensors(), + MutableSet.builder().addAll(DEFAULT_SENSORS).remove(SENSOR_ADDED).build().asUnmodifiable()); + + assertEventuallyListenerEventsEqual(ImmutableList.of( + BasicSensorEvent.ofUnchecked(SENSOR_REMOVED, entity, SENSOR_ADDED))); + } + + @Test + public void testRemoveSensors() throws Exception { + entity.getMutableEntityType().removeSensor(SENSOR_ADDED.getName()); + entity.getMutableEntityType().removeSensor(POLICY_ADDED.getName()); + assertEquals(entity.getEntityType().getSensors(), + MutableSet.builder().addAll(DEFAULT_SENSORS).remove(SENSOR_ADDED).remove(POLICY_ADDED).build().asUnmodifiable()); + + final RecordingSensorEventListener<?> listener = this.listener; + Asserts.succeedsEventually(new Runnable() { + @Override + public void run() { + assertEquals(Iterables.size(listener.getEvents()), 2); + } + }); + assertEventuallyListenerEventsEqual(ImmutableList.of( + BasicSensorEvent.ofUnchecked(SENSOR_REMOVED, entity, SENSOR_ADDED), + BasicSensorEvent.ofUnchecked(SENSOR_REMOVED, entity, POLICY_ADDED))); + } + + @Test + public void testGetSensor() throws Exception { + Sensor<?> sensor = entity.getEntityType().getSensor("entity.sensor.added"); + assertEquals(sensor.getDescription(), "Sensor dynamically added to entity"); + assertEquals(sensor.getName(), "entity.sensor.added"); + + assertNull(entity.getEntityType().getSensor("does.not.exist")); + } + + @Test + public void testHasSensor() throws Exception { + assertTrue(entity.getEntityType().hasSensor("entity.sensor.added")); + assertFalse(entity.getEntityType().hasSensor("does.not.exist")); + } + + // Previously EntityDynamicType's constructor when passed `entity` during the entity's construction (!) + // would pass this to EntityDynamicType.findEffectors, which would do log.warn in some cirumstances, + // with entity.toString as part of the log message. But if the toString called getConfig() this would + // fail because we were still in the middle of constructing the entity.entityType! + @Test + public void testEntityDynamicTypeDoesNotCallToStringDuringConstruction() throws Exception { + entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).impl(EntityWithToStringAccessingConfig.class)); + entity.toString(); + } + + public static class EntityWithToStringAccessingConfig extends TestEntityImpl { + + // to cause warning to be logged: non-static constant + public final MethodEffector<Void> NON_STATIC_EFFECTOR = new MethodEffector<Void>(EntityWithToStringAccessingConfig.class, "nonStaticEffector"); + + public void nonStaticEffector() { + } + + @Override + public String toString() { + return super.toString() + getConfig(CONF_NAME); + } + } +}
