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/11/23 19:29:44 UTC
[15/20] incubator-brooklyn git commit: Fix location handling in
integration test and remove unnecessary classes.
Fix location handling in integration test and remove unnecessary classes.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/b2713ca4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/b2713ca4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/b2713ca4
Branch: refs/heads/master
Commit: b2713ca4d7382ff1057531a6ef92a8a038a59d39
Parents: 6017880
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Wed Nov 18 12:59:25 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Wed Nov 18 14:35:48 2015 +0000
----------------------------------------------------------------------
.../test/framework/SimpleShellCommand.java | 75 ------
.../test/framework/SimpleShellCommandImpl.java | 260 -------------------
...impleShellCommandLifecycleEffectorTasks.java | 57 ----
.../test/framework/SimpleShellCommandTest.java | 31 ++-
.../framework/SimpleShellCommandTestImpl.java | 199 ++++++++++++--
.../SimpleShellCommandIntegrationTest.java | 47 ++--
6 files changed, 236 insertions(+), 433 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b2713ca4/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommand.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommand.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommand.java
deleted file mode 100644
index fc182ef..0000000
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommand.java
+++ /dev/null
@@ -1,75 +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.test.framework;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-
-import static org.apache.brooklyn.core.config.ConfigKeys.newConfigKey;
-
-/**
- * Entity to invoke on a node a simple command that will immediately succeed or fail.
- *
- * Invokes the command in the start operation, and declares itself RUNNING.
- */
-@ImplementedBy(SimpleShellCommandImpl.class)
-public interface SimpleShellCommand extends Entity, Startable {
-
- String TMP_DEFAULT = "/tmp";
-
- /**
- * Result of a command invocation.
- */
- interface Result {
- int getExitCode();
- String getStdout();
- String getStderr();
-
- }
-
- /**
- * Supply the command to invoke directly. Cannot be used together with {@link #DOWNLOAD_URL}.
- */
- @SetFromFlag(nullable = false)
- ConfigKey<String> COMMAND = ConfigKeys.newConfigKey(String.class, "command", "Command to invoke");
-
- /**
- * Download a script to invoke. Cannot be used together with {@link #COMMAND}.
- */
- @SetFromFlag("downloadUrl")
- AttributeSensorAndConfigKey<String, String> DOWNLOAD_URL = SoftwareProcess.DOWNLOAD_URL;
-
- /**
- * Where the script will be downloaded on the target machine.
- */
- @SetFromFlag("scriptDir")
- ConfigKey<String> SCRIPT_DIR = newConfigKey("script.dir", "directory where downloaded scripts should be put", TMP_DEFAULT);
-
- /**
- * The working directory that the script will be run from on the target machine.
- */
- @SetFromFlag("runDir")
- ConfigKey<String> RUN_DIR = newConfigKey(String.class, "run.dir", "directory where downloaded scripts should be run from");
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b2713ca4/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandImpl.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandImpl.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandImpl.java
deleted file mode 100644
index c63e1fc..0000000
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandImpl.java
+++ /dev/null
@@ -1,260 +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.test.framework;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.location.Locations;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshTasks;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-
-import static org.apache.brooklyn.core.entity.lifecycle.Lifecycle.*;
-import static org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.setExpectedState;
-import static org.apache.brooklyn.util.text.Strings.isBlank;
-import static org.apache.brooklyn.util.text.Strings.isNonBlank;
-
-/**
- * Implementation for {@link SimpleShellCommand}.
- */
-public class SimpleShellCommandImpl extends AbstractEntity implements SimpleShellCommand {
-
- private static final Logger LOG = LoggerFactory.getLogger(SimpleShellCommandImpl.class);
- private static final int A_LINE = 80;
- public static final String DEFAULT_NAME = "download.sh";
- private static final String CD = "cd";
-
- @Override
- public void init() {
- super.init();
- getLifecycleEffectorTasks().attachLifecycleEffectors(this);
- }
-
- @Override
- public void start(Collection<? extends Location> locations) {
- addLocations(filterLocations(locations));
- setExpectedState(this, STARTING);
- }
-
-
- @Override
- public void stop() {
- LOG.debug("{} Stopping simple command", this);
- setUpAndRunState(false, STOPPED);
- }
-
- @Override
- public void restart() {
- LOG.debug("{} Restarting simple command", this);
- setUpAndRunState(true, RUNNING);
- }
-
- protected SimpleShellCommandLifecycleEffectorTasks getLifecycleEffectorTasks() {
- return new SimpleShellCommandLifecycleEffectorTasks();
- }
-
- /**
- * Gives the opportunity to sub-classes to do additional work based on the result of the command.
- */
- protected void handle(SimpleShellCommand.Result result) {
- LOG.debug("{}, Result is {}\nwith output [\n{}\n] and error [\n{}\n]", new Object[] {
- this, result.getExitCode(), shorten(result.getStdout()), shorten(result.getStderr())
- });
- }
-
- private String shorten(String text) {
- return Strings.maxlenWithEllipsis(text, A_LINE);
- }
-
- /**
- * Does nothing in this class but gives sub-classes the opportunity to filter locations according to some criterion.
- */
- public Collection<? extends Location> filterLocations(Collection<? extends Location> locations) {
- return locations;
- }
-
- private void setUpAndRunState(boolean up, Lifecycle status) {
- sensors().set(SERVICE_UP, up);
- setExpectedState(this, status);
- }
-
- public void execute(MachineLocation machineLocation) {
- try {
- executeCommand(machineLocation);
- setUpAndRunState(true, RUNNING);
- } catch (Exception e) {
- setUpAndRunState(false, ON_FIRE);
- throw Exceptions.propagate(e);
- }
- }
-
- private void executeCommand(MachineLocation machineLocation) {
-
- SimpleShellCommand.Result result = null;
- String downloadUrl = getConfig(DOWNLOAD_URL);
- String command = getConfig(COMMAND);
-
- String downloadName = DOWNLOAD_URL.getName();
- String commandName = COMMAND.getName();
-
- if (!(isNonBlank(downloadUrl) ^ isNonBlank(command))) {
- throw illegal("Must specify exactly one of", downloadName, "and", commandName);
- }
-
- if (isNonBlank(downloadUrl)) {
- String scriptDir = getConfig(SCRIPT_DIR);
- String scriptPath = calculateDestPath(downloadUrl, scriptDir);
- result = executeDownloadedScript(machineLocation, downloadUrl, scriptPath);
- }
-
- if (isNonBlank(command)) {
- result = executeShellCommand(machineLocation, command);
- }
-
- handle(result);
- }
-
- private SimpleShellCommand.Result executeDownloadedScript(MachineLocation machineLocation, String url, String scriptPath) {
-
- SshMachineLocation machine = getSshMachine(ImmutableList.<Location>of(machineLocation));
-
- TaskFactory<?> install = SshTasks.installFromUrl(ImmutableMap.<String, Object>of(), machine, url, scriptPath);
- DynamicTasks.queue(install);
- DynamicTasks.waitForLast();
-
- List<String> commands = new ArrayList<>();
- commands.add("chmod u+x " + scriptPath);
- maybeCdToRunDir(commands);
- commands.add(scriptPath);
-
- return runCommands(machine, commands);
- }
-
- private SimpleShellCommand.Result executeShellCommand(MachineLocation machineLocation, String command) {
-
- SshMachineLocation machine = getSshMachine(ImmutableList.of(machineLocation));
-
- List<String> commands = new ArrayList<>();
- maybeCdToRunDir(commands);
- commands.add(command);
-
- return runCommands(machine, commands);
- }
-
- private void maybeCdToRunDir(List<String> commands) {
- String runDir = getConfig(RUN_DIR);
- if (!isBlank(runDir)) {
- commands.add(CD + " " + runDir);
- }
- }
-
- private Result runCommands(SshMachineLocation machine, List<String> commands) {
- SshEffectorTasks.SshEffectorTaskFactory<Integer> etf = SshEffectorTasks.ssh(machine, commands.toArray(new String[]{}));
-
- ProcessTaskWrapper<Integer> job = DynamicTasks.queue(etf);
- DynamicTasks.waitForLast();
- return buildResult(job);
- }
-
- private <T> SimpleShellCommand.Result buildResult(final ProcessTaskWrapper<Integer> job) {
- final int exitCode = job.get();
- final String stdout = job.getStdout().trim();
- final String stderr = job.getStderr().trim();
- return new SimpleShellCommand.Result() {
-
- @Override
- public int getExitCode() {
- return exitCode;
- }
-
- @Override
- public String getStdout() {
- return stdout;
- }
-
- @Override
- public String getStderr() {
- return stderr;
- }
- };
- }
-
- private IllegalArgumentException illegal(String message, String ...messages) {
- return new IllegalArgumentException(Joiner.on(' ').join(this.toString() + ":", message, messages));
- }
-
- private SshMachineLocation getSshMachine(Collection<? extends Location> hostLocations) {
- Maybe<SshMachineLocation> host = Locations.findUniqueSshMachineLocation(hostLocations);
- if (host.isAbsent()) {
- throw new IllegalArgumentException("No SSH machine found to run command");
- }
- return host.get();
- }
-
- private String calculateDestPath(String url, String directory) {
- try {
- URL asUrl = new URL(url);
- Iterable<String> path = Splitter.on("/").split(asUrl.getPath());
- String scriptName = getLastPartOfPath(path, DEFAULT_NAME);
- return Joiner.on("/").join(directory, "test-" + randomDir(), scriptName);
- } catch (MalformedURLException e) {
- throw illegal("Malformed URL:", url);
- }
- }
-
- private String randomDir() {
- return Integer.valueOf(new Random(System.currentTimeMillis()).nextInt(100000)).toString();
- }
-
- private static String getLastPartOfPath(Iterable<String> path, String defaultName) {
- MutableList<String> parts = MutableList.copyOf(path);
- Collections.reverse(parts);
- Iterator<String> it = parts.iterator();
- String scriptName = null;
-
- // strip any trailing "/" parts of URL
- while (isBlank(scriptName) && it.hasNext()) {
- scriptName = it.next();
- }
- if (isBlank(scriptName)) {
- scriptName = defaultName;
- }
- return scriptName;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b2713ca4/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandLifecycleEffectorTasks.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandLifecycleEffectorTasks.java
deleted file mode 100644
index fdccd99..0000000
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandLifecycleEffectorTasks.java
+++ /dev/null
@@ -1,57 +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.test.framework;
-
-import com.google.common.base.Supplier;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.Nullable;
-import java.util.Collection;
-
-public class SimpleShellCommandLifecycleEffectorTasks extends MachineLifecycleEffectorTasks {
-
- private static final Logger LOG = LoggerFactory.getLogger(SimpleShellCommandLifecycleEffectorTasks.class);
-
- protected Location getLocation(@Nullable Collection<? extends Location> locations) {
- return super.getLocation(entity().filterLocations(locations));
- }
-
-
- @Override
- protected String startProcessesAtMachine(Supplier<MachineLocation> machineS) {
- LOG.debug("Performing lifecycle startProcessesAtMachine on simple command");
- MachineLocation machineLocation = machineS.get();
- entity().execute(machineLocation);
- return "Started simple command on " + machineLocation;
- }
-
- @Override
- protected String stopProcessesAtMachine() {
- LOG.debug("No action needed on simple command stopped");
- return "Stopped";
- }
-
- protected SimpleShellCommandImpl entity() {
- return (SimpleShellCommandImpl) super.entity();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b2713ca4/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTest.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTest.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTest.java
index 17621d9..0b71f2f 100644
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTest.java
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTest.java
@@ -22,15 +22,21 @@ import com.google.common.collect.Maps;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import java.util.Map;
+import static org.apache.brooklyn.core.config.ConfigKeys.newConfigKey;
+
/**
* Tests using a simple command execution.
*/
@ImplementedBy(SimpleShellCommandTestImpl.class)
-public interface SimpleShellCommandTest extends SimpleShellCommand, BaseTest {
+public interface SimpleShellCommandTest extends BaseTest {
+
+ String TMP_DEFAULT = "/tmp";
/**
* Equals assertion on command result.
@@ -53,6 +59,29 @@ public interface SimpleShellCommandTest extends SimpleShellCommand, BaseTest {
String IS_EMPTY = "isEmpty";
/**
+ * Supply the command to invoke directly. Cannot be used together with {@link #DOWNLOAD_URL}.
+ */
+ @SetFromFlag(nullable = false)
+ ConfigKey<String> COMMAND = ConfigKeys.newConfigKey(String.class, "command", "Command to invoke");
+
+ /**
+ * Download a script to invoke. Cannot be used together with {@link #COMMAND}.
+ */
+ @SetFromFlag("downloadUrl")
+ AttributeSensorAndConfigKey<String, String> DOWNLOAD_URL = SoftwareProcess.DOWNLOAD_URL;
+
+ /**
+ * Where the script will be downloaded on the target machine.
+ */
+ @SetFromFlag("scriptDir")
+ ConfigKey<String> SCRIPT_DIR = newConfigKey("script.dir", "directory where downloaded scripts should be put", TMP_DEFAULT);
+
+ /**
+ * The working directory that the script will be run from on the target machine.
+ */
+ @SetFromFlag("runDir")
+ ConfigKey<String> RUN_DIR = newConfigKey(String.class, "run.dir", "directory where downloaded scripts should be run from");
+ /**
* Assertions on the exit code of the simple command.
*
* If not explicitly configured, the default assertion is a non-zero exit code.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b2713ca4/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTestImpl.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTestImpl.java b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTestImpl.java
index 6a35e73..c0ce8fc 100644
--- a/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTestImpl.java
+++ b/usage/test-framework/src/main/java/org/apache/brooklyn/test/framework/SimpleShellCommandTestImpl.java
@@ -20,39 +20,92 @@ package org.apache.brooklyn.test.framework;
import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
-import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshTasks;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.text.Identifiers;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import static org.apache.brooklyn.core.entity.lifecycle.Lifecycle.*;
+import static org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.setExpectedState;
import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.truth;
+import static org.apache.brooklyn.util.text.Strings.isBlank;
+import static org.apache.brooklyn.util.text.Strings.isNonBlank;
import static org.apache.commons.collections.MapUtils.isEmpty;
-public class SimpleShellCommandTestImpl extends SimpleShellCommandImpl implements SimpleShellCommandTest {
+public class SimpleShellCommandTestImpl extends AbstractTest implements SimpleShellCommandTest {
public static final int SUCCESS = 0;
+ private static final Logger LOG = LoggerFactory.getLogger(SimpleShellCommandTestImpl.class);
+ private static final int A_LINE = 80;
+ public static final String DEFAULT_NAME = "download.sh";
+ private static final String CD = "cd";
+
@Override
- public Entity resolveTarget() {
- return AbstractTest.resolveTarget(getExecutionContext(), this);
+ public void start(Collection<? extends Location> locations) {
+ setExpectedState(this, STARTING);
+ execute();
}
- /**
- * The test will choose the location of its target entity.
- */
- public Collection<? extends Location> filterLocations(Collection<? extends Location> locations) {
- Entity target = resolveTarget();
- Collection<Location> targetLocations = target.getLocations();
- return targetLocations;
+ @Override
+ public void stop() {
+ LOG.debug("{} Stopping simple command", this);
+ setUpAndRunState(false, STOPPED);
}
@Override
- protected void handle(SimpleShellCommand.Result result) {
+ public void restart() {
+ LOG.debug("{} Restarting simple command", this);
+ execute();
+ }
+
+ private void setUpAndRunState(boolean up, Lifecycle status) {
+ sensors().set(SERVICE_UP, up);
+ setExpectedState(this, status);
+ }
+
+ private static class Result {
+ int exitCode;
+ String stdout;
+ String stderr;
+ public Result(final ProcessTaskWrapper<Integer> job) {
+ exitCode = job.get();
+ stdout = job.getStdout().trim();
+ stderr = job.getStderr().trim();
+ }
+ public int getExitCode() {
+ return exitCode;
+ }
+ public String getStdout() {
+ return stdout;
+ }
+ public String getStderr() {
+ return stderr;
+ }
+ }
+
+ protected void handle(Result result) {
+ LOG.debug("{}, Result is {}\nwith output [\n{}\n] and error [\n{}\n]", new Object[] {
+ this, result.getExitCode(), shorten(result.getStdout()), shorten(result.getStderr())
+ });
AssertionSupport support = new AssertionSupport();
checkAssertions(support, exitCodeAssertions(), "exit code", result.getExitCode());
checkAssertions(support, getConfig(ASSERT_OUT), "stdout", result.getStdout());
@@ -60,6 +113,120 @@ public class SimpleShellCommandTestImpl extends SimpleShellCommandImpl implement
support.validate();
}
+ private String shorten(String text) {
+ return Strings.maxlenWithEllipsis(text, A_LINE);
+ }
+
+ public void execute() {
+ try {
+ SshMachineLocation machineLocation =
+ Machines.findUniqueMachineLocation(resolveTarget().getLocations(), SshMachineLocation.class).get();
+ executeCommand(machineLocation);
+ setUpAndRunState(true, RUNNING);
+ } catch (Throwable t) {
+ setUpAndRunState(false, ON_FIRE);
+ throw Exceptions.propagate(t);
+ }
+ }
+
+ private void executeCommand(SshMachineLocation machineLocation) {
+
+ Result result = null;
+ String downloadUrl = getConfig(DOWNLOAD_URL);
+ String command = getConfig(COMMAND);
+
+ String downloadName = DOWNLOAD_URL.getName();
+ String commandName = COMMAND.getName();
+
+ if (!(isNonBlank(downloadUrl) ^ isNonBlank(command))) {
+ throw illegal("Must specify exactly one of", downloadName, "and", commandName);
+ }
+
+ if (isNonBlank(downloadUrl)) {
+ String scriptDir = getConfig(SCRIPT_DIR);
+ String scriptPath = calculateDestPath(downloadUrl, scriptDir);
+ result = executeDownloadedScript(machineLocation, downloadUrl, scriptPath);
+ }
+
+ if (isNonBlank(command)) {
+ result = executeShellCommand(machineLocation, command);
+ }
+
+ handle(result);
+ }
+
+ private Result executeDownloadedScript(SshMachineLocation machineLocation, String url, String scriptPath) {
+
+ TaskFactory<?> install = SshTasks.installFromUrl(ImmutableMap.<String, Object>of(), machineLocation, url, scriptPath);
+ DynamicTasks.queue(install);
+ DynamicTasks.waitForLast();
+
+ List<String> commands = new ArrayList<>();
+ commands.add("chmod u+x " + scriptPath);
+ maybeCdToRunDir(commands);
+ commands.add(scriptPath);
+
+ return runCommands(machineLocation, commands);
+ }
+
+ private Result executeShellCommand(SshMachineLocation machineLocation, String command) {
+
+ List<String> commands = new ArrayList<>();
+ maybeCdToRunDir(commands);
+ commands.add(command);
+
+ return runCommands(machineLocation, commands);
+ }
+
+ private void maybeCdToRunDir(List<String> commands) {
+ String runDir = getConfig(RUN_DIR);
+ if (!isBlank(runDir)) {
+ commands.add(CD + " " + runDir);
+ }
+ }
+
+ private Result runCommands(SshMachineLocation machine, List<String> commands) {
+ SshEffectorTasks.SshEffectorTaskFactory<Integer> etf = SshEffectorTasks.ssh(commands.toArray(new String[]{}))
+ .machine(machine);
+
+ ProcessTaskWrapper<Integer> job = DynamicTasks.queue(etf);
+ job.asTask().blockUntilEnded();
+ return new Result(job);
+ }
+
+
+
+ private IllegalArgumentException illegal(String message, String ...messages) {
+ return new IllegalArgumentException(Joiner.on(' ').join(this.toString() + ":", message, messages));
+ }
+
+ private String calculateDestPath(String url, String directory) {
+ try {
+ URL asUrl = new URL(url);
+ Iterable<String> path = Splitter.on("/").split(asUrl.getPath());
+ String scriptName = getLastPartOfPath(path, DEFAULT_NAME);
+ return Joiner.on("/").join(directory, "test-" + Identifiers.makeRandomId(8), scriptName);
+ } catch (MalformedURLException e) {
+ throw illegal("Malformed URL:", url);
+ }
+ }
+
+ private static String getLastPartOfPath(Iterable<String> path, String defaultName) {
+ MutableList<String> parts = MutableList.copyOf(path);
+ Collections.reverse(parts);
+ Iterator<String> it = parts.iterator();
+ String scriptName = null;
+
+ // strip any trailing "/" parts of URL
+ while (isBlank(scriptName) && it.hasNext()) {
+ scriptName = it.next();
+ }
+ if (isBlank(scriptName)) {
+ scriptName = defaultName;
+ }
+ return scriptName;
+ }
+
private <T> void checkAssertions(AssertionSupport support, Map<?, ?> assertions, String target, T actual) {
if (null == assertions) {
return;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b2713ca4/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/SimpleShellCommandIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/SimpleShellCommandIntegrationTest.java b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/SimpleShellCommandIntegrationTest.java
index 7f8f078..c6b5b87 100644
--- a/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/SimpleShellCommandIntegrationTest.java
+++ b/usage/test-framework/src/test/java/org/apache/brooklyn/test/framework/SimpleShellCommandIntegrationTest.java
@@ -21,38 +21,37 @@ package org.apache.brooklyn.test.framework;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Random;
import static org.apache.brooklyn.test.framework.BaseTest.TARGET_ENTITY;
-import static org.apache.brooklyn.test.framework.SimpleShellCommand.COMMAND;
import static org.apache.brooklyn.test.framework.SimpleShellCommandTest.*;
import static org.assertj.core.api.Assertions.assertThat;
public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSupport {
private static final String UP = "up";
- private LocalhostMachineProvisioningLocation localhost;
-
- protected void setUpApp() {
- super.setUpApp();
- localhost = app.getManagementContext().getLocationManager()
- .createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+ private LocalhostMachineProvisioningLocation loc;
+ private SshMachineLocation machine;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws Exception {
+ super.setUp();
+ loc = app.newLocalhostProvisioningLocation();
+ machine = loc.obtain();
}
@DataProvider(name = "shouldInsistOnJustOneOfCommandAndScript")
@@ -66,15 +65,15 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
};
}
- @Test(dataProvider = "shouldInsistOnJustOneOfCommandAndScript")
- public void shouldInsistOnJustOneOfCommandAndScript(String command, String script, boolean valid) throws Exception{
+ @Test(groups= "Integration", dataProvider = "shouldInsistOnJustOneOfCommandAndScript")
+ public void shouldInsistOnJustOneOfCommandAndScript(String command, String script, boolean valid) throws Exception {
Path scriptPath = null;
String scriptUrl = null;
if (null != script) {
scriptPath = createTempScript("pwd", "pwd");
scriptUrl = "file:" + scriptPath;
}
- TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
app.createAndManageChild(EntitySpec.create(SimpleShellCommandTest.class)
.configure(TARGET_ENTITY, testEntity)
@@ -82,7 +81,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
.configure(DOWNLOAD_URL, scriptUrl));
try {
- app.start(ImmutableList.of(localhost));
+ app.start(ImmutableList.of(loc));
if (!valid) {
Asserts.shouldHaveFailedPreviously();
}
@@ -99,7 +98,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
@Test(groups = "Integration")
public void shouldInvokeCommand() {
- TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
SimpleShellCommandTest uptime = app.createAndManageChild(EntitySpec.create(SimpleShellCommandTest.class)
.configure(TARGET_ENTITY, testEntity)
@@ -107,7 +106,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
.configure(ASSERT_STATUS, ImmutableMap.of(EQUALS, 0))
.configure(ASSERT_OUT, ImmutableMap.of(CONTAINS, UP)));
- app.start(ImmutableList.of(localhost));
+ app.start(ImmutableList.of(loc));
assertThat(uptime.sensors().get(SERVICE_UP)).isTrue()
.withFailMessage("Service should be up");
@@ -118,7 +117,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
@Test(groups = "Integration")
public void shouldNotBeUpIfAssertionFails() {
- TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
SimpleShellCommandTest uptime = app.createAndManageChild(EntitySpec.create(SimpleShellCommandTest.class)
.configure(TARGET_ENTITY, testEntity)
@@ -126,7 +125,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
.configure(ASSERT_STATUS, ImmutableMap.of(EQUALS, 1)));
try {
- app.start(ImmutableList.of(localhost));
+ app.start(ImmutableList.of(loc));
} catch (Exception e) {
assertThat(e.getCause().getMessage().contains("exit code equals 1"));
}
@@ -138,7 +137,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
@Test(groups = "Integration")
public void shouldInvokeScript() throws Exception {
- TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
String text = "hello world";
Path testScript = createTempScript("script", "echo " + text);
@@ -150,7 +149,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
.configure(ASSERT_STATUS, ImmutableMap.of(EQUALS, 0))
.configure(ASSERT_OUT, ImmutableMap.of(CONTAINS, text)));
- app.start(ImmutableList.of(localhost));
+ app.start(ImmutableList.of(loc));
assertThat(uptime.sensors().get(SERVICE_UP)).isTrue()
.withFailMessage("Service should be up");
@@ -162,9 +161,9 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
}
}
- @Test
+ @Test(groups = "Integration")
public void shouldExecuteInTheRunDir() throws Exception {
- TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity testEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
Path pwdPath = createTempScript("pwd", "pwd");
@@ -184,7 +183,7 @@ public class SimpleShellCommandIntegrationTest extends BrooklynAppUnitTestSuppor
.configure(ASSERT_STATUS, ImmutableMap.of(EQUALS, 0))
.configure(ASSERT_OUT, ImmutableMap.of(CONTAINS, "/tmp")));
- app.start(ImmutableList.of(localhost));
+ app.start(ImmutableList.of(loc));
assertThat(pwd.sensors().get(SERVICE_UP)).isTrue().withFailMessage("Service should be up");
assertThat(ServiceStateLogic.getExpectedState(pwd)).isEqualTo(Lifecycle.RUNNING)