Merge pull request #931 from abiquo/abiquo-live-tests

Added live tests in the Abiquo provider
This commit is contained in:
Adrian Cole 2012-10-30 11:32:38 -07:00
commit cd330a759b
7 changed files with 441 additions and 111 deletions

View File

@ -45,11 +45,12 @@ import com.google.inject.Module;
* @author Ignasi Barrera * @author Ignasi Barrera
*/ */
@Test(groups = "live", testName = "AbiquoComputeServiceLiveTest", singleThreaded = true) @Test(groups = "live", testName = "AbiquoComputeServiceLiveTest", singleThreaded = true)
// Made abstract to avoid executing tests. Since the base class has test // Since the base class has test configuration, even if we disable tests here,
// configuration, even if we // or comment them out, the ones in the base class will be executed.
// disable tests here, or comment them out, the ones in the base class will be // This class is still a work in progress and will fail until the race condition
// executed // (when creating the virtual appliance) in the AbiquoComputeServiceAdapter is
public class AbiquoComputeServiceLiveTest extends BaseComputeServiceLiveTest { // fixed and a proper test environment is configured.
public abstract class AbiquoComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public AbiquoComputeServiceLiveTest() { public AbiquoComputeServiceLiveTest() {
provider = "abiquo"; provider = "abiquo";
} }

View File

@ -0,0 +1,59 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.jclouds.abiquo.domain.cloud;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.jclouds.abiquo.domain.enterprise.Enterprise;
import org.jclouds.abiquo.internal.BaseAbiquoLiveApiTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Live integration tests
*
* @author Susana Acedo
*/
@Test(groups = "live", testName = "AccountLiveTest")
public class AccountLiveTest extends BaseAbiquoLiveApiTest {
private Enterprise enterprise;
@BeforeClass(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();
enterprise = view.getAdministrationService().getCurrentEnterprise();
}
public void testGetCurrentUser() {
assertEquals(view.getAdministrationService().getCurrentUser().getNick(), view.getApiContext().getIdentity());
}
public void testAllowedDatacenters() {
assertTrue(enterprise.listAllowedDatacenters().size() > 0);
}
public void testAvailableTemplates() {
assertTrue(enterprise.listTemplates().size() > 0);
}
}

View File

@ -0,0 +1,128 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.jclouds.abiquo.domain.cloud;
import static com.google.common.collect.Iterables.getLast;
import static org.jclouds.abiquo.reference.AbiquoTestConstants.PREFIX;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import java.util.concurrent.TimeUnit;
import org.jclouds.abiquo.domain.task.AsyncTask;
import org.jclouds.abiquo.features.services.MonitoringService;
import org.jclouds.abiquo.internal.BaseAbiquoLiveApiTest;
import org.jclouds.abiquo.predicates.cloud.VirtualAppliancePredicates;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.abiquo.server.core.cloud.VirtualApplianceState;
import com.abiquo.server.core.cloud.VirtualMachineState;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Longs;
/**
* Live integration tests for the {@link VirtualAppliance} domain class.
*
* @author Susana Acedo
*/
@Test(groups = "live", testName = "VirtualApplianceLiveTest")
public class VirtualApplianceLiveTest extends BaseAbiquoLiveApiTest {
private static final long MAX_WAIT = 2;
private VirtualDatacenter vdc;
private VirtualAppliance vapp;
private VirtualMachine vm;
private VirtualMachineTemplate vmt;
private MonitoringService monitoringService;
@BeforeClass(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();
monitoringService = view.getMonitoringService();
vdc = getLast(view.getCloudService().listVirtualDatacenters());
vmt = templateBySize().min(vdc.listAvailableTemplates());
}
public void testCreateVirtualAppliance() {
vapp = VirtualAppliance.builder(view.getApiContext(), vdc).name(PREFIX + "Virtual Appliance Ohana").build();
vapp.save();
assertNotNull(vapp.getId());
}
@Test(dependsOnMethods = "testCreateVirtualAppliance")
public void testUpdateVirtualAppliance() {
vapp.setName(PREFIX + "Virtual Appliance Updated");
vapp.update();
// Reload the appliance to check the updated name
VirtualAppliance updated = vdc.getVirtualAppliance(vapp.getId());
assertEquals(updated.getName(), PREFIX + "Virtual Appliance Updated");
}
@Test(dependsOnMethods = "testUpdateVirtualAppliance")
public void testDeployVirtualAppliance() {
vm = VirtualMachine.builder(view.getApiContext(), vapp, vmt).cpu(1).nameLabel(PREFIX + "VM Makua").ram(128)
.build();
vm.save();
assertNotNull(vm.getId());
AsyncTask[] tasks = vapp.deploy();
assertEquals(tasks.length, 1); // One task for each VM in the VAPP
monitoringService.getVirtualApplianceMonitor().awaitCompletionDeploy(MAX_WAIT, TimeUnit.MINUTES, vapp);
assertEquals(vapp.getState(), VirtualApplianceState.DEPLOYED);
assertEquals(vm.getState(), VirtualMachineState.ON);
}
@Test(dependsOnMethods = "testDeployVirtualAppliance")
public void testUndeployVirtualAppliance() {
AsyncTask[] tasks = vapp.undeploy();
assertEquals(tasks.length, 1); // One task for each VM in the VAPP
monitoringService.getVirtualApplianceMonitor().awaitCompletionUndeploy(MAX_WAIT, TimeUnit.MINUTES, vapp);
assertEquals(vapp.getState(), VirtualApplianceState.NOT_DEPLOYED);
assertEquals(vm.getState(), VirtualMachineState.NOT_ALLOCATED);
}
@Test(dependsOnMethods = "testUndeployVirtualAppliance")
public void testDeleteVirtualAppliance() {
vapp.delete();
assertNull(view.getCloudService().findVirtualAppliance(
VirtualAppliancePredicates.name(PREFIX + "Virtual Appliance Updated")));
}
private static Ordering<VirtualMachineTemplate> templateBySize() {
return new Ordering<VirtualMachineTemplate>() {
@Override
public int compare(final VirtualMachineTemplate left, final VirtualMachineTemplate right) {
return Longs.compare(left.getDiskFileSize(), right.getDiskFileSize());
}
};
}
}

View File

@ -0,0 +1,184 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.jclouds.abiquo.domain.cloud;
import static com.google.common.collect.Iterables.getLast;
import static org.jclouds.abiquo.reference.AbiquoTestConstants.PREFIX;
import static org.jclouds.abiquo.util.Assert.assertHasError;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.fail;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.core.Response.Status;
import org.jclouds.abiquo.domain.enterprise.Enterprise;
import org.jclouds.abiquo.domain.exception.AbiquoException;
import org.jclouds.abiquo.domain.network.Ip;
import org.jclouds.abiquo.domain.task.AsyncTask;
import org.jclouds.abiquo.features.services.MonitoringService;
import org.jclouds.abiquo.internal.BaseAbiquoLiveApiTest;
import org.jclouds.abiquo.predicates.cloud.VirtualMachinePredicates;
import org.jclouds.abiquo.predicates.network.IpPredicates;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.abiquo.server.core.cloud.VirtualMachineState;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Longs;
/**
* Live integration tests for the {@link VirtualMachine} domain class.
*
* @author Susana Acedo
*/
@Test(groups = "live", testName = "VirtualMachineLiveTest")
public class VirtualMachineLiveTest extends BaseAbiquoLiveApiTest {
private static final long MAX_WAIT = 2;
private VirtualDatacenter vdc;
private VirtualAppliance vapp;
private VirtualMachine vm;
private VirtualMachineTemplate vmt;
private MonitoringService monitoringService;
@BeforeClass(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();
monitoringService = view.getMonitoringService();
vdc = getLast(view.getCloudService().listVirtualDatacenters());
vmt = templateBySize().min(vdc.listAvailableTemplates());
vapp = VirtualAppliance.builder(view.getApiContext(), vdc).name(PREFIX + "Virtual Appliance Wahine").build();
vapp.save();
assertNotNull(vapp.getId());
}
@AfterClass(groups = { "integration", "live" })
@Override
protected void tearDownContext() {
vapp.delete();
super.tearDownContext();
}
@Test
public void testCreateVirtualMachine() {
vm = VirtualMachine.builder(view.getApiContext(), vapp, vmt).cpu(1).nameLabel(PREFIX + "VM Kane").ram(128)
.build();
vm.save();
assertNotNull(vm.getId());
}
@Test(dependsOnMethods = "testCreateVirtualMachine")
public void testUpdateVirtualMachineWhenNotDeployed() {
vm.setNameLabel(PREFIX + "VM Kane Updated");
AsyncTask task = vm.update();
assertNull(task);
VirtualMachine updated = vapp.findVirtualMachine(VirtualMachinePredicates.nameLabel(PREFIX + "VM Kane Updated"));
assertNotNull(updated);
}
@Test(dependsOnMethods = "testUpdateVirtualMachineWhenNotDeployed")
public void testDeployVirtualMachine() {
AsyncTask task = vm.deploy(true);
assertNotNull(task);
monitoringService.getVirtualMachineMonitor().awaitCompletionDeploy(MAX_WAIT, TimeUnit.MINUTES, vm);
assertEquals(vm.getState(), VirtualMachineState.ON);
}
@Test(dependsOnMethods = "testDeployVirtualMachine")
public void testChangeVirtualMachineState() {
AsyncTask task = vm.changeState(VirtualMachineState.OFF);
assertNotNull(task);
monitoringService.getVirtualMachineMonitor().awaitState(MAX_WAIT, TimeUnit.MINUTES, VirtualMachineState.OFF, vm);
assertEquals(vm.getState(), VirtualMachineState.OFF);
}
@Test(dependsOnMethods = "testChangeVirtualMachineState")
public void testReconfigure() {
Ip<?, ?> ip = getLast(vdc.getDefaultNetwork().listUnusedIps());
AsyncTask task = vm.setNics(Lists.<Ip<?, ?>> newArrayList(ip));
assertNotNull(task);
monitoringService.getVirtualMachineMonitor().awaitState(MAX_WAIT, TimeUnit.MINUTES, VirtualMachineState.OFF, vm);
assertNotNull(vm.findAttachedNic(IpPredicates.address(ip.getIp())));
}
@Test(dependsOnMethods = "testReconfigure")
public void testUndeployVirtualMachine() {
AsyncTask task = vm.undeploy();
assertNotNull(task);
monitoringService.getVirtualMachineMonitor().awaitCompletionUndeploy(MAX_WAIT, TimeUnit.MINUTES, vm);
assertEquals(vm.getState(), VirtualMachineState.NOT_ALLOCATED);
}
@Test(dependsOnMethods = "testUndeployVirtualMachine")
public void testDeployFailsWhenHardLimitsAreExceeded() {
Enterprise ent = view.getAdministrationService().getCurrentEnterprise();
if (vdc.getCpuCountHardLimit() != 0) {
vm.setCpu(vdc.getCpuCountHardLimit() + 1);
} else if (ent.getCpuCountHardLimit() != 0) {
vm.setCpu(ent.getCpuCountHardLimit() + 1);
}
AsyncTask task = vm.update();
assertNull(task);
try {
vm.deploy(true);
fail("Deployments over the hard limits should not be allowed");
} catch (AbiquoException ex) {
assertHasError(ex, Status.CONFLICT, "LIMIT_EXCEEDED");
}
}
@Test(dependsOnMethods = "testDeployFailsWhenHardLimitsAreExceeded")
public void tesDeleteVirtualMachine() {
Integer vmId = vm.getId();
vm.delete();
assertNull(vapp.getVirtualMachine(vmId));
}
private static Ordering<VirtualMachineTemplate> templateBySize() {
return new Ordering<VirtualMachineTemplate>() {
@Override
public int compare(final VirtualMachineTemplate left, final VirtualMachineTemplate right) {
return Longs.compare(left.getDiskFileSize(), right.getDiskFileSize());
}
};
}
}

View File

@ -0,0 +1,64 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.jclouds.abiquo.features;
import java.util.Properties;
import javax.ws.rs.core.MediaType;
import org.jclouds.abiquo.AbiquoApi;
import org.jclouds.abiquo.AbiquoApiMetadata;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.BaseRestApiExpectTest;
import com.google.common.base.Function;
import com.google.inject.Module;
/**
* Base class for Abiquo expect tests.
*
* @author Ignasi Barrera
*/
public abstract class BaseAbiquoRestApiExpectTest<S> extends BaseRestApiExpectTest<S> {
protected final String basicAuth = "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==";
public BaseAbiquoRestApiExpectTest() {
provider = "abiquo";
}
@Override
protected ApiMetadata createApiMetadata() {
return new AbiquoApiMetadata();
}
@Override
public S createClient(final Function<HttpRequest, HttpResponse> fn, final Module module, final Properties props) {
return clientFrom(createInjector(fn, module, props).getInstance(AbiquoApi.class));
}
protected abstract S clientFrom(AbiquoApi api);
protected String normalize(final String mediatType) {
return MediaType.valueOf(mediatType).toString();
}
}

View File

@ -1,103 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.jclouds.abiquo.features;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.jclouds.abiquo.config.AbiquoRestClientModule;
import org.jclouds.abiquo.rest.internal.AbiquoHttpAsyncClient;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
/**
* Tests that all features have a unit test.
*
* @author Ignasi Barrera
*/
@Test(groups = "unit", testName = "FeatureCoverageTest")
public class FeatureCoverageTest {
/** A collection with all async api classes. */
private Collection<Class<?>> featureClasses;
@BeforeMethod
public void setup() {
featureClasses = new ArrayList<Class<?>>();
featureClasses.addAll(AbiquoRestClientModule.DELEGATE_MAP.values());
featureClasses.add(AbiquoHttpAsyncClient.class);
}
public void testAllFeaturesHaveTest() throws ClassNotFoundException {
List<String> missingTests = new ArrayList<String>();
for (Class<?> featureClass : featureClasses) {
try {
Class<?> testClass = loadTestClass(featureClass);
Iterable<String> testMethodNames = methodNames(testClass);
for (Method method : featureClass.getMethods()) {
if (!hasTest(testMethodNames, method)) {
missingTests.add(method.getDeclaringClass().getSimpleName() + "." + method.getName());
}
}
} catch (ClassNotFoundException ex) {
fail("Missing tests for class: " + featureClass.getName());
}
}
assertTrue(missingTests.isEmpty(), "Missing tests: " + Joiner.on(", ").join(missingTests));
}
private Class<?> loadTestClass(final Class<?> featureClass) throws ClassNotFoundException {
String testClassName = featureClass.getName() + "Test";
return Thread.currentThread().getContextClassLoader().loadClass(testClassName);
}
private static Iterable<String> methodNames(final Class<?> clazz) {
return Iterables.transform(Arrays.asList(clazz.getMethods()), new Function<Method, String>() {
@Override
public String apply(final Method input) {
return input.getName();
}
});
}
private static boolean hasTest(final Iterable<String> testMethodNames, final Method method) {
String testMethod = Iterables.find(testMethodNames, new Predicate<String>() {
@Override
public boolean apply(final String input) {
return input.toLowerCase().contains(method.getName().toLowerCase());
}
}, null);
return testMethod != null;
}
}

View File

@ -21,7 +21,6 @@ package org.jclouds.abiquo.internal;
import java.util.Properties; import java.util.Properties;
import org.jclouds.Constants;
import org.jclouds.abiquo.AbiquoContext; import org.jclouds.abiquo.AbiquoContext;
import org.jclouds.apis.BaseViewLiveTest; import org.jclouds.apis.BaseViewLiveTest;
import org.jclouds.logging.config.LoggingModule; import org.jclouds.logging.config.LoggingModule;
@ -42,8 +41,6 @@ public abstract class BaseAbiquoLiveApiTest extends BaseViewLiveTest<AbiquoConte
@Override @Override
protected Properties setupProperties() { protected Properties setupProperties() {
Properties overrides = super.setupProperties(); Properties overrides = super.setupProperties();
overrides.put(Constants.PROPERTY_MAX_RETRIES, "0");
overrides.put(Constants.PROPERTY_MAX_REDIRECTS, "0");
// Wait at most one minute in Machine discovery // Wait at most one minute in Machine discovery
overrides.put("jclouds.timeouts.InfrastructureApi.discoverSingleMachine", "60000"); overrides.put("jclouds.timeouts.InfrastructureApi.discoverSingleMachine", "60000");
overrides.put("jclouds.timeouts.InfrastructureApi.discoverMultipleMachines", "60000"); overrides.put("jclouds.timeouts.InfrastructureApi.discoverMultipleMachines", "60000");