/* * 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; import static org.testng.Assert.fail; import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.core.internal.BrooklynProperties; import org.apache.brooklyn.core.location.Machines; import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport; import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; import org.apache.brooklyn.entity.software.base.SoftwareProcess; import org.apache.brooklyn.location.jclouds.JcloudsLocation; import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig; import org.apache.brooklyn.location.ssh.SshMachineLocation; import org.apache.brooklyn.test.Asserts; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.ssh.BashCommands; import org.apache.brooklyn.util.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; /** * Runs a test with many different distros and versions. */ public abstract class AbstractEc2LiveTest extends BrooklynAppLiveTestSupport { // FIXME Currently have just focused on test_Debian_6; need to test the others as well! // TODO No nice fedora VMs // TODO Instead of this sub-classing approach, we could use testng's "provides" mechanism // to say what combo of provider/region/flags should be used. The problem with that is the // IDE integration: one can't just select a single test to run. private static final Logger LOG = LoggerFactory.getLogger(AbstractEc2LiveTest.class); public static final String PROVIDER = "aws-ec2"; public static final String REGION_NAME = "us-east-1"; public static final String LOCATION_SPEC = PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME); public static final String TINY_HARDWARE_ID = "t1.micro"; public static final String SMALL_HARDWARE_ID = "m1.small"; protected BrooklynProperties brooklynProperties; protected Location jcloudsLocation; @BeforeMethod(alwaysRun=true) @Override public void setUp() throws Exception { // Don't let any defaults from brooklyn.properties (except credentials) interfere with test brooklynProperties = BrooklynProperties.Factory.newDefault(); brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-description-regex"); brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-name-regex"); brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-id"); brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".inboundPorts"); brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".hardware-id"); // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty") brooklynProperties.remove("brooklyn.ssh.config.scriptHeader"); mgmt = new LocalManagementContextForTests(brooklynProperties); super.setUp(); } // Image ids for Debian: https://wiki.debian.org/Cloud/AmazonEC2Image/Squeeze @Test(groups = {"Live"}) public void test_Debian_6() throws Exception { // release codename "squeeze" runTest(ImmutableMap.of("imageId", "us-east-1/ami-5e12dc36", "loginUser", "admin", "hardwareId", SMALL_HARDWARE_ID)); } @Test(groups = {"Live"}) public void test_Debian_7_2() throws Exception { // release codename "wheezy" runTest(ImmutableMap.of("imageId", "us-east-1/ami-5586a43c", "loginUser", "admin", "hardwareId", SMALL_HARDWARE_ID)); } @Test(groups = {"Live"}) public void test_Ubuntu_10_0() throws Exception { // Image: {id=us-east-1/ami-5e008437, providerId=ami-5e008437, name=RightImage_Ubuntu_10.04_x64_v5.8.8.3, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=10.04, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, version=5.8.8.3, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}} runTest(ImmutableMap.of("imageId", "us-east-1/ami-5e008437", "loginUser", "root", "hardwareId", SMALL_HARDWARE_ID)); } @Test(groups = {"Live"}) public void test_Ubuntu_12_0() throws Exception { // Image: {id=us-east-1/ami-d0f89fb9, providerId=ami-d0f89fb9, name=ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=12.04, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, is64Bit=true}, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, version=20130411.1, status=AVAILABLE[available], loginUser=ubuntu, userMetadata={owner=099720109477, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}} runTest(ImmutableMap.of("imageId", "us-east-1/ami-d0f89fb9", "loginUser", "ubuntu", "hardwareId", SMALL_HARDWARE_ID)); } @Test(groups = {"Live"}) public void test_CentOS_6_3() throws Exception { // TODO Should openIptables=true be the default?! // Image: {id=us-east-1/ami-a96b01c0, providerId=ami-a96b01c0, name=CentOS-6.3-x86_64-GA-EBS-02-85586466-5b6c-4495-b580-14f72b4bcf51-ami-bb9af1d2.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=6.3, description=aws-marketplace/CentOS-6.3-x86_64-GA-EBS-02-85586466-5b6c-4495-b580-14f72b4bcf51-ami-bb9af1d2.1, is64Bit=true}, description=CentOS-6.3-x86_64-GA-EBS-02 on EBS x86_64 20130527:1219, version=bb9af1d2.1, status=AVAILABLE[available], loginUser=root, userMetadata={owner=679593333241, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}) runTest(ImmutableMap.of("imageId", "us-east-1/ami-a96b01c0", "hardwareId", SMALL_HARDWARE_ID, JcloudsLocation.OPEN_IPTABLES.getName(), true)); } @Test(groups = {"Live"}) public void test_CentOS_5() throws Exception { // Image: {id=us-east-1/ami-e4bffe8d, providerId=ami-e4bffe8d, name=RightImage_CentOS_5.9_x64_v12.11.4_EBS, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=5.0, description=411009282317/RightImage_CentOS_5.9_x64_v12.11.4_EBS, is64Bit=true}, description=RightImage_CentOS_5.9_x64_v12.11.4_EBS, version=12.11.4_EBS, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}} runTest(ImmutableMap.of("imageId", "us-east-1/ami-e4bffe8d", "hardwareId", SMALL_HARDWARE_ID)); } @Test(groups = {"Live"}) public void test_Red_Hat_Enterprise_Linux_6() throws Exception { // Image: {id=us-east-1/ami-a35a33ca, providerId=ami-a35a33ca, name=RHEL-6.3_GA-x86_64-5-Hourly2, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=rhel, arch=paravirtual, version=6.0, description=309956199498/RHEL-6.3_GA-x86_64-5-Hourly2, is64Bit=true}, description=309956199498/RHEL-6.3_GA-x86_64-5-Hourly2, version=Hourly2, status=AVAILABLE[available], loginUser=root, userMetadata={owner=309956199498, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}} runTest(ImmutableMap.of("imageId", "us-east-1/ami-a35a33ca", "hardwareId", SMALL_HARDWARE_ID, JcloudsLocationConfig.OPEN_IPTABLES.getName(), "true")); } @Test(groups = {"Live"}) public void test_Suse_11sp3() throws Exception { // Image: {id=us-east-1/ami-c08fcba8, providerId=ami-c08fcba8, name=suse-sles-11-sp3-v20150127-pv-ssd-x86_64, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=suse, arch=paravirtual, version=, description=amazon/suse-sles-11-sp3-v20150127-pv-ssd-x86_64, is64Bit=true}, description=SUSE Linux Enterprise Server 11 Service Pack 3 (PV, 64-bit, SSD-Backed), version=x86_64, status=AVAILABLE[available], loginUser=root, userMetadata={owner=013907871322, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}} runTest(ImmutableMap.of("imageId", "us-east-1/ami-c08fcba8", "hardwareId", SMALL_HARDWARE_ID, "loginUser", "ec2-user"));//, JcloudsLocationConfig.OPEN_IPTABLES.getName(), "true")); } protected void runTest(Map<String,?> flags) throws Exception { Map<String,?> allFlags = MutableMap.<String,Object>builder() .put("tags", ImmutableList.of(getClass().getName())) .putAll(flags) .build(); jcloudsLocation = mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags); doTest(jcloudsLocation); } protected abstract void doTest(Location loc) throws Exception; protected void assertExecSsh(SoftwareProcess entity, List<String> commands) { SshMachineLocation machine = Machines.findUniqueMachineLocation(entity.getLocations(), SshMachineLocation.class).get(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ByteArrayOutputStream errStream = new ByteArrayOutputStream(); int result = machine.execScript(ImmutableMap.of("out", outStream, "err", errStream), "url-reachable", commands); String out = new String(outStream.toByteArray()); String err = new String(errStream.toByteArray()); if (result == 0) { LOG.debug("Successfully executed: cmds="+commands+"; stderr="+err+"; out="+out); } else { fail("Failed to execute: result="+result+"; cmds="+commands+"; stderr="+err+"; out="+out); } } protected void assertViaSshLocalPortListeningEventually(final SoftwareProcess server, final int port) { Asserts.succeedsEventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), new Runnable() { public void run() { assertExecSsh(server, ImmutableList.of("netstat -antp", "netstat -antp | grep LISTEN | grep "+port)); }}); } protected void assertViaSshLocalUrlListeningEventually(final SoftwareProcess server, final String url) { Asserts.succeedsEventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), new Runnable() { public void run() { assertExecSsh(server, ImmutableList.of(BashCommands.installPackage("curl"), "netstat -antp", "curl -k --retry 3 "+url)); }}); } }