You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pr...@apache.org on 2013/04/11 22:25:06 UTC

[27/34] git commit: updated refs/heads/master to 6137d32

bvt: marvin test for the affinity groups feature

The test deploys two VMs in the simulator context and verifies that the
default host -antiaffinity processor placed the VMs on two distinct
hosts.

Signed-off-by: Prasanna Santhanam <ts...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/79812c25
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/79812c25
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/79812c25

Branch: refs/heads/master
Commit: 79812c253f26841523c9fe3c04ce7c6c47d98314
Parents: e52bf52
Author: Prasanna Santhanam <ts...@apache.org>
Authored: Mon Apr 8 23:18:00 2013 +0530
Committer: Prachi Damle <pr...@cloud.com>
Committed: Thu Apr 11 13:23:32 2013 -0700

----------------------------------------------------------------------
 client/tomcatconf/simulatorComponentContext.xml.in |   23 +-
 test/integration/smoke/test_affinity_groups.py     |  297 ++++++++-------
 tools/marvin/marvin/integration/lib/base.py        |   29 ++-
 3 files changed, 212 insertions(+), 137 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79812c25/client/tomcatconf/simulatorComponentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/simulatorComponentContext.xml.in b/client/tomcatconf/simulatorComponentContext.xml.in
index fc5cf54..435b9e2 100644
--- a/client/tomcatconf/simulatorComponentContext.xml.in
+++ b/client/tomcatconf/simulatorComponentContext.xml.in
@@ -1,4 +1,3 @@
-
 <!--
   ~ Licensed to the Apache Software Foundation (ASF) under one
   ~ or more contributor license agreements.  See the NOTICE file
@@ -34,8 +33,8 @@
   <!--
     OSS deployment component configuration
   -->
-  <bean id="databaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker" />
-  <bean id="configurationDaoImpl" class="com.cloud.configuration.dao.ConfigurationDaoImpl" />
+  <bean id="databaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker"/>
+  <bean id="configurationDaoImpl" class="com.cloud.configuration.dao.ConfigurationDaoImpl"/>
 
   <!-- simulator components -->
   <bean id="SimulatorSecondaryDiscoverer" class="com.cloud.resource.SimulatorSecondaryDiscoverer">
@@ -122,9 +121,9 @@
   <bean id="deploymentPlanners" class="com.cloud.utils.component.AdapterList">
     <property name="Adapters">
       <list>
-        <ref bean="FirstFitPlanner" />
-        <ref bean="UserDispersingPlanner" />
-        <ref bean="UserConcentratedPodPlanner" />
+        <ref bean="FirstFitPlanner"/>
+        <ref bean="UserDispersingPlanner"/>
+        <ref bean="UserConcentratedPodPlanner"/>
 
         <!--
                   <ref bean="BareMetalPlanner" />
@@ -215,6 +214,16 @@
     </property>
   </bean>
 
-  <bean id="GlobalLoadBalancingRulesServiceImpl" class ="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" />
+  <bean id="GlobalLoadBalancingRulesServiceImpl"
+        class="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl"/>
+
+  <!--
+  AffinityGroup Processors
+  -->
+  <bean id="HostAntiAffinityProcessor" class="org.apache.cloudstack.affinity.HostAntiAffinityProcessor">
+    <property name="name" value="HostAntiAffinityProcessor"/>
+    <property name="type" value="host anti-affinity"/>
+  </bean>
+
 
 </beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79812c25/test/integration/smoke/test_affinity_groups.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_affinity_groups.py b/test/integration/smoke/test_affinity_groups.py
index 432751c..83fccf5 100644
--- a/test/integration/smoke/test_affinity_groups.py
+++ b/test/integration/smoke/test_affinity_groups.py
@@ -16,142 +16,181 @@
 # specific language governing permissions and limitations
 # under the License.
 
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from marvin.integration.lib.utils import *
+from marvin.integration.lib.base import *
+from marvin.integration.lib.common import *
+from marvin import remoteSSHClient
+from nose.plugins.attrib import attr
+
+class Services:
+    """Test Account Services
+    """
 
