provisionr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From as...@apache.org
Subject [05/21] PROVISIONR-20. Change groupId from com.axemblr.provisionr to org.apache.provisionr
Date Mon, 01 Apr 2013 08:52:28 GMT
http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java
new file mode 100644
index 0000000..2a84985
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/AmazonActivityLiveTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
+import org.apache.provisionr.amazon.AmazonProvisionr;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.amazon.core.ProviderClientCacheSupplier;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.test.Generics;
+import org.apache.provisionr.test.ProvisionrLiveTestSupport;
+import com.google.common.base.Throwables;
+import java.lang.reflect.Constructor;
+import java.util.UUID;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AmazonActivityLiveTest<T extends AmazonActivity> extends ProvisionrLiveTestSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AmazonActivityLiveTest.class);
+
+    protected final String BUSINESS_KEY = "j-" + UUID.randomUUID().toString();
+
+    /**
+     * Cloud provider credentials collected from system properties
+     */
+    protected Provider provider;
+
+    /**
+     * Instance of the AmazonActivity being tested. Automatically created
+     * from the generic type class argument
+     */
+    protected T activity;
+
+    /**
+     * Amazon EC2 client
+     */
+    protected AmazonEC2 client;
+
+    /**
+     * A cache of AmazonEC2 client instances by Provider
+     */
+    private ProviderClientCache clientCache;
+
+    public AmazonActivityLiveTest() {
+        super(AmazonProvisionr.ID);
+    }
+
+    /**
+     * Create an instance using the default constructor for the class type argument
+     *
+     * @param klass
+     * @param clientCache cache for AmazonEC2 client connections
+     */
+    protected <A extends AmazonActivity> A createAmazonActivityInstance(
+        Class<A> klass, ProviderClientCache clientCache
+    ) {
+        try {
+            Constructor<A> constructor = klass.getConstructor(ProviderClientCache.class);
+            return (A) constructor.newInstance(clientCache);
+
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    /**
+     * Retrieve the generic class type argument.
+     */
+    protected Class<T> getAmazonActivityClass() {
+        return Generics.getTypeParameter(getClass(), AmazonActivity.class);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        final String region = getProviderProperty(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
+
+        provider = collectProviderCredentialsFromSystemProperties()
+            .option(ProviderOptions.REGION, region).createProvider();
+        LOG.info("Using provider {}", provider);
+
+        clientCache = (new ProviderClientCacheSupplier()).get();
+        client = clientCache.getUnchecked(provider);
+
+        activity = createAmazonActivityInstance(getAmazonActivityClass(), clientCache);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        client.shutdown();
+    }
+
+    protected void executeActivitiesInSequence(
+        DelegateExecution execution, Class<? extends AmazonActivity>... classes
+    ) throws Exception {
+        for (Class<? extends AmazonActivity> klass : classes) {
+            createAmazonActivityInstance(klass, clientCache).execute(execution);
+        }
+    }
+
+    protected void quietlyDeleteSecurityGroupIfExists(String groupName) {
+        try {
+            client.deleteSecurityGroup(new DeleteSecurityGroupRequest().withGroupName(groupName));
+
+        } catch (AmazonServiceException e) {
+            if (!e.getErrorCode().equals("InvalidGroup.NotFound")) {
+                throw Throwables.propagate(e);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java
new file mode 100644
index 0000000..18e0644
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/CreatePoolLiveTest.java
@@ -0,0 +1,72 @@
+package org.apache.provisionr.amazon.activities;
+
+import java.util.ArrayList;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.hardware.BlockDevice;
+import org.apache.provisionr.api.hardware.Hardware;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.software.Software;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public abstract class CreatePoolLiveTest<T extends AmazonActivity> extends AmazonActivityLiveTest<T> {
+
+    protected DelegateExecution execution;
+    protected Pool pool;
+    protected Hardware hardware;
+    protected Software software;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        execution = mock(DelegateExecution.class);
+        pool = mock(Pool.class);
+
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        final Network network = Network.builder().addRules(
+            Rule.builder().anySource().tcp().port(22).createRule()).createNetwork();
+
+        hardware = mock(Hardware.class);
+        when(hardware.getType()).thenReturn("t1.micro");
+        when(hardware.getBlockDevices()).thenReturn(new ArrayList<BlockDevice>());
+
+        software = mock(Software.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+        when(pool.getNetwork()).thenReturn(network);
+
+        when(pool.getMinSize()).thenReturn(1);
+        when(pool.getExpectedSize()).thenReturn(1);
+
+        when(pool.getHardware()).thenReturn(hardware);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        executeActivitiesInSequence(execution,
+            EnsureKeyPairExists.class,
+            EnsureSecurityGroupExists.class
+        );
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void tearDown() throws Exception {
+        executeActivitiesInSequence(execution,
+            DeleteSecurityGroup.class,
+            DeleteKeyPair.class
+        );
+        super.tearDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
new file mode 100644
index 0000000..5257c85
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteKeyPairLiveTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
+import com.amazonaws.services.ec2.model.ImportKeyPairRequest;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.ErrorCodes;
+import org.apache.provisionr.amazon.core.KeyPairs;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DeleteKeyPairLiveTest extends AmazonActivityLiveTest<DeleteKeyPair> {
+
+    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        client.importKeyPair(new ImportKeyPairRequest().withKeyName(KEYPAIR_NAME)
+            .withPublicKeyMaterial(getResourceAsString("keys/test.pub")));
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(KEYPAIR_NAME));
+        super.tearDown();
+    }
+
+    @Test
+    public void testDeleteKeyPair() throws Exception {
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+        when(pool.getProvider()).thenReturn(provider);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        activity.execute(execution);
+        assertKeyNotFound(KEYPAIR_NAME);
+
+        /* the second call should just do nothing */
+        activity.execute(execution);
+    }
+
+    public void assertKeyNotFound(String keyName) {
+        final DescribeKeyPairsRequest request = new DescribeKeyPairsRequest().withKeyNames(keyName);
+        try {
+            DescribeKeyPairsResult result = client.describeKeyPairs(request);
+            fail("Found key " + result.getKeyPairs().get(0));
+
+        } catch (AmazonServiceException e) {
+            assertThat(e.getErrorCode()).isEqualTo(ErrorCodes.KEYPAIR_NOT_FOUND);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
new file mode 100644
index 0000000..245af79
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/DeleteSecurityGroupLiveTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.SecurityGroups;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.fest.assertions.api.Assertions.fail;
+import org.junit.After;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DeleteSecurityGroupLiveTest extends AmazonActivityLiveTest<DeleteSecurityGroup> {
+
+    private final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @After
+    public void tearDown() throws Exception {
+        quietlyDeleteSecurityGroupIfExists(SECURITY_GROUP_NAME);
+        super.tearDown();
+    }
+
+    @Test
+    public void testDeleteSecurityGroup() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+
+        client.createSecurityGroup(new CreateSecurityGroupRequest()
+            .withGroupName(SECURITY_GROUP_NAME).withDescription("Just for test"));
+
+        activity.execute(execution);
+
+        try {
+            client.describeSecurityGroups(new DescribeSecurityGroupsRequest()
+                .withGroupNames(SECURITY_GROUP_NAME));
+            fail("Did not throw AmazonServiceException as expected");
+
+        } catch (AmazonServiceException e) {
+            assertThat(e.getErrorCode()).isEqualTo("InvalidGroup.NotFound");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
new file mode 100644
index 0000000..8eebf13
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureKeyPairExistsLiveTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.KeyPairs;
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class EnsureKeyPairExistsLiveTest extends AmazonActivityLiveTest<EnsureKeyPairExists> {
+
+    /**
+     * Computed in an Amazon specific way
+     */
+    public static final String TEST_KEY_FINGERPRINT = "2f:e9:a0:bc:17:71:3a:7e:d7:c0:16:99:0d:62:8e:be";
+
+    private final String KEYPAIR_NAME = KeyPairs.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @Override
+    public void tearDown() throws Exception {
+        client.deleteKeyPair(new DeleteKeyPairRequest().withKeyName(KEYPAIR_NAME));
+        super.tearDown();
+    }
+
+    @Test
+    public void testEnsureKeyPairExists() throws Exception {
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .username("admin")
+            .publicKey(getResourceAsString("keys/test.pub"))
+            .privateKey(getResourceAsString("keys/test"))
+            .createAdminAccess();
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+
+        activity.execute(execution);
+        assertKeyPairWasImportedAsExpected();
+
+        /* the second call should just re-import the key */
+        activity.execute(execution);
+        assertKeyPairWasImportedAsExpected();
+    }
+
+    private void assertKeyPairWasImportedAsExpected() {
+        final DescribeKeyPairsRequest request = new DescribeKeyPairsRequest().withKeyNames(KEYPAIR_NAME);
+        DescribeKeyPairsResult result = client.describeKeyPairs(request);
+
+        assertThat(result.getKeyPairs()).hasSize(1);
+        assertThat(result.getKeyPairs().get(0).getKeyFingerprint()).isEqualTo(TEST_KEY_FINGERPRINT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
new file mode 100644
index 0000000..d4fc69b
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/EnsureSecurityGroupExistsLiveTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
+import com.amazonaws.services.ec2.model.IpPermission;
+import com.amazonaws.services.ec2.model.RevokeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.SecurityGroup;
+import com.google.common.collect.ImmutableSet;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Lists.newArrayList;
+import com.google.common.collect.Sets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.core.SecurityGroups;
+import org.apache.provisionr.amazon.functions.ConvertIpPermissionToRule;
+import org.apache.provisionr.amazon.functions.ConvertRuleToIpPermission;
+import org.apache.provisionr.api.network.Network;
+import org.apache.provisionr.api.network.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.CoreProcessVariables;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.After;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnsureSecurityGroupExistsLiveTest extends AmazonActivityLiveTest<EnsureSecurityGroupExists> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EnsureSecurityGroupExistsLiveTest.class);
+
+    protected final String SECURITY_GROUP_NAME = SecurityGroups.formatNameFromBusinessKey(BUSINESS_KEY);
+
+    @After
+    public void tearDown() throws Exception {
+        quietlyDeleteSecurityGroupIfExists(SECURITY_GROUP_NAME);
+        super.tearDown();
+    }
+
+    @Test
+    public void testCreateSecurityGroup() throws Exception {
+        DelegateExecution execution = mock(DelegateExecution.class);
+
+        final ImmutableSet<Rule> ingressRules = ImmutableSet.of(
+            Rule.builder().anySource().icmp().createRule(),
+            Rule.builder().anySource().port(22).tcp().createRule(),
+            Rule.builder().anySource().port(53).udp().createRule()
+        );
+
+        final Network network = Network.builder().ingress(ingressRules).createNetwork();
+
+        Pool pool = mock(Pool.class);
+
+        when(pool.getProvider()).thenReturn(provider);
+        when(pool.getNetwork()).thenReturn(network);
+
+        when(execution.getVariable(CoreProcessVariables.POOL)).thenReturn(pool);
+        when(execution.getProcessBusinessKey()).thenReturn(BUSINESS_KEY);
+
+        activity.execute(execution);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
+
+        /* If any permissions is removed it should converge on a second run */
+        Set<Rule> expectedAfterRevoke = revokeAnyRule(ingressRules);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, expectedAfterRevoke);
+
+        activity.execute(execution);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
+
+        /* If any permissions is added it should converge on a second run */
+        final IpPermission permission = new IpPermission().withIpProtocol("tcp")
+            .withIpRanges("0.0.0.0/0").withFromPort(100).withToPort(120);
+
+        client.authorizeSecurityGroupIngress(new AuthorizeSecurityGroupIngressRequest()
+            .withGroupName(SECURITY_GROUP_NAME).withIpPermissions(permission));
+
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, Sets.<Rule>union(ingressRules,
+            ImmutableSet.of(ConvertIpPermissionToRule.FUNCTION.apply(permission))));
+
+        activity.execute(execution);
+        assertSecurityGroupExistsWithRules(SECURITY_GROUP_NAME, ingressRules);
+    }
+
+    private Set<Rule> revokeAnyRule(Set<Rule> ingressRules) {
+        List<IpPermission> permissions = newArrayList(transform(ingressRules, ConvertRuleToIpPermission.FUNCTION));
+        Collections.shuffle(permissions);
+
+        IpPermission permission = permissions.get(0);
+        LOG.info(">> Revoking permission {} on {} for test.", permission, SECURITY_GROUP_NAME);
+
+        client.revokeSecurityGroupIngress(new RevokeSecurityGroupIngressRequest()
+            .withGroupName(SECURITY_GROUP_NAME).withIpPermissions(permission));
+
+        return Sets.difference(ingressRules, ImmutableSet.of(ConvertIpPermissionToRule.FUNCTION.apply(permission)));
+    }
+
+    public void assertSecurityGroupExistsWithRules(String groupName, final Set<Rule> ingressRules) {
+        DescribeSecurityGroupsResult result = client.describeSecurityGroups(
+            new DescribeSecurityGroupsRequest().withGroupNames(groupName));
+
+        assertThat(result.getSecurityGroups()).hasSize(1);
+        SecurityGroup group = getOnlyElement(result.getSecurityGroups());
+
+        assertThat(group.getIpPermissions()).hasSize(ingressRules.size());
+        assertThat(ingressRules).containsAll(transform(group.getIpPermissions(),
+            ConvertIpPermissionToRule.FUNCTION));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java
new file mode 100644
index 0000000..e65867c
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/PublishListOfMachinesTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.DescribeInstancesResult;
+import com.amazonaws.services.ec2.model.Instance;
+import com.amazonaws.services.ec2.model.Reservation;
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.core.ProviderClientCache;
+import org.apache.provisionr.api.pool.Machine;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.core.CoreProcessVariables;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import org.mockito.Matchers;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PublishListOfMachinesTest {
+
+    @Test
+    public void testPublishListOfMachines() throws Exception {
+        AmazonEC2 client = mock(AmazonEC2.class);
+
+        ProviderClientCache clientCache = mock(ProviderClientCache.class);
+        when(clientCache.get(Matchers.<Provider>any())).thenReturn(client);
+
+        DelegateExecution execution = mock(DelegateExecution.class);
+        List<String> instanceIds = Lists.newArrayList("i-123", "i-456");
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(instanceIds);
+
+        when(client.describeInstances(Matchers.<DescribeInstancesRequest>any()))
+            .thenReturn(new DescribeInstancesResult()
+                .withReservations(new Reservation().withInstances(
+                    new Instance().withInstanceId("i-123").withPublicDnsName("i1.amazonaws.com")
+                        .withPublicIpAddress("1.2.3.4").withPrivateDnsName("i1.internal").withPrivateIpAddress("10.1.2.3"),
+                    new Instance().withInstanceId("i-456").withPublicDnsName("i2.amazonaws.com")
+                        .withPublicIpAddress("5.6.7.8").withPrivateDnsName("i2.internal").withPrivateIpAddress("10.4.5.6")
+                )));
+
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        AmazonActivity activity = new PublishListOfMachines(clientCache);
+        activity.execute(client, null /* not used */, execution);
+
+        @SuppressWarnings("unchecked")
+        List<Machine> machines = (List<Machine>) collector.getVariable(CoreProcessVariables.MACHINES);
+
+        assertThat(machines).hasSize(2);
+        assertThat(machines.get(0).getPublicDnsName()).isEqualTo("i1.amazonaws.com");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
new file mode 100644
index 0000000..58745c6
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunOnDemandInstancesLiveTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.DescribeInstancesResult;
+import com.amazonaws.services.ec2.model.DescribeVolumesRequest;
+import com.amazonaws.services.ec2.model.DescribeVolumesResult;
+import com.amazonaws.services.ec2.model.Instance;
+import com.amazonaws.services.ec2.model.InstanceBlockDeviceMapping;
+import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
+import com.amazonaws.services.ec2.model.Volume;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.api.hardware.BlockDevice;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Uninterruptibles;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+
+public class RunOnDemandInstancesLiveTest extends CreatePoolLiveTest<RunOnDemandInstances> {
+
+    private static final String UBUNTU_AMI_ID = "ami-1e831d77"; // Ubuntu 13.04 amd64
+    private ProcessVariablesCollector collector;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        collector = new ProcessVariablesCollector();
+        collector.install(execution);
+    }
+
+    @Test
+    public void testRunInstances() throws Exception {
+
+        activity.execute(execution);
+
+        verify(execution).setVariable(eq(ProcessVariables.RESERVATION_ID), anyString());
+        verify(execution).setVariable(eq(ProcessVariables.INSTANCE_IDS), any());
+
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+
+        /* the second call should do nothing */
+        activity.execute(execution);
+
+        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+            .withInstanceIds(instanceIds));
+
+        assertThat(result.getReservations()).hasSize(1);
+        assertThat(result.getReservations().get(0).getInstances()).hasSize(1);
+
+    }
+
+    @Test
+    public void testRunInstancesWithBlockDevices() throws Exception {
+        // TODO: maybe we should also test for spot instances
+        BlockDevice blockDevice = mock(BlockDevice.class);
+        when(blockDevice.getSize()).thenReturn(8); // TODO: understand why it doesn't work for smaller volumes
+        when(blockDevice.getName()).thenReturn("/dev/sda1");
+        BlockDevice blockDevice2 = mock(BlockDevice.class);
+        when(blockDevice2.getSize()).thenReturn(16);
+        when(blockDevice2.getName()).thenReturn("/dev/sda4");
+        when(hardware.getBlockDevices()).thenReturn(Lists.newArrayList(blockDevice, blockDevice2));
+
+        activity.execute(execution);
+
+        Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
+
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+            .withInstanceIds(instanceIds));
+
+        Instance instance = result.getReservations().get(0).getInstances().get(0);
+        List<InstanceBlockDeviceMapping> bdm = instance.getBlockDeviceMappings();
+        assertThat(bdm).hasSize(2);
+        List<String> volumeIds = Lists.newArrayList();
+        for (int i = 0; i < bdm.size(); i++) {
+            assertThat(bdm.get(i).getDeviceName()).isEqualTo("/dev/sda" + ((i+1) * (i+1)));
+            assertThat(bdm.get(i).getEbs().getDeleteOnTermination()).isTrue();
+            volumeIds.add(bdm.get(i).getEbs().getVolumeId());
+        }
+
+        DescribeVolumesResult volumesResult = client.describeVolumes(
+                new DescribeVolumesRequest().withVolumeIds(volumeIds));
+        for (Volume volume : volumesResult.getVolumes()) {
+            assertThat(volume.getState()).isIn(Lists.newArrayList("creating", "available", "in-use"));
+        }
+        assertThat(volumesResult.getVolumes().get(0).getSize()).isNotEqualTo(volumesResult.getVolumes().get(1).getSize());
+    }
+
+    @Test
+    public void testRunInstancesWithABaseImageId() throws Exception {
+        when(software.getImageId()).thenReturn(UBUNTU_AMI_ID);
+        when(pool.getSoftware()).thenReturn(software);
+        activity.execute(execution);
+
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+        DescribeInstancesResult result = client.describeInstances(new DescribeInstancesRequest()
+            .withInstanceIds(instanceIds));
+
+        Instance instance = result.getReservations().get(0).getInstances().get(0);
+        assertThat(instance.getImageId()).isEqualTo(UBUNTU_AMI_ID);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        @SuppressWarnings("unchecked")
+        List<String> instanceIds = (List<String>) collector.getVariable(ProcessVariables.INSTANCE_IDS);
+        client.terminateInstances(new TerminateInstancesRequest().withInstanceIds(instanceIds));
+
+        // TODO: this behaves strangely, if it tries to delete the security group 
+        // and the instances are not yet killed, the test fails with an error
+        Uninterruptibles.sleepUninterruptibly(45, TimeUnit.SECONDS);
+        super.tearDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
new file mode 100644
index 0000000..0e526da
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/RunSpotInstancesLiveTest.java
@@ -0,0 +1,107 @@
+/*
+* Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+*
+* Licensed 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.activities;
+
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsRequest;
+import com.amazonaws.services.ec2.model.DescribeSpotInstanceRequestsResult;
+import com.amazonaws.services.ec2.model.Filter;
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.amazon.options.ProviderOptions;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import com.google.common.util.concurrent.Uninterruptibles;
+
+public class RunSpotInstancesLiveTest extends CreatePoolLiveTest<RunSpotInstances> {
+
+    /**
+     * This should be set a bit higher than the on demand instance
+     * price to avoid the situation in which the test fails because
+     * the spot bid is too low. 
+     */
+    public static String AMAZON_SPOT_BID = "0.04";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        final String region = getProviderProperty(ProviderOptions.REGION, ProviderOptions.DEFAULT_REGION);
+        provider = collectProviderCredentialsFromSystemProperties()
+                .option(ProviderOptions.REGION, region)
+                .option(ProviderOptions.SPOT_BID, AMAZON_SPOT_BID)
+                .createProvider();
+        when(pool.getProvider()).thenReturn(provider);
+    }
+
+    @Test
+    public void testRunSpotInstances() throws Exception {
+        ProcessVariablesCollector collector = new ProcessVariablesCollector();
+        collector.install(execution);
+
+        activity.execute(execution);
+
+        @SuppressWarnings("unchecked")
+        ArgumentCaptor<List<String>> argument = (ArgumentCaptor<List<String>>) 
+                (Object) ArgumentCaptor.forClass(List.class);
+        verify(execution).setVariable(eq(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS), argument.capture());
+        when(execution.getVariable(ProcessVariables.SPOT_INSTANCE_REQUEST_IDS)).thenReturn(argument.getValue());
+        /* The timeout is needed because the describe calls don't return immediately. */
+        // TODO: see if we can eliminate this after adding the process variables conditions
+        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
+
+        // shouldn't do anything
+        activity.execute(execution);
+
+        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
+
+        DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(
+                new DescribeSpotInstanceRequestsRequest().withFilters(new Filter()
+                    .withName("launch-group").withValues(BUSINESS_KEY)));
+
+        assertThat(result.getSpotInstanceRequests()).hasSize(1);
+        /* we also need to sleep before the teardown */
+        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void tearDown() throws Exception {
+        // cleanup any pending requests or instances
+        ArgumentCaptor<List<String>> argument = (ArgumentCaptor<List<String>>) 
+                (Object) ArgumentCaptor.forClass(List.class);
+
+        executeActivitiesInSequence(execution,
+                CancelSpotRequests.class, 
+                GetInstanceIdsFromSpotRequests.class);
+
+        verify(execution).setVariable(eq(ProcessVariables.INSTANCE_IDS), argument.capture());
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(argument.getValue());
+
+        executeActivitiesInSequence(execution, TerminateInstances.class);
+        super.tearDown();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java
new file mode 100644
index 0000000..2f21a6f
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/SetupAdminAccessTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import org.apache.provisionr.api.access.AdminAccess;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.core.activities.PuppetActivity;
+import org.apache.provisionr.test.TestConstants;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SetupAdminAccessTest {
+
+    @Test
+    public void testCreatePuppetScript() throws Exception {
+        Pool pool = mock(Pool.class);
+
+        final AdminAccess adminAccess = AdminAccess.builder()
+            .privateKey(TestConstants.PRIVATE_KEY)
+            .publicKey(TestConstants.PUBLIC_KEY)
+            .username(System.getProperty("user.name"))
+            .createAdminAccess();
+
+        when(pool.getAdminAccess()).thenReturn(adminAccess);
+
+        PuppetActivity activity = new SetupAdminAccess();
+        String content = activity.createPuppetScript(pool, null);
+
+        final String username = adminAccess.getUsername();
+
+        assertThat(content).contains(username)
+            .contains(adminAccess.getPublicKey().split(" ")[1])
+            .contains(String.format("user { \"%s\":", username))
+            .contains(String.format("file { \"/home/%s/.ssh\":", username));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java
new file mode 100644
index 0000000..a095c4a
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/activities/TerminateInstancesLiveTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.activities;
+
+import org.apache.provisionr.amazon.ProcessVariables;
+import org.apache.provisionr.test.ProcessVariablesCollector;
+import org.junit.Test;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TerminateInstancesLiveTest extends CreatePoolLiveTest<TerminateInstances> {
+
+    private ProcessVariablesCollector collector;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        collector = new ProcessVariablesCollector();
+        collector.install(execution);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testTerminateInstances() throws Exception {
+        executeActivitiesInSequence(execution,
+                EnsureKeyPairExists.class,
+                EnsureSecurityGroupExists.class,
+                RunOnDemandInstances.class
+            );
+
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS))
+            .thenReturn(collector.getVariable(ProcessVariables.INSTANCE_IDS));
+
+        activity.execute(execution);
+
+        /* the second execution should do nothing */
+        activity.execute(execution);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testTerminateInstancesNoIdsPresent() throws Exception {
+        executeActivitiesInSequence(execution,
+                EnsureKeyPairExists.class,
+                EnsureSecurityGroupExists.class
+            );
+        when(execution.getVariable(ProcessVariables.INSTANCE_IDS)).thenReturn(null);
+
+        // should not throw any exception and should not do anything
+        activity.execute(execution);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java
new file mode 100644
index 0000000..394d526
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/config/DefaultProviderConfigTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.config;
+
+import org.apache.provisionr.api.provider.Provider;
+import com.google.common.base.Optional;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class DefaultProviderConfigTest {
+
+    @Test
+    public void testProviderIsAbsentIfCredentialsAreEmpty() {
+        DefaultProviderConfig config = new DefaultProviderConfig("", "", "us-east-1", "");
+        assertThat(config.createProvider().isPresent()).isFalse();
+    }
+
+    @Test
+    public void testProviderWithNoRegionAndEndpoint() {
+        DefaultProviderConfig config = new DefaultProviderConfig("access", "secret", "", "");
+
+        Optional<Provider> provider = config.createProvider();
+        assertThat(provider.isPresent()).isTrue();
+
+        assertThat(provider.get().getEndpoint().isPresent()).isFalse();
+        assertThat(provider.get().getOptions().containsKey("region")).isFalse();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java
new file mode 100644
index 0000000..145c77e
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableQueryTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.core;
+
+import java.io.IOException;
+import org.junit.Test;
+
+public class ImageTableQueryTest {
+
+    public final ImageTable table;
+
+    public ImageTableQueryTest() throws IOException {
+        this.table = ImageTable.fromCsvResource("/org/apache/provisionr/amazon/ubuntu.csv");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testQueryFailsWithMultipleResults() {
+        table.query().filterBy("region", "us-east-1").singleResult();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java
new file mode 100644
index 0000000..50c7f1c
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/core/ImageTableTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.core;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Table;
+import com.google.common.collect.Tables;
+import java.io.IOException;
+import java.util.Map;
+import static org.fest.assertions.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class ImageTableTest {
+
+    @Test
+    public void testLoadAmiTableFromResource() throws IOException {
+        ImageTable table = ImageTable.fromCsvResource("/org/apache/provisionr/amazon/ubuntu.csv");
+
+        String id = table.query().filterBy("region", "us-east-1").filterBy("version", "12.04 LTS")
+            .filterBy("arch", "amd64").filterBy("type", "instance-store").singleResult();
+
+        assertThat(id).isEqualTo("ami-9a873ff3");
+    }
+
+    @Test
+    public void testExtractHeaderLine() throws Exception {
+        Iterable<String> headers = ImageTable.extractHeaders(ImmutableList.of("a,b,c", "1,2,3"));
+        assertThat(headers).containsAll(ImmutableList.of("a", "b", "c"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testCombineHeadersWithLinePartsAsTableCells() {
+        final ImmutableList<String> headers = ImmutableList.of("a", "b");
+        final ImmutableList<String> lineParts = ImmutableList.of("1", "2");
+
+        Iterable<Table.Cell<String, String, String>> cells =
+            ImageTable.combineHeadersWithLinePartsAsTableCells(0, headers, lineParts);
+
+        assertThat(cells).contains(Tables.immutableCell("0", "a", "1"));
+    }
+
+    @Test
+    public void testZipIterators() {
+        Iterable<Map.Entry<String, String>> entries = ImageTable.zip(
+            ImmutableList.of("a", "b"), ImmutableList.of("1", "2"));
+
+        assertThat(entries).containsAll(ImmutableList.of(
+            Maps.immutableEntry("a", "1"), Maps.immutableEntry("b", "2")));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
----------------------------------------------------------------------
diff --git a/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java b/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
new file mode 100644
index 0000000..9016344
--- /dev/null
+++ b/providers/amazon/src/test/java/org/apache/provisionr/amazon/functions/ConvertIpPermissionToRuleAndBackTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.functions;
+
+import com.amazonaws.services.ec2.model.IpPermission;
+import org.apache.provisionr.api.network.Protocol;
+import org.apache.provisionr.api.network.Rule;
+import static org.fest.assertions.api.Assertions.assertThat;
+import static org.junit.Assert.assertNotNull;
+import org.junit.Test;
+
+public class ConvertIpPermissionToRuleAndBackTest {
+
+    @Test
+    public void testConvertTcpIpPermissionToRuleAndBack() {
+        IpPermission expected = new IpPermission().withFromPort(1).withToPort(1024)
+            .withIpProtocol("tcp").withIpRanges("0.0.0.0/0");
+
+        Rule rule = ConvertIpPermissionToRule.FUNCTION.apply(expected);
+        assertNotNull(rule);
+
+        assertThat(rule.getCidr()).isEqualTo("0.0.0.0/0");
+        assertThat(rule.getProtocol()).isEqualTo(Protocol.TCP);
+
+        assertThat(rule.getPorts().lowerEndpoint()).isEqualTo(1);
+        assertThat(rule.getPorts().upperEndpoint()).isEqualTo(1024);
+
+        IpPermission actual = ConvertRuleToIpPermission.FUNCTION.apply(rule);
+        assertThat(actual).isEqualTo(expected);
+    }
+
+    @Test
+    public void testConvertIcmpPermissionToRule() {
+        IpPermission expected = new IpPermission().withIpProtocol("icmp")
+            .withFromPort(-1).withToPort(-1).withIpRanges("0.0.0.0/0");
+
+        Rule rule = ConvertIpPermissionToRule.FUNCTION.apply(expected);
+        assertNotNull(rule);
+
+        assertThat(rule.getProtocol()).isEqualTo(Protocol.ICMP);
+        assertThat(rule.getCidr()).isEqualTo("0.0.0.0/0");
+
+        IpPermission actual = ConvertRuleToIpPermission.FUNCTION.apply(rule);
+        assertThat(actual).isEqualTo(expected);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack-tests/pom.xml
----------------------------------------------------------------------
diff --git a/providers/cloudstack-tests/pom.xml b/providers/cloudstack-tests/pom.xml
index 9ba2f5a..b4eba7e 100644
--- a/providers/cloudstack-tests/pom.xml
+++ b/providers/cloudstack-tests/pom.xml
@@ -15,25 +15,26 @@
   ~ limitations under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: CloudStack Integration Tests</name>
+    <name>Apache Provisionr :: CloudStack Integration Tests</name>
     <artifactId>provisionr-cloudstack-tests</artifactId>
 
-    <dependencies>    
+    <dependencies>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-cloudstack</artifactId>
         </dependency>
         <dependency>
@@ -41,12 +42,12 @@
             <artifactId>activiti-engine</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-features</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java b/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
deleted file mode 100644
index 2a892ed..0000000
--- a/providers/cloudstack-tests/src/test/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * Licensed 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 com.axemblr.provisionr.cloudstack;
-
-import com.axemblr.provisionr.api.Provisionr;
-import com.axemblr.provisionr.api.access.AdminAccess;
-import com.axemblr.provisionr.api.hardware.Hardware;
-import com.axemblr.provisionr.api.network.Network;
-import com.axemblr.provisionr.api.network.Rule;
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.api.software.Software;
-import static com.axemblr.provisionr.test.KarafTests.installProvisionrFeatures;
-import static com.axemblr.provisionr.test.KarafTests.installProvisionrTestSupportBundle;
-import static com.axemblr.provisionr.test.KarafTests.passThroughAllSystemPropertiesWithPrefix;
-import static com.axemblr.provisionr.test.KarafTests.useDefaultKarafAsInProjectWithJunitBundles;
-import com.axemblr.provisionr.test.ProvisionrLiveTestSupport;
-import java.security.Security;
-import java.util.UUID;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import static org.ops4j.pax.exam.CoreOptions.maven;
-import static org.ops4j.pax.exam.CoreOptions.scanFeatures;
-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;
-
-@RunWith(JUnit4TestRunner.class)
-@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
-public class CloudStackProvisionrLiveTest extends ProvisionrLiveTestSupport {
-
-    public CloudStackProvisionrLiveTest() {
-        super(CloudStackProvisionr.ID);
-    }
-
-    @Configuration
-    public Option[] configuration() throws Exception {
-        return new Option[]{
-            useDefaultKarafAsInProjectWithJunitBundles(),
-            passThroughAllSystemPropertiesWithPrefix("test.cloudstack."),
-            scanFeatures(maven().groupId("org.jclouds.karaf").artifactId("jclouds-karaf")
-                .type("xml").classifier("features").versionAsInProject(), "jclouds-api-cloudstack"),
-            installProvisionrFeatures("axemblr-provisionr-cloudstack"),
-            installProvisionrTestSupportBundle()
-        };
-    }
-
-    @Test
-    public void startProvisioningProcess() throws Exception {
-        waitForProcessDeployment(CloudStackProvisionr.ID);
-        Provisionr provisionr = getOsgiService(Provisionr.class, 5000);
-
-//        listAvailableJceProviders();
-
-        final Provider provider = collectProviderCredentialsFromSystemProperties()
-            // TODO: get more options as needed for CloudStack
-            .createProvider();
-
-        final Network network = Network.builder()
-            .addRules(Rule.builder().anySource().tcp().port(22).createRule())
-            .createNetwork();
-
-        final Software software = Software.builder().imageId("ubuntu-10.04")
-            .packages("nginx").createSoftware();
-
-        final AdminAccess adminAccess = AdminAccess.builder().asCurrentUser().createAdminAccess();
-
-        final Hardware hardware = Hardware.builder().type("offering").createHardware();
-
-        final Pool pool = Pool.builder().network(network).provider(provider).adminAccess(adminAccess)
-            .software(software).hardware(hardware).minSize(1).expectedSize(1).createPool();
-
-        String processId = provisionr.startPoolManagementProcess(UUID.randomUUID().toString(), pool);
-        waitForProcessEnd(processId);
-        // TODO: check that the environment is clean
-    }
-
-    /**
-     * debug utility method for https://github.com/axemblr/axemblr-provisionr/issues/80
-     */
-    private void listAvailableJceProviders() {
-        for (java.security.Provider provider : Security.getProviders()) {
-            System.out.println(provider.toString());
-            for (java.security.Provider.Service service : provider.getServices()) {
-                System.out.println("\t" + service.toString());
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java b/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
new file mode 100644
index 0000000..c77f460
--- /dev/null
+++ b/providers/cloudstack-tests/src/test/java/org/apache/provisionr/cloudstack/CloudStackProvisionrLiveTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
+ *
+ * Licensed 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.cloudstack;
+
+import java.security.Security;
+import java.util.UUID;
+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.Rule;
+import org.apache.provisionr.api.pool.Pool;
+import org.apache.provisionr.api.provider.Provider;
+import org.apache.provisionr.api.software.Software;
+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 org.junit.Test;
+import org.junit.runner.RunWith;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.scanFeatures;
+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;
+
+@RunWith(JUnit4TestRunner.class)
+@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)
+public class CloudStackProvisionrLiveTest extends ProvisionrLiveTestSupport {
+
+    public CloudStackProvisionrLiveTest() {
+        super(CloudStackProvisionr.ID);
+    }
+
+    @Configuration
+    public Option[] configuration() throws Exception {
+        return new Option[]{
+            useDefaultKarafAsInProjectWithJunitBundles(),
+            passThroughAllSystemPropertiesWithPrefix("test.cloudstack."),
+            scanFeatures(maven().groupId("org.jclouds.karaf").artifactId("jclouds-karaf")
+                .type("xml").classifier("features").versionAsInProject(), "jclouds-api-cloudstack"),
+            installProvisionrFeatures("provisionr-cloudstack"),
+            installProvisionrTestSupportBundle()
+        };
+    }
+
+    @Test
+    public void startProvisioningProcess() throws Exception {
+        waitForProcessDeployment(CloudStackProvisionr.ID);
+        Provisionr provisionr = getOsgiService(Provisionr.class, 5000);
+
+//        listAvailableJceProviders();
+
+        final Provider provider = collectProviderCredentialsFromSystemProperties()
+            // TODO: get more options as needed for CloudStack
+            .createProvider();
+
+        final Network network = Network.builder()
+            .addRules(Rule.builder().anySource().tcp().port(22).createRule())
+            .createNetwork();
+
+        final Software software = Software.builder().imageId("ubuntu-10.04")
+            .packages("nginx").createSoftware();
+
+        final AdminAccess adminAccess = AdminAccess.builder().asCurrentUser().createAdminAccess();
+
+        final Hardware hardware = Hardware.builder().type("offering").createHardware();
+
+        final Pool pool = Pool.builder().network(network).provider(provider).adminAccess(adminAccess)
+            .software(software).hardware(hardware).minSize(1).expectedSize(1).createPool();
+
+        String processId = provisionr.startPoolManagementProcess(UUID.randomUUID().toString(), pool);
+        waitForProcessEnd(processId);
+        // TODO: check that the environment is clean
+    }
+
+    /**
+     * debug utility method
+     */
+    private void listAvailableJceProviders() {
+        for (java.security.Provider provider : Security.getProviders()) {
+            System.out.println(provider.toString());
+            for (java.security.Provider.Service service : provider.getServices()) {
+                System.out.println("\t" + service.toString());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/pom.xml
----------------------------------------------------------------------
diff --git a/providers/cloudstack/pom.xml b/providers/cloudstack/pom.xml
index 3dc93f7..f56fc9a 100644
--- a/providers/cloudstack/pom.xml
+++ b/providers/cloudstack/pom.xml
@@ -15,16 +15,17 @@
   ~ limitations under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>provisionr-parent</artifactId>
-        <groupId>com.axemblr.provisionr</groupId>
+        <groupId>org.apache.provisionr</groupId>
         <version>0.4.0-SNAPSHOT</version>
         <relativePath>../../parent</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <name>Axemblr Provisionr :: CloudStack</name>
+    <name>Apache Provisionr :: CloudStack</name>
     <artifactId>provisionr-cloudstack</artifactId>
     <packaging>bundle</packaging>
 
@@ -34,15 +35,15 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-core</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.axemblr.provisionr</groupId>
+            <groupId>org.apache.provisionr</groupId>
             <artifactId>provisionr-test-support</artifactId>
             <scope>test</scope>
             <exclusions>
@@ -188,7 +189,7 @@
                                 </artifact>
                                 <artifact>
                                     <file>
-                                        ${project.build.directory}/classes/com.axemblr.provisionr.cloudstack.cfg
+                                        ${project.build.directory}/classes/org.apache.provisionr.cloudstack.cfg
                                     </file>
                                     <type>cfg</type>
                                     <classifier>defaults</classifier>
@@ -215,7 +216,7 @@
                                 <descriptor>file:${project.build.directory}/classes/features.xml</descriptor>
                             </descriptors>
                             <features>
-                                <feature>axemblr-provisionr-cloudstack</feature>
+                                <feature>provisionr-cloudstack</feature>
                             </features>
                             <repository>target/features-repo</repository>
                         </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java
deleted file mode 100644
index 7c1f243..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/CloudStackProvisionr.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * Licensed 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 com.axemblr.provisionr.cloudstack;
-
-import com.axemblr.provisionr.api.pool.Pool;
-import com.axemblr.provisionr.api.provider.Provider;
-import com.axemblr.provisionr.core.CoreConstants;
-import com.axemblr.provisionr.core.CoreProcessVariables;
-import com.axemblr.provisionr.core.ProvisionrSupport;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class CloudStackProvisionr extends ProvisionrSupport {
-
-    private static final Logger LOG = LoggerFactory.getLogger(CloudStackProvisionr.class);
-    public static final String ID = "cloudstack";
-    /**
-     * Process key must match the one in
-     * axemblr-provisionr/providers/cloudstack/src/main/resources/OSGI-INF/activiti/cloudstack.bpmn20.xml
-     */
-    public static final String PROCESS_KEY = "cloudstack";
-
-    private final ProcessEngine processEngine;
-    private final Optional<Provider> defaultProvider;
-
-    public CloudStackProvisionr(ProcessEngine processEngine, DefaultProviderConfig providerConfig) {
-        this.processEngine = checkNotNull(processEngine, "processEngine is null");
-        this.defaultProvider = providerConfig.createProvider();
-
-        if (defaultProvider.isPresent()) {
-            LOG.info("Default provider for CloudStackProvisionr is {}", defaultProvider.get());
-        } else {
-            LOG.info("No default provider configured for CloudStackProvisionr");
-        }
-    }
-
-    @Override
-    public String getId() {
-        return ID;
-    }
-
-    @Override
-    public Optional<Provider> getDefaultProvider() {
-        return defaultProvider;
-    }
-
-    @Override
-    public String startPoolManagementProcess(String businessKey, Pool pool) {
-        Map<String, Object> arguments = Maps.newHashMap();
-
-        arguments.put(CoreProcessVariables.POOL, pool);
-        arguments.put(CoreProcessVariables.PROVIDER, getId());
-        arguments.put(CoreProcessVariables.POOL_BUSINESS_KEY, businessKey);
-        arguments.put(CoreProcessVariables.BOOTSTRAP_TIMEOUT, 
-                convertTimeoutToISO8601TimeDuration(pool.getBootstrapTimeInSeconds()));
-
-        /* Authenticate as kermit to make the process visible in the Explorer UI */
-        processEngine.getIdentityService().setAuthenticatedUserId(CoreConstants.ACTIVITI_EXPLORER_DEFAULT_USER);
-
-        RuntimeService runtimeService = processEngine.getRuntimeService();
-        ProcessInstance instance = runtimeService.startProcessInstanceByKey(PROCESS_KEY, businessKey, arguments);
-
-        return instance.getProcessInstanceId();
-    }
-
-    @Override
-    public void destroyPool(String businessKey) {
-        LOG.info("**** CloudStack (destroyPool) id: " + businessKey);
-        // TODO use triggerSignalEvent as needed
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java
deleted file mode 100644
index 6dae538..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/DefaultProviderConfig.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * Licensed 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 com.axemblr.provisionr.cloudstack;
-
-import com.axemblr.provisionr.api.provider.Provider;
-import com.google.common.base.Optional;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class DefaultProviderConfig {
-
-    private final String endpoint;
-    private final String accessKey;
-    private final String secretKey;
-    private final String zoneId;
-    private final String templateId;
-    private final String serviceOffering;
-
-    public DefaultProviderConfig(
-        String endpoint, String accessKey, String secretKey, String zoneId, String templateId, String serviceOffering
-    ) {
-        this.endpoint = checkNotNull(endpoint, "endpoint is null");
-        this.accessKey = checkNotNull(accessKey, "access key is null");
-        this.secretKey = checkNotNull(secretKey, "secret key is null");
-        this.zoneId = checkNotNull(zoneId, "zone id is null");
-        this.templateId = checkNotNull(templateId, "template id is null");
-        this.serviceOffering = checkNotNull(serviceOffering, "service offering is null");
-    }
-
-    public Optional<Provider> createProvider() {
-        if (accessKey.isEmpty() || secretKey.isEmpty() || endpoint.isEmpty()) {
-            return Optional.absent();
-        }
-        return Optional.of(Provider.builder()
-            .id(CloudStackProvisionr.ID)
-            .endpoint(endpoint)
-            .accessKey(accessKey)
-            .secretKey(secretKey)
-            .option(ProviderOptions.ZONE_ID, zoneId)
-            .option(ProviderOptions.TEMPLATE_ID, templateId)
-            .option(ProviderOptions.SERVICE_OFFERING_ID, serviceOffering)
-            .createProvider());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java
deleted file mode 100644
index bc256d3..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/NetworkOptions.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013 S.C. Axemblr Software Solutions S.R.L
- *
- * Licensed 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 com.axemblr.provisionr.cloudstack;
-
-/**
- * {@link com.axemblr.provisionr.api.network.Network Network} configuration is passed via the
- * {@link com.axemblr.provisionr.api.pool.Pool Pool} object. This class stores names for those options.
- */
-public class NetworkOptions {
-
-    private NetworkOptions() {
-        throw new RuntimeException("Do not instantiate");
-    }
-
-    /**
-     * Pass this option if you wish to use an existing CloudStack network.
-     */
-    public static final String EXISTING_NETWORK_ID = "existingNetworkId";
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java
deleted file mode 100644
index 97911e3..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProcessVariables.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * Licensed 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 com.axemblr.provisionr.cloudstack;
-
-public class ProcessVariables {
-
-    private ProcessVariables() {
-        // prevent instantiation
-    }
-
-    public static final String NETWORK_ID = "networkId";
-}

http://git-wip-us.apache.org/repos/asf/incubator-provisionr/blob/6ba40c4b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java
----------------------------------------------------------------------
diff --git a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java b/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java
deleted file mode 100644
index 1fa7125..0000000
--- a/providers/cloudstack/src/main/java/com/axemblr/provisionr/cloudstack/ProviderOptions.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012 S.C. Axemblr Software Solutions S.R.L
- *
- * Licensed 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 com.axemblr.provisionr.cloudstack;
-
-
-/**
- * Building a pool of VM's on CloudStack requires more knowledge of the cloud's architecture,
- * You need to know things like in what zone to build the pool, the ID's of service offerings, network offerings,
- * and more.
- * <p/>
- * All the information is passed via Provider Options. This class stores some of the option names.
- */
-public class ProviderOptions {
-
-    private ProviderOptions() {
-        throw new RuntimeException(ProviderOptions.class.getName() + " should not be instantiated");
-    }
-
-    public static final String ZONE_ID = "zoneId";
-    public static final String TEMPLATE_ID = "templateId";
-    public static final String SERVICE_OFFERING_ID = "serviceOfferingId";
-    public static final String NETWORK_OFFERING_ID = "networkOfferingId";
-}


Mime
View raw message