You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/08/19 13:09:24 UTC
[06/72] [abbrv] incubator-brooklyn git commit: BROOKLYN-162 - apply
org.apache package prefix to software-base, tidying package names,
and moving a few sensory things to core
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
new file mode 100644
index 0000000..474ce0f
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.software.base.test.group;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.entity.core.EntityPredicates;
+import org.apache.brooklyn.entity.group.DynamicCluster;
+import org.apache.brooklyn.entity.group.DynamicClusterWithAvailabilityZonesTest;
+import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.MultiLocation;
+import org.apache.brooklyn.test.Asserts;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/**
+ * Uses {@link SoftwareProcess}, so test can't be in core project.
+ *
+ * Different from {@link DynamicClusterWithAvailabilityZonesTest} in the use of {@link MultiLocation}.
+ * However, the difference is important: the {@link SoftwareProcess} entity has two locations
+ * (the {@link MachineProvisioningLocation} and the {@link MachineLocation}, which was previously
+ * causing a failure - now fixed and tested here.
+ */
+public class DynamicClusterWithAvailabilityZonesMultiLocationTest extends BrooklynAppUnitTestSupport {
+
+ private DynamicCluster cluster;
+
+ private LocalhostMachineProvisioningLocation subLoc1;
+ private LocalhostMachineProvisioningLocation subLoc2;
+ private MultiLocation<?> multiLoc;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+ .configure(DynamicCluster.ENABLE_AVAILABILITY_ZONES, true)
+ .configure(DynamicCluster.INITIAL_SIZE, 0)
+ .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(EmptySoftwareProcess.class)));
+
+ subLoc1 = app.newLocalhostProvisioningLocation(ImmutableMap.of("displayName", "loc1"));
+ subLoc2 = app.newLocalhostProvisioningLocation(ImmutableMap.of("displayName", "loc2"));
+ multiLoc = mgmt.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
+ .configure(MultiLocation.SUB_LOCATIONS, ImmutableList.<MachineProvisioningLocation<?>>of(subLoc1, subLoc2)));
+ }
+
+ @Test
+ public void testReplacesEntityInSameZone() throws Exception {
+ ((EntityLocal)cluster).config().set(DynamicCluster.ENABLE_AVAILABILITY_ZONES, true);
+ cluster.start(ImmutableList.of(multiLoc));
+
+ cluster.resize(4);
+ List<String> locsUsed = getLocationNames(getLocationsOf(cluster.getMembers(), Predicates.instanceOf(MachineProvisioningLocation.class)));
+ Asserts.assertEqualsIgnoringOrder(locsUsed, ImmutableList.of("loc1", "loc1", "loc2", "loc2"));
+
+ String idToRemove = Iterables.getFirst(cluster.getMembers(), null).getId();
+ String idAdded = cluster.replaceMember(idToRemove);
+ locsUsed = getLocationNames(getLocationsOf(cluster.getMembers(), Predicates.instanceOf(MachineProvisioningLocation.class)));
+ Asserts.assertEqualsIgnoringOrder(locsUsed, ImmutableList.of("loc1", "loc1", "loc2", "loc2"));
+ assertNull(Iterables.find(cluster.getMembers(), EntityPredicates.idEqualTo(idToRemove), null));
+ assertNotNull(Iterables.find(cluster.getMembers(), EntityPredicates.idEqualTo(idAdded), null));
+ }
+
+ protected List<Location> getLocationsOf(Iterable<? extends Entity> entities, Predicate<? super Location> filter) {
+ List<Location> result = Lists.newArrayList();
+ for (Entity entity : entities) {
+ Iterables.addAll(result, Iterables.filter(entity.getLocations(), filter));
+ }
+ return result;
+ }
+
+ protected List<String> getLocationNames(Iterable<? extends Location> locs) {
+ List<String> result = Lists.newArrayList();
+ for (Location subLoc : locs) {
+ result.add(subLoc.getDisplayName());
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/GeneralisedDynamicMBean.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/GeneralisedDynamicMBean.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/GeneralisedDynamicMBean.java
new file mode 100644
index 0000000..9c6c551
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/GeneralisedDynamicMBean.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.entity.software.base.test.jmx;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.DynamicMBean;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+
+/**
+ * A quick-and-simple general-purpose implementation of DynamicMBean.
+ *
+ * This class provides an implementation of {@link DynamicMBean}. Its initial set of attribute names and values are
+ * provided to the constructor; from this it figures an {@link MBeanInfo}.
+ * <p>
+ * It presently assumes that all attributes are read-only; operations and notifications are not currently supported.
+ * Choosing the descriptions is not supported - they are set to be the same as the name.
+ * <p>
+ * Getting a valid dynamic MBean (in Groovy) is as simple as:
+ * <pre>
+ * new GeneralisedDynamicMBean(meaning: 42, advice: "Don't panic")
+ * </pre>
+ */
+public class GeneralisedDynamicMBean implements DynamicMBean {
+ private final MBeanInfo mBeanInfo;
+ private final Map<String,Object> attributes = Maps.newLinkedHashMap();
+ private final Map<String,Function> operations = Maps.newLinkedHashMap();
+
+ public GeneralisedDynamicMBean(Map<String,?> initialAttributes, Map<?,?> initialOperations) {
+ attributes.putAll(initialAttributes);
+
+ for (Entry<?,?> entry : initialOperations.entrySet()) {
+ checkArgument(entry.getKey() instanceof String || entry.getKey() instanceof MBeanOperationInfo, "entry.key=%s", entry.getKey());
+ String opName = (entry.getKey() instanceof String) ? (String)entry.getKey() : ((MBeanOperationInfo)entry.getKey()).getName();
+ operations.put(opName, (Function) entry.getValue());
+ }
+
+ Iterable<MBeanAttributeInfo> attrInfo = Iterables.transform(initialAttributes.entrySet(), new Function<Map.Entry<String,?>, MBeanAttributeInfo>() {
+ @Override public MBeanAttributeInfo apply(Map.Entry<String,?> entry) {
+ return new MBeanAttributeInfo(entry.getKey(), entry.getValue().getClass().getName(), entry.getKey(), true, false, false);
+ }
+ });
+
+ Iterable<MBeanOperationInfo> opInfo = Iterables.transform(initialOperations.keySet(), new Function<Object, MBeanOperationInfo>() {
+ public MBeanOperationInfo apply(Object it) {
+ if (it instanceof MBeanOperationInfo) {
+ return (MBeanOperationInfo) it;
+ } else if (it instanceof CharSequence) {
+ return new MBeanOperationInfo(
+ it.toString(),
+ "my descr",
+ new MBeanParameterInfo[0],
+ "void",
+ MBeanOperationInfo.ACTION_INFO);
+ } else {
+ throw new IllegalArgumentException("Cannot convert "+it+" to MBeanOperationInfo");
+ }
+ }});
+
+ mBeanInfo = new MBeanInfo(
+ GeneralisedDynamicMBean.class.getName(),
+ GeneralisedDynamicMBean.class.getName(),
+ Iterables.toArray(attrInfo, MBeanAttributeInfo.class),
+ new MBeanConstructorInfo[0],
+ Iterables.toArray(opInfo, MBeanOperationInfo.class),
+ new MBeanNotificationInfo[0]);
+ }
+
+ public void updateAttributeValue(String name, Object value) {
+ attributes.put(name, value);
+ }
+
+ @Override
+ public Object getAttribute(String s) {
+ return attributes.get(s);
+ }
+
+ @Override
+ public void setAttribute(Attribute attribute) {
+ attributes.put(attribute.getName(), attribute.getValue());
+ }
+
+ @Override
+ public AttributeList getAttributes(String[] strings) {
+ AttributeList result = new AttributeList();
+ for (Object obj : mBeanInfo.getAttributes()) {
+ Attribute attrib = (Attribute) obj;
+ result.add(new Attribute(attrib.getName(), attributes.get(attrib.getName())));
+ }
+ return result;
+ }
+
+ @Override
+ public AttributeList setAttributes(AttributeList attributeList) {
+ for (Object element : attributeList) {
+ Attribute attrib = (Attribute) element;
+ attributes.put(attrib.getName(), attrib.getValue());
+ }
+ return attributeList;
+ }
+
+ @Override
+ public Object invoke(String s, Object[] objects, String[] strings) {
+ Function op = operations.get(s);
+ if (op != null) {
+ return op.apply(objects);
+ } else {
+ throw new RuntimeException("Unknown operation "+s);
+ }
+ }
+
+ @Override
+ public MBeanInfo getMBeanInfo() {
+ return mBeanInfo;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java
new file mode 100644
index 0000000..bb7b2a5
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java
@@ -0,0 +1,172 @@
+/*
+ * 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.software.base.test.jmx;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.ObjectName;
+import javax.management.StandardEmitterMBean;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import mx4j.tools.naming.NamingService;
+import mx4j.tools.naming.NamingServiceMBean;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Set up a JMX service ready for clients to connect. This consists of an MBean server, a connector server and a naming
+ * service.
+ */
+public class JmxService {
+ private static final Logger logger = LoggerFactory.getLogger(JmxService.class);
+
+ private MBeanServer server;
+ private NamingServiceMBean namingServiceMBean;
+ private JMXConnectorServer connectorServer;
+ private String jmxHost;
+ private int jmxPort;
+ private String url;
+
+ public JmxService() throws Exception {
+ this("localhost", 28000 + (int)Math.floor(new Random().nextDouble() * 1000));
+ logger.warn("use of deprecated default host and port in JmxService");
+ }
+
+ /**
+ * @deprecated since 0.6.0; either needs abandoning, or updating to support JmxSupport (and JmxmpAgent, etc) */
+ public JmxService(Entity e) throws Exception {
+ this(e.getAttribute(Attributes.HOSTNAME) != null ? e.getAttribute(Attributes.HOSTNAME) : "localhost",
+ e.getAttribute(UsesJmx.JMX_PORT) != null ? e.getAttribute(UsesJmx.JMX_PORT) : null);
+ }
+
+ public JmxService(String jmxHost, Integer jmxPort) throws Exception {
+ this.jmxHost = jmxHost;
+ Preconditions.checkNotNull(jmxPort, "JMX_PORT must be set when starting JmxService");
+ this.jmxPort = jmxPort;
+ url = JmxHelper.toRmiJmxUrl(jmxHost, jmxPort, jmxPort, "jmxrmi");
+
+ try {
+ JMXServiceURL address = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + jmxHost + ":" + jmxPort + "/jmxrmi");
+ connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(address, null, null);
+ server = MBeanServerFactory.createMBeanServer();
+ ObjectName cntorServerName = ObjectName.getInstance("connectors:protocol=rmi");
+ server.registerMBean(connectorServer, cntorServerName);
+
+ ObjectName naming = new ObjectName("Naming:type=registry");
+ server.registerMBean(new NamingService(jmxPort), naming);
+ Object proxy = MBeanServerInvocationHandler.newProxyInstance(server, naming, NamingServiceMBean.class, false);
+ namingServiceMBean = (NamingServiceMBean) proxy;
+ try {
+ namingServiceMBean.start();
+ } catch (Exception e) {
+ // may take a bit of time for port to be available, if it had just been used
+ logger.warn("JmxService couldn't start test mbean ("+e+"); will delay then retry once");
+ Thread.sleep(1000);
+ namingServiceMBean.start();
+ }
+
+ connectorServer.start();
+ logger.info("JMX tester service started at URL {}", address);
+ } catch (Exception e) {
+ try {
+ shutdown();
+ } catch (Exception e2) {
+ logger.warn("Error shutting down JmxService, after error during startup; rethrowing original error", e2);
+ }
+ throw e;
+ }
+ }
+
+ public int getJmxPort() {
+ return jmxPort;
+ }
+
+ public void shutdown() throws IOException {
+ if (connectorServer != null) connectorServer.stop();
+ if (namingServiceMBean != null) namingServiceMBean.stop();
+ if (server != null) MBeanServerFactory.releaseMBeanServer(server);
+ connectorServer = null;
+ namingServiceMBean = null;
+ server = null;
+ logger.info("JMX tester service stopped ({}:{})", jmxHost, jmxPort);
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public GeneralisedDynamicMBean registerMBean(String name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException, NullPointerException {
+ return registerMBean(ImmutableMap.of(), ImmutableMap.of(), name);
+ }
+
+ /**
+ * Construct a {@link GeneralisedDynamicMBean} and register it with this MBean server.
+ *
+ * @param initialAttributes a {@link Map} of attributes that make up the MBean's initial set of attributes and their * values
+ * @param name the name of the MBean
+ * @return the newly created and registered MBean
+ * @throws NullPointerException
+ * @throws MalformedObjectNameException
+ * @throws NotCompliantMBeanException
+ * @throws MBeanRegistrationException
+ * @throws InstanceAlreadyExistsException
+ */
+ public GeneralisedDynamicMBean registerMBean(Map initialAttributes, String name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException, NullPointerException {
+ return registerMBean(initialAttributes, ImmutableMap.of(), name);
+ }
+
+ public GeneralisedDynamicMBean registerMBean(Map initialAttributes, Map operations, String name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException, NullPointerException {
+ GeneralisedDynamicMBean mbean = new GeneralisedDynamicMBean(initialAttributes, operations);
+ server.registerMBean(mbean, new ObjectName(name));
+ return mbean;
+ }
+
+ public StandardEmitterMBean registerMBean(List<String> notifications, String name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, MalformedObjectNameException, NullPointerException {
+ String[] types = (String[]) notifications.toArray(new String[0]);
+ MBeanNotificationInfo info = new MBeanNotificationInfo(types, Notification.class.getName(), "Notification");
+ NotificationEmitter emitter = new NotificationBroadcasterSupport(info);
+ StandardEmitterMBean mbean = new StandardEmitterMBean(emitter, NotificationEmitter.class, emitter);
+ server.registerMBean(mbean, new ObjectName(name));
+ return mbean;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsEc2LiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsEc2LiveTest.java
new file mode 100644
index 0000000..b9e3d68
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsEc2LiveTest.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.entity.software.base.test.location;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.entity.AbstractEc2LiveTest;
+import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
+import org.apache.brooklyn.entity.trait.Startable;
+import org.apache.brooklyn.location.basic.BasicMachineDetails;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+// This test really belongs in brooklyn-location but depends on AbstractEc2LiveTest in brooklyn-software-base
+public class MachineDetailsEc2LiveTest extends AbstractEc2LiveTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsEc2LiveTest.class);
+ private static final int TIMEOUT_MS = 1000 * 60 * 10; // ten minutes
+
+ @Override
+ protected void doTest(Location loc) throws Exception {
+ Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
+ app.start(ImmutableList.of(loc));
+ EntityTestUtils.assertAttributeEqualsEventually(MutableMap.of("timeout", TIMEOUT_MS),
+ testEntity, Startable.SERVICE_UP, true);
+
+ SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
+ MachineDetails machine = app.getExecutionContext()
+ .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
+ .getUnchecked();
+ LOG.info("Found the following at {}: {}", loc, machine);
+ assertNotNull(machine);
+ OsDetails details = machine.getOsDetails();
+ assertNotNull(details);
+ assertNotNull(details.getArch());
+ assertNotNull(details.getName());
+ assertNotNull(details.getVersion());
+ assertFalse(details.getArch().startsWith("architecture:"));
+ assertFalse(details.getName().startsWith("name:"));
+ assertFalse(details.getVersion().startsWith("version:"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsGoogleComputeLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsGoogleComputeLiveTest.java
new file mode 100644
index 0000000..1234f41
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/MachineDetailsGoogleComputeLiveTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.software.base.test.location;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.entity.AbstractGoogleComputeLiveTest;
+import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
+import org.apache.brooklyn.entity.trait.Startable;
+import org.apache.brooklyn.location.basic.BasicMachineDetails;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+// This test really belongs in brooklyn-location but depends on AbstractGoogleComputeLiveTest in brooklyn-software-base
+public class MachineDetailsGoogleComputeLiveTest extends AbstractGoogleComputeLiveTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsGoogleComputeLiveTest.class);
+
+ @Override
+ protected void doTest(Location loc) throws Exception {
+ Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
+ app.start(ImmutableList.of(loc));
+ EntityTestUtils.assertAttributeEqualsEventually(testEntity, Startable.SERVICE_UP, true);
+
+ SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
+ MachineDetails machine = app.getExecutionContext()
+ .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
+ .getUnchecked();
+ LOG.info("Found the following at {}: {}", loc, machine);
+ assertNotNull(machine);
+ OsDetails details = machine.getOsDetails();
+ assertNotNull(details);
+ assertNotNull(details.getArch());
+ assertNotNull(details.getName());
+ assertNotNull(details.getVersion());
+ assertFalse(details.getArch().startsWith("architecture:"));
+ assertFalse(details.getName().startsWith("name:"));
+ assertFalse(details.getVersion().startsWith("version:"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
new file mode 100644
index 0000000..12727fa
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.software.base.test.location;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.jclouds.JcloudsWinRmMachineLocation;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class WinRmMachineLocationLiveTest {
+
+ // FIXME failing locally with:
+ // Caused by: Traceback (most recent call last):
+ // File "__pyclasspath__/winrm/__init__.py", line 40, in run_cmd
+ // File "__pyclasspath__/winrm/protocol.py", line 118, in open_shell
+ // File "__pyclasspath__/winrm/protocol.py", line 190, in send_message
+ // File "__pyclasspath__/winrm/transport.py", line 112, in send_message
+ // winrm.exceptions.WinRMTransportError: 500 WinRMTransport. [Errno 20001] getaddrinfo failed
+ // at org.python.core.PyException.doRaise(PyException.java:226)
+
+ private static final Logger LOG = LoggerFactory.getLogger(BrooklynAppLiveTestSupport.class);
+
+ protected JcloudsLocation loc;
+ protected TestApplication app;
+ protected ManagementContextInternal mgmt;
+
+ private JcloudsWinRmMachineLocation machine;
+
+ @BeforeClass(alwaysRun=true)
+ public void setUpClass() throws Exception {
+ mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newDefault());
+ JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-2", ImmutableMap.of(
+ "inboundPorts", ImmutableList.of(5985, 3389),
+ "displayName", "AWS Oregon (Windows)",
+ "imageId", "us-west-2/ami-8fd3f9bf",
+ "hardwareId", "m3.medium",
+ "useJcloudsSshInit", false));
+ machine = (JcloudsWinRmMachineLocation) loc.obtain();
+ }
+
+ @AfterClass(alwaysRun=true)
+ public void tearDownClass() throws Exception {
+ try {
+ if (machine != null) loc.release(machine);
+ if (mgmt != null) Entities.destroyAll(mgmt);
+ } catch (Throwable t) {
+ LOG.error("Caught exception in tearDown method", t);
+ } finally {
+ mgmt = null;
+ }
+ }
+
+ @Test(groups="Live")
+ public void testExecScript() throws Exception {
+ WinRmToolResponse response = machine.executeScript("echo true");
+ assertEquals(response.getStatusCode(), 0);
+ assertEquals(response.getStdErr(), "");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationTest.java
new file mode 100644
index 0000000..8880d88
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.software.base.test.location;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.entity.core.BrooklynConfigKeys;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.util.net.Networking;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class WinRmMachineLocationTest extends BrooklynAppUnitTestSupport {
+
+ @Test
+ public void testConfigurePrivateAddresses() throws Exception {
+ WinRmMachineLocation host = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
+ .configure("address", Networking.getLocalHost())
+ .configure(WinRmMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
+ .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
+
+ assertEquals(host.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
new file mode 100644
index 0000000..e7bc7d8
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.entity.software.base.test.mysql;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+
+public abstract class AbstractToyMySqlEntityTest extends BrooklynAppLiveTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(AbstractToyMySqlEntityTest.class);
+
+ protected MachineProvisioningLocation<? extends SshMachineLocation> targetLocation;
+
+ @Override
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ super.setUp();
+
+ targetLocation = createLocation();
+ }
+
+ protected MachineProvisioningLocation<? extends SshMachineLocation> createLocation() {
+ return mgmt.getLocationManager().createLocation(LocationSpec.create(
+ LocalhostMachineProvisioningLocation.class));
+ }
+
+ protected abstract Entity createMysql();
+
+ // deliberately not marked as a test here so that subclasses mark it correctly (Live v Integration)
+ public void testMySqlOnProvisioningLocation() throws Exception {
+ Entity mysql = createMysql();
+ app.start(MutableList.of(targetLocation));
+ checkStartsRunning(mysql);
+ checkIsRunningAndStops(mysql, (SshMachineLocation) Iterables.getOnlyElement( mysql.getLocations() ));
+ }
+
+ protected Integer getPid(Entity mysql) {
+ return mysql.getAttribute(Attributes.PID);
+ }
+
+ protected void checkStartsRunning(Entity mysql) {
+ // should be starting within a few seconds (and almost certainly won't complete in that time)
+ EntityTestUtils.assertAttributeEventually(
+ mysql,
+ Attributes.SERVICE_STATE_ACTUAL,
+ Predicates.or(Predicates.equalTo(Lifecycle.STARTING), Predicates.equalTo(Lifecycle.RUNNING)));
+ // should be up and running within 5m
+ EntityTestUtils.assertAttributeEqualsEventually(MutableMap.of("timeout", Duration.FIVE_MINUTES),
+ mysql, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+ }
+
+ protected void checkIsRunningAndStops(Entity mysql, SshMachineLocation lh) {
+ Integer pid = getPid(mysql);
+ Assert.assertNotNull(pid, "PID should be set as an attribute (or getPid() overridden to supply)");
+ Entities.submit(app, SshEffectorTasks.requirePidRunning(pid).machine(lh).newTask() ).get();
+
+ app.stop();
+
+ // let the kill -1 take effect
+ Time.sleep(Duration.ONE_SECOND);
+
+ // and assert it has died
+ log.info("mysql in pid "+pid+" should be dead now");
+ // (app has stopped, so submit on mgmt context)
+ ProcessTaskWrapper<Integer> t = SshEffectorTasks.codePidRunning(pid).machine(lh).newTask();
+ mgmt.getExecutionManager().submit(t);
+ Assert.assertNotEquals(t.block().getExitCode(), (Integer)0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
new file mode 100644
index 0000000..650c28c
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
@@ -0,0 +1,189 @@
+/*
+ * 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.software.base.test.mysql;
+
+import java.io.File;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityInitializer;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.EntityLocal;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
+import org.apache.brooklyn.entity.stock.BasicStartable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.basic.BasicOsDetails.OsVersions;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshTasks;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.ssh.BashCommands;
+import org.apache.brooklyn.util.text.ComparableVersion;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Splitter;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.Iterables;
+
+public class DynamicToyMySqlEntityBuilder {
+
+ private static final Logger log = LoggerFactory.getLogger(DynamicToyMySqlEntityBuilder.class);
+
+ public static EntitySpec<? extends Entity> spec() {
+ return EntitySpec.create(BasicStartable.class).addInitializer(MySqlEntityInitializer.class);
+ }
+
+ public static final String downloadUrl(Entity e, boolean isLocalhost) {
+ if (isLocalhost) {
+ for (int i=50; i>20; i--) {
+ String f = System.getProperty("user.home")+"/.brooklyn/repository/MySqlNode/5.5."+i+"/mysql-5.5."+i+"-osx10.6-x86_64.tar.gz";
+ if (new File(f).exists())
+ return "file://"+f;
+ }
+ }
+ // download
+ String version = "5.5.37";
+ String osTag = getOsTag(e);
+ String mirrorUrl = "http://www.mirrorservice.org/sites/ftp.mysql.com/";
+ return "http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-"+version+"-"+osTag+".tar.gz/from/"+mirrorUrl;
+ }
+
+ public static final String installDir(Entity e, boolean isLocalhost) {
+ String url = downloadUrl(e, isLocalhost);
+ String archive = Iterables.find(Splitter.on('/').omitEmptyStrings().split(url), Predicates.containsPattern(".tar.gz"));
+ return archive.replace(".tar.gz", "");
+ }
+
+ public static final String dir(Entity e) {
+ return "/tmp/brooklyn-mysql-"+e.getId();
+ }
+
+ // copied from MySqlSshDriver
+ public static String getOsTag(Entity e) {
+ // e.g. "osx10.6-x86_64"; see http://www.mysql.com/downloads/mysql/#downloads
+ OsDetails os = ((SshMachineLocation)Iterables.getOnlyElement(e.getLocations())).getOsDetails();
+ if (os == null) return "linux-glibc2.5-x86_64";
+ if (os.isMac()) {
+ String osp1 = os.getVersion()==null ? "osx10.8" //lowest common denominator
+ : new ComparableVersion(os.getVersion()).isGreaterThanOrEqualTo(OsVersions.MAC_10_9) ? "osx10.9"
+ : "osx10.8"; //lowest common denominator
+ if (!os.is64bit()) {
+ throw new IllegalStateException("Only 64 bit MySQL build is available for OS X");
+ }
+ return osp1+"-x86_64";
+ }
+ //assume generic linux
+ String osp1 = "linux-glibc2.5";
+ String osp2 = os.is64bit() ? "x86_64" : "i686";
+ return osp1+"-"+osp2;
+ }
+
+ public static class MySqlEntityInitializer implements EntityInitializer {
+ public void apply(final EntityLocal entity) {
+ new MachineLifecycleEffectorTasks() {
+ @Override
+ protected String startProcessesAtMachine(Supplier<MachineLocation> machineS) {
+ DynamicTasks.queue(
+ SshEffectorTasks.ssh(
+ "mkdir "+dir(entity),
+ "cd "+dir(entity),
+ BashCommands.downloadToStdout(downloadUrl(entity, isLocalhost(machineS)))+" | tar xvz"
+ ).summary("download mysql").returning(SshTasks.returningStdoutLoggingInfo(log, true)));
+ if (isLinux(machineS)) {
+ DynamicTasks.queue(SshEffectorTasks.ssh(BashCommands.installPackage("libaio1")));
+ }
+ DynamicTasks.queue(
+ SshEffectorTasks.put(".my.cnf")
+ .contents(String.format("[mysqld]\nbasedir=%s/%s\n", dir(entity), installDir(entity, isLocalhost(machineS)))),
+ SshEffectorTasks.ssh(
+ "cd "+dir(entity)+"/*",
+ "./scripts/mysql_install_db",
+ "./support-files/mysql.server start > out.log 2> err.log < /dev/null"
+ ).summary("setup and run mysql").returning(SshTasks.returningStdoutLoggingInfo(log, true)));
+ return "submitted start";
+ }
+ protected void postStartCustom() {
+ // if it's still up after 5s assume we are good
+ Time.sleep(Duration.FIVE_SECONDS);
+ if (!DynamicTasks.queue(SshEffectorTasks.isPidFromFileRunning(dir(entity)+"/*/data/*.pid")).get()) {
+ // but if it's not up add a bunch of other info
+ log.warn("MySQL did not start: "+dir(entity));
+ ProcessTaskWrapper<Integer> info = DynamicTasks.queue(SshEffectorTasks.ssh(
+ "cd "+dir(entity)+"/*",
+ "cat out.log",
+ "cat err.log > /dev/stderr")).block();
+ log.info("STDOUT:\n"+info.getStdout());
+ log.info("STDERR:\n"+info.getStderr());
+ BrooklynTaskTags.addTagsDynamically(Tasks.current(),
+ BrooklynTaskTags.tagForStream("console (nohup stdout)", Suppliers.ofInstance(info.getStdout()), null),
+ BrooklynTaskTags.tagForStream("console (nohup stderr)", Suppliers.ofInstance(info.getStderr()), null));
+ throw new IllegalStateException("MySQL appears not to be running");
+ }
+
+ // and set the PID
+ entity().setAttribute(Attributes.PID,
+ Integer.parseInt(DynamicTasks.queue(SshEffectorTasks.ssh("cat "+dir(entity)+"/*/data/*.pid")).block().getStdout().trim()));
+
+ // TODO Without this, tests fail because nothing else sets serviceUp!
+ // Really should set this with a Feed that checks pid periodically.
+ // Should this instead be using SERVICE_NOT_UP_INDICATORS?
+ entity().setAttribute(Attributes.SERVICE_UP, true);
+ }
+
+ @Override
+ protected String stopProcessesAtMachine() {
+ // TODO Where is best place to set?
+ // Really should set this with a Feed that checks pid periodically.
+ entity().setAttribute(Attributes.SERVICE_UP, false);
+
+ Integer pid = entity().getAttribute(Attributes.PID);
+ if (pid==null) {
+ log.info("mysql not running");
+ return "No pid -- is it running?";
+ }
+
+ DynamicTasks.queue(SshEffectorTasks.ssh(
+ "cd "+dir(entity)+"/*",
+ "./support-files/mysql.server stop"
+ ).summary("stop mysql"));
+ return "submitted stop";
+ }
+ }.attachLifecycleEffectors(entity);
+ }
+ }
+
+ private static boolean isLocalhost(Supplier<MachineLocation> machineS) {
+ return machineS.get() instanceof LocalhostMachine;
+ }
+
+ private static boolean isLinux(Supplier<MachineLocation> machineS) {
+ return machineS.get().getMachineDetails().getOsDetails().isLinux();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityTest.java
new file mode 100644
index 0000000..d676c00
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.software.base.test.mysql;
+
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.util.collections.MutableMap;
+
+
+public class DynamicToyMySqlEntityTest extends AbstractToyMySqlEntityTest {
+
+ private static final Logger log = LoggerFactory.getLogger(DynamicToyMySqlEntityTest.class);
+
+ protected Entity createMysql() {
+ Entity mysql = app.createAndManageChild(DynamicToyMySqlEntityBuilder.spec());
+ log.debug("created "+mysql);
+ return mysql;
+ }
+
+ // put right group on test (also help Eclipse IDE pick it up)
+ @Override
+ @Test(groups = "Integration")
+ public void testMySqlOnProvisioningLocation() throws Exception {
+ super.testMySqlOnProvisioningLocation();
+ }
+
+ @Test(groups="Integration")
+ public void testMySqlOnMachineLocation() throws Exception {
+ Entity mysql = createMysql();
+ SshMachineLocation lh = targetLocation.obtain(MutableMap.of());
+
+ app.start(Arrays.asList(lh));
+ checkStartsRunning(mysql);
+ checkIsRunningAndStops(mysql, lh);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java
new file mode 100644
index 0000000..66049b5
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.software.base.test.sensor.core;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
+import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
+
+import com.google.common.collect.ImmutableList;
+
+public class PortAttributeSensorAndConfigKeyTest extends BrooklynAppUnitTestSupport {
+
+ /*
+ * FIXME Fails because port is never released. Nothing calls PortSupplier.releasePort(int).
+ * The stacktrace below shows where it is obtained:
+ *
+ Daemon Thread [brooklyn-execmanager-XwLLLdS4-5] (Suspended (breakpoint at line 244 in LocalhostMachineProvisioningLocation$LocalhostMachine))
+ LocalhostMachineProvisioningLocation$LocalhostMachine.obtainPort(PortRange) line: 244
+ PortAttributeSensorAndConfigKey.convertConfigToSensor(PortRange, Entity) line: 78
+ PortAttributeSensorAndConfigKey.convertConfigToSensor(Object, Entity) line: 1
+ PortAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<ConfigType,SensorType>).getAsSensorValue(Entity) line: 93
+ ConfigToAttributes.apply(EntityLocal, AttributeSensorAndConfigKey<?,T>) line: 28
+ ConfigToAttributes.apply(EntityLocal) line: 17
+ SoftwareProcessDriverLifecycleEffectorTasks(MachineLifecycleEffectorTasks).preStartCustom(MachineLocation) line: 343
+ SoftwareProcessDriverLifecycleEffectorTasks.preStartCustom(MachineLocation) line: 69
+ MachineLifecycleEffectorTasks$6.run() line: 283
+ */
+ @Test(enabled=false, groups="Integration") // test is slow (for some reason - why?)
+ public void testStoppingEntityReleasesPortFromMachineForReuse() throws Exception {
+ LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost");
+ SshMachineLocation machine = loc.obtain();
+ runStoppingEntityReleasesPortFromLocalhostForReuse(machine);
+ }
+
+ @Test(groups="Integration") // test is slow (for some reason - why?)
+ public void testStoppingEntityReleasesPortFromLocalhostProvisioningLocationForReuse() throws Exception {
+ LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost");
+ runStoppingEntityReleasesPortFromLocalhostForReuse(loc);
+ }
+
+ protected void runStoppingEntityReleasesPortFromLocalhostForReuse(Location loc) throws Exception {
+ MyEntity e1 = app.createAndManageChild(EntitySpec.create(MyEntity.class));
+ e1.start(ImmutableList.of(loc));
+ assertEquals(e1.getAttribute(MyEntity.MY_PORT), (Integer)47653);
+
+ e1.stop();
+ Entities.unmanage(e1);
+ MyEntity e2 = app.createAndManageChild(EntitySpec.create(MyEntity.class));
+ e2.start(ImmutableList.of(loc));
+ assertEquals(e2.getAttribute(MyEntity.MY_PORT), (Integer)47653);
+ }
+
+ @ImplementedBy(MyEntityImpl.class)
+ public interface MyEntity extends EmptySoftwareProcess {
+ PortAttributeSensorAndConfigKey MY_PORT = new PortAttributeSensorAndConfigKey("myport", "", "47653");
+ }
+
+ public static class MyEntityImpl extends EmptySoftwareProcessImpl implements MyEntity {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
new file mode 100644
index 0000000..c51725c
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.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.entity.software.base.test.ssh;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.sensor.ssh.SshCommandEffector;
+import org.apache.brooklyn.sensor.ssh.SshCommandSensor;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+
+import com.google.common.collect.ImmutableList;
+
+public class SshCommandIntegrationTest {
+
+ final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
+ final static Effector<String> EFFECTOR_SAY_HI = Effectors.effector(String.class, "sayHi").buildAbstract();
+
+ private TestApplication app;
+ private SshMachineLocation machine;
+ private EntityLocal entity;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ machine = app.newLocalhostProvisioningLocation().obtain();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
+ app.start(ImmutableList.<Location>of());
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ }
+
+ @Test(groups="Integration")
+ public void testSshSensor() throws Exception {
+ File tempFile = File.createTempFile("testSshCommand", "txt");
+ tempFile.deleteOnExit();
+ new SshCommandSensor<String>(ConfigBag.newInstance()
+ .configure(SshCommandSensor.SENSOR_PERIOD, Duration.millis(100))
+ .configure(SshCommandSensor.SENSOR_NAME, SENSOR_STRING.getName())
+ .configure(SshCommandSensor.SENSOR_COMMAND, "echo foo > "+tempFile.getAbsolutePath()+"\n"
+ + "wc "+tempFile.getAbsolutePath()))
+ .apply(entity);
+ entity.setAttribute(Attributes.SERVICE_UP, true);
+
+ String val = EntityTestUtils.assertAttributeEventuallyNonNull(entity, SENSOR_STRING);
+ assertTrue(val.contains("1"), "val="+val);
+ String[] counts = val.trim().split("\\s+");
+ Assert.assertEquals(counts.length, 4, "val="+val);
+ Assert.assertEquals(counts[0], "1", "val="+val);
+ }
+
+ @Test(groups="Integration")
+ public void testSshEffector() throws Exception {
+ File tempFile = File.createTempFile("testSshCommand", "txt");
+ tempFile.deleteOnExit();
+ new SshCommandEffector(ConfigBag.newInstance()
+ .configure(SshCommandEffector.EFFECTOR_NAME, "sayHi")
+ .configure(SshCommandEffector.EFFECTOR_COMMAND, "echo hi"))
+ .apply(entity);
+
+ String val = entity.invoke(EFFECTOR_SAY_HI, MutableMap.<String,String>of()).get();
+ Assert.assertEquals(val.trim(), "hi", "val="+val);
+ }
+
+ @Test(groups="Integration")
+ public void testSshEffectorWithParameters() throws Exception {
+ File tempFile = File.createTempFile("testSshCommand", "txt");
+ tempFile.deleteOnExit();
+ new SshCommandEffector(ConfigBag.newInstance()
+ .configure(SshCommandEffector.EFFECTOR_NAME, "sayHi")
+ .configure(SshCommandEffector.EFFECTOR_COMMAND, "echo $foo")
+ .configure(SshCommandEffector.EFFECTOR_PARAMETER_DEFS,
+ MutableMap.<String,Object>of("foo", MutableMap.of("defaultValue", "hi"))))
+ .apply(entity);
+
+ String val;
+ // explicit value
+ val = entity.invoke(EFFECTOR_SAY_HI, MutableMap.<String,String>of("foo", "bar")).get();
+ Assert.assertEquals(val.trim(), "bar", "val="+val);
+
+ // default value
+ val = entity.invoke(EFFECTOR_SAY_HI, MutableMap.<String,String>of()).get();
+ Assert.assertEquals(val.trim(), "hi", "val="+val);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
new file mode 100644
index 0000000..87ad639
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.system_service;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.entity.core.EntityPredicates;
+import org.apache.brooklyn.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
+import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcessImpl;
+import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcessSshDriver;
+import org.apache.brooklyn.entity.system_service.SystemServiceEnricher;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.ssh.BashCommands;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class SystemServiceEnricherTest extends BrooklynAppLiveTestSupport {
+ //requires /etc/init.d OS, for example CentOS 6.5
+ private static final String LOCATION_SPEC = "named:service-live-test-location";
+ private JcloudsLocation location;
+
+ @Override
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ super.setUp();
+ location = (JcloudsLocation) mgmt.getLocationRegistry().resolve(LOCATION_SPEC);
+ }
+
+ @Test(groups = "Live")
+ public void testRestartLaunchesService() {
+ String launchCmd = "nohup bash -c \"echo \\$\\$ > $PID_FILE; while true; do sleep 1000; done\" &";
+ EntitySpec<VanillaSoftwareProcess> procSpec = EntitySpec.create(VanillaSoftwareProcess.class)
+ .configure(VanillaSoftwareProcess.LAUNCH_COMMAND, launchCmd)
+ .enricher(EnricherSpec.create(SystemServiceEnricher.class));
+ VanillaSoftwareProcess proc = app.createAndManageChild(procSpec);
+ app.start(ImmutableList.of(location));
+
+ waitHealthy(proc);
+
+ SshMachineLocation machine = EffectorTasks.getSshMachine(proc);
+ String pidFile = getPidFile(proc);
+ String killCmd = "kill -9 `cat " + pidFile + "`";
+ machine.execCommands("kill process", ImmutableList.of(killCmd));
+
+ waitFailed(proc);
+
+ int restartCode = machine.execCommands("restart machine", ImmutableList.of(BashCommands.sudo("/sbin/shutdown -r now")));
+ assertEquals(restartCode, 0);
+
+ waitHealthy(proc);
+ }
+
+ private String getPidFile(VanillaSoftwareProcess proc) {
+ VanillaSoftwareProcessImpl impl = (VanillaSoftwareProcessImpl)Entities.deproxy(proc);
+ return ((VanillaSoftwareProcessSshDriver)impl.getDriver()).getPidFile();
+ }
+
+ private void waitFailed(VanillaSoftwareProcess proc) {
+ Asserts.eventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE));
+ }
+
+ private void waitHealthy(VanillaSoftwareProcess proc) {
+ Asserts.eventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
deleted file mode 100644
index 39f787f..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
+++ /dev/null
@@ -1,68 +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.location.basic;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineDetails;
-import org.apache.brooklyn.api.location.OsDetails;
-import org.apache.brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.entity.basic.EmptySoftwareProcess;
-
-// This test really belongs in brooklyn-location but depends on AbstractEc2LiveTest in brooklyn-software-base
-public class MachineDetailsEc2LiveTest extends AbstractEc2LiveTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsEc2LiveTest.class);
- private static final int TIMEOUT_MS = 1000 * 60 * 10; // ten minutes
-
- @Override
- protected void doTest(Location loc) throws Exception {
- Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
- app.start(ImmutableList.of(loc));
- EntityTestUtils.assertAttributeEqualsEventually(MutableMap.of("timeout", TIMEOUT_MS),
- testEntity, Startable.SERVICE_UP, true);
-
- SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
- MachineDetails machine = app.getExecutionContext()
- .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
- .getUnchecked();
- LOG.info("Found the following at {}: {}", loc, machine);
- assertNotNull(machine);
- OsDetails details = machine.getOsDetails();
- assertNotNull(details);
- assertNotNull(details.getArch());
- assertNotNull(details.getName());
- assertNotNull(details.getVersion());
- assertFalse(details.getArch().startsWith("architecture:"));
- assertFalse(details.getName().startsWith("name:"));
- assertFalse(details.getVersion().startsWith("version:"));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
deleted file mode 100644
index 6f2a06a..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
+++ /dev/null
@@ -1,65 +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.location.basic;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineDetails;
-import org.apache.brooklyn.api.location.OsDetails;
-import org.apache.brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import brooklyn.entity.AbstractGoogleComputeLiveTest;
-import brooklyn.entity.basic.EmptySoftwareProcess;
-
-// This test really belongs in brooklyn-location but depends on AbstractGoogleComputeLiveTest in brooklyn-software-base
-public class MachineDetailsGoogleComputeLiveTest extends AbstractGoogleComputeLiveTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsGoogleComputeLiveTest.class);
-
- @Override
- protected void doTest(Location loc) throws Exception {
- Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
- app.start(ImmutableList.of(loc));
- EntityTestUtils.assertAttributeEqualsEventually(testEntity, Startable.SERVICE_UP, true);
-
- SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
- MachineDetails machine = app.getExecutionContext()
- .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
- .getUnchecked();
- LOG.info("Found the following at {}: {}", loc, machine);
- assertNotNull(machine);
- OsDetails details = machine.getOsDetails();
- assertNotNull(details);
- assertNotNull(details.getArch());
- assertNotNull(details.getName());
- assertNotNull(details.getVersion());
- assertFalse(details.getArch().startsWith("architecture:"));
- assertFalse(details.getName().startsWith("name:"));
- assertFalse(details.getVersion().startsWith("version:"));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
deleted file mode 100644
index 1651f15..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
+++ /dev/null
@@ -1,92 +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.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.core.internal.BrooklynProperties;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.entity.core.Entities;
-import org.apache.brooklyn.location.jclouds.JcloudsLocation;
-
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.jclouds.JcloudsWinRmMachineLocation;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class WinRmMachineLocationLiveTest {
-
- // FIXME failing locally with:
- // Caused by: Traceback (most recent call last):
- // File "__pyclasspath__/winrm/__init__.py", line 40, in run_cmd
- // File "__pyclasspath__/winrm/protocol.py", line 118, in open_shell
- // File "__pyclasspath__/winrm/protocol.py", line 190, in send_message
- // File "__pyclasspath__/winrm/transport.py", line 112, in send_message
- // winrm.exceptions.WinRMTransportError: 500 WinRMTransport. [Errno 20001] getaddrinfo failed
- // at org.python.core.PyException.doRaise(PyException.java:226)
-
- private static final Logger LOG = LoggerFactory.getLogger(BrooklynAppLiveTestSupport.class);
-
- protected JcloudsLocation loc;
- protected TestApplication app;
- protected ManagementContextInternal mgmt;
-
- private JcloudsWinRmMachineLocation machine;
-
- @BeforeClass(alwaysRun=true)
- public void setUpClass() throws Exception {
- mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newDefault());
- JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-2", ImmutableMap.of(
- "inboundPorts", ImmutableList.of(5985, 3389),
- "displayName", "AWS Oregon (Windows)",
- "imageId", "us-west-2/ami-8fd3f9bf",
- "hardwareId", "m3.medium",
- "useJcloudsSshInit", false));
- machine = (JcloudsWinRmMachineLocation) loc.obtain();
- }
-
- @AfterClass(alwaysRun=true)
- public void tearDownClass() throws Exception {
- try {
- if (machine != null) loc.release(machine);
- if (mgmt != null) Entities.destroyAll(mgmt);
- } catch (Throwable t) {
- LOG.error("Caught exception in tearDown method", t);
- } finally {
- mgmt = null;
- }
- }
-
- @Test(groups="Live")
- public void testExecScript() throws Exception {
- WinRmToolResponse response = machine.executeScript("echo true");
- assertEquals(response.getStatusCode(), 0);
- assertEquals(response.getStdErr(), "");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
deleted file mode 100644
index ea00d15..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
+++ /dev/null
@@ -1,43 +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.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.entity.core.BrooklynConfigKeys;
-import org.apache.brooklyn.util.net.Networking;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class WinRmMachineLocationTest extends BrooklynAppUnitTestSupport {
-
- @Test
- public void testConfigurePrivateAddresses() throws Exception {
- WinRmMachineLocation host = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
- .configure("address", Networking.getLocalHost())
- .configure(WinRmMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
- .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
-
- assertEquals(host.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
- }
-}