+    def __init__(self):
+        self.services = {
+            "domain": {
+                "name": "Domain",
+            },
+            "account": {
+                "email": "test@test.com",
+                "firstname": "Test",
+                "lastname": "User",
+                "username": "test",
+                # Random characters are appended for unique
+                # username
+                "password": "password",
+            },
+            "service_offering": {
+                "name": "Tiny Instance",
+                "displaytext": "Tiny Instance",
+                "cpunumber": 1,
+                "cpuspeed": 100,
+                # in MHz
+                "memory": 64,
+                # In MBs
+            },
+            "ostype": 'CentOS 5.3 (64-bit)',
+            "mode": 'advanced',
+            "affinity": {
+                "name": "webvms",
+                "type": "host anti-affinity",
+            }
+        }
 
-import marvin
-from marvin.cloudstackTestCase import *
-from marvin.remoteSSHClient import remoteSSHClient
-import hashlib
-import random
 
 class TestDeployVmWithAffinityGroup(cloudstackTestCase):
     """
     This test deploys a virtual machine into a user account
     using the small service offering and builtin template
     """
-    def setUp(self):
-		"""
-		CloudStack internally saves its passwords in md5 form and that is how we
-		specify it in the API. Python's hashlib library helps us to quickly hash
-		strings as follows
-		"""
-		mdf = hashlib.md5()
-		mdf.update('password')
-		mdf_pass = mdf.hexdigest()
-
-		self.apiClient = self.testClient.getApiClient() #Get ourselves an API client
-
-		self.acct = createAccount.createAccountCmd() #The createAccount command
-		self.acct.accounttype = 0					#We need a regular user. admins have accounttype=1
-		self.acct.firstname = 'test'
-		self.acct.lastname = 'user'				 #What's up doc?
-		self.acct.password = mdf_pass				#The md5 hashed password string
-		self.acct.username = 'testuser'
-		self.acct.email = 'testuser@xyz.com'
-		self.acct.account = 'testacct'
-		self.acct.domainid = 1					   #The default ROOT domain
-		self.acctResponse = self.apiClient.createAccount(self.acct)
-		# And upon successful creation we'll log a helpful message in our logs
-		# using the default debug logger of the test framework
-		self.debug("successfully created account: %s, user: %s, id: \
-				   %s"%(self.acctResponse.account.account, \
-						self.acctResponse.account.username, \
-						self.acctResponse.account.id))
-
-
-		self.zone = listZones.listZonesCmd()
-		self.zone.uuid = self.apiClient.listZones(self.zone)[0].id
-
-		self.service_offering = listServiceOfferings.listServiceOfferingsCmd()
-		self.service_offering.uuid = self.apiClient.listServiceOfferings(self.service_offering)[0].id
-
-		self.template = listTemplates.listTemplatesCmd()
-		self.template.templatefilter = 'featured'
-		self.template.name = 'CentOS'
-		self.template.uuid = self.apiClient.listTemplates(self.template)[0].id
-
-    def test_DeployVm(self):
-        """
-        Let's start by defining the attributes of our VM that we will be
-        deploying on CloudStack. We will be assuming a single zone is available
-        and is configured and all templates are Ready
-
-        The hardcoded values are used only for brevity.
 
-		First create the host anti-affinity group for this account
+    @classmethod
+    def setUpClass(cls):
+        cls.api_client = super(TestDeployVmWithAffinityGroup, cls).getClsTestClient().getApiClient()
+        cls.services = Services().services
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client, cls.services)
+        cls.zone = get_zone(cls.api_client, cls.services)
+        cls.disk_offering = DiskOffering.create(
+            cls.api_client,
+            cls.services["disk_offering"]
+        )
+        cls.template = get_template(
+            cls.api_client,
+            cls.zone.id,
+            cls.services["ostype"]
+        )
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+        cls.services["volume"]["zoneid"] = cls.zone.id
+
+        cls.services["template"] = cls.template.id
+        cls.services["zoneid"] = cls.zone.id
+
+        cls.account = Account.create(
+            cls.api_client,
+            cls.services["account"],
+            domainid=cls.domain.id
+        )
+
+        cls.services["account"] = cls.account.account.name
+
+        cls.service_offering = ServiceOffering.create(
+            cls.api_client,
+            cls.services["service_offering"]
+        )
+
+        cls.ag = AffinityGroup.create(cls.api_client, cls.services["affinity"], domainid=cls.domain.id)
+
+        cls._cleanup = [
+            cls.service_offering,
+            cls.disk_offering,
+            cls.account,
+        ]
+        return
+
+    @attr(tags=["simulator", "basic", "advanced"])
+    def test_DeployVmAntiAffinityGroup(self):
+        """
+        Deploys a couple of VMs in the same affinity group and verifies they are not on the same host
         """
-	createAGCmd = createAffinityGroup.createAffinityGroupCmd()
-	createAGCmd.name = 'webvms1'
-	createAGCmd.type = 'host anti-affinity'
-	createAGCmd.account = self.acct.account
-	createAGCmd.domainid = self.acct.domainid
-
-	createAGResponse = self.apiClient.createAffinityGroup(createAGCmd)
-	self.debug("AffinityGroup %s was created in the job %s"%(createAGResponse.id, createAGResponse.jobid))
-
-
-	deployVmCmd = deployVirtualMachine.deployVirtualMachineCmd()
-	deployVmCmd.zoneid = self.zone.uuid
-	deployVmCmd.templateid = self.template.uuid #CentOS 5.6 builtin
-	deployVmCmd.serviceofferingid = self.service_offering.uuid
-	deployVmCmd.account = self.acct.account
-	deployVmCmd.domainid = self.acct.domainid
-	deployVmCmd.affinitygroupnames=[]
-	deployVmCmd.affinitygroupnames.append(str(createAGResponse.name))
-	deployVmResponse = self.apiClient.deployVirtualMachine(deployVmCmd)
-	self.debug("VM %s was deployed in the job %s"%(deployVmResponse.id, deployVmResponse.jobid))
-
-	# At this point our VM is expected to be Running. Let's find out what
-	# listVirtualMachines tells us about VMs in this account
-
-	listVmCmd = listVirtualMachines.listVirtualMachinesCmd()
-	listVmCmd.id = deployVmResponse.id
-	listVmResponse = self.apiClient.listVirtualMachines(listVmCmd)
-
-	self.assertNotEqual(len(listVmResponse), 0, "Check if the list API \
-						returns a non-empty response")
-
-	vm = listVmResponse[0]
-	self.assertEqual(vm.state, "Running", "Check if VM has reached Running state in CS")
-
-	VM1hostid = vm.hostid
-
-	#Deploy another VM in same affinity group
-	deployVm2Cmd = deployVirtualMachine.deployVirtualMachineCmd()
-	deployVm2Cmd.zoneid = self.zone.uuid
-	deployVm2Cmd.templateid = self.template.uuid #CentOS 5.6 builtin
-	deployVm2Cmd.serviceofferingid = self.service_offering.uuid
-	deployVm2Cmd.account = self.acct.account
-	deployVm2Cmd.domainid = self.acct.domainid
-	deployVm2Cmd.affinitygroupnames=[]
-	deployVm2Cmd.affinitygroupnames.append(str(createAGResponse.name))
-
-	deployVm2Response = self.apiClient.deployVirtualMachine(deployVm2Cmd)
-	self.debug("VM2 %s was deployed in the job %s"%(deployVm2Response.id, deployVm2Response.jobid))
-
-	# At this point our VM is expected to be Running. Let's find out what
-	# listVirtualMachines tells us about VMs in this account
-
-	listVm2Cmd = listVirtualMachines.listVirtualMachinesCmd()
-	listVm2Cmd.id = deployVm2Response.id
-	listVm2Response = self.apiClient.listVirtualMachines(listVm2Cmd)
-
-	self.assertNotEqual(len(listVm2Response), 0, "Check if the list API \
-						returns a non-empty response")
-
-	vm2 = listVm2Response[0]
-	self.assertEqual(vm2.state, "Running", "Check if VM has reached Running state in CS")
-
-	VM2hostid = vm2.hostid
-
-	self.assertNotEqual(VM1hostid, VM2hostid, "The hosts of the 2 VM's in the host anti-affinity group are not different, test failed")
-
-    def tearDown(self):
-	"""
-		And finally let us cleanup the resources we created by deleting the
-		account. All good unittests are atomic and rerunnable this way
-		"""
-        deleteAcct = deleteAccount.deleteAccountCmd()
-        deleteAcct.id = self.acctResponse.account.id
-        self.apiClient.deleteAccount(deleteAcct)
-        self.testClient.close()
+        #deploy VM1 in affinity group created in setUp
+        vm1 = VirtualMachine.create(
+            self.api_client,
+            self.services["virtual_machine"],
+            templateid=self.template.id,
+            accountid=self.account.account.name,
+            domainid=self.account.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            affinitygroupnames=self.ag.name,
+            mode=self.services["mode"]
+        )
+
+        list_vm1 = list_virtual_machines(
+            self.api_client,
+            id=vm1.id
+        )
+        self.assertEqual(
+            isinstance(list_vm1, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        self.assertNotEqual(
+            len(list_vm1),
+            0,
+            "Check VM available in List Virtual Machines"
+        )
+        vm1_response = list_vm1[0]
+        self.assertEqual(
+            vm1_response.state,
+            'Running',
+            msg="VM is not in Running state"
+        )
+        host_of_vm1 = vm1_response.hostid
+
+        #deploy VM2 in affinity group created in setUp
+        vm2 = VirtualMachine.create(
+            self.api_client,
+            self.services["virtual_machine"],
+            templateid=self.template.id,
+            accountid=self.account.account.name,
+            domainid=self.account.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            affinitygroupnames=self.ag.name,
+            mode=self.services["mode"]
+        )
+        list_vm2 = list_virtual_machines(
+            self.api_client,
+            id=self.vm1.id
+        )
+        self.assertEqual(
+            isinstance(list_vm2, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        self.assertNotEqual(
+            len(list_vm2),
+            0,
+            "Check VM available in List Virtual Machines"
+        )
+        vm2_response = list_vm2[0]
+        self.assertEqual(
+            vm2_response.state,
+            'Running',
+            msg="VM is not in Running state"
+        )
+        host_of_vm2 = vm2_response.hostid
+
+        self.assertNotEqual(host_of_vm1, host_of_vm2,
+            msg="Both VMs of affinity group %s are on the same host" % self.ag.name)
+
+
+        @classmethod
+        def tearDown(cls):
+            try:
+                cls.api_client = super(TestDeployVmWithAffinityGroup, cls).getClsTestClient().getApiClient()
+                #Clean up, terminate the created templates
+                cleanup_resources(cls.api_client, cls.cleanup)
+            except Exception as e:
+                raise Exception("Warning: Exception during cleanup : %s" % e)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79812c25/tools/marvin/marvin/integration/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py
index f3370eb..8c7470e 100644
--- a/tools/marvin/marvin/integration/lib/base.py
+++ b/tools/marvin/marvin/integration/lib/base.py
@@ -223,7 +223,7 @@ class VirtualMachine:
     def create(cls, apiclient, services, templateid=None, accountid=None,
                     domainid=None, zoneid=None, networkids=None, serviceofferingid=None,
                     securitygroupids=None, projectid=None, startvm=None,
-                    diskofferingid=None, hostid=None, mode='basic'):
+                    diskofferingid=None, affinitygroupname=None, hostid=None, mode='basic'):
         """Create the instance"""
 
         cmd = deployVirtualMachine.deployVirtualMachineCmd()
@@ -268,6 +268,9 @@ class VirtualMachine:
         if "userdata" in services:
             cmd.userdata = base64.b64encode(services["userdata"])
 
+        if "affinitygroupnames" in services:
+            cmd.affinitygroupnames  = services["affinitygroupnames"]
+
         if projectid:
             cmd.projectid = projectid
 
@@ -2424,3 +2427,27 @@ class VPC:
         cmd = listVPCs.listVPCsCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         return(apiclient.listVPCs(cmd))
+
+
+class AffinityGroup:
+    def __init__(self, items):
+        self.__dict__.update(items)
+
+    @classmethod
+    def create(cls, apiclient, services, account=None, domainid=None):
+        agCmd = createAffinityGroup.createAffinityGroupCmd()
+        agCmd.name = services['name']
+        agCmd.displayText = services['displaytext'] if 'displaytext' in services else services['name']
+        agCmd.type = services['type']
+        agCmd.account = services['account'] if 'account' in services else account
+        agCmd.domainid = services['domainid'] if 'domainid' in services else domainid
+
+    def update(self):
+        pass
+
+    def delete(self):
+        pass
+
+    @classmethod
+    def list(cls):
+        pass
\ No newline at end of file