Package org.apache.provisionr.amazon

Source Code of org.apache.provisionr.amazon.AmazonProvisionrLiveTest

/*
* 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.provisionr.amazon;

import com.google.common.base.Stopwatch;
import java.io.IOException;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.connection.channel.direct.Session;
import org.apache.provisionr.amazon.options.ProviderOptions;
import org.apache.provisionr.api.Provisionr;
import org.apache.provisionr.api.access.AdminAccess;
import org.apache.provisionr.api.hardware.Hardware;
import org.apache.provisionr.api.network.Network;
import org.apache.provisionr.api.network.Protocol;
import org.apache.provisionr.api.network.Rule;
import org.apache.provisionr.api.pool.Machine;
import org.apache.provisionr.api.pool.Pool;
import org.apache.provisionr.api.provider.Provider;
import org.apache.provisionr.api.software.Software;
import org.apache.provisionr.core.PoolStatus;
import org.apache.provisionr.core.Ssh;
import org.apache.provisionr.core.templates.PoolTemplate;
import static org.apache.provisionr.test.KarafTests.installProvisionrFeatures;
import static org.apache.provisionr.test.KarafTests.installProvisionrTestSupportBundle;
import static org.apache.provisionr.test.KarafTests.passThroughAllSystemPropertiesWithPrefix;
import static org.apache.provisionr.test.KarafTests.useDefaultKarafAsInProjectWithJunitBundles;
import org.apache.provisionr.test.ProvisionrLiveTestSupport;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.Configuration;
import org.ops4j.pax.exam.junit.ExamReactorStrategy;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RunWith(JUnit4TestRunner.class)
@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
public class AmazonProvisionrLiveTest extends ProvisionrLiveTestSupport {

    public static final Logger LOG = LoggerFactory.getLogger(AmazonProvisionrLiveTest.class);

    public static final int TEST_POOL_SIZE = 2;
    public static final String TEST_SPOT_BID_PRICE = "0.04";
    public static final String TEST_INSTANCE_TYPE = "t1.micro";
    public static final String TEST_POOL_TEMPLATE = "jenkins";

    public AmazonProvisionrLiveTest() {
        super(AmazonProvisionr.ID);
    }

    @Configuration
    public Option[] configuration() throws Exception {
        return new Option[]{
            useDefaultKarafAsInProjectWithJunitBundles(),
            passThroughAllSystemPropertiesWithPrefix("test.amazon."),
            installProvisionrFeatures("provisionr-amazon", "provisionr-examples"),
            installProvisionrTestSupportBundle()
        };
    }

    @Test
    public void startProvisioningProcessForOnDemandInstances() throws Exception {
        startProvisioningProcess(null);
    }

    @Test
    public void startProvisioningProcessForSpotInstances() throws Exception {
        startProvisioningProcess(TEST_SPOT_BID_PRICE);
    }

    private void startProvisioningProcess(String spotBid) throws Exception {
        waitForProcessDeployment(AmazonProvisionr.MANAGEMENT_PROCESS_KEY);

        final Provisionr provisionr = getOsgiService(Provisionr.class, 5000);

        Provider provider = collectProviderCredentialsFromSystemProperties()
            .option(ProviderOptions.REGION, getProviderProperty(
                ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION))
            .createProvider();

        if (spotBid != null) {
            provider = provider.toBuilder()
                .option(ProviderOptions.SPOT_BID, spotBid)
                .createProvider();
        }

        final Network network = Network.builder().addRules(
            Rule.builder().anySource().icmp().createRule(),
            Rule.builder().anySource().port(22).protocol(Protocol.TCP).createRule()
        ).createNetwork();

        final Hardware hardware = Hardware.builder().type(TEST_INSTANCE_TYPE).createHardware();

        final AdminAccess adminAccess = AdminAccess.builder().asCurrentUser().createAdminAccess();

        final String destinationPath = "/home/" + adminAccess.getUsername() + "/provisionr.html";
        final Software software = Software.builder()
            .imageId("default")
            .file("http://provisionr.incubator.apache.org", destinationPath)
            .createSoftware();

        PoolTemplate template = getPoolTemplateWithId(TEST_POOL_TEMPLATE, 5000);
        final Pool pool = template.apply(Pool.builder()
            .provider(provider)
            .network(network)
            .adminAccess(adminAccess)
            .software(software)
            .hardware(hardware)
            .minSize(TEST_POOL_SIZE)
            .expectedSize(TEST_POOL_SIZE)
            .createPool());

        final String businessKey = "j-" + UUID.randomUUID().toString();
        String processInstanceId = provisionr.startPoolManagementProcess(businessKey, pool);

        try {
            waitForPoolStatus(provisionr, businessKey, PoolStatus.READY);

            List<Machine> machines = provisionr.getMachines(businessKey);
            assertTrue(machines.size() >= TEST_POOL_SIZE && machines.size() <= TEST_POOL_SIZE);

            for (Machine machine : machines) {
                assertSshCommand(machine, adminAccess, "test -f " + destinationPath);

                /* These are added through the Jenkins Debian template */
                assertSshCommand(machine, adminAccess, "hash git >/dev/null 2>&1");
                assertSshCommand(machine, adminAccess, "hash java >/dev/null 2>&1");
                assertSshCommand(machine, adminAccess, "test -f /etc/apt/sources.list.d/jenkins.list");
            }
        } finally {
            provisionr.destroyPool(businessKey);

            waitForPoolStatus(provisionr, businessKey, PoolStatus.TERMINATED);
            waitForProcessEnd(processInstanceId);
        }
    }

    private PoolTemplate getPoolTemplateWithId(String templateId, int timeoutInMilliseconds)
        throws TimeoutException, InterruptedException {
        ServiceTracker tracker = new ServiceTracker(bundleContext,
            PoolTemplate.class.getCanonicalName(), null);
        tracker.open(true);

        try {
            Stopwatch stopwatch = new Stopwatch().start();
            while (stopwatch.elapsedMillis() < timeoutInMilliseconds) {
                for (Object candidate : tracker.getServices()) {
                    if (PoolTemplate.class.cast(candidate).getId().equals(templateId)) {
                        return PoolTemplate.class.cast(candidate);
                    }
                }
                TimeUnit.MILLISECONDS.sleep(100);
            }

            throw new TimeoutException(String.format("Status check timed out after %d milliseconds",
                stopwatch.elapsedMillis()));

        } finally {
            tracker.close();
        }
    }

    private void assertSshCommand(Machine machine, AdminAccess adminAccess, String bashCommand) throws IOException {
        LOG.info("Checking return code for command '{}' on machine {}", bashCommand, machine.getExternalId());
        SSHClient client = Ssh.newClient(machine, adminAccess);
        try {
            Session session = client.startSession();
            try {
                session.allocateDefaultPTY();
                Session.Command command = session.exec(bashCommand);

                command.join();
                assertTrue("Exit code was " + command.getExitStatus() + " for command " + bashCommand,
                    command.getExitStatus() == 0);
            } finally {
                session.close();
            }
        } finally {
            client.close();
        }
    }

    private void waitForPoolStatus(Provisionr provisionr, String businessKey,
                                   String expectedStatus) throws InterruptedException, TimeoutException {
        String status;
        for (int i = 0; i < 120; i++) {
            try {
                status = provisionr.getStatus(businessKey);

            } catch (NoSuchElementException e) {
                LOG.info(String.format("Pool management process not found with key %s. " +
                    "Assuming process terminated as expected.", businessKey));
                return/* The process ended as expected */
            }

            if (status.equals(expectedStatus)) {
                LOG.info("Pool status is '{}'. Advancing.", status);
                return;
            } else {
                LOG.info("Pool status is '{}'. Waiting 10s for '{}'. Try {}/120",
                    new Object[]{status, expectedStatus, i});
                TimeUnit.SECONDS.sleep(10);
            }
        }
        throw new TimeoutException("Status check timed out after 20 minutes");
    }
}
TOP

Related Classes of org.apache.provisionr.amazon.AmazonProvisionrLiveTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.