From ff1f46ca2c81220179321fd01b33572ff1aaa5d3 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sat, 19 Feb 2011 19:59:47 -0800 Subject: [PATCH] added state predicates to cloudstack --- .../cloudstack/predicates/JobComplete.java | 65 ++++++++++++++ .../predicates/VirtualMachineDestroyed.java | 67 ++++++++++++++ .../predicates/VirtualMachineRunning.java | 69 ++++++++++++++ .../VirtualMachineClientLiveTest.java | 90 ++++++++++++------- .../ListSecurityGroupsResponseTest.java | 30 +++---- .../resources/listsecuritygroupsresponse.json | 2 +- 6 files changed, 273 insertions(+), 50 deletions(-) create mode 100644 sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/JobComplete.java create mode 100644 sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineDestroyed.java create mode 100644 sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineRunning.java diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/JobComplete.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/JobComplete.java new file mode 100644 index 0000000000..e5ca531dbd --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/JobComplete.java @@ -0,0 +1,65 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.jclouds.cloudstack.predicates; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Resource; +import javax.inject.Singleton; + +import org.jclouds.cloudstack.CloudStackClient; +import org.jclouds.cloudstack.domain.AsyncJob; +import org.jclouds.logging.Logger; + +import com.google.common.base.Predicate; +import com.google.inject.Inject; + +/** + * + * Tests to see if a job is in progress. + * + * @author Adrian Cole + */ +@Singleton +public class JobComplete implements Predicate { + + private final CloudStackClient client; + + @Resource + protected Logger logger = Logger.NULL; + + @Inject + public JobComplete(CloudStackClient client) { + this.client = client; + } + + public boolean apply(Long jobId) { + logger.trace("looking for status on job %s", checkNotNull(jobId, "jobId")); + AsyncJob job = refresh(jobId); + if (job == null) + return false; + logger.trace("%s: looking for job status %s: currently: %s", job.getId(), 1, job.getStatus()); + return job.getStatus() > 0; + } + + private AsyncJob refresh(Long jobId) { + return client.getAsyncJobClient().getAsyncJob(jobId); + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineDestroyed.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineDestroyed.java new file mode 100644 index 0000000000..cd4fc37a4f --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineDestroyed.java @@ -0,0 +1,67 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.jclouds.cloudstack.predicates; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Resource; +import javax.inject.Singleton; + +import org.jclouds.cloudstack.CloudStackClient; +import org.jclouds.cloudstack.domain.VirtualMachine; +import org.jclouds.cloudstack.domain.VirtualMachine.State; +import org.jclouds.logging.Logger; + +import com.google.common.base.Predicate; +import com.google.inject.Inject; + +/** + * + * Tests to see if a virtualMachine is running + * + * @author Adrian Cole + */ +@Singleton +public class VirtualMachineDestroyed implements Predicate { + + private final CloudStackClient client; + + @Resource + protected Logger logger = Logger.NULL; + + @Inject + public VirtualMachineDestroyed(CloudStackClient client) { + this.client = client; + } + + public boolean apply(VirtualMachine virtualMachine) { + logger.trace("looking for state on virtualMachine %s", checkNotNull(virtualMachine, "virtualMachine")); + virtualMachine = refresh(virtualMachine); + if (virtualMachine == null) + return true; + logger.trace("%s: looking for virtualMachine state %s: currently: %s", virtualMachine.getId(), State.DESTROYED, + virtualMachine.getState()); + return virtualMachine.getState() == State.DESTROYED; + } + + private VirtualMachine refresh(VirtualMachine virtualMachine) { + return client.getVirtualMachineClient().getVirtualMachine(virtualMachine.getId()); + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineRunning.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineRunning.java new file mode 100644 index 0000000000..88be8469a2 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/VirtualMachineRunning.java @@ -0,0 +1,69 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.jclouds.cloudstack.predicates; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Resource; +import javax.inject.Singleton; + +import org.jclouds.cloudstack.CloudStackClient; +import org.jclouds.cloudstack.domain.VirtualMachine; +import org.jclouds.cloudstack.domain.VirtualMachine.State; +import org.jclouds.logging.Logger; + +import com.google.common.base.Predicate; +import com.google.inject.Inject; + +/** + * + * Tests to see if a virtualMachine is running + * + * @author Adrian Cole + */ +@Singleton +public class VirtualMachineRunning implements Predicate { + + private final CloudStackClient client; + + @Resource + protected Logger logger = Logger.NULL; + + @Inject + public VirtualMachineRunning(CloudStackClient client) { + this.client = client; + } + + public boolean apply(VirtualMachine virtualMachine) { + logger.trace("looking for state on virtualMachine %s", checkNotNull(virtualMachine, "virtualMachine")); + virtualMachine = refresh(virtualMachine); + if (virtualMachine == null) + return false; + logger.trace("%s: looking for virtualMachine state %s: currently: %s", virtualMachine.getId(), State.RUNNING, + virtualMachine.getState()); + if (virtualMachine.getState() == State.ERROR) + throw new IllegalStateException("virtualMachine in error state: " + virtualMachine); + return virtualMachine.getState() == State.RUNNING; + } + + private VirtualMachine refresh(VirtualMachine virtualMachine) { + return client.getVirtualMachineClient().getVirtualMachine(virtualMachine.getId()); + } +} diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java index b748ee771e..937a47f63a 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java @@ -19,8 +19,6 @@ package org.jclouds.cloudstack.features; -import static com.google.common.base.Predicates.equalTo; -import static com.google.common.base.Predicates.or; import static com.google.common.collect.Iterables.find; import static com.google.common.collect.Iterables.get; import static com.google.common.collect.Iterables.getOnlyElement; @@ -28,19 +26,26 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import java.util.Set; +import java.util.concurrent.TimeUnit; import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.GuestIPType; import org.jclouds.cloudstack.domain.NIC; import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.NetworkType; +import org.jclouds.cloudstack.domain.SecurityGroup; import org.jclouds.cloudstack.domain.ServiceOffering; import org.jclouds.cloudstack.domain.Template; import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.options.DeployVirtualMachineOptions; import org.jclouds.cloudstack.options.ListVirtualMachinesOptions; +import org.jclouds.cloudstack.predicates.JobComplete; +import org.jclouds.cloudstack.predicates.VirtualMachineDestroyed; +import org.jclouds.cloudstack.predicates.VirtualMachineRunning; +import org.jclouds.predicates.RetryablePredicate; import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import com.google.common.base.Predicate; @@ -54,12 +59,25 @@ import com.google.common.collect.Ordering; */ @Test(groups = "live", sequential = true, testName = "VirtualMachineClientLiveTest") public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { - VirtualMachine vm = null; + private VirtualMachine vm = null; + private RetryablePredicate jobComplete; + private RetryablePredicate virtualMachineRunning; + private RetryablePredicate virtualMachineDestroyed; + + @BeforeGroups(groups = "live") + public void setupClient() { + super.setupClient(); + jobComplete = new RetryablePredicate(new JobComplete(client), 600, 5, TimeUnit.SECONDS); + virtualMachineRunning = new RetryablePredicate(new VirtualMachineRunning(client), 600, 5, + TimeUnit.SECONDS); + virtualMachineDestroyed = new RetryablePredicate(new VirtualMachineDestroyed(client), 600, 5, + TimeUnit.SECONDS); + } static final Ordering DEFAULT_SIZE_ORDERING = new Ordering() { public int compare(ServiceOffering left, ServiceOffering right) { - return ComparisonChain.start().compare(left.getCpuNumber(), right.getCpuNumber()) - .compare(left.getMemory(), right.getMemory()).result(); + return ComparisonChain.start().compare(left.getCpuNumber(), right.getCpuNumber()).compare(left.getMemory(), + right.getMemory()).result(); } }; @@ -78,7 +96,7 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { }).getId(); DeployVirtualMachineOptions options = new DeployVirtualMachineOptions(); - if (zone.getNetworkType() == NetworkType.ADVANCED) + if (zone.getNetworkType() == NetworkType.ADVANCED) { options.networkId(find(client.getNetworkClient().listNetworks(), new Predicate() { @Override @@ -87,41 +105,49 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { } }).getId()); + } else { + options.securityGroupId(find(client.getSecurityGroupClient().listSecurityGroups(), + new Predicate() { + + @Override + public boolean apply(SecurityGroup arg0) { + return arg0.getName().equals("default"); + } + + }).getId()); + } System.out.printf("serviceOfferingId %d, templateId %d, zoneId %d, options %s%n", serviceOfferingId, templateId, - zone.getId(), options); + zone.getId(), options); AsyncCreateResponse job = client.getVirtualMachineClient().deployVirtualMachine(serviceOfferingId, templateId, - zone.getId(), options); + zone.getId(), options); + assert jobComplete.apply(job.getJobId()); vm = client.getVirtualMachineClient().getVirtualMachine(job.getId()); + assert virtualMachineRunning.apply(vm); assertEquals(vm.getServiceOfferingId(), serviceOfferingId); assertEquals(vm.getTemplateId(), templateId); assertEquals(vm.getZoneId(), zone.getId()); - assert or(equalTo("NetworkFilesystem"), equalTo("Not created")).apply(vm.getRootDeviceType()) : vm; + assertEquals(vm.getRootDeviceType(), "NetworkFilesystem"); checkVm(vm); - } @AfterGroups(groups = "live") protected void tearDown() { if (vm != null) { - try { - Long job = client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()); - assert job != null; - assertEquals(client.getVirtualMachineClient().getVirtualMachine(vm.getId()), null); - } catch (AssertionError e) { - e.printStackTrace(); - } + Long job = client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()); + assert job != null; + assert jobComplete.apply(job); + assert virtualMachineDestroyed.apply(vm); } super.tearDown(); } public void testListVirtualMachines() throws Exception { Set response = client.getVirtualMachineClient().listVirtualMachines(); - System.out.println(response); assert null != response; assertTrue(response.size() >= 0); for (VirtualMachine vm : response) { VirtualMachine newDetails = getOnlyElement(client.getVirtualMachineClient().listVirtualMachines( - ListVirtualMachinesOptions.Builder.id(vm.getId()))); + ListVirtualMachinesOptions.Builder.id(vm.getId()))); assertEquals(vm.getId(), newDetails.getId()); checkVm(vm); } @@ -159,22 +185,22 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { assert nic.getTrafficType() != null : vm; assert nic.getGuestIPType() != null : vm; switch (vm.getState()) { - case RUNNING: - assert nic.getNetmask() != null : vm; - assert nic.getGateway() != null : vm; - assert nic.getIPAddress() != null : vm; - break; - default: - if (nic.getGuestIPType() == GuestIPType.VIRTUAL) { + case RUNNING: assert nic.getNetmask() != null : vm; assert nic.getGateway() != null : vm; assert nic.getIPAddress() != null : vm; - } else { - assert nic.getNetmask() == null : vm; - assert nic.getGateway() == null : vm; - assert nic.getIPAddress() == null : vm; - } - break; + break; + default: + if (nic.getGuestIPType() == GuestIPType.VIRTUAL) { + assert nic.getNetmask() != null : vm; + assert nic.getGateway() != null : vm; + assert nic.getIPAddress() != null : vm; + } else { + assert nic.getNetmask() == null : vm; + assert nic.getGateway() == null : vm; + assert nic.getIPAddress() == null : vm; + } + break; } } diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/ListSecurityGroupsResponseTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/ListSecurityGroupsResponseTest.java index 4ba372ee7f..21e7984f2d 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/ListSecurityGroupsResponseTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/functions/ListSecurityGroupsResponseTest.java @@ -59,26 +59,22 @@ public class ListSecurityGroupsResponseTest { public void test() { InputStream is = getClass().getResourceAsStream("/listsecuritygroupsresponse.json"); - Set expects = ImmutableSet. of( - SecurityGroup - .builder() - .id(3) - .name("default") - .description("Default Security Group") - .account("adrian") - .domainId(1) - .domain("ROOT") - .ingressRules( - ImmutableSet.of( - IngressRule.builder().id(8).protocol("tcp").startPort(22).endPort(22).CIDR("0.0.0.0/32") - .build(), IngressRule.builder().id(9).protocol("icmp").ICMPType(-1).ICMPCode(-1) - .securityGroupName("default").account("adrian").build())).build(), + Set expects = ImmutableSet. of(SecurityGroup.builder().id(3).name("default") + .description("Default Security Group").account("adrian").domainId(1).domain("ROOT").ingressRules( + ImmutableSet.of(IngressRule.builder().id(8).protocol("tcp").startPort(22).endPort(22).CIDR( + "0.0.0.0/32").build(), - SecurityGroup.builder().id(15).name("adriancole").account("adrian").domainId(1).domain("ROOT").build()); + IngressRule.builder().id(9).protocol("icmp").ICMPType(-1).ICMPCode(-1).securityGroupName( + "default").account("adrian").build(), + + IngressRule.builder().id(10).protocol("tcp").startPort(80).endPort(80).securityGroupName( + "default").account("adrian").build())).build(), + + SecurityGroup.builder().id(15).name("adriancole").account("adrian").domainId(1).domain("ROOT").build()); UnwrapOnlyNestedJsonValue> parser = i.getInstance(Key - .get(new TypeLiteral>>() { - })); + .get(new TypeLiteral>>() { + })); Set response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is))); assertEquals(Sets.newHashSet(response), expects); diff --git a/sandbox-apis/cloudstack/src/test/resources/listsecuritygroupsresponse.json b/sandbox-apis/cloudstack/src/test/resources/listsecuritygroupsresponse.json index cba658eabe..26a812df70 100644 --- a/sandbox-apis/cloudstack/src/test/resources/listsecuritygroupsresponse.json +++ b/sandbox-apis/cloudstack/src/test/resources/listsecuritygroupsresponse.json @@ -1 +1 @@ -{ "listsecuritygroupsresponse" : { "securitygroup" : [ {"id":3,"name":"default","description":"Default Security Group","account":"adrian","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":8,"protocol":"tcp","startport":22,"endport":22,"cidr":"0.0.0.0/32"},{"ruleid":9,"protocol":"icmp","icmptype":-1,"icmpcode":-1,"securitygroupname":"default","account":"adrian"}]}, {"id":15,"name":"adriancole","account":"adrian","domainid":1,"domain":"ROOT"} ] } } \ No newline at end of file +{ "listsecuritygroupsresponse" : { "securitygroup" : [ {"id":3,"name":"default","description":"Default Security Group","account":"adrian","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":8,"protocol":"tcp","startport":22,"endport":22,"cidr":"0.0.0.0/32"},{"ruleid":9,"protocol":"icmp","icmptype":-1,"icmpcode":-1,"securitygroupname":"default","account":"adrian"},{"ruleid":10,"protocol":"tcp","startport":80,"endport":80,"securitygroupname":"default","account":"adrian"}]}, {"id":15,"name":"adriancole","account":"adrian","domainid":1,"domain":"ROOT"} ] } } \ No newline at end of file