You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2014/07/28 23:14:11 UTC
[43/50] [abbrv] git commit: updated refs/heads/4.4 to 2025f35
Added a simulator based test for VM sync
(cherry picked from commit a83212afdc5558582d2aa60727bb28648472d95d)
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e1cfd8de
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e1cfd8de
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e1cfd8de
Branch: refs/heads/4.4
Commit: e1cfd8dedf03a7b10ad4dd5246e6dcded444cef3
Parents: 999daec
Author: Koushik Das <ko...@apache.org>
Authored: Mon Jul 7 12:53:05 2014 +0530
Committer: Daan Hoogland <da...@onecht.net>
Committed: Mon Jul 28 23:12:55 2014 +0200
----------------------------------------------------------------------
.../api/commands/ConfigureSimulatorCmd.java | 5 +-
.../cloud/simulator/MockConfigurationVO.java | 2 +-
test/integration/smoke/test_vm_sync.py | 151 +++++++++++++++++++
tools/marvin/marvin/config/test_data.py | 22 ++-
tools/marvin/marvin/lib/base.py | 4 +-
5 files changed, 173 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e1cfd8de/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java
index 9498a93..b891c6c 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java
@@ -69,12 +69,15 @@ public class ConfigureSimulatorCmd extends BaseCmd {
@Parameter(name=ApiConstants.COUNT, type=CommandType.INTEGER, description="number of times the mock is active")
private Integer count;
- @Parameter(name="jsonresponse", type=CommandType.STRING, description="agent command response to be returned")
+ @Parameter(name="jsonresponse", type=CommandType.STRING, description="agent command response to be returned", length=4096)
private String jsonResponse;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
+ if (hostId != null && jsonResponse != null) {
+ jsonResponse = jsonResponse.replace("\"hostId\":0", "\"hostId\":" + hostId);
+ }
Long id = _simMgr.configureSimulator(zoneId, podId, clusterId, hostId, command, values, count, jsonResponse);
if (id == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to configure simulator");
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e1cfd8de/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java
index 1beff76..6edec12 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java
@@ -60,7 +60,7 @@ public class MockConfigurationVO implements InternalIdentity {
@Column(name="count")
private Integer count;
- @Column(name="json_response")
+ @Column(name="json_response", length=4096)
private String jsonResponse;
@Column(name="removed")
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e1cfd8de/test/integration/smoke/test_vm_sync.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_vm_sync.py b/test/integration/smoke/test_vm_sync.py
new file mode 100644
index 0000000..6d56945
--- /dev/null
+++ b/test/integration/smoke/test_vm_sync.py
@@ -0,0 +1,151 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+#Test from the Marvin - Testing in Python wiki
+
+import time
+
+#All tests inherit from cloudstackTestCase
+from marvin.cloudstackTestCase import cloudstackTestCase
+
+#Import Integration Libraries
+
+#base - contains all resources as entities and defines create, delete, list operations on them
+from marvin.lib.base import Account, VirtualMachine, Cluster, Host, ServiceOffering, Configurations, SimulatorMock
+
+#utils - utility classes for common cleanup, external library wrappers etc
+from marvin.lib.utils import cleanup_resources
+
+#common - commonly used methods for all tests are listed here
+from marvin.lib.common import get_zone, get_domain, get_template
+
+from nose.plugins.attrib import attr
+
+class TestDeployVMSync(cloudstackTestCase):
+ """Test VM Sync
+ """
+
+ def setUp(self):
+ self.testdata = self.testClient.getParsedTestDataConfig()
+ self.apiclient = self.testClient.getApiClient()
+
+ # Get Zone, Domain and Default Built-in template
+ self.domain = get_domain(self.apiclient)
+ self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
+
+ self.testdata["mode"] = self.zone.networktype
+ self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"])
+
+ hosts = Host.list(self.apiclient, type='Routing')
+ self.assertTrue(isinstance(hosts, list) and len(hosts) > 0, msg = "No hosts found")
+ self.host = hosts[0]
+ #update host tags
+ Host.update(self.apiclient, id=self.host.id, hosttags=self.testdata["service_offerings"]["taggedsmall"]["hosttags"])
+
+ #create a user account
+ self.account = Account.create(
+ self.apiclient,
+ self.testdata["account"],
+ domainid=self.domain.id
+ )
+ #create a service offering
+ self.service_offering = ServiceOffering.create(
+ self.apiclient,
+ self.testdata["service_offerings"]["taggedsmall"]
+ )
+ #deploy vms
+ self.vm1 = VirtualMachine.create(
+ self.apiclient,
+ self.testdata["small"],
+ accountid=self.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ templateid=self.template.id
+ )
+ self.vm2 = VirtualMachine.create(
+ self.apiclient,
+ self.testdata["small"],
+ accountid=self.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ templateid=self.template.id
+ )
+ self.vm3 = VirtualMachine.create(
+ self.apiclient,
+ self.testdata["small"],
+ accountid=self.account.name,
+ zoneid=self.zone.id,
+ domainid=self.account.domainid,
+ serviceofferingid=self.service_offering.id,
+ templateid=self.template.id
+ )
+ list_vms = VirtualMachine.list(self.apiclient, ids=[self.vm1.id, self.vm2.id, self.vm3.id], listAll=True)
+ self.assertTrue(isinstance(list_vms, list) and len(list_vms) == 3, msg = "List VM response is empty")
+ clusters = Cluster.list(self.apiclient, id=self.host.clusterid)
+ self.assertTrue(isinstance(clusters, list) and len(clusters) > 0, msg = "Cluster not found")
+
+ json_response = '{"com.cloud.agent.api.PingRoutingWithNwGroupsCommand":{"newGroupStates":{},"newStates":{},"_hostVmStateReport":{"%s":{"state":"PowerOn","host":"%s"},"%s":{"state":"PowerOff","host":"%s"}},"_gatewayAccessible":true,"_vnetAccessible":true,"hostType":"Routing","hostId":0,"contextMap":{},"wait":0}}'
+ json_response = json_response%(self.vm1.instancename, self.host.name, self.vm2.instancename, self.host.name)
+
+ #create a mock to simulate vm1 as power-on, vm2 as power-off and vm3 as missing
+ self.mock_ping = SimulatorMock.create(
+ apiclient=self.apiclient,
+ command="PingRoutingWithNwGroupsCommand",
+ zoneid=self.zone.id,
+ podid=clusters[0].podid,
+ clusterid=clusters[0].id,
+ hostid=self.host.id,
+ value='',
+ jsonresponse=json_response,
+ method='POST')
+
+ #build cleanup list
+ self.cleanup = [
+ self.service_offering,
+ self.account,
+ self.mock_ping
+ ]
+
+ @attr(tags = ['advanced'], required_hardware="false", BugId="CLOUDSTACK-6873")
+ def test_vm_sync(self):
+ """Test VM Sync
+
+ # Validate the following:
+ # vm1 should be running, vm2 should be stopped as power report says PowerOff, vm3 should be stopped as missing from power report
+ """
+
+ #wait for vmsync to happen
+ ping_interval = Configurations.list(self.apiclient, name="ping.interval")
+ total_duration = int(float(ping_interval[0].value) * 3.2)
+ time.sleep(total_duration)
+
+ list_vms = VirtualMachine.list(self.apiclient, ids=[self.vm1.id, self.vm2.id, self.vm3.id], listAll=True)
+ self.assertTrue(isinstance(list_vms, list) and len(list_vms) == 3, msg = "List VM response is empty")
+ for vm in list_vms:
+ if vm.id == self.vm1.id:
+ self.assertTrue(vm.state == "Running", msg = "VM {0} is expected to be in running state".format(vm.name))
+ elif vm.id == self.vm2.id or vm.id == self.vm3.id:
+ self.assertTrue(vm.state == "Stopped", msg = "VM {0} is expected to be in stopped state".format(vm.name))
+
+ def tearDown(self):
+ try:
+ Host.update(self.apiclient, id=self.host.id, hosttags="")
+ cleanup_resources(self.apiclient, self.cleanup)
+ except Exception as e:
+ self.debug("Warning! Exception in tearDown: %s" % e)
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e1cfd8de/tools/marvin/marvin/config/test_data.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 61c1338..3cd4b6c 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -91,7 +91,7 @@ test_data = {
"memory": 128,
"tiny": {
- "name": "Tiny Instance",
+ "name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100,
@@ -120,12 +120,20 @@ test_data = {
},
"hasmall": {
"name": "HA Small Instance",
- "displaytext": "HA Small Instance",
- "cpunumber": 1,
- "cpuspeed": 100,
- "memory": 256,
- "hosttags": "ha",
- "offerha": True,
+ "displaytext": "HA Small Instance",
+ "cpunumber": 1,
+ "cpuspeed": 100,
+ "memory": 256,
+ "hosttags": "ha",
+ "offerha": True,
+ },
+ "taggedsmall": {
+ "name": "Tagged Small Instance",
+ "displaytext": "Tagged Small Instance",
+ "cpunumber": 1,
+ "cpuspeed": 100,
+ "memory": 256,
+ "hosttags": "vmsync",
},
},
"disk_offering": {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e1cfd8de/tools/marvin/marvin/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index b216bca..ff75176 100644
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -4656,7 +4656,7 @@ class SimulatorMock:
@classmethod
def create(cls, apiclient, command, zoneid=None, podid=None,
clusterid=None, hostid=None, value="result:fail",
- count=None, jsonresponse=None):
+ count=None, jsonresponse=None, method="GET"):
"""Creates simulator mock"""
cmd = configureSimulator.configureSimulatorCmd()
@@ -4669,7 +4669,7 @@ class SimulatorMock:
cmd.count = count
cmd.jsonresponse = jsonresponse
try:
- simulatormock = apiclient.configureSimulator(cmd)
+ simulatormock = apiclient.configureSimulator(cmd, method=method)
if simulatormock is not None:
return SimulatorMock(simulatormock.__dict__)
except Exception as e: