Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 94687d98a -> 206d78256


Adds jclouds rebind tests

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

Branch: refs/heads/master
Commit: eb7d1208b4b3d0453ac33c388f949d02b09ba7a1
Parents: fa131b1
Author: Aled Sage <[email protected]>
Authored: Thu Oct 8 20:33:29 2015 +0100
Committer: Aled Sage <[email protected]>
Committed: Thu Oct 8 20:33:29 2015 +0100

----------------------------------------------------------------------
 .../core/mgmt/rebind/RebindTestFixture.java     |   4 +
 .../jclouds/AbstractJcloudsLiveTest.java        |  25 +-
 .../jclouds/JcloudsByonRebindLiveTest.java      | 165 ++++++++++++
 .../location/jclouds/JcloudsRebindLiveTest.java | 188 ++++++++++++++
 .../location/jclouds/JcloudsRebindStubTest.java | 250 +++++++++++++++++++
 5 files changed, 623 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/eb7d1208/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
index df2e658..c9acdf3 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
@@ -124,6 +124,10 @@ public abstract class RebindTestFixture<T extends 
StartableApplication> {
         newApp = null;
     }
 
+    protected ManagementContext mgmt() {
+        return (newManagementContext != null) ? newManagementContext : 
origManagementContext;
+    }
+    
     public static void waitForTaskCountToBecome(final ManagementContext mgmt, 
final int allowedMax) {
         waitForTaskCountToBecome(mgmt, allowedMax, false);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/eb7d1208/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
index 13138a5..3a475c0 100644
--- 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
@@ -81,14 +81,7 @@ public class AbstractJcloudsLiveTest {
         List<Exception> exceptions = Lists.newArrayList();
         try {
             if (machines != null) {
-                for (JcloudsSshMachineLocation machine : machines) {
-                    try {
-                        releaseMachine(machine);
-                    } catch (Exception e) {
-                        LOG.warn("Error releasing machine "+machine+"; 
continuing...", e);
-                        exceptions.add(e);
-                    }
-                }
+                exceptions.addAll(releaseMachineSafely(machines));
                 machines.clear();
             }
         } finally {
@@ -115,7 +108,7 @@ public class AbstractJcloudsLiveTest {
         return 
LocalManagementContextForTests.builder(true).useDefaultProperties().build();
     }
     
-    protected void stripBrooklynProperties(BrooklynProperties props) {
+    protected static void stripBrooklynProperties(BrooklynProperties props) {
         // remove all location properties except for identity and credential
         // (so key, scripts, etc settings don't interfere with tests) 
         for (String key : 
ImmutableSet.copyOf(props.asMapWithStringKeys().keySet())) {
@@ -155,6 +148,20 @@ public class AbstractJcloudsLiveTest {
         machines.remove(machine);
         jcloudsLocation.release(machine);
     }
+    
+    protected List<Exception> releaseMachineSafely(Iterable<? extends 
JcloudsSshMachineLocation> machines) {
+        List<Exception> exceptions = Lists.newArrayList();
+        
+        for (JcloudsSshMachineLocation machine : machines) {
+            try {
+                releaseMachine(machine);
+            } catch (Exception e) {
+                LOG.warn("Error releasing machine "+machine+"; continuing...", 
e);
+                exceptions.add(e);
+            }
+        }
+        return exceptions;
+    }
 
     protected void suspendMachine(MachineLocation machine) {
         assertNotNull(jcloudsLocation);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/eb7d1208/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonRebindLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonRebindLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonRebindLiveTest.java
new file mode 100644
index 0000000..705935b
--- /dev/null
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonRebindLiveTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.jclouds;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.location.byon.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
+import org.apache.brooklyn.util.stream.Streams;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+/**
+ * Tests rebind (i.e. restarting Brooklyn server) when there are live 
JcloudsSshMachineLocation object(s),
+ * created using the JcloudsByonLocationResolver.
+ */
+public class JcloudsByonRebindLiveTest extends RebindTestFixtureWithApp {
+
+    // TODO Duplication of AbstractJcloudsLiveTest, because we're subclassing 
RebindTestFixture instead.
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(JcloudsByonRebindLiveTest.class);
+
+    public static final String SOFTLAYER_PROVIDER = 
AbstractJcloudsLiveTest.SOFTLAYER_PROVIDER;
+    public static final String SOFTLAYER_REGION = 
AbstractJcloudsLiveTest.SOFTLAYER_AMS01_REGION_NAME;
+    public static final String SOFTLAYER_LOCATION_SPEC = "jclouds:" + 
SOFTLAYER_PROVIDER + ":" + SOFTLAYER_REGION;
+    public static final String SOFTLAYER_IMAGE_ID = "UBUNTU_14_64";
+
+    private LocalManagementContext provisioningManagementContext;
+    private JcloudsSshMachineLocation provisionedMachine;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+        
+        // For provisioning VMs (to subsequently be used for BYON)
+        provisioningManagementContext = 
LocalManagementContextForTests.builder(true).useDefaultProperties().build();
+        
AbstractJcloudsLiveTest.stripBrooklynProperties(provisioningManagementContext.getBrooklynProperties());
+        
+        // Don't let any defaults from brooklyn.properties (except 
credentials) interfere with test
+        
AbstractJcloudsLiveTest.stripBrooklynProperties(origManagementContext.getBrooklynProperties());
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        List<Exception> exceptions = Lists.newArrayList();
+        try {
+            if (provisioningManagementContext != null && provisionedMachine != 
null) {
+                provisionedMachine.getParent().release(provisionedMachine);
+            }
+        } finally {
+            Entities.destroyAll(provisioningManagementContext);
+            provisioningManagementContext = null;
+            provisionedMachine = null;
+            
+            super.tearDown();
+        }
+        
+        if (exceptions.size() > 0) {
+            throw new CompoundRuntimeException("Error in tearDown of 
"+getClass(), exceptions);
+        }
+    }
+
+    @Override
+    protected boolean useLiveManagementContext() {
+        return true;
+    }
+
+    @Test(groups = {"Live"})
+    public void testRebind() throws Exception {
+        ImmutableMap<String, Object> obtainFlags = 
ImmutableMap.<String,Object>builder()
+                .put("imageId", SOFTLAYER_IMAGE_ID)
+                .put("inboundPorts", ImmutableList.of(22))
+                .build();
+        JcloudsLocation provisioningLoc = (JcloudsLocation) 
provisioningManagementContext.getLocationRegistry().resolve(SOFTLAYER_LOCATION_SPEC);
+        provisionedMachine = (JcloudsSshMachineLocation) 
provisioningLoc.obtain(obtainFlags);
+        
+        // Test with a jclouds-byon
+        String locSpec = 
"jcloudsByon:(provider=\""+SOFTLAYER_PROVIDER+"\",region=\""+SOFTLAYER_REGION+"\",user=\""+provisionedMachine.getUser()+"\",hosts=\""+provisionedMachine.getNode().getProviderId()+"\")";
+        
+        FixedListMachineProvisioningLocation<?> origByon = 
(FixedListMachineProvisioningLocation<?>) 
mgmt().getLocationRegistry().resolve(locSpec);
+        
+        JcloudsSshMachineLocation origMachine = 
(JcloudsSshMachineLocation)origByon.obtain(ImmutableMap.<String,Object>of());
+        JcloudsLocation origJcloudsLocation = origMachine.getParent();
+        String origHostname = origMachine.getHostname();
+        NodeMetadata origNode = origMachine.getNode();
+        Template origTemplate = origMachine.getTemplate();
+        assertSshable(origMachine);
+
+        rebind();
+        
+        // Check the machine is as before
+        JcloudsSshMachineLocation newMachine = (JcloudsSshMachineLocation) 
newManagementContext.getLocationManager().getLocation(origMachine.getId());
+        FixedListMachineProvisioningLocation<?> newByon = 
(FixedListMachineProvisioningLocation<?>) 
newManagementContext.getLocationManager().getLocation(origByon.getId());
+        JcloudsLocation newJcloudsLocation = newMachine.getParent();
+        String newHostname = newMachine.getHostname();
+        NodeMetadata newNode = newMachine.getNode();
+        Template newTemplate = newMachine.getTemplate();
+        assertSshable(newMachine);
+        
+        assertEquals(newHostname, origHostname);
+        assertEquals(origNode.getId(), newNode.getId());
+        
+        assertEquals(newJcloudsLocation.getProvider(), 
origJcloudsLocation.getProvider());
+    }
+    
+    protected void assertSshable(Map<?,?> machineConfig) {
+        SshMachineLocation machineWithThatConfig = 
mgmt().getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(machineConfig));
+        try {
+            assertSshable(machineWithThatConfig);
+        } finally {
+            Streams.closeQuietly(machineWithThatConfig);
+        }
+    }
+
+    protected void assertNotSshable(Map<?,?> machineConfig) {
+        try {
+            assertSshable(machineConfig);
+            Assert.fail("ssh should not have succeeded "+machineConfig);
+        } catch (Exception e) {
+            // expected
+            LOG.debug("Exception as expected when testing sshable 
"+machineConfig);
+        }
+    }
+
+    protected void assertSshable(SshMachineLocation machine) {
+        int result = machine.execScript("simplecommand", 
ImmutableList.of("true"));
+        assertEquals(result, 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/eb7d1208/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindLiveTest.java
new file mode 100644
index 0000000..b81d930
--- /dev/null
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindLiveTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.jclouds;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.core.location.Locations;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
+import org.apache.brooklyn.util.stream.Streams;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+/**
+ * Tests rebind (i.e. restarting Brooklyn server) when there are live 
JcloudsSshMachineLocation object(s).
+ */
+public class JcloudsRebindLiveTest extends RebindTestFixtureWithApp {
+
+    // TODO Duplication of AbstractJcloudsLiveTest, because we're subcalling 
RebindTestFixture instead.
+
+    // TODO The mgmts tracking was added when I tried to combine 
JcloudsRebindLiveTest and JcloudsByonRebindLiveTest, 
+    // but turns out that is not worth the effort!
+    
+    private static final Logger LOG = 
LoggerFactory.getLogger(JcloudsRebindLiveTest.class);
+
+    public static final String AWS_EC2_REGION_NAME = 
AbstractJcloudsLiveTest.AWS_EC2_USEAST_REGION_NAME;
+    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + 
AbstractJcloudsLiveTest.AWS_EC2_PROVIDER + (AWS_EC2_REGION_NAME == null ? "" : 
":" + AWS_EC2_REGION_NAME);
+    
+    // Image: {id=us-east-1/ami-7d7bfc14, providerId=ami-7d7bfc14, 
name=RightImage_CentOS_6.3_x64_v5.8.8.5, location={scope=REGION, id=us-east-1, 
description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, 
os={family=centos, arch=paravirtual, version=6.0, 
description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, 
is64Bit=true}, 
description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, 
version=5.8.8.5, status=AVAILABLE[available], loginUser=root, 
userMetadata={owner=411009282317, rootDeviceType=instance-store, 
virtualizationType=paravirtual, hypervisor=xen}}
+    public static final String AWS_EC2_CENTOS_IMAGE_ID = 
"us-east-1/ami-7d7bfc14";
+
+    public static final String SOFTLAYER_LOCATION_SPEC = "jclouds:" + 
AbstractJcloudsLiveTest.SOFTLAYER_PROVIDER;
+    
+    protected List<JcloudsSshMachineLocation> machines;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+        machines = Lists.newCopyOnWriteArrayList();
+        
+        // Don't let any defaults from brooklyn.properties (except 
credentials) interfere with test
+        
AbstractJcloudsLiveTest.stripBrooklynProperties(origManagementContext.getBrooklynProperties());
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        List<Exception> exceptions = Lists.newArrayList();
+        try {
+            exceptions.addAll(releaseMachineSafely(machines));
+            machines.clear();
+        } finally {
+            super.tearDown();
+        }
+        
+        if (exceptions.size() > 0) {
+            throw new CompoundRuntimeException("Error in tearDown of 
"+getClass(), exceptions);
+        }
+    }
+
+    @Override
+    protected boolean useLiveManagementContext() {
+        return true;
+    }
+
+    @Test(groups = {"Live"})
+    public void testEc2Rebind() throws Exception {
+        ImmutableMap<String, Object> obtainFlags = 
ImmutableMap.<String,Object>builder()
+                .put("imageId", AWS_EC2_CENTOS_IMAGE_ID)
+                .put("hardwareId", 
AbstractJcloudsLiveTest.AWS_EC2_SMALL_HARDWARE_ID)
+                .put("inboundPorts", ImmutableList.of(22))
+                .build();
+        runTest(AWS_EC2_LOCATION_SPEC, obtainFlags);
+    }
+    
+    @Test(groups = {"Live"})
+    public void testSoftlayerRebind() throws Exception {
+        runTest(SOFTLAYER_LOCATION_SPEC, ImmutableMap.of("inboundPorts", 
ImmutableList.of(22)));
+    }
+    
+    protected void runTest(String locSpec, Map<String, ?> obtainFlags) throws 
Exception {
+        JcloudsLocation location = (JcloudsLocation) 
mgmt().getLocationRegistry().resolve(locSpec);
+        
+        JcloudsSshMachineLocation origMachine = obtainMachine(location, 
obtainFlags);
+        String origHostname = origMachine.getHostname();
+        NodeMetadata origNode = origMachine.getNode();
+        Template origTemplate = origMachine.getTemplate();
+        assertSshable(origMachine);
+
+        rebind();
+        
+        // Check the machine is as before
+        JcloudsSshMachineLocation newMachine = (JcloudsSshMachineLocation) 
newManagementContext.getLocationManager().getLocation(origMachine.getId());
+        JcloudsLocation newLocation = newMachine.getParent();
+        String newHostname = newMachine.getHostname();
+        NodeMetadata newNode = newMachine.getNode();
+        Template newTemplate = newMachine.getTemplate();
+        assertSshable(newMachine);
+        
+        assertEquals(newHostname, origHostname);
+        assertEquals(origNode.getId(), newNode.getId());
+    }
+    
+    protected void assertSshable(Map<?,?> machineConfig) {
+        SshMachineLocation machineWithThatConfig = 
mgmt().getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(machineConfig));
+        try {
+            assertSshable(machineWithThatConfig);
+        } finally {
+            Streams.closeQuietly(machineWithThatConfig);
+        }
+    }
+
+    protected void assertNotSshable(Map<?,?> machineConfig) {
+        try {
+            assertSshable(machineConfig);
+            Assert.fail("ssh should not have succeeded "+machineConfig);
+        } catch (Exception e) {
+            // expected
+            LOG.debug("Exception as expected when testing sshable 
"+machineConfig);
+        }
+    }
+
+    protected void assertSshable(SshMachineLocation machine) {
+        int result = machine.execScript("simplecommand", 
ImmutableList.of("true"));
+        assertEquals(result, 0);
+    }
+
+    // Use this utility method to ensure machines are released on tearDown
+    protected JcloudsSshMachineLocation 
obtainMachine(MachineProvisioningLocation<?> location, Map<?, ?> conf) throws 
Exception {
+        JcloudsSshMachineLocation result = 
(JcloudsSshMachineLocation)location.obtain(conf);
+        machines.add(checkNotNull(result, "result"));
+        return result;
+    }
+
+    protected void releaseMachine(JcloudsSshMachineLocation machine) {
+        if (!Locations.isManaged(machine)) return;
+        machines.remove(machine);
+        machine.getParent().release(machine);
+    }
+    
+    protected List<Exception> releaseMachineSafely(Iterable<? extends 
JcloudsSshMachineLocation> machines) {
+        List<Exception> exceptions = Lists.newArrayList();
+        List<JcloudsSshMachineLocation> machinesCopy = 
ImmutableList.copyOf(machines);
+        
+        for (JcloudsSshMachineLocation machine : machinesCopy) {
+            try {
+                releaseMachine(machine);
+            } catch (Exception e) {
+                LOG.warn("Error releasing machine "+machine+"; continuing...", 
e);
+                exceptions.add(e);
+            }
+        }
+        return exceptions;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/eb7d1208/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindStubTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindStubTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindStubTest.java
new file mode 100644
index 0000000..ac7fd56
--- /dev/null
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsRebindStubTest.java
@@ -0,0 +1,250 @@
+/*
+ * 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.jclouds;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadata.Status;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.internal.HardwareImpl;
+import org.jclouds.compute.domain.internal.NodeMetadataImpl;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.domain.internal.LocationImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+
+/**
+ * Tests rebind (i.e. restarting Brooklyn server) when there are live 
JcloudsSshMachineLocation object(s).
+ * 
+ * It is still a live test because it connects to the Softlayer API for 
finding images, etc.
+ * But it does not provision any VMs, so is much faster/cheaper.
+ */
+public class JcloudsRebindStubTest extends RebindTestFixtureWithApp {
+
+    // TODO Duplication of AbstractJcloudsLiveTest, because we're subclassing 
RebindTestFixture instead.
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(JcloudsRebindStubTest.class);
+
+    public static final String SOFTLAYER_LOCATION_SPEC = "jclouds:" + 
AbstractJcloudsLiveTest.SOFTLAYER_PROVIDER;
+    public static final String SOFTLAYER_IMAGE_ID = "UBUNTU_14_64";
+    
+    protected List<ManagementContext> mgmts;
+    protected Multimap<ManagementContext, JcloudsSshMachineLocation> machines;
+    protected BrooklynProperties brooklynProperties;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+        mgmts = 
Lists.newCopyOnWriteArrayList(ImmutableList.<ManagementContext>of(origManagementContext));
+        machines = 
Multimaps.synchronizedMultimap(ArrayListMultimap.<ManagementContext, 
JcloudsSshMachineLocation>create());
+        
+        // Don't let any defaults from brooklyn.properties (except 
credentials) interfere with test
+        brooklynProperties = origManagementContext.getBrooklynProperties();
+        AbstractJcloudsLiveTest.stripBrooklynProperties(brooklynProperties);
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        List<Exception> exceptions = Lists.newArrayList();
+        for (ManagementContext mgmt : mgmts) {
+            try {
+                if (mgmt.isRunning()) Entities.destroyAll(mgmt);
+            } catch (Exception e) {
+                LOG.warn("Error destroying management context", e);
+                exceptions.add(e);
+            }
+        }
+        mgmts.clear();
+        origManagementContext = null;
+        newManagementContext = null;
+        origApp = null;
+        newApp = null;
+        
+        super.tearDown();
+        
+        if (exceptions.size() > 0) {
+            throw new CompoundRuntimeException("Error in tearDown of 
"+getClass(), exceptions);
+        }
+    }
+
+    @Override
+    protected boolean useLiveManagementContext() {
+        return true;
+    }
+
+    @Override
+    protected TestApplication rebind() throws Exception {
+        TestApplication result = super.rebind();
+        mgmts.add(newManagementContext);
+        return result;
+    }
+    
+    @Test(groups={"Live", "Live-sanity"})
+    public void testRebind() throws Exception {
+        LocationImpl locImpl = new LocationImpl(
+                LocationScope.REGION, 
+                "myLocId", 
+                "myLocDescription", 
+                null, 
+                ImmutableList.<String>of(), // iso3166Codes 
+                ImmutableMap.<String,Object>of()); // metadata
+        
+        NodeMetadata node = new NodeMetadataImpl(
+                "softlayer", 
+                "myname", 
+                "myid", 
+                locImpl,
+                URI.create("http://myuri.com";), 
+                ImmutableMap.<String, String>of(), // userMetadata 
+                ImmutableSet.<String>of(), // tags
+                "mygroup",
+                new HardwareImpl(
+                        "myHardwareProviderId", 
+                        "myHardwareName", 
+                        "myHardwareId", 
+                        locImpl, 
+                        URI.create("http://myuri.com";), 
+                        ImmutableMap.<String, String>of(), // userMetadata 
+                        ImmutableSet.<String>of(), // tags
+                        ImmutableList.<Processor>of(), 
+                        1024, 
+                        ImmutableList.<Volume>of(), 
+                        Predicates.<Image>alwaysTrue(), // supportsImage, 
+                        (String)null, // hypervisor
+                        false),
+                SOFTLAYER_IMAGE_ID,
+                new OperatingSystem(
+                        OsFamily.CENTOS, 
+                        "myOsName", 
+                        "myOsVersion", 
+                        "myOsArch", 
+                        "myDescription", 
+                        true), // is64Bit
+                Status.RUNNING,
+                "myBackendStatus",
+                22, // login-port
+                ImmutableList.of("1.2.3.4"), // publicAddresses, 
+                ImmutableList.of("10.2.3.4"), // privateAddresses, 
+                
LoginCredentials.builder().identity("myidentity").password("mypassword").build(),
 
+                "myHostname");
+        
+        ByonComputeServiceRegistry computeServiceRegistry = new 
ByonComputeServiceRegistry(node);
+        JcloudsLocation origJcloudsLoc = (JcloudsLocation) 
mgmt().getLocationRegistry().resolve("jclouds:softlayer", ImmutableMap.of(
+                JcloudsLocation.COMPUTE_SERVICE_REGISTRY, 
computeServiceRegistry,
+                JcloudsLocation.WAIT_FOR_SSHABLE, false,
+                JcloudsLocation.USE_JCLOUDS_SSH_INIT, false));
+    
+        JcloudsSshMachineLocation origMachine = (JcloudsSshMachineLocation) 
origJcloudsLoc.obtain(ImmutableMap.of("imageId", SOFTLAYER_IMAGE_ID));
+        
+        String origHostname = origMachine.getHostname();
+        NodeMetadata origNode = origMachine.getNode();
+        Template origTemplate = origMachine.getTemplate();
+
+        rebind();
+        
+        // Check the machine is as before
+        JcloudsSshMachineLocation newMachine = (JcloudsSshMachineLocation) 
newManagementContext.getLocationManager().getLocation(origMachine.getId());
+        JcloudsLocation newJcloudsLoc = newMachine.getParent();
+        String newHostname = newMachine.getHostname();
+        NodeMetadata newNode = newMachine.getNode();
+        Template newTemplate = newMachine.getTemplate();
+        
+        assertEquals(newHostname, origHostname);
+        assertEquals(origNode.getId(), newNode.getId());
+        
+        assertEquals(newJcloudsLoc.getProvider(), 
origJcloudsLoc.getProvider());
+    }
+    
+    protected static class ByonComputeServiceRegistry extends 
ComputeServiceRegistryImpl implements ComputeServiceRegistry {
+        private final NodeMetadata node;
+
+        ByonComputeServiceRegistry(NodeMetadata node) throws Exception {
+            this.node = node;
+        }
+
+        @Override
+        public ComputeService findComputeService(ConfigBag conf, boolean 
allowReuse) {
+            ComputeService delegate = super.findComputeService(conf, 
allowReuse);
+            return new StubComputeService(delegate, node);
+        }
+    }
+
+    static class StubComputeService extends DelegatingComputeService {
+        private final NodeMetadata node;
+        
+        public StubComputeService(ComputeService delegate, NodeMetadata node) {
+            super(delegate);
+            this.node = checkNotNull(node, "node");
+        }
+        
+        @Override
+        public void destroyNode(String id) {
+            // no-op
+        }
+        
+        @Override
+        public Set<? extends NodeMetadata> createNodesInGroup(String group, 
int count) throws RunNodesException {
+            return ImmutableSet.of(node);
+        }
+        
+        @Override
+        public Set<? extends NodeMetadata> createNodesInGroup(String group, 
int count, Template template) throws RunNodesException {
+            return ImmutableSet.of(node);
+        }
+        
+        @Override
+        public Set<? extends NodeMetadata> createNodesInGroup(String group, 
int count, TemplateOptions templateOptions) throws RunNodesException {
+            return ImmutableSet.of(node);
+        }
+    }
+}

Reply via email to