brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject [3/4] brooklyn-server git commit: Added test for SSH member tracking policy
Date Thu, 11 Aug 2016 13:59:19 GMT
Added test for SSH member tracking policy


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/40cd2436
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/40cd2436
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/40cd2436

Branch: refs/heads/master
Commit: 40cd24362c4e05ba7801221d4aa102f434a0afd3
Parents: 7eaba7c
Author: Andrew Donald Kennedy <andrew.kennedy@cloudsoftcorp.com>
Authored: Wed Aug 10 07:16:19 2016 +0100
Committer: Andrew Donald Kennedy <andrew.kennedy@cloudsoftcorp.com>
Committed: Wed Aug 10 22:50:39 2016 +0100

----------------------------------------------------------------------
 .../core/entity/internal/EntityConfigMap.java   |   2 +-
 .../SshCommandMembershipTrackingPolicy.java     |  31 +++--
 .../SshCommandMembershipTrackingPolicyTest.java | 121 +++++++++++++++++++
 3 files changed, 146 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/40cd2436/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
b/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
index c32ff8f..25d1561 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
@@ -132,7 +132,7 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
 
         // Get own value
         if (((ConfigKeySelfExtracting<T>)key).isSet(ownConfig)) {
-            Map<ConfigKey<?>, ?> ownCopy = null;
+            Map<ConfigKey<?>, ?> ownCopy;
             synchronized (ownConfig) {
                 ownCopy = MutableMap.copyOf(ownConfig);
             }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/40cd2436/core/src/main/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicy.java
b/core/src/main/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicy.java
index 2b8f012..bf899ba 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicy.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicy.java
@@ -18,19 +18,24 @@
  */
 package org.apache.brooklyn.entity.group;
 
+import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.CaseFormat;
+
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.config.MapConfigKey;
 import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
 import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
 import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.location.Locations;
 import org.apache.brooklyn.core.location.Machines;
 import org.apache.brooklyn.core.sensor.ssh.SshCommandSensor;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
@@ -45,11 +50,18 @@ import org.apache.brooklyn.util.text.Strings;
 /**
  * Policy which tracks membership of a group, and executes SSH commands
  * on MEMBER{ADDED,REMOVED} events, as well as SERVICE_UP {true,false} for those members.
+ * <p>
+ * Sets the environment variable {@code EVENT_TYPE} to the value of the {@link EventType}
+ * for the invocation, and {@code MEMBER_ID} to the ID of the entity that is being
+ * added, removed or updated.
  */
 public class SshCommandMembershipTrackingPolicy extends AbstractMembershipTrackingPolicy
{
 
     private static final Logger LOG = LoggerFactory.getLogger(SshCommandMembershipTrackingPolicy.class);
 
+    public static final String EVENT_TYPE = "EVENT_TYPE";
+    public static final String MEMBER_ID = "MEMBER_ID";
+
     public static final ConfigKey<String> EXECUTION_DIR = ConfigKeys.newStringConfigKey("executionDir",
"Directory where the command should run; "
         + "if not supplied, executes in the entity's run dir (or home dir if no run dir is
defined); "
         + "use '~' to always execute in the home dir, or 'custom-feed/' to execute in a custom-feed
dir relative to the run dir");
@@ -62,16 +74,17 @@ public class SshCommandMembershipTrackingPolicy extends AbstractMembershipTracki
      * Called when a member is updated or group membership changes.
      */
     @Override
-    protected void onEntityEvent(EventType type, Entity entity) {
-        LOG.trace("Event {} received for {} in {}", new Object[] { type, entity, getGroup()
});
+    protected void onEntityEvent(EventType type, Entity member) {
+        LOG.trace("Event {} received for {} in {}", new Object[] { type, member, getGroup()
});
         String command = config().get(UPDATE_COMMAND);
         if (Strings.isNonBlank(command)) {
-            execute(command);
+            execute(command, type.name(), member.getId());
         }
     }
 
-    public void execute(String command) {
-        Maybe<SshMachineLocation> machine = Machines.findUniqueMachineLocation(entity.getLocations(),
SshMachineLocation.class);
+    public void execute(String command, String type, String memberId) {
+        Collection<? extends Location> locations = Locations.getLocationsCheckingAncestors(entity.getLocations(),
entity);
+        Maybe<SshMachineLocation> machine = Machines.findUniqueMachineLocation(locations,
SshMachineLocation.class);
         if (machine.isAbsentOrNull()) {
             throw new IllegalStateException("No machine available to execute command");
         }
@@ -84,11 +97,15 @@ public class SshCommandMembershipTrackingPolicy extends AbstractMembershipTracki
         env.putAll(MutableMap.copyOf(entity.config().get(BrooklynConfigKeys.SHELL_ENVIRONMENT)));
         env.putAll(MutableMap.copyOf(config().get(BrooklynConfigKeys.SHELL_ENVIRONMENT)));
 
+        // Add variables describing this invocation
+        env.put(EVENT_TYPE, type);
+        env.put(MEMBER_ID, memberId);
+
         // Try to resolve the configuration in the env Map
         try {
             env = (Map<String, Object>) Tasks.resolveDeepValue(env, Object.class, ((EntityInternal)
entity).getExecutionContext());
         } catch (InterruptedException | ExecutionException e) {
-            Exceptions.propagateIfFatal(e);
+            throw Exceptions.propagate(e);
         }
 
         // Execute the command with the serialized environment strings
@@ -96,7 +113,7 @@ public class SshCommandMembershipTrackingPolicy extends AbstractMembershipTracki
         SshEffectorTasks.SshEffectorTaskFactory<String> task = SshEffectorTasks.ssh(sshCommand)
                 .machine(machine.get())
                 .requiringZeroAndReturningStdout()
-                .summary("group-membership-updated")
+                .summary("group-" + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN,
type))
                 .environmentVariables(serializer.serialize(env));
 
         String output = DynamicTasks.submit(task.newTask(), entity).getUnchecked();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/40cd2436/core/src/test/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicyTest.java
b/core/src/test/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicyTest.java
new file mode 100644
index 0000000..9b444e3
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/entity/group/SshCommandMembershipTrackingPolicyTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.entity.group;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.EntityManager;
+import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy.EventType;
+import org.apache.brooklyn.entity.stock.BasicStartable;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool;
+import org.apache.brooklyn.util.time.Duration;
+
+public class SshCommandMembershipTrackingPolicyTest extends BrooklynAppUnitTestSupport {
+
+    private SimulatedLocation loc;
+    private EntityManager entityManager;
+    private BasicGroup group;
+    private BasicStartable entity;
+    private LocationSpec<SshMachineLocation> machine;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        machine = LocationSpec.create(SshMachineLocation.class)
+                .configure("address", "1.2.3.4")
+                .configure("sshToolClass", RecordingSshTool.class.getName());
+        loc = mgmt.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
+        entityManager = app.getManagementContext().getEntityManager();
+
+        group = app.createAndManageChild(EntitySpec.create(BasicGroup.class)
+                .configure("childrenAsMembers", true));
+
+        entity = app.createAndManageChild(EntitySpec.create(BasicStartable.class).location(machine));
+        entity.policies().add(PolicySpec.create(SshCommandMembershipTrackingPolicy.class)
+                .configure("group", group)
+                .configure("shell.env.TEST", "test")
+                .configure("update.command", "echo ignored"));
+
+        app.start(ImmutableList.of(loc));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        RecordingSshTool.clear();
+    }
+
+    @Test
+    public void testCommandExecutedWithEnvironment() throws Exception {
+        TestEntity member = entityManager.createEntity(EntitySpec.create(TestEntity.class).parent(group));
+
+        assertExecSizeEventually(1);
+        assertEquals(RecordingSshTool.getLastExecCmd().commands, ImmutableList.of("echo ignored"));
+
+        Map<?, ?> env = RecordingSshTool.getLastExecCmd().env;
+        assertTrue(env.containsKey(SshCommandMembershipTrackingPolicy.EVENT_TYPE));
+        assertEquals(env.get(SshCommandMembershipTrackingPolicy.EVENT_TYPE), EventType.ENTITY_ADDED.name());
+        assertTrue(env.containsKey(SshCommandMembershipTrackingPolicy.MEMBER_ID));
+        assertEquals(env.get(SshCommandMembershipTrackingPolicy.MEMBER_ID), member.getId());
+        assertTrue(env.containsKey("TEST"));
+        assertEquals(env.get("TEST"), "test");
+
+        member.sensors().set(Startable.SERVICE_UP, true);
+        Duration.seconds(1).countdownTimer().waitForExpiry();
+
+        assertExecSizeEventually(2);
+        assertEquals(RecordingSshTool.getLastExecCmd().env.get(SshCommandMembershipTrackingPolicy.EVENT_TYPE),
EventType.ENTITY_CHANGE.name());
+
+        member.clearParent();
+
+        assertExecSizeEventually(3);
+        assertEquals(RecordingSshTool.getLastExecCmd().env.get(SshCommandMembershipTrackingPolicy.EVENT_TYPE),
EventType.ENTITY_REMOVED.name());
+    }
+
+    protected void assertExecSizeEventually(final int expectedSize) {
+        Asserts.succeedsEventually(new Runnable() {
+            @Override
+            public void run() {
+                assertEquals(RecordingSshTool.getExecCmds().size(), expectedSize);
+            }
+        });
+    }
+
+}


Mime
View raw message