| # 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 | |
| import unittest | |
| from marvin.cloudstackAPI import (updateStoragePool, | |
| resizeVolume, | |
| listCapacity, | |
| addCluster) | |
| from marvin.sshClient import SshClient | |
| from marvin.lib.common import (get_zone, | |
| get_template, | |
| get_domain, | |
| list_volumes, | |
| get_pod, | |
| is_config_suitable) | |
| from marvin.lib.base import (Domain, | |
| Account, | |
| Template, | |
| VirtualMachine, | |
| Volume, | |
| DiskOffering, | |
| StoragePool, | |
| ServiceOffering, | |
| Configurations) | |
| from marvin.lib.utils import cleanup_resources | |
| from nose.plugins.attrib import attr | |
| import time | |
| class Test42xBugsMgmtSvr(cloudstackTestCase): | |
| @classmethod | |
| def setUpClass(cls): | |
| try: | |
| cls._cleanup = [] | |
| cls.testClient = super(Test42xBugsMgmtSvr, cls).getClsTestClient() | |
| cls.apiClient = cls.api_client = cls.testClient.getApiClient() | |
| cls.services = cls.testClient.getParsedTestDataConfig() | |
| cls.hypervisor = cls.testClient.getHypervisorInfo() | |
| # Get Domain, Zone, Template | |
| cls.domain = get_domain(cls.api_client) | |
| cls.zone = get_zone(cls.api_client, | |
| cls.testClient.getZoneForTests()) | |
| cls.pod = get_pod(cls.apiClient, zone_id=cls.zone.id) | |
| cls.template = get_template( | |
| cls.api_client, | |
| cls.zone.id, | |
| cls.services["ostype"] | |
| ) | |
| cls.services['mode'] = cls.zone.networktype | |
| cls.services["hypervisor"] = cls.testClient.getHypervisorInfo() | |
| # Creating Disk offering, Service Offering and Account | |
| cls.service_offering = ServiceOffering.create( | |
| cls.apiClient, | |
| cls.services["service_offerings"]["tiny"] | |
| ) | |
| cls.account = Account.create( | |
| cls.api_client, | |
| cls.services["account"], | |
| domainid=cls.domain.id | |
| ) | |
| # Create account | |
| cls.account_2 = Account.create( | |
| cls.api_client, | |
| cls.services["account2"], | |
| 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 | |
| ) | |
| # add objects created in setUpCls to the _cleanup list | |
| cls._cleanup = [cls.account, | |
| cls.account_2, | |
| cls.service_offering] | |
| 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 resources | |
| 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) | |
| return | |
| @attr(tags=["advanced", "basic", "tested"]) | |
| @attr(required_hardware="false") | |
| @attr(configuration='apply.allocation.algorithm.to.pods') | |
| def test_es_1223_apply_algo_to_pods(self): | |
| """ | |
| @Desc: Test VM creation while "apply.allocation.algorithm.to.pods" is | |
| set to true | |
| @Reference: https://issues.apache.org/jira/browse/CLOUDSTACK-4947 | |
| @Steps: | |
| Step1: Set global configuration "apply.allocation.algorithm.to.pods" | |
| to true | |
| Step2: Restart management server | |
| Step3: Verifying that VM creation is successful | |
| """ | |
| # Step1: set global configuration | |
| # "apply.allocation.algorithm.to.pods" to true | |
| # Configurations.update(self.apiClient, | |
| # "apply.allocation.algorithm.to.pods", "true") | |
| # TODO: restart management server | |
| if not is_config_suitable(apiclient=self.apiClient, | |
| name='apply.allocation.algorithm.to.pods', | |
| value='true'): | |
| self.skipTest('apply.allocation.algorithm.to.pods ' | |
| 'should be true. skipping') | |
| # TODO:Step2: Restart management server | |
| self.services["virtual_machine"]["zoneid"] = self.zone.id | |
| self.services["virtual_machine"]["template"] = self.template.id | |
| # Step3: Verifying that VM creation is successful | |
| virtual_machine = VirtualMachine.create( | |
| self.apiClient, | |
| self.services["virtual_machine2"], | |
| accountid=self.account.name, | |
| domainid=self.account.domainid, | |
| serviceofferingid=self.service_offering.id, | |
| ) | |
| self.cleanup.append(virtual_machine) | |
| # Verify VM state | |
| self.assertEqual( | |
| virtual_machine.state, | |
| 'Running', | |
| "Check VM state is Running or not" | |
| ) | |
| # cleanup: set global configuration | |
| # "apply.allocation.algorithm.to.pods" back to false | |
| Configurations.update( | |
| self.apiClient, | |
| name="apply.allocation.algorithm.to.pods", | |
| value="false" | |
| ) | |
| # TODO:cleanup: Restart management server | |
| return | |
| @attr(tags=["advanced", "basic", "tested"]) | |
| @attr(required_hardware="false") | |
| def test_local_storage_data_disk_tag(self): | |
| """ | |
| @Desc: Test whether tags are honoured while creating | |
| data disks on local storage | |
| @Steps: | |
| This test needs multiple local storages | |
| Step1: create a tag 'loc' on the local storage | |
| Step2: create a disk offering with this storage tag 'loc' | |
| Step3: create a VM and create disk by selecting the disk offering | |
| created in step2 | |
| step4: check whether the data disk created in step3 is created on | |
| local storage with tag 'loc' | |
| """ | |
| if not self.zone.localstorageenabled: | |
| self.skipTest('Local storage is not enable for this ' | |
| 'zone. skipping') | |
| local_storages = StoragePool.list(self.apiClient, | |
| zoneid=self.zone.id, | |
| scope='HOST') | |
| self.assertEqual( | |
| isinstance(local_storages, list), | |
| True, | |
| "Check list response returns a valid list" | |
| ) | |
| self.assertNotEqual( | |
| local_storages, | |
| None, | |
| "Check if local storage pools exists in ListStoragePools" | |
| ) | |
| cmd = updateStoragePool.updateStoragePoolCmd() | |
| cmd.zoneid = self.zone.id | |
| cmd.tags = 'loc' | |
| cmd.id = local_storages[0].id | |
| self.apiClient.updateStoragePool(cmd) | |
| self.services["disk_offering"]["storagetype"] = 'local' | |
| self.services["disk_offering"]["tags"] = 'loc' | |
| disk_offering = DiskOffering.create( | |
| self.apiClient, | |
| self.services["disk_offering"] | |
| ) | |
| self.services["virtual_machine"]["zoneid"] = self.zone.id | |
| self.services["virtual_machine"]["template"] = self.template.id | |
| # Step3: Verifying that VM creation is successful | |
| virtual_machine = VirtualMachine.create( | |
| self.apiClient, | |
| self.services["virtual_machine"], | |
| accountid=self.account.name, | |
| domainid=self.account.domainid, | |
| serviceofferingid=self.service_offering.id, | |
| mode=self.services["mode"] | |
| ) | |
| self.cleanup.append(virtual_machine) | |
| self.cleanup.append(disk_offering) | |
| # Verify VM state | |
| self.assertEqual( | |
| virtual_machine.state, | |
| 'Running', | |
| "Check VM state is Running or not" | |
| ) | |
| self.volume = Volume.create( | |
| self.apiClient, | |
| self.services["volume"], | |
| zoneid=self.zone.id, | |
| account=self.account.name, | |
| domainid=self.account.domainid, | |
| diskofferingid=disk_offering.id | |
| ) | |
| virtual_machine.attach_volume(self.apiClient, self.volume) | |
| self.attached = True | |
| list_volume_response = Volume.list( | |
| self.apiClient, | |
| id=self.volume.id | |
| ) | |
| self.assertEqual( | |
| isinstance(list_volume_response, list), | |
| True, | |
| "Check list response returns a valid list" | |
| ) | |
| self.assertNotEqual( | |
| list_volume_response, | |
| None, | |
| "Check if volume exists in ListVolumes" | |
| ) | |
| volume = list_volume_response[0] | |
| self.assertNotEqual( | |
| volume.virtualmachineid, | |
| None, | |
| "Check if volume state (attached) is reflected" | |
| ) | |
| storage_pool = StoragePool.list(self.apiClient, id=volume.storageid) | |
| self.assertEqual( | |
| volume.storagetype, | |
| 'local', | |
| "Check list storage pool response has local as storage type" | |
| ) | |
| self.assertEqual( | |
| storage_pool[0].tags, | |
| 'loc', | |
| "Check list storage pool response has tag" | |
| ) | |
| return | |
| @attr(tags=["advanced", "basic"]) | |
| @attr(required_hardware="false") | |
| def test_es_1236_cloudstack_sccs(self): | |
| """ | |
| @Desc: Test whether cloudstack-sccs is available on management server | |
| @Steps: | |
| Step1: run cloudstack-sccs on management server | |
| Step2: It should return a commit hash | |
| """ | |
| # Step1: run cloudstack-sccs on management server | |
| mgmt_ssh = SshClient( | |
| self.apiClient.connection.mgtSvr, | |
| 22, | |
| self.apiClient.connection.user, | |
| self.apiClient.connection.passwd | |
| ) | |
| mgmt_ssh.execute("cloudstack-sccs") | |
| # Step2: It should return a commit hash | |
| return | |
| # @attr(tags=["advanced", "basic"]) | |
| # @attr(required_hardware="false") | |
| # @attr(storage="s3") | |
| @attr(tags=["TODO"], required_hardware="false") | |
| def test_es_1863_register_template_s3_domain_admin_user(self): | |
| """ | |
| @Desc: Test whether cloudstack allows Domain admin or user | |
| to register a template using S3/Swift object store. | |
| @Steps: | |
| Step1: create a Domain and users in it. | |
| Step2: Register a template as Domain admin. | |
| Step3: Register a template as Domain user. | |
| Step4: Template should be registered successfully. | |
| """ | |
| # Step1: create a Domain and users in it. | |
| self.newdomain = Domain.create(self.apiClient, | |
| self.services["domain"]) | |
| # create account in the domain | |
| self.account_domain = Account.create( | |
| self.apiClient, | |
| self.services["account"], | |
| domainid=self.newdomain.id | |
| ) | |
| self.cleanup.append(self.account_domain) | |
| self.cleanup.append(self.newdomain) | |
| # Getting authentication for user in newly created Account in domain | |
| self.domain_user = self.account_domain.user[0] | |
| self.domain_userapiclient = self.testClient.getUserApiClient( | |
| self.domain_user.username, self.newdomain.name | |
| ) | |
| # Step2: Register a template as Domain admin. | |
| self.services["templateregister"]["ostype"] = self.services["ostype"] | |
| self.domain_template = Template.register( | |
| self.apiClient, | |
| self.services["templateregister"], | |
| zoneid=self.zone.id, | |
| account=self.account_domain.name, | |
| domainid=self.newdomain.id, | |
| hypervisor=self.hypervisor | |
| ) | |
| # Wait for template to download | |
| self.domain_template.download(self.api_client) | |
| # Wait for template status to be changed across | |
| time.sleep(60) | |
| # Step3: Register a template as Domain user. | |
| self.domain_user_template = Template.register( | |
| self.domain_userapiclient, | |
| self.services["templateregister"], | |
| zoneid=self.zone.id, | |
| account=self.account_domain.name, | |
| domainid=self.newdomain.id, | |
| hypervisor=self.hypervisor | |
| ) | |
| # Wait for template to download | |
| self.domain_user_template.download(self.api_client) | |
| # Wait for template status to be changed across | |
| time.sleep(60) | |
| # TODO: Step4: Template should be registered successfully. | |
| return | |
| @attr(tags=["advanced", "basic"]) | |
| @attr(required_hardware="true") | |
| @attr(hypervisor="KVM") | |
| def test_CLOUDSTACK_6181_stoppedvm_root_resize(self): | |
| """ | |
| @Desc: Test root volume resize of stopped VM | |
| @Reference: https://issues.apache.org/jira/browse/CLOUDSTACK-6181 | |
| @Steps: | |
| Step1: Deploy VM in stopped state (startvm=false), | |
| resize via 'resizeVolume', start VM. Root is new size. | |
| """ | |
| # Check whether usage server is running or not | |
| if self.hypervisor.lower() != 'kvm': | |
| self.skipTest("Test can be run only on KVM hypervisor") | |
| # deploy virtual machine in stopped state | |
| self.services["virtual_machine"]["zoneid"] = self.zone.id | |
| self.services["virtual_machine"]["template"] = self.template.id | |
| # Step3: Verifying that VM creation is successful | |
| virtual_machine = VirtualMachine.create( | |
| self.apiClient, | |
| self.services["virtual_machine"], | |
| accountid=self.account.name, | |
| domainid=self.account.domainid, | |
| serviceofferingid=self.service_offering.id, | |
| startvm=False | |
| ) | |
| self.cleanup.append(virtual_machine) | |
| # Verify VM state | |
| self.assertEqual( | |
| virtual_machine.state, | |
| 'Stopped', | |
| "Check VM state is Stopped or not" | |
| ) | |
| volumes = list_volumes( | |
| self.apiClient, | |
| virtualmachineid=virtual_machine.id, | |
| type='ROOT', | |
| listall=True | |
| ) | |
| self.assertIsNotNone(volumes, "root volume is not returned properly") | |
| newrootsize = (self.template.size >> 30) + 2 | |
| cmd = resizeVolume.resizeVolumeCmd() | |
| cmd.id = volumes[0].id | |
| cmd.size = newrootsize | |
| self.apiClient.resizeVolume(cmd) | |
| virtual_machine.start(self.apiClient) | |
| volumes_after_resize = list_volumes( | |
| self.apiClient, | |
| virtualmachineid=virtual_machine.id, | |
| type='ROOT', | |
| listall=True | |
| ) | |
| rootvolume = volumes_after_resize[0] | |
| success = False | |
| if rootvolume is not None and rootvolume.size == (newrootsize << 30): | |
| success = True | |
| self.assertEqual( | |
| success, | |
| True, | |
| "Check if the root volume resized appropriately" | |
| ) | |
| return | |
| @attr(tags=["advanced", "basic"]) | |
| @attr(required_hardware="true") | |
| @attr(hypervisor="KVM") | |
| def test_CLOUDSTACK_6181_vm_root_resize(self): | |
| """ | |
| @Desc: Test root volume resize of running VM | |
| @Reference: https://issues.apache.org/jira/browse/CLOUDSTACK-6181 | |
| @Steps: | |
| Step1: Deploy VM, resize root volume via 'resizeVolume'. | |
| """ | |
| # Check whether usage server is running or not | |
| if self.hypervisor.lower() != 'kvm': | |
| self.skipTest("Test can be run only on KVM hypervisor") | |
| # deploy virtual machine in stopped state | |
| self.services["virtual_machine"]["zoneid"] = self.zone.id | |
| self.services["virtual_machine"]["template"] = self.template.id | |
| # Step3: Verifying that VM creation is successful | |
| virtual_machine = VirtualMachine.create( | |
| self.apiClient, | |
| self.services["virtual_machine"], | |
| accountid=self.account.name, | |
| domainid=self.account.domainid, | |
| serviceofferingid=self.service_offering.id, | |
| ) | |
| self.cleanup.append(virtual_machine) | |
| # Verify VM state | |
| self.assertEqual( | |
| virtual_machine.state, | |
| 'Running', | |
| "Check VM state is Running or not" | |
| ) | |
| volumes = list_volumes( | |
| self.apiClient, | |
| virtualmachineid=virtual_machine.id, | |
| type='ROOT', | |
| listall=True | |
| ) | |
| self.assertIsNotNone(volumes, "root volume is not returned properly") | |
| newrootsize = (self.template.size >> 30) + 2 | |
| cmd = resizeVolume.resizeVolumeCmd() | |
| cmd.id = volumes[0].id | |
| cmd.size = newrootsize | |
| self.apiClient.resizeVolume(cmd) | |
| volumes_after_resize = list_volumes( | |
| self.apiClient, | |
| virtualmachineid=virtual_machine.id, | |
| type='ROOT', | |
| listall=True | |
| ) | |
| rootvolume = volumes_after_resize[0] | |
| success = False | |
| if rootvolume is not None and rootvolume.size == (newrootsize << 30): | |
| success = True | |
| self.assertEqual( | |
| success, | |
| True, | |
| "Check if the root volume resized appropriately" | |
| ) | |
| return | |
| @unittest.skip('In progress') | |
| @attr(tags=["advanced", "basic"]) | |
| @attr(required_hardware="false") | |
| def test_CLOUDSTACK_5023(self): | |
| """ | |
| @Desc: Test whether we are able to delete PF rule while | |
| rabbit mq is collecting usage events. | |
| @Steps: | |
| step1. Run Usage server | |
| step2. Delete a PF rule and check whether it is | |
| successful and usage event is generated | |
| Configure RabbitMQ for usage event generation | |
| """ | |
| # TBA | |
| return | |
| @attr(tags=["advanced", "basic"]) | |
| @attr(required_hardware="false") | |
| @attr(configuration='apply.allocation.algorithm.to.pods') | |
| def test_es_47_list_os_types_win_2012(self): | |
| """ | |
| @Desc: Test VM creation while "apply.allocation.algorithm.to.pods" | |
| is set to true | |
| @Reference: https://issues.apache.org/jira/browse/CLOUDSTACK-4947 | |
| @Steps: | |
| Step1: register windows 2012 VM template as windows 8 template | |
| Step2: deploy a VM with windows2012 template and Verify | |
| that VM creation is successful | |
| """ | |
| if not is_config_suitable(apiclient=self.apiClient, | |
| name='apply.allocation.algorithm.to.pods', | |
| value='true'): | |
| self.skipTest('apply.allocation.algorithm.to.pods ' | |
| 'should be true. skipping') | |
| # register windows 2012 VM template as windows 8 template | |
| self.hypervisor = self.testClient.getHypervisorInfo() | |
| if self.hypervisor.lower() in ['lxc']: | |
| self.skipTest( | |
| "windows VM is not supported on %s" % | |
| self.hypervisor.lower()) | |
| self.win2012_template = Template.register( | |
| self.apiClient, | |
| self.services["win2012template"], | |
| zoneid=self.zone.id, | |
| account=self.account.name, | |
| domainid=self.domain.id, | |
| hypervisor=self.hypervisor | |
| ) | |
| # Wait for template to download | |
| self.win2012_template.download(self.apiClient) | |
| self.cleanup.append(self.win2012_template) | |
| # Wait for template status to be changed across | |
| time.sleep(60) | |
| # Deploy | |
| self.debug("Deploying win 2012 VM in account: %s" % self.account.name) | |
| self.services["virtual_machine"]["displayname"] = "win2012" | |
| self.services["virtual_machine"]["zoneid"] = self.zone.id | |
| self.services["virtual_machine"]["template"] = self.win2012_template.id | |
| vm1 = VirtualMachine.create( | |
| self.apiClient, | |
| self.services["virtual_machine"], | |
| accountid=self.account.name, | |
| domainid=self.account.domainid, | |
| serviceofferingid=self.service_offering.id | |
| ) | |
| self.cleanup.append(vm1) | |
| # Verify VM state | |
| self.assertEqual( | |
| vm1.state, | |
| 'Running', | |
| "Check VM state is Running or not" | |
| ) | |
| return | |
| @attr(tags=["advanced", "basic", "test"]) | |
| @attr(required_hardware="true") | |
| def test_secondary_storage_stats(self): | |
| """ | |
| @Desc: Dashboard is not showing correct secondary | |
| storage statistics | |
| @Steps: | |
| Step1: listCapacity api should show correct secondary | |
| storage statistics | |
| """ | |
| cmd = listCapacity.listCapacityCmd() | |
| cmd.type = 6 | |
| cmd.zoneid = self.zone.id | |
| response = self.apiClient.listCapacity(cmd) | |
| self.assertEqual( | |
| isinstance(response, list), | |
| True, | |
| "Check list response returns a valid list" | |
| ) | |
| self.assertNotEqual( | |
| response, | |
| None, | |
| "Check if listCapacity has returned properly" | |
| ) | |
| self.assertNotEqual( | |
| response[0].capacitytotal, | |
| 0, | |
| "check the total capacity of secondary storage returned" | |
| ) | |
| return | |
| @attr(tags=["advanced", "basic"]) | |
| @attr(required_hardware="false") | |
| def test_multiple_mgmt_srvr_session_timeout(self): | |
| """ | |
| @Desc: Check whether mgmt server session times out with in 30s | |
| @Steps: | |
| Step1: run 'telnet localhot 8250' on the management server | |
| and see that it times out with in 30seconds | |
| """ | |
| # Step1: run cloudstack-sccs on management server | |
| mgmt_ssh = SshClient( | |
| self.apiClient.connection.mgtSvr, | |
| 22, | |
| self.apiClient.connection.user, | |
| self.apiClient.connection.passwd | |
| ) | |
| mgmt_ssh.execute("time telnet localhost 8250") | |
| # Step2: It should return a commit hash | |
| return | |
| @attr(tags=["advanced", "basic"]) | |
| @attr(required_hardware="true") | |
| def test_add_cluster_datacenter_spaces(self): | |
| """ | |
| @Desc: Add VmWare cluster to the CS with the data center | |
| name contains space in between | |
| @Steps: | |
| Step1: Add VmWare cluster to the CS with the data center | |
| name contains space in between. | |
| """ | |
| if self.hypervisor.lower() != 'vmware': | |
| self.skipTest('Can be run only on vmware zone. skipping') | |
| cmd = addCluster.addClusterCmd() | |
| cmd.zoneid = self.zone.id | |
| cmd.hypervisor = self.hypervisor | |
| cmd.clustertype = self.services["configurableData"][ | |
| "vmware_cluster"]["clustertype"] | |
| cmd.podid = self.pod.id | |
| cmd.username = self.services["configurableData"][ | |
| "vmware_cluster"]["username"] | |
| cmd.password = self.services["configurableData"][ | |
| "vmware_cluster"]["password"] | |
| cmd.publicswitchtype = 'vmwaredvs' | |
| cmd.guestswitchtype = 'vmwaredvs' | |
| cmd.url = self.services["configurableData"]["vmware_cluster"]["url"] | |
| cmd.clustername = self.services[ | |
| "configurableData"]["vmware_cluster"]["url"] | |
| self.apiClient.addCluster(cmd) | |
| return |