From bdc50338b5ae3495e9a5dc834cb5223c41431f52 Mon Sep 17 00:00:00 2001 From: shweta agarwal Date: Thu, 4 Feb 2016 12:19:39 +0530 Subject: [PATCH 1/4] automated 9277 9276 9275 9274 9273 9179 9178 9177 --- .../maint/test_escalations_instances.py | 270 ++++++++++++++++++ .../component/test_escalations_instances.py | 90 +++++- .../component/test_escalations_vmware.py | 62 ++++ .../component/test_project_resources.py | 15 +- .../component/test_project_usage.py | 235 ++++++++++++++- test/integration/component/test_usage.py | 129 ++++++++- tools/marvin/marvin/config/test_data.py | 41 ++- tools/marvin/marvin/lib/base.py | 1 + 8 files changed, 821 insertions(+), 22 deletions(-) create mode 100644 test/integration/component/maint/test_escalations_instances.py diff --git a/test/integration/component/maint/test_escalations_instances.py b/test/integration/component/maint/test_escalations_instances.py new file mode 100644 index 00000000000..db97e392066 --- /dev/null +++ b/test/integration/component/maint/test_escalations_instances.py @@ -0,0 +1,270 @@ +# 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. + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import (cleanup_resources, + validateList, + get_hypervisor_type) +from marvin.lib.base import (Account, + VirtualMachine, + ServiceOffering, + Volume, + DiskOffering, + Template, + listConfigurations,Configurations) +from marvin.lib.common import (get_domain,list_isos, + get_zone, + get_template) +from nose.plugins.attrib import attr +from ast import literal_eval +from marvin.codes import PASS +from marvin.cloudstackException import CloudstackAPIException +from marvin.sshClient import SshClient +from marvin.cloudstackException import CloudstackAPIException +import time + +class TestInstance(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + try: + cls._cleanup = [] + cls.testClient = super(TestInstance, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + # Get Domain, Zone, Template + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + if cls.zone.localstorageenabled: + cls.storagetype = 'local' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' + cls.services["disk_offering"]["storagetype"] = 'local' + else: + cls.storagetype = 'shared' + cls.services["service_offerings"]["tiny"]["storagetype"] = 'shared' + cls.services["disk_offering"]["storagetype"] = 'shared' + + cls.services['mode'] = cls.zone.networktype + cls.services["virtual_machine"]["hypervisor"] = cls.testClient.getHypervisorInfo() + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["custom_volume"]["zoneid"] = cls.zone.id + # Creating Disk offering, Service Offering and Account + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offerings"]["small"] + ) + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + # Getting authentication for user in newly created Account + cls.user = cls.account.user[0] + cls.userapiclient = cls.testClient.getUserApiClient(cls.user.username, cls.domain.name) + cls._cleanup.append(cls.disk_offering) + cls._cleanup.append(cls.service_offering) + cls._cleanup.append(cls.account) + cls.mgtSvrDetails = cls.config.__dict__["mgtSvr"][0].__dict__ + except Exception as e: + cls.tearDownClass() + raise Exception("Warning: Exception in setup : %s" % e) + return + + def setUp(self): + + self.apiClient = self.testClient.getApiClient() + self.cleanup = [] + + def tearDown(self): + #Clean up, terminate the created volumes + cleanup_resources(self.apiClient, self.cleanup) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def RestartServers(self): + """ Restart management server and usage server """ + + sshClient = SshClient( + self.mgtSvrDetails["mgtSvrIp"], + 22, + self.mgtSvrDetails["user"], + self.mgtSvrDetails["passwd"] + ) + command = "service cloudstack-management restart" + sshClient.execute(command) + return + + def updateConfigurAndRestart(self,name, value): + Configurations.update(self.apiClient, + name,value ) + self.RestartServers() + time.sleep(self.services["sleep"]) + + @attr(tags=["advanced"], required_hardware="true") + def test1_attach_volume(self): + """ + @desc: Unable to attach 7th Disk to windows server 2012R2 instance + Step1: Set global config vmware.root.disk.controller to 'osdefault' + Step2: Deploy a Windows 2012 R2 instance. + Step3: Attach 6 disks to the VM. + Step4: Try attaching a 7th disk to the VM + Verify that step4 succeeds without any exception + """ + self.hypervisor = str(get_hypervisor_type(self.api_client)).lower() + if self.hypervisor != "vmware": + self.skipTest("This test can be run only on vmware") + self.updateConfigurAndRestart("vmware.root.disk.controller","osdefault") + + + template = Template.register( + self.userapiclient, + self.services["Windows Server 2012"], + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.assertIsNotNone(template,"Failed to register Windows server 2012 R2 template") + self.debug( + "Registered a template with format {} and id {}".format( + self.services["Windows Server 2012"]["format"],template.id) + ) + template.download(self.userapiclient) + self.cleanup.append(template) + + # Creating a big service offering for windows VM launch + big_service_offering = ServiceOffering.create( + self.apiClient, + self.services["service_offerings"]["big"] + ) + self.cleanup.append(big_service_offering) + vm = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=big_service_offering.id, + templateid=template.id, + zoneid=self.zone.id + ) + self.assertIsNotNone(vm,"Failed to deploy virtual machine") + self.cleanup.append(vm) + response = VirtualMachine.list(self.userapiclient,id=vm.id) + status = validateList(response) + self.assertEqual(status[0],PASS,"list vm response returned invalid list") + + for i in range(0,7): + self.services["volume"]["diskname"]=i + disk = Volume.create( + self.userapiclient, + self.services["volume"], + zoneid=self.zone.id, + diskofferingid=self.disk_offering.id + ) + self.assertIsNotNone(disk,"Failed to create custom volume") + self.cleanup.append(disk) + try: + vm.attach_volume(self.userapiclient,disk) + list_volumes = Volume.list( + self.userapiclient, + listall=self.services["listall"], + id=disk.id + ) + + attached_volume = list_volumes[0] + self.assertEqual( + disk.id, + attached_volume.id, + "list volume response does not match with the volume created and attached to vm" + ) + except Exception as e: + self.fail("Failed to attach {} data disk to Windows server 2012 R2 vm ".format(i)) + return + @attr(tags=["advanced"], required_hardware="true") + def test_Scale_VM(self): + """ + @desc: + 1. Enable dynamic scaling in Global settings + 2. Register an CentOS 7 tempplate(with tools) and tick dynamic scaling + 3. Deploy VM with this template + 4.Start the VM and try to change service offering + + """ + self.hypervisor = str(get_hypervisor_type(self.api_client)).lower() + if self.hypervisor != "xenserver": + self.skipTest("This test can be run only on xenserver") + self.updateConfigurAndRestart("enable.dynamic.scale.vm","true") + template = Template.register( + self.userapiclient, + self.services["CentOS7template"], + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.assertIsNotNone(template,"Failed to register CentOS 7 template") + self.debug( + "Registered a template with format {} and id {}".format( + self.services["Windows Server 2012"]["format"],template.id) + ) + template.download(self.userapiclient) + self.cleanup.append(template) + vm = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=template.id, + zoneid=self.zone.id + ) + self.assertIsNotNone(vm,"Failed to deploy virtual machine") + self.cleanup.append(vm) + response = VirtualMachine.list(self.userapiclient,id=vm.id) + status = validateList(response) + self.assertEqual(status[0],PASS,"list vm response returned invalid list") + self.assertEqual(status[1].state,"Running", "vm is not running") + + service_offering = ServiceOffering.create( + self.apiClient, + self.services["service_offerings"]["big"] + ) + time.sleep(self.services["sleep"]) + vm.scale(self.userapiclient,service_offering.id) + scaleresponse = VirtualMachine.list(self.userapiclient,id=vm.id) + scalestatus = validateList(scaleresponse) + self.assertEqual(scalestatus[0],PASS,"list vm response returned invalid list") + self.assertEqual(scalestatus[1].serviceofferingname,service_offering.name, " service offering is not same") + self.assertEqual(scalestatus[1].serviceofferingid,service_offering.id, " service offering ids are not same") + + + return diff --git a/test/integration/component/test_escalations_instances.py b/test/integration/component/test_escalations_instances.py index 82e832c61ca..69f3fabb07f 100644 --- a/test/integration/component/test_escalations_instances.py +++ b/test/integration/component/test_escalations_instances.py @@ -42,7 +42,7 @@ from marvin.codes import PASS from marvin.sshClient import SshClient from nose.plugins.attrib import attr import time - +from marvin.cloudstackException import CloudstackAPIException class TestListInstances(cloudstackTestCase): @classmethod @@ -2068,6 +2068,94 @@ class TestListInstances(cloudstackTestCase): "VM NIC is not same as expected" ) return + @attr(tags=["advanced", "basic"], required_hardware="true") + def test_14_Create_vm_with_same_sshkey(self): + """ + @Desc: Test to verify API call Register ssh key pair fails when uses same public key for differnet key name + """ + + + # Listing all the SSH Key pairs + list_keypairs_before = SSHKeyPair.list( + self.userapiclient + ) + list_keypairs_before_size = 0 + if list_keypairs_before is not None: + list_keypairs_before_size = len(list_keypairs_before) + + # Registering first Key pair + new_keypair1 = SSHKeyPair.register( + self.userapiclient, + name="keypair1", + publickey="ssh-rsa: e6:9a:1e:b5:98:75:88:5d:56:bc:92:7b:43:48:05:b2") + self.assertIsNotNone( + new_keypair1, + "New Key pair generation failed" + ) + self.assertEquals( + "keypair1", + new_keypair1.name, + "Key Pair not created with given name" + ) + # Listing all the SSH Key pairs again + list_keypairs_after = SSHKeyPair.list( + self.userapiclient + ) + status = validateList(list_keypairs_after) + self.assertEquals( + PASS, + status[0], + "Listing of Key pairs failed" + ) + # Verifying that list size is increased by 1 + self.assertEquals( + list_keypairs_before_size + 1, + len(list_keypairs_after), + "List count is not matching" + ) + try: + + # Registering second key pair using same public key + new_keypair2 = SSHKeyPair.register( + self.userapiclient, + name="keypair2", + publickey="ssh-rsa: e6:9a:1e:b5:98:75:88:5d:56:bc:92:7b:43:48:05:b2") + self.fail("SSH Key creation passed using same public key ") + except CloudstackAPIException as e: + self.assertRaises("Exception Raised : %s" % e) + + # Deploying a VM with keypair 1 + first_vm_created = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + keypair=new_keypair1.name + ) + self.assertIsNotNone( + first_vm_created, + "VM creation failed" + ) + # Listing all the VMs for a user again + list_vms_after = VirtualMachine.list( + self.userapiclient,id=first_vm_created.id, + listall=True, + ) + status = validateList(list_vms_after) + self.assertEquals( + PASS, + status[0], + "VM creation failed" + ) + vm = list_vms_after[0] + self.assertEqual( + vm.state, + "Running", + "VM state should be running after deployment") + self.assertEqual(vm.keypair , new_keypair1.name , "VM keypair name is not keypair1") + + return class TestInstances(cloudstackTestCase): diff --git a/test/integration/component/test_escalations_vmware.py b/test/integration/component/test_escalations_vmware.py index aba4af0fc51..c3918eaca5b 100644 --- a/test/integration/component/test_escalations_vmware.py +++ b/test/integration/component/test_escalations_vmware.py @@ -267,4 +267,66 @@ class TestVMware(cloudstackTestCase): self.assertEqual(attachedIsoName, "vmware-tools.iso", "vmware-tools.iso not attached") return + @attr(tags=["advanced", "basic"], required_hardware="true") + def test3_attach_ISO_in_RHEL7OSVM(self): + """ + @desc:Incorrect guest os mapping in vmware for Rhel7 + Step1 :Register an RHEL 7 template + Step2 :Launch a VM + Step3: Try to attach VMware Tools ISO + Step4: Verify VMware tools ISO attached correctly + """ + self.hypervisor = str(get_hypervisor_type(self.api_client)).lower() + if self.hypervisor != "vmware": + self.skipTest("This test can be run only on vmware") + template = Template.register( + self.userapiclient, + self.services["Rhel7template"], + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + hypervisor=self.hypervisor + ) + self.debug( + "Registered a template with format {} and id {}".format( + self.services["Rhel7template"]["format"],template.id) + ) + template.download(self.userapiclient) + self.cleanup.append(template) + vm = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=template.id, + zoneid=self.zone.id + ) + self.cleanup.append(vm) + response = VirtualMachine.list(self.userapiclient,id=vm.id) + status = validateList(response) + self.assertEqual(status[0],PASS,"list vm response returned invalid list") + list_default_iso_response = list_isos( + self.api_client, + name="vmware-tools.iso", + account="system", + isready="true" + ) + status = validateList(list_default_iso_response) + self.assertEquals( + PASS, + status[0], + "ISO list is empty") + self.debug( + "Registered a ISO with name {}".format(list_default_iso_response[0].name)) + try: + vm.attach_iso(self.userapiclient,list_default_iso_response[0]) + except CloudstackAPIException as e: + self.fail("Attached ISO failed : %s" % e) + response = VirtualMachine.list(self.userapiclient, id=vm.id) + status = validateList(response) + self.assertEqual(status[0], PASS,"list vm response returned invalid list") + attachedIsoName=response[0].isoname; + self.assertEqual(attachedIsoName, "vmware-tools.iso", "vmware-tools.iso not attached") + return diff --git a/test/integration/component/test_project_resources.py b/test/integration/component/test_project_resources.py index 0816e9d516f..7302476e0f7 100644 --- a/test/integration/component/test_project_resources.py +++ b/test/integration/component/test_project_resources.py @@ -45,7 +45,7 @@ from marvin.lib.common import (get_zone, from marvin.lib.utils import cleanup_resources import random - +import time class Services: """Test Resource creation Services @@ -626,13 +626,15 @@ class TestTemplates(cloudstackTestCase): return @attr(tags=["advanced", "basic", "sg", "eip", "advancedns"], required_hardware="false") - def test_04_public_template_use_in_project(self): + def test_04_public_private_template_use_in_project(self): """Test Templates creation in projects """ # 1. Create a project # 2. Verify Public templates can be used without any restriction - # 3. Verify that template created in project can be used in project - # without any restrictions + # 3. Verify that private template created in project belongs to this project + # Verify that list template api wth project id list this template + + try: self.debug("Deploying VM for with public template: %s" % @@ -682,6 +684,11 @@ class TestTemplates(cloudstackTestCase): True, "Check Template is in ready state or not" ) + # Verify list template with project id is listing this template + templatelist = Template.list(self.apiclient,projectid=self.project.id,id=template_1.id,templatefilter="all") + self.assertEqual(templatelist[0].id,template_1.id,"template created does not belong to the project") + + except Exception as e: self.fail("Exception occured: %s" % e) return diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py index 81aed15483c..da88a95d11a 100644 --- a/test/integration/component/test_project_usage.py +++ b/test/integration/component/test_project_usage.py @@ -20,7 +20,7 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest from marvin.cloudstackAPI import deleteVolume -from marvin.lib.utils import (cleanup_resources) +from marvin.lib.utils import (cleanup_resources, validateList) from marvin.lib.base import (Project, VirtualMachine, Account, @@ -35,14 +35,17 @@ from marvin.lib.base import (Project, DiskOffering, LoadBalancerRule, Template, - Iso) + Iso, + VmSnapshot) from marvin.lib.common import (get_domain, get_zone, get_template, list_volumes, get_builtin_template_info, - find_storage_pool_type) + find_storage_pool_type + ) import time +from marvin.codes import PASS class Services: """Test Snapshots Services @@ -67,8 +70,8 @@ class Services: "name": "Tiny Instance", "displaytext": "Tiny Instance", "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs + "cpuspeed": 256, # in MHz + "memory": 256, # In MBs }, "disk_offering": { "displaytext": "Small", @@ -142,14 +145,14 @@ class TestVmUsage(cloudstackTestCase): cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.services['mode'] = cls.zone.networktype - template = get_template( + cls.template = get_template( cls.api_client, cls.zone.id, cls.services["ostype"] ) cls.services["server"]["zoneid"] = cls.zone.id - cls.services["template"] = template.id + cls.services["template"] = cls.template.id # Create Account, VMs etc cls.account = Account.create( @@ -171,13 +174,7 @@ class TestVmUsage(cloudstackTestCase): cls.api_client, cls.services["service_offering"] ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) + cls._cleanup = [ cls.project, cls.service_offering, @@ -213,6 +210,7 @@ class TestVmUsage(cloudstackTestCase): """Test Create/Destroy VM and verify usage calculation """ # Validate the following + # Validate 'listProjects' return tags 'vmstopped' or 'vmrunning' when their value is zero # 1. Create a VM. Verify usage_events table contains VM .create, # VM.start , Network.offering.assign , Volume.create events # 2. Stop the VM. Verify usage_events table contains @@ -221,10 +219,35 @@ class TestVmUsage(cloudstackTestCase): # VM.Destroy and volume .delete Event for the created account # 4. Delete the account + projectlist=Project.list(self.apiclient,account=self.account.name, + domainid=self.account.domainid,id=self.project.id) + + self.assertEqual(projectlist[0].vmrunning,0,"vmrunning value is not returned") + self.assertEqual(projectlist[0].vmstopped,0,"vmstopped value is not returned") + + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["server"], + templateid=self.template.id, + serviceofferingid=self.service_offering.id, + projectid=self.project.id + ) + + projectlist=Project.list(self.apiclient,account=self.account.name, + domainid=self.account.domainid,id=self.project.id) + + self.assertEqual(projectlist[0].vmrunning,1,"vmrunning value is not returned") + self.assertEqual(projectlist[0].vmstopped,0,"vmstopped value is not returned") try: self.debug("Stopping the VM: %s" % self.virtual_machine.id) # Stop the VM self.virtual_machine.stop(self.apiclient) + projectlist=Project.list(self.apiclient,account=self.account.name, + domainid=self.account.domainid,id=self.project.id) + + self.assertEqual(projectlist[0].vmrunning,0,"vmrunning value is not returned") + self.assertEqual(projectlist[0].vmstopped,1,"vmstopped value is not returned") + except Exception as e: self.fail("Failed to stop VM: %s" % e) @@ -308,6 +331,8 @@ class TestVmUsage(cloudstackTestCase): "Check VM.STOP in events table" ) + + self.assertEqual( qresult.count('NETWORK.OFFERING.REMOVE'), 1, @@ -322,7 +347,7 @@ class TestVmUsage(cloudstackTestCase): self.assertEqual( qresult.count('VOLUME.DELETE'), - 1, + 2, "Check VOLUME.DELETE in events table" ) return @@ -1819,3 +1844,183 @@ class TestVpnUsage(cloudstackTestCase): "Check VPN.USER.ADD in events table" ) return + +class TestVMSnapshotUsage(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.testClient = super(TestVMSnapshotUsage, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.hypervisor = cls.testClient.getHypervisorInfo() + cls.snapshotSupported = True + cls._cleanup = [] + if cls.hypervisor.lower() in ['hyperv', 'lxc', 'kvm','baremetal']: + cls.snapshotSupported = False + return + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + cls.hypervisor = cls.testClient.getHypervisorInfo() + template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["server"]["zoneid"] = cls.zone.id + + cls.services["template"] = template.id + + # Create Account, VMs etc + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + + cls.services["account"] = cls.account.name + + cls.project = Project.create( + cls.api_client, + cls.services["project"], + account=cls.account.name, + domainid=cls.account.domainid + ) + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.virtual_machine = VirtualMachine.create( + cls.api_client, + cls.services["server"], + templateid=template.id, + serviceofferingid=cls.service_offering.id, + projectid=cls.project.id + ) + cls._cleanup = [ + cls.project, + cls.service_offering, + cls.account, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + if not self.snapshotSupported: + self.skipTest("Snapshots are not supported on %s" % self.hypervisor) + return + + def tearDown(self): + try: + #Clean up, terminate the created instance and snapshots + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(speed = "slow") + @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"], required_hardware="false") + def test_01_vmsnapshot_usage(self): + """Test Create/Delete a manual snap shot and verify + correct usage is recorded + """ + # Validate the following + # 1. Create vmsnapshot of the VM for this account. vm.Snapshot.create + # event is there for the created account in cloud.usage_event table + # 2. Destroy the snapshot after some time. vm.Snapshot.delete event is + # generated for the destroyed Snapshot + # 3. Delete the account + + vmsnapshot=VmSnapshot.create(self.apiclient,self.virtual_machine.id,snapshotmemory="true") + vmsnap = VmSnapshot.list( + self.apiclient, + projectid=self.project.id, + type='ROOT', + listall=True + ) + self.assertEqual( + isinstance(vmsnap, list), + True, + "Check if list volumes return a valid data" + ) + self.assertEqual(vmsnapshot.projectid, self.project.id, "check if list vmsnapshot api returns projectid") + self.assertEqual(vmsnapshot.project, self.project.name,"check if list vmsnapshot returns project name") + + # Delete snapshot Rule + self.debug("Deleting vmsnapshot: %s" % vmsnapshot.id) + VmSnapshot.deleteVMSnapshot(self.apiclient,vmsnapshot.id) + + + # Fetch project account ID from project UUID + self.debug( + "select project_account_id from projects where uuid = '%s';" \ + % self.project.id) + + qresultset = self.dbclient.execute( + "select project_account_id from projects where uuid = '%s';" \ + % self.project.id + ) + self.assertEqual( + isinstance(qresultset, list), + True, + "Check DB query result set for valid data" + ) + + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set" + ) + qresult = qresultset[0] + + account_id = qresult[0] + self.debug("select type from usage_event where account_id = '%s';" \ + % account_id) + + qresultset = self.dbclient.execute( + "select type from usage_event where account_id = '%s';" \ + % account_id + ) + + self.assertEqual( + isinstance(qresultset, list), + True, + "Check if database query returns a valid data" + ) + + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set" + ) + + qresult = str(qresultset) + self.debug("Query Result: %s" % qresult) + + # Check for VM.SNAPSHOT.CREATE, VM.SNAPSHOT.DELETE events in cloud.usage_event + # table + self.assertEqual( + qresult.count('VMSNAPSHOT.CREATE'), + 1, + "Check VM.SNAPSHOT.CREATE event in events table" + ) + + self.assertEqual( + qresult.count('VMSNAPSHOT.DELETE'), + 1, + "Check VM.SNAPSHOT.DELETE in events table" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index ddb0196879f..035b92d49c6 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -20,7 +20,7 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import cloudstackTestCase, unittest from marvin.cloudstackAPI import deleteVolume -from marvin.lib.utils import (cleanup_resources) +from marvin.lib.utils import (cleanup_resources,get_hypervisor_type) from marvin.lib.base import (Account, ServiceOffering, NATRule, @@ -491,6 +491,7 @@ class TestVolumeUsage(cloudstackTestCase): cls.api_client = cls.testClient.getApiClient() cls.services = Services().services + cls.testdata = cls.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) @@ -586,6 +587,11 @@ class TestVolumeUsage(cloudstackTestCase): # 3. Detach the data disk from this VM # 4. Destroy the Data disk. Volume.delete event is generated for data # disk of the destroyed VM + # Upload a volume + # Verify Volume.upload event in usage table + # attach the uploaded volume to a VM + # Verify Volume.create Event is there for the attached volume + try: # Stop VM @@ -674,6 +680,127 @@ class TestVolumeUsage(cloudstackTestCase): 1, "Check VOLUME.DELETE in events table" ) + self.hypervisor = str(get_hypervisor_type(self.apiclient)).lower() + if self.hypervisor == "vmware": + self.testdata["coreos_volume"][ + "url"] = self.testdata["coreos_volume"]["urlvmware"] + self.testdata["coreos_volume"]["format"] = "OVA" + elif self.hypervisor == "xenserver": + self.testdata["coreos_volume"][ + "url"] = self.testdata["coreos_volume"]["urlxen"] + self.testdata["coreos_volume"]["format"] = "VHD" + elif self.hypervisor == "kvm": + self.testdata["coreos_volume"][ + "url"] = self.testdata["coreos_volume"]["urlkvm"] + self.testdata["coreos_volume"]["format"] = "QCOW2" + elif self.hypervisor == "hyperv": + self.testdata["coreos_volume"][ + "url"] = self.testdata["coreos_volume"]["urlxen"] + self.testdata["coreos_volume"]["format"] = "VHD" + + volume_uploaded = Volume.upload( + self.apiclient, + self.testdata["coreos_volume"], + self.zone.id, + account=self.account.name, + domainid=self.account.domainid) + self.assertIsNotNone(volume_uploaded, "Volume creation failed") + volume_uploaded.wait_for_upload(self.apiclient) + # Fetch volume ID from volume_uuid + self.debug("select id from volumes where uuid = '%s';" + % volume_uploaded.id) + + qresultset = self.dbclient.execute( + "select id from volumes where uuid = '%s';" + % volume_uploaded.id + ) + self.assertEqual( + isinstance(qresultset, list), + True, + "Check DB query result set for valid data" + ) + + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set" + ) + qresult = qresultset[0] + + volume_id = qresult[0] + + self.debug("select type from usage_event where volume_id = '%s';" + % volume_id) + + qresultset = self.dbclient.execute( + "select type from usage_event where resource_id = '%s';" + % volume_id + ) + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set" + ) + self.assertEqual( + isinstance(qresultset, list), + True, + "Check DB query result set for valid data" + ) + + qresult = str(qresultset) + self.debug("Query result: %s" % qresult) + # Check VOLUME.UPLOAD event in cloud.usage_event table + self.assertEqual( + qresult.count('VOLUME.UPLOAD'), + 1, + "Check VOLUME.UPLOAD event in events table" + ) + self.virtual_machine.start(self.apiclient) + vms = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return the valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "VM state should be running after deployment" + ) + self.virtual_machine.attach_volume(self.apiclient,volume_uploaded) + self.debug("select type from usage_event where offering_id = 6 and volume_id = '%s';" + % volume_id) + + qresultset = self.dbclient.execute( + "select type from usage_event where offering_id = 6 and resource_id = '%s';" + % volume_id + ) + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set" + ) + self.assertEqual( + isinstance(qresultset, list), + True, + "Check DB query result set for valid data" + ) + + qresult = str(qresultset) + self.debug("Query result: %s" % qresult) + # Check VOLUME.CREATE event in cloud.usage_event table + self.assertEqual( + qresult.count('VOLUME.CREATE'), + 1, + "Check VOLUME.CREATE event in events table" + ) + + return diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index 9249c055383..ebe4c0f3e46 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -121,7 +121,7 @@ test_data = { "name": "LargeInstance", "displaytext": "LargeInstance", "cpunumber": 1, - "cpuspeed": 500, + "cpuspeed": 1024, "memory": 2048, }, "hasmall": { @@ -833,6 +833,15 @@ test_data = { "ostype": "CentOS 5.6 (64-bit)" }, + "coreos_volume": { + "diskname": "Volume_core", + "urlvmware":"http://10.147.28.7/templates/coreos/coreos_production_vmware.ova", + "urlxen":"http://10.147.28.7/templates/coreos/" \ + "coreos_production_cloudstack_image-xen.vhd.bz2", + "urlkvm": "http://dl.openvm.eu/cloudstack/coreos/x86_64/" \ + "coreos_production_cloudstack_image-kvm.qcow2.bz2", + "urlhyperv":"http://dl.openvm.eu/cloudstack/coreos/x86_64/coreos_production_cloudstack_image-hyperv.vhd.zip" + }, "CentOS6.3template": { "displaytext": "Centos", "name": "Centos", @@ -842,6 +851,26 @@ test_data = { "format": "OVA", "ispublic": "true" }, + "CentOS7template": { + "displaytext": "Centos", + "name": "Centos", + "passwordenabled": False, + "isdynamicallyscalable":True, + "ostype": "CentOS 7", + "url": "http://10.147.28.7/templates/cenots7/Centos7.vhd", + "format": "VHD", + "ispublic": "true", + "hypervisor":"Xenserver" + }, + "Rhel7template": { + "displaytext": "Rhel", + "name": "Rhel", + "passwordenabled": False, + "ostype": "Red Hat Enterprise Linux 7", + "url": "http://10.147.28.7/templates/rhel71.ova", + "format": "OVA", + "ispublic": "true" + }, "template_2": { "displaytext": "Public Template", "name": "Public template", @@ -862,6 +891,16 @@ test_data = { "ispublic": "true", "hypervisor": "XenServer" }, + "Windows Server 2012": { + "displaytext": "Windows Server 2012", + "name": "Windows Server 2012", + "passwordenabled": False, + "url": "http://10.147.28.7/templates/Windows2012/WindowsServer2012R2.ova.gz", + "format": "OVA", + "ostype": "Windows Server 2012 (64-bit)", + "ispublic": "true", + "hypervisor": "Vmware" + }, "privatetemplate": { "displaytext": "Public Template", "name": "Public template", diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index e81fd18c87c..3862b42d19c 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -1253,6 +1253,7 @@ class Template: "ispublic"] if "ispublic" in services else False cmd.isextractable = services[ "isextractable"] if "isextractable" in services else False + cmd.isdynamicallyscalable=services["isdynamicallyscalable"] if "isdynamicallyscalable" in services else False cmd.passwordenabled = services[ "passwordenabled"] if "passwordenabled" in services else False From 5bbf498faf5621f1f4b810372741ca35e473daeb Mon Sep 17 00:00:00 2001 From: shweta Date: Fri, 17 Feb 2017 15:33:45 +0530 Subject: [PATCH 2/4] Adressed review comment for automating bugs 9277 9276 9275 9274 9273 9179 9178 9177 --- .../maint/test_escalations_instances.py | 13 +++++------- .../component/test_escalations_instances.py | 21 ++++++++++--------- .../component/test_escalations_vmware.py | 3 ++- .../component/test_project_usage.py | 9 +++++--- tools/marvin/marvin/config/test_data.py | 9 +++----- 5 files changed, 27 insertions(+), 28 deletions(-) diff --git a/test/integration/component/maint/test_escalations_instances.py b/test/integration/component/maint/test_escalations_instances.py index db97e392066..f2410ea4b3e 100644 --- a/test/integration/component/maint/test_escalations_instances.py +++ b/test/integration/component/maint/test_escalations_instances.py @@ -26,16 +26,13 @@ from marvin.lib.base import (Account, Volume, DiskOffering, Template, - listConfigurations,Configurations) -from marvin.lib.common import (get_domain,list_isos, + Configurations) +from marvin.lib.common import (get_domain, get_zone, get_template) from nose.plugins.attrib import attr -from ast import literal_eval from marvin.codes import PASS -from marvin.cloudstackException import CloudstackAPIException from marvin.sshClient import SshClient -from marvin.cloudstackException import CloudstackAPIException import time class TestInstance(cloudstackTestCase): @@ -134,7 +131,7 @@ class TestInstance(cloudstackTestCase): @attr(tags=["advanced"], required_hardware="true") def test1_attach_volume(self): """ - @desc: Unable to attach 7th Disk to windows server 2012R2 instance + @desc: Unable to attach 7th Disk to windows server 2012R2 instance. Add a valid windows server 2012 URL to execute this test case Step1: Set global config vmware.root.disk.controller to 'osdefault' Step2: Deploy a Windows 2012 R2 instance. Step3: Attach 6 disks to the VM. @@ -146,7 +143,7 @@ class TestInstance(cloudstackTestCase): self.skipTest("This test can be run only on vmware") self.updateConfigurAndRestart("vmware.root.disk.controller","osdefault") - + self.services["Windows Server 2012"]["url"]="http://10.147.28.7/templates/Windows2012/WindowsServer2012R2.ova.gz", template = Template.register( self.userapiclient, self.services["Windows Server 2012"], @@ -234,7 +231,7 @@ class TestInstance(cloudstackTestCase): self.assertIsNotNone(template,"Failed to register CentOS 7 template") self.debug( "Registered a template with format {} and id {}".format( - self.services["Windows Server 2012"]["format"],template.id) + self.services["CentOS7template"]["format"],template.id) ) template.download(self.userapiclient) self.cleanup.append(template) diff --git a/test/integration/component/test_escalations_instances.py b/test/integration/component/test_escalations_instances.py index 69f3fabb07f..bbff9074c76 100644 --- a/test/integration/component/test_escalations_instances.py +++ b/test/integration/component/test_escalations_instances.py @@ -2113,16 +2113,6 @@ class TestListInstances(cloudstackTestCase): len(list_keypairs_after), "List count is not matching" ) - try: - - # Registering second key pair using same public key - new_keypair2 = SSHKeyPair.register( - self.userapiclient, - name="keypair2", - publickey="ssh-rsa: e6:9a:1e:b5:98:75:88:5d:56:bc:92:7b:43:48:05:b2") - self.fail("SSH Key creation passed using same public key ") - except CloudstackAPIException as e: - self.assertRaises("Exception Raised : %s" % e) # Deploying a VM with keypair 1 first_vm_created = VirtualMachine.create( @@ -2155,6 +2145,17 @@ class TestListInstances(cloudstackTestCase): "VM state should be running after deployment") self.assertEqual(vm.keypair , new_keypair1.name , "VM keypair name is not keypair1") + try: + + # Registering second key pair using same public key + new_keypair2 = SSHKeyPair.register( + self.userapiclient, + name="keypair2", + publickey="ssh-rsa: e6:9a:1e:b5:98:75:88:5d:56:bc:92:7b:43:48:05:b2") + self.fail("SSH Key creation passed using same public key ") + except CloudstackAPIException as e: + self.assertRaises("Exception Raised : %s" % e) + return diff --git a/test/integration/component/test_escalations_vmware.py b/test/integration/component/test_escalations_vmware.py index c3918eaca5b..11696251268 100644 --- a/test/integration/component/test_escalations_vmware.py +++ b/test/integration/component/test_escalations_vmware.py @@ -270,7 +270,7 @@ class TestVMware(cloudstackTestCase): @attr(tags=["advanced", "basic"], required_hardware="true") def test3_attach_ISO_in_RHEL7OSVM(self): """ - @desc:Incorrect guest os mapping in vmware for Rhel7 + @desc:Incorrect guest os mapping in vmware for Rhel7. Add a valid RHEL7 URL to execute this test case Step1 :Register an RHEL 7 template Step2 :Launch a VM Step3: Try to attach VMware Tools ISO @@ -279,6 +279,7 @@ class TestVMware(cloudstackTestCase): self.hypervisor = str(get_hypervisor_type(self.api_client)).lower() if self.hypervisor != "vmware": self.skipTest("This test can be run only on vmware") + self.services["Rhel7template"]["url"]="http://10.147.28.7/templates/rhel71.ova", template = Template.register( self.userapiclient, self.services["Rhel7template"], diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py index da88a95d11a..0c7374ea7a7 100644 --- a/test/integration/component/test_project_usage.py +++ b/test/integration/component/test_project_usage.py @@ -221,8 +221,11 @@ class TestVmUsage(cloudstackTestCase): projectlist=Project.list(self.apiclient,account=self.account.name, domainid=self.account.domainid,id=self.project.id) - + self.assertEqual(hasattr(projectlist[0],"vmrunning"), True , + "vmrunningattribute is not returned in list project api ") self.assertEqual(projectlist[0].vmrunning,0,"vmrunning value is not returned") + self.assertEqual(hasattr(projectlist[0], "vmrunning"), True, + "vmrunningattribute is not returned in list project api ") self.assertEqual(projectlist[0].vmstopped,0,"vmstopped value is not returned") self.virtual_machine = VirtualMachine.create( @@ -1931,8 +1934,8 @@ class TestVMSnapshotUsage(cloudstackTestCase): raise Exception("Warning: Exception during cleanup : %s" % e) return - @attr(speed = "slow") - @attr(tags=["advanced", "basic", "sg", "eip", "advancedns", "simulator"], required_hardware="false") + + @attr(tags=["advanced", "basic"]) def test_01_vmsnapshot_usage(self): """Test Create/Delete a manual snap shot and verify correct usage is recorded diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index ebe4c0f3e46..eb742544657 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -835,9 +835,8 @@ test_data = { }, "coreos_volume": { "diskname": "Volume_core", - "urlvmware":"http://10.147.28.7/templates/coreos/coreos_production_vmware.ova", - "urlxen":"http://10.147.28.7/templates/coreos/" \ - "coreos_production_cloudstack_image-xen.vhd.bz2", + "urlvmware":"http://dl.openvm.eu/cloudstack/coreos/x86_64/coreos_production_cloudstack_image-vmware.ova", + "urlxen":"http://dl.openvm.eu/cloudstack/coreos/x86_64/coreos_production_cloudstack_image-xen.vhd.bz2", "urlkvm": "http://dl.openvm.eu/cloudstack/coreos/x86_64/" \ "coreos_production_cloudstack_image-kvm.qcow2.bz2", "urlhyperv":"http://dl.openvm.eu/cloudstack/coreos/x86_64/coreos_production_cloudstack_image-hyperv.vhd.zip" @@ -857,7 +856,7 @@ test_data = { "passwordenabled": False, "isdynamicallyscalable":True, "ostype": "CentOS 7", - "url": "http://10.147.28.7/templates/cenots7/Centos7.vhd", + "url": "http://dl.openvm.eu/cloudstack/centos/vanilla/7/x86_64/CentOS-7-x86_64-vanilla-xen.vhd.bz2", "format": "VHD", "ispublic": "true", "hypervisor":"Xenserver" @@ -867,7 +866,6 @@ test_data = { "name": "Rhel", "passwordenabled": False, "ostype": "Red Hat Enterprise Linux 7", - "url": "http://10.147.28.7/templates/rhel71.ova", "format": "OVA", "ispublic": "true" }, @@ -895,7 +893,6 @@ test_data = { "displaytext": "Windows Server 2012", "name": "Windows Server 2012", "passwordenabled": False, - "url": "http://10.147.28.7/templates/Windows2012/WindowsServer2012R2.ova.gz", "format": "OVA", "ostype": "Windows Server 2012 (64-bit)", "ispublic": "true", From 7d80c1b349d7321b1d87367f5098e56c8504efe2 Mon Sep 17 00:00:00 2001 From: shweta Date: Fri, 5 May 2017 11:57:16 +0530 Subject: [PATCH 3/4] Modified a test case to include simulator scenario --- test/integration/component/test_usage.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index 035b92d49c6..f5475fd4653 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -697,6 +697,10 @@ class TestVolumeUsage(cloudstackTestCase): self.testdata["coreos_volume"][ "url"] = self.testdata["coreos_volume"]["urlxen"] self.testdata["coreos_volume"]["format"] = "VHD" + elif self.hypervisor == "simulator": + self.testdata["coreos_volume"][ + "url"] = self.testdata["coreos_volume"]["urlxen"] + self.testdata["coreos_volume"]["format"] = "VHD" volume_uploaded = Volume.upload( self.apiclient, From d5d1bd9fc736b8f4711e2f253ae432fa1d661203 Mon Sep 17 00:00:00 2001 From: shweta Date: Fri, 5 May 2017 14:04:35 +0530 Subject: [PATCH 4/4] Modified further based on Travis failures --- test/integration/component/test_project_usage.py | 2 +- test/integration/component/test_usage.py | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py index 0c7374ea7a7..829cbc7e09a 100644 --- a/test/integration/component/test_project_usage.py +++ b/test/integration/component/test_project_usage.py @@ -350,7 +350,7 @@ class TestVmUsage(cloudstackTestCase): self.assertEqual( qresult.count('VOLUME.DELETE'), - 2, + 1, "Check VOLUME.DELETE in events table" ) return diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index f5475fd4653..e6c65650496 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -574,9 +574,8 @@ class TestVolumeUsage(cloudstackTestCase): "basic", "sg", "eip", - "advancedns", - "simulator"], - required_hardware="false") + "advancedns"], + required_hardware="true") def test_01_volume_usage(self): """Test Create/delete a volume and verify correct usage is recorded """ @@ -697,10 +696,6 @@ class TestVolumeUsage(cloudstackTestCase): self.testdata["coreos_volume"][ "url"] = self.testdata["coreos_volume"]["urlxen"] self.testdata["coreos_volume"]["format"] = "VHD" - elif self.hypervisor == "simulator": - self.testdata["coreos_volume"][ - "url"] = self.testdata["coreos_volume"]["urlxen"] - self.testdata["coreos_volume"]["format"] = "VHD" volume_uploaded = Volume.upload( self.apiclient,