| # 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. |
| """ P1 tests for Browser Based Upload Volumes |
| """ |
| # Import Local Modules |
| |
| import marvin |
| from nose.plugins.attrib import attr |
| from marvin.cloudstackTestCase import cloudstackTestCase |
| import unittest |
| from marvin.cloudstackAPI import * |
| from marvin.lib.utils import * |
| from marvin.lib.base import * |
| from marvin.lib.common import * |
| from marvin.codes import FAILED |
| |
| import requests |
| import random |
| import string |
| import time |
| _multiprocess_shared_ = True |
| |
| class TestBrowseUploadVolume(cloudstackTestCase): |
| |
| """ |
| Testing Browse Upload Volume Feature |
| """ |
| @classmethod |
| def setUpClass(cls): |
| cls.testClient = super(TestBrowseUploadVolume,cls).getClsTestClient() |
| #print cls.testClient.getParsedTestDataConfig() |
| cls.testdata = cls.testClient.getParsedTestDataConfig() |
| cls.apiclient = cls.testClient.getApiClient() |
| cls.hypervisor = cls.testClient.getHypervisorInfo() |
| cls._cleanup = [] |
| cls.domain = get_domain(cls.apiclient) |
| cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) |
| cls.unsupportedHypervisor = False |
| hosts = list_hosts( |
| cls.apiclient, |
| type="Routing" |
| ) |
| |
| if cls.hypervisor.lower() in ['lxc']: |
| # Template creation from root volume is not supported in LXC |
| cls.unsupportedHypervisor = True |
| return |
| |
| if hosts is None: |
| raise unittest.SkipTest( |
| "There are no hypervisor's available.Check listhosts response") |
| |
| cls.account = Account.create( |
| cls.apiclient, |
| cls.testdata["account"], |
| domainid=cls.domain.id |
| ) |
| cls._cleanup.append(cls.account) |
| |
| cls.template = get_template( |
| cls.apiclient, |
| cls.zone.id) |
| |
| if cls.template == FAILED: |
| raise unittest.SkipTest( |
| "Check for default cent OS template readiness ") |
| |
| cls.service_offering = ServiceOffering.create( |
| cls.apiclient, |
| cls.testdata["service_offering"] |
| ) |
| cls._cleanup.append(cls.service_offering) |
| cls.disk_offering = DiskOffering.create( |
| cls.apiclient, |
| cls.testdata["resized_disk_offering"], |
| custom=True |
| ) |
| cls._cleanup.append(cls.disk_offering) |
| cls.project = Project.create( |
| cls.apiclient, |
| cls.testdata["project"], |
| account=cls.account.name, |
| domainid=cls.account.domainid |
| ) |
| cls._cleanup.append(cls.project) |
| |
| def setUp(self): |
| |
| if "kvm" in self.hypervisor.lower(): |
| self.test_template = registerTemplate.registerTemplateCmd() |
| self.test_template = registerTemplate.registerTemplateCmd() |
| self.test_template.checksum = "{SHA-1}" + "bf580a13f791d86acf3449a7b457a91a14389264" |
| self.test_template.hypervisor = self.hypervisor |
| self.test_template.zoneid = self.zone.id |
| self.test_template.name = 'test sha-1' |
| self.test_template.displaytext = 'test sha-1' |
| self.test_template.url = "http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-kvm.qcow2.bz2" |
| self.test_template.format = "QCOW2" |
| self.test_template.ostypeid = self.getOsType("Other Linux (64-bit)") |
| self.md5 = "ada77653dcf1e59495a9e1ac670ad95f" |
| self.sha256 = "0efc03633f2b8f5db08acbcc5dc1be9028572dfd8f1c6c8ea663f0ef94b458c5" |
| |
| if "vmware" in self.hypervisor.lower(): |
| self.test_template = registerTemplate.registerTemplateCmd() |
| self.test_template = registerTemplate.registerTemplateCmd() |
| self.test_template.checksum = "{SHA-1}" + "b25d404de8335b4348ff01e49a95b403c90df466" |
| self.test_template.hypervisor = self.hypervisor |
| self.test_template.zoneid = self.zone.id |
| self.test_template.name = 'test sha-2333' |
| self.test_template.displaytext = 'test sha-1' |
| self.test_template.url = "http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-vmware.ova" |
| self.test_template.format = "OVA" |
| self.test_template.ostypeid = self.getOsType(self, "Other Linux (64-bit)") |
| self.md5 = "d6d97389b129c7d898710195510bf4fb" |
| self.sha256 = "f57b59f118ab59284a70d6c63229d1de8f2d69bffc5a82b773d6c47e769c12d9" |
| |
| if "xen" in self.hypervisor.lower(): |
| self.test_template = registerTemplate.registerTemplateCmd() |
| self.test_template = registerTemplate.registerTemplateCmd() |
| self.test_template.checksum = "{SHA-1}" + "427fad501d0d8a1d63b8600a9a469fbf91191314" |
| self.test_template.hypervisor = self.hypervisor |
| self.test_template.zoneid = self.zone.id |
| self.test_template.name = 'test sha-2333' |
| self.test_template.displaytext = 'test sha-1' |
| self.test_template.url = "http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-xen.vhd.bz2" |
| self.test_template.format = "VHD" |
| self.test_template.ostypeid = self.getOsType("Other Linux (64-bit)") |
| self.md5 = "54ebc933e6e07ae58c0dc97dfd37c824" |
| self.sha256 = "bddd9876021d33df9792b71ae4b776598680ac68ecf55e9d9af33c80904cc1f3" |
| |
| if self.unsupportedHypervisor: |
| self.skipTest("Skipping test because unsupported hypervisor\ |
| %s" % self.hypervisor) |
| |
| self.cleanup = [] |
| |
| def getOsType(self, param): |
| cmd = listOsTypes.listOsTypesCmd() |
| cmd.description = param |
| return self.apiclient.listOsTypes(cmd)[0].id |
| |
| def __verify_values(self, expected_vals, actual_vals): |
| |
| return_flag = True |
| |
| if len(expected_vals) != len(actual_vals): |
| return False |
| |
| keys = list(expected_vals.keys()) |
| for i in range(0, len(expected_vals)): |
| exp_val = expected_vals[keys[i]] |
| act_val = actual_vals[keys[i]] |
| if exp_val == act_val: |
| return_flag = return_flag and True |
| else: |
| return_flag = return_flag and False |
| self.debug( |
| "expected Value: %s, is not matching with actual value:\ |
| %s" % |
| (exp_val, act_val)) |
| return return_flag |
| |
| def validate_uploaded_template(self, apiclient, template_id, retries=70, interval=5): |
| """Check if template download will finish in 1 minute""" |
| while retries > -1: |
| time.sleep(interval) |
| template_response = Template.list( |
| apiclient, |
| id=template_id, |
| zoneid=self.zone.id, |
| templatefilter='self' |
| ) |
| |
| if isinstance(template_response, list): |
| template = template_response[0] |
| if not hasattr(template, 'status') or not template or not template.status: |
| retries = retries - 1 |
| continue |
| |
| # If template is ready, |
| # template.status = Download Complete |
| # Downloading - x% Downloaded |
| # if Failed |
| # Error - Any other string |
| if 'Failed' in template.status: |
| raise Exception( |
| "Failed to download template: status - %s" % |
| template.status) |
| |
| elif template.status == 'Download Complete' and template.isready: |
| return |
| |
| elif 'Downloaded' in template.status: |
| retries = retries - 1 |
| continue |
| |
| elif 'Installing' not in template.status: |
| if retries >= 0: |
| retries = retries - 1 |
| continue |
| raise Exception( |
| "Error in downloading template: status - %s" % |
| template.status) |
| |
| else: |
| retries = retries - 1 |
| raise Exception("Template download failed exception.") |
| |
| def gettemplatelimts(self): |
| |
| totalresourcelist=Account.list( |
| self.apiclient, |
| id=self.account.id |
| ) |
| totaltemplates=totalresourcelist[0].templatetotal |
| |
| return(totaltemplates) |
| |
| def getstoragelimits(self, rtype): |
| |
| cmd=updateResourceCount.updateResourceCountCmd() |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.resourcetype=rtype |
| |
| response=self.apiclient.updateResourceCount(cmd) |
| |
| totalstorage=response[0].resourcecount |
| |
| return(totalstorage) |
| |
| def browse_upload_template(self): |
| cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd() |
| cmd.zoneid = self.test_template.zoneid |
| cmd.format = self.test_template.format |
| cmd.name=self.test_template.name + self.account.name + (random.choice(string.ascii_uppercase)) |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.displaytext=self.test_template.name + self.account.name + (random.choice(string.ascii_uppercase)) |
| cmd.hypervisor=self.test_template.hypervisor |
| cmd.ostypeid=self.test_template.ostypeid |
| #cmd.isdynamicallyscalable="false" |
| #cmd.type="template" |
| getuploadparamsresponse=self.apiclient.getUploadParamsForTemplate(cmd) |
| |
| signt=getuploadparamsresponse.signature |
| posturl=getuploadparamsresponse.postURL |
| metadata=getuploadparamsresponse.metadata |
| expiredata=getuploadparamsresponse.expires |
| #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd' |
| url=self.test_template.url |
| |
| uploadfile = url.split('/')[-1] |
| r = requests.get(url, stream=True) |
| with open(uploadfile, 'wb') as f: |
| for chunk in r.iter_content(chunk_size=1024): |
| if chunk: # filter out keep-alive new chunks |
| f.write(chunk) |
| f.flush() |
| |
| #uploadfile='rajani-thin-volume.vhd' |
| |
| #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')} |
| |
| #headers={'x-signature':signt,'x-metadata':metadata,'x-expires':expiredata} |
| |
| files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')} |
| |
| headers={'x-signature':signt,'x-metadata':metadata,'x-expires':expiredata} |
| |
| results = requests.post(posturl,files=files,headers=headers,verify=False) |
| |
| print(results.status_code) |
| if results.status_code !=200: |
| self.fail("Upload is not fine") |
| |
| self.validate_uploaded_template(self.apiclient, getuploadparamsresponse.id) |
| |
| return(getuploadparamsresponse) |
| |
| def browse_upload_template_with_out_zoneid(self): |
| |
| cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd() |
| cmd.format = self.test_template.format |
| cmd.name=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.displaytext=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.hypervisor=self.test_template.hypervisor |
| cmd.ostypeid=self.test_template.ostypeid |
| |
| success= False |
| try: |
| getuploadparamsresponse=self.apiclient.getUploadParamsForTemplate(cmd) |
| except Exception as ex: |
| if "Invalid Parameter" in str(ex): |
| success = True |
| self.assertEqual( |
| success, |
| True, |
| "Upload Template - verify upload Template API request is handled without mandatory params - zoneid ") |
| |
| return |
| |
| def browse_upload_template_with_out_ostypeid(self): |
| |
| |
| cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd() |
| cmd.zoneid = self.zone.id |
| cmd.format = self.test_template.format |
| cmd.name=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.displaytext=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.hypervisor=self.test_template.hypervisor |
| |
| success= False |
| try: |
| getuploadparamsresponse=self.apiclient.getUploadParamsForTemplate(cmd) |
| except Exception as ex: |
| if "Invalid Parameter" in str(ex): |
| success = True |
| self.assertEqual( |
| success, |
| True, |
| "Upload Template - verify upload template API request is handled without mandatory params - ostypeid") |
| |
| return |
| |
| def browse_upload_template_with_projectid(self,projectid): |
| cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd() |
| cmd.zoneid = self.zone.id |
| cmd.format = self.test_template.format |
| cmd.name=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.displaytext=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.hypervisor=self.test_template.hypervisor |
| cmd.ostypeid=self.test_template.ostypeid |
| cmd.projectid=projectid |
| #cmd.isdynamicallyscalable="false" |
| #cmd.type="template" |
| getuploadparamsresponse=self.apiclient.getUploadParamsForTemplate(cmd) |
| |
| signt=getuploadparamsresponse.signature |
| posturl=getuploadparamsresponse.postURL |
| metadata=getuploadparamsresponse.metadata |
| expiredata=getuploadparamsresponse.expires |
| #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd' |
| url=self.test_template.url |
| |
| uploadfile = url.split('/')[-1] |
| r = requests.get(url, stream=True) |
| with open(uploadfile, 'wb') as f: |
| for chunk in r.iter_content(chunk_size=1024): |
| if chunk: # filter out keep-alive new chunks |
| f.write(chunk) |
| f.flush() |
| |
| files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')} |
| |
| headers={'x-signature':signt,'x-metadata':metadata,'x-expires':expiredata} |
| |
| results = requests.post(posturl,files=files,headers=headers,verify=False) |
| |
| print(results.status_code) |
| if results.status_code !=200: |
| self.fail("Upload is not fine") |
| |
| self.validate_uploaded_template(self.apiclient, getuploadparamsresponse.id) |
| |
| return(getuploadparamsresponse) |
| |
| def browse_upload_template_multiplezones(self,lzones): |
| |
| cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd() |
| cmd.zoneid ="-1" |
| cmd.format = self.test_template.format |
| cmd.name=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.displaytext=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.hypervisor=self.test_template.hypervisor |
| cmd.ostypeid=self.test_template.ostypeid |
| #cmd.isdynamicallyscalable="false" |
| #cmd.type="template" |
| getuploadparamsresponse=self.apiclient.getUploadParamsForTemplate(cmd) |
| |
| signt=getuploadparamsresponse.signature |
| posturl=getuploadparamsresponse.postURL |
| metadata=getuploadparamsresponse.metadata |
| expiredata=getuploadparamsresponse.expires |
| #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd' |
| url=self.test_template.url |
| |
| uploadfile = url.split('/')[-1] |
| r = requests.get(url, stream=True) |
| with open(uploadfile, 'wb') as f: |
| for chunk in r.iter_content(chunk_size=1024): |
| if chunk: # filter out keep-alive new chunks |
| f.write(chunk) |
| f.flush() |
| |
| #uploadfile='rajani-thin-volume.vhd' |
| |
| #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')} |
| |
| #headers={'x-signature':signt,'x-metadata':metadata,'x-expires':expiredata} |
| |
| files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')} |
| |
| headers={'x-signature':signt,'x-metadata':metadata,'x-expires':expiredata} |
| |
| results = requests.post(posturl,files=files,headers=headers,verify=False) |
| |
| print(results.status_code) |
| if results.status_code !=200: |
| self.fail("Upload is not fine") |
| |
| for z1 in lzones: |
| self.validate_uploaded_template(self.apiclient, getuploadparamsresponse.id) |
| |
| return(getuploadparamsresponse) |
| |
| def uploadtemplate(self): |
| cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd() |
| cmd.zoneid = self.zone.id |
| cmd.format = self.test_template.format |
| cmd.name=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.displaytext=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.hypervisor=self.test_template.hypervisor |
| cmd.ostypeid=self.test_template.ostypeid |
| #cmd.type="template" |
| getuploadparamsresponse=self.apiclient.getUploadParamsForTemplate(cmd) |
| |
| signt=getuploadparamsresponse.signature |
| posturl=getuploadparamsresponse.postURL |
| metadata=getuploadparamsresponse.metadata |
| expiredata=getuploadparamsresponse.expires |
| #url = 'http://10.147.28.7/templates/rajani-thin-volume.vhd' |
| url=self.test_template.url |
| |
| uploadfile = url.split('/')[-1] |
| r = requests.get(url, stream=True) |
| with open(uploadfile, 'wb') as f: |
| for chunk in r.iter_content(chunk_size=1024): |
| if chunk: # filter out keep-alive new chunks |
| f.write(chunk) |
| f.flush() |
| |
| #uploadfile='rajani-thin-volume.vhd' |
| |
| #files={'file':('rajani-thin-volume.vhd',open(uploadfile,'rb'),'application/octet-stream')} |
| |
| #headers={'x-signature':signt,'x-metadata':metadata,'x-expires':expiredata} |
| |
| files={'file':(uploadfile,open(uploadfile,'rb'),'application/octet-stream')} |
| |
| headers={'x-signature':signt,'x-metadata':metadata,'x-expires':expiredata} |
| |
| results = requests.post(posturl,files=files,headers=headers,verify=False) |
| time.sleep(60) |
| |
| print(results.status_code) |
| if results.status_code !=200: |
| self.fail("Upload is not fine") |
| |
| return(getuploadparamsresponse) |
| |
| def multiple_browse_upload_template(self): |
| |
| templ1=self.uploadtemplate() |
| templ2=self.uploadtemplate() |
| templ3=self.uploadtemplate() |
| |
| self.validate_uploaded_template(self.apiclient, templ1.id) |
| self.validate_uploaded_template(self.apiclient, templ2.id) |
| self.validate_uploaded_template(self.apiclient, templ3.id) |
| |
| self.delete_template(templ1) |
| self.delete_template(templ2) |
| self.delete_template(templ3) |
| return |
| |
| def validate_vm(self, apiclient, vm_id, state, retries=72, interval=5): |
| |
| """Check if vm will be running in 6 minute""" |
| while retries > -1: |
| time.sleep(interval) |
| vm_response = list_virtual_machines( |
| apiclient, |
| id=vm_id |
| ) |
| |
| if isinstance(vm_response, list): |
| vm = vm_response[0] |
| if not hasattr(vm, 'state'): |
| retries = retries - 1 |
| continue |
| |
| # If vm is Running for x number of retries |
| if vm.state == state: |
| return |
| |
| else: |
| retries = retries - 1 |
| continue |
| |
| else: |
| retries = retries - 1 |
| raise Exception("VM failed exception.") |
| |
| def deploy_vm(self,template): |
| virtual_machine = VirtualMachine.create( |
| self.apiclient, |
| self.testdata["virtual_machine"], |
| templateid=template.id, |
| zoneid=self.zone.id, |
| accountid=self.account.name, |
| domainid=self.account.domainid, |
| serviceofferingid=self.service_offering.id, |
| ) |
| self.validate_vm(self.apiclient, vm_id = virtual_machine.id, state="Running") |
| return(virtual_machine) |
| |
| def attach_volume(self,vmlist,volid): |
| |
| list_volume_response = Volume.list( |
| self.apiclient, |
| id=volid |
| ) |
| print(list_volume_response[0]) |
| vmlist.attach_volume( |
| self.apiclient, |
| list_volume_response[0] |
| ) |
| list_volume_response = Volume.list( |
| self.apiclient, |
| virtualmachineid=vmlist.id, |
| type='DATADISK', |
| listall=True |
| ) |
| self.assertNotEqual( |
| list_volume_response, |
| None, |
| "Check if volume exists in ListVolumes") |
| self.assertEqual( |
| isinstance(list_volume_response, list), |
| True, |
| "Check list volumes response for valid list") |
| self.validate_uploaded_volume(volid,'Ready') |
| |
| def validate_uploaded_volume(self, volid, status): |
| list_volume_response = Volume.list( |
| self.apiclient, |
| id=volid, |
| listall=True |
| ) |
| |
| self.assertNotEqual( |
| list_volume_response, |
| None, |
| "Check if volume exists in ListTemplates" |
| ) |
| |
| self.assertEqual( |
| list_volume_response[0].status, |
| status, |
| "Check volume status in List Volumes" |
| ) |
| return |
| |
| def reboot_vm(self,vmdetails): |
| vmdetails.reboot(self.apiclient) |
| self.validate_vm(self.apiclient, vm_id=vmdetails.id, state="Running") |
| |
| def stop_vm(self,vmdetails): |
| vmdetails.stop(self.apiclient) |
| self.validate_vm(self.apiclient, vm_id=vmdetails.id, state="Stopped") |
| |
| def start_vm(self,vmdetails): |
| vmdetails.start(self.apiclient) |
| self.validate_vm(self.apiclient, vm_id=vmdetails.id, state="Running") |
| |
| def vmoperations(self,vmdetails): |
| self.reboot_vm(vmdetails) |
| |
| self.stop_vm(vmdetails) |
| |
| self.start_vm(vmdetails) |
| |
| def detach_volume(self,vmdetails,volid): |
| """Detach a Volume attached to a VM |
| """ |
| list_volume_response = Volume.list( |
| self.apiclient, |
| id=volid |
| ) |
| print(list_volume_response[0]) |
| vmdetails.detach_volume(self.apiclient,list_volume_response[0]) |
| |
| # Sleep to ensure the current state will reflected in other calls |
| time.sleep(self.testdata["sleep"]) |
| |
| list_volume_response = Volume.list( |
| self.apiclient, |
| id=volid |
| ) |
| self.assertNotEqual( |
| list_volume_response, |
| None, |
| "Check if volume exists in ListVolumes" |
| ) |
| self.assertEqual( |
| isinstance(list_volume_response, list), |
| True, |
| "Check list volumes response for valid list" |
| ) |
| volume = list_volume_response[0] |
| self.assertEqual( |
| volume.virtualmachineid, |
| None, |
| "Check if volume state (detached) is reflected" |
| ) |
| |
| self.assertEqual( |
| volume.vmname, |
| None, |
| "Check if volume state (detached) is reflected" |
| ) |
| return |
| |
| def restore_vm(self,vmdetails): |
| """Test recover Virtual Machine |
| """ |
| cmd = restoreVirtualMachine.restoreVirtualMachineCmd() |
| cmd.virtualmachineid = vmdetails.id |
| self.apiclient.recoverVirtualMachine(cmd) |
| |
| list_vm_response = list_virtual_machines( |
| self.apiclient, |
| id=vmdetails.id |
| ) |
| self.assertEqual( |
| isinstance(list_vm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| |
| self.assertNotEqual( |
| len(list_vm_response), |
| 0, |
| "Check VM available in List Virtual Machines" |
| ) |
| |
| self.assertEqual( |
| list_vm_response[0].state, |
| "Running", |
| "Check virtual machine is in Running state" |
| ) |
| |
| return |
| |
| def restore_vm_fail(self,vmdetails): |
| |
| cmd = restoreVirtualMachine.restoreVirtualMachineCmd() |
| cmd.virtualmachineid = vmdetails.id |
| success= False |
| try: |
| self.apiclient.recoverVirtualMachine(cmd) |
| except Exception as ex: |
| if "isn't available in the zone" in str(ex): |
| success = True |
| self.assertEqual( |
| success, |
| True, |
| "Restore VM with Deleted Template - Verify Restore VM is handled when template with which VM created id deleted") |
| |
| return |
| |
| def deletevolume(self,volumeid): |
| """Delete a Volume attached to a VM |
| """ |
| |
| cmd = deleteVolume.deleteVolumeCmd() |
| cmd.id = volumeid |
| |
| self.apiclient.deleteVolume(cmd) |
| |
| list_volume_response = Volume.list( |
| self.apiclient, |
| id=volumeid, |
| type='DATADISK' |
| ) |
| self.assertEqual( |
| list_volume_response, |
| None, |
| "Check if volume exists in ListVolumes" |
| ) |
| return |
| |
| def destroy_vm(self,vmdetails): |
| |
| vmdetails.delete(self.apiclient, expunge=False) |
| |
| list_vm_response = list_virtual_machines( |
| self.apiclient, |
| id=vmdetails.id |
| ) |
| self.assertEqual( |
| isinstance(list_vm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| |
| self.assertNotEqual( |
| len(list_vm_response), |
| 0, |
| "Check VM available in List Virtual Machines" |
| ) |
| |
| self.assertEqual( |
| list_vm_response[0].state, |
| "Destroyed", |
| "Check virtual machine is in destroyed state" |
| ) |
| return |
| |
| def recover_destroyed_vm(self,vmdetails): |
| |
| cmd = recoverVirtualMachine.recoverVirtualMachineCmd() |
| cmd.id = vmdetails.id |
| self.apiclient.recoverVirtualMachine(cmd) |
| |
| list_vm_response = list_virtual_machines( |
| self.apiclient, |
| id=vmdetails.id |
| ) |
| self.assertEqual( |
| isinstance(list_vm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| |
| self.assertNotEqual( |
| len(list_vm_response), |
| 0, |
| "Check VM available in List Virtual Machines" |
| ) |
| |
| self.assertEqual( |
| list_vm_response[0].state, |
| "Stopped", |
| "Check virtual machine is in Stopped state" |
| ) |
| |
| return |
| |
| def expunge_vm(self,vmdetails): |
| |
| self.debug("Expunge VM-ID: %s" % vmdetails.id) |
| |
| cmd = destroyVirtualMachine.destroyVirtualMachineCmd() |
| cmd.id = vmdetails.id |
| self.apiclient.destroyVirtualMachine(cmd) |
| |
| config = Configurations.list( |
| self.apiclient, |
| name='expunge.delay' |
| ) |
| |
| expunge_delay = int(config[0].value) |
| time.sleep(expunge_delay * 2) |
| |
| #VM should be destroyed unless expunge thread hasn't run |
| #Wait for two cycles of the expunge thread |
| config = Configurations.list( |
| self.apiclient, |
| name='expunge.interval' |
| ) |
| expunge_cycle = int(config[0].value) |
| wait_time = expunge_cycle * 4 |
| while wait_time >= 0: |
| list_vm_response = list_virtual_machines( |
| self.apiclient, |
| id=vmdetails.id |
| ) |
| if not list_vm_response: |
| break |
| self.debug("Waiting for VM to expunge") |
| time.sleep(expunge_cycle) |
| wait_time = wait_time - expunge_cycle |
| |
| self.debug("listVirtualMachines response: %s" % list_vm_response) |
| |
| self.assertEqual(list_vm_response,None,"Check Expunged virtual machine is in listVirtualMachines response") |
| return |
| |
| list_vm_response = list_virtual_machines( |
| self.apiclient, |
| id=vmdetails.id |
| ) |
| if isinstance(list_vm_response, list): |
| self.fail("VM has not been expunged") |
| |
| def waitForSystemVMAgent(self, vmname): |
| timeout = self.testdata["timeout"] |
| |
| while True: |
| list_host_response = list_hosts( |
| self.apiclient, |
| name=vmname |
| ) |
| |
| if list_host_response and list_host_response[0].state == 'Up': |
| break |
| |
| if timeout == 0: |
| raise Exception("Timed out waiting for SSVM agent to be Up") |
| |
| time.sleep(self.testdata["sleep"]) |
| timeout = timeout - 1 |
| |
| def ssvm_internals(self): |
| |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| systemvmtype='secondarystoragevm', |
| state='Running', |
| zoneid=self.zone.id |
| ) |
| self.assertEqual( |
| isinstance(list_ssvm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| ssvm = list_ssvm_response[0] |
| |
| hosts = list_hosts( |
| self.apiclient, |
| id=ssvm.hostid |
| ) |
| self.assertEqual( |
| isinstance(hosts, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| host = hosts[0] |
| |
| self.debug("Running SSVM check script") |
| |
| if self.hypervisor.lower() in ('vmware', 'hyperv'): |
| #SSH into SSVMs is done via management server for Vmware and Hyper-V |
| result = get_process_status( |
| self.apiclient.connection.mgtSvr, |
| 22, |
| self.apiclient.connection.user, |
| self.apiclient.connection.passwd, |
| ssvm.privateip, |
| "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL", |
| hypervisor=self.hypervisor |
| ) |
| else: |
| try: |
| host.user, host.passwd = get_host_credentials(self.config, host.ipaddress) |
| result = get_process_status( |
| host.ipaddress, |
| 22, |
| host.user, |
| host.passwd, |
| ssvm.linklocalip, |
| "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL" |
| ) |
| except KeyError: |
| self.skipTest("Marvin configuration has no host credentials to check router services") |
| res = str(result) |
| self.debug("SSVM script output: %s" % res) |
| |
| self.assertEqual( |
| res.count("ERROR"), |
| 1, |
| "Check for Errors in tests" |
| ) |
| |
| self.assertEqual( |
| res.count("WARNING"), |
| 1, |
| "Check for warnings in tests" |
| ) |
| |
| #Check status of cloud service |
| if self.hypervisor.lower() in ('vmware', 'hyperv'): |
| #SSH into SSVMs is done via management server for Vmware and Hyper-V |
| result = get_process_status( |
| self.apiclient.connection.mgtSvr, |
| 22, |
| self.apiclient.connection.user, |
| self.apiclient.connection.passwd, |
| ssvm.privateip, |
| "systemctl is-active cloud", |
| hypervisor=self.hypervisor |
| ) |
| else: |
| try: |
| host.user, host.passwd = get_host_credentials(self.config, host.ipaddress) |
| result = get_process_status( |
| host.ipaddress, |
| 22, |
| host.user, |
| host.passwd, |
| ssvm.linklocalip, |
| "systemctl is-active cloud" |
| ) |
| except KeyError: |
| self.skipTest("Marvin configuration has no host credentials to check router services") |
| res = str(result) |
| self.debug("Cloud Process status: %s" % res) |
| # Apache CloudStack service (type=secstorage) is running: process id: 2346 |
| self.assertEqual( |
| res.count("active"), |
| 1, |
| "Check cloud service is running or not" |
| ) |
| return |
| |
| def list_sec_storage_vm(self): |
| |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| systemvmtype='secondarystoragevm', |
| state='Running', |
| ) |
| self.assertEqual( |
| isinstance(list_ssvm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| #Verify SSVM response |
| self.assertNotEqual( |
| len(list_ssvm_response), |
| 0, |
| "Check list System VMs response" |
| ) |
| |
| list_zones_response = list_zones(self.apiclient) |
| |
| self.assertEqual( |
| isinstance(list_zones_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| |
| self.debug("Number of zones: %s" % len(list_zones_response)) |
| self.debug("Number of SSVMs: %s" % len(list_ssvm_response)) |
| # Number of Sec storage VMs = No of Zones |
| self.assertEqual( |
| len(list_ssvm_response), |
| len(list_zones_response), |
| "Check number of SSVMs with number of zones" |
| ) |
| #For each secondary storage VM check private IP, |
| #public IP, link local IP and DNS |
| for ssvm in list_ssvm_response: |
| |
| self.debug("SSVM state: %s" % ssvm.state) |
| self.assertEqual( |
| ssvm.state, |
| 'Running', |
| "Check whether state of SSVM is running" |
| ) |
| |
| self.assertEqual( |
| hasattr(ssvm, 'privateip'), |
| True, |
| "Check whether SSVM has private IP field" |
| ) |
| |
| self.assertEqual( |
| hasattr(ssvm, 'linklocalip'), |
| True, |
| "Check whether SSVM has link local IP field" |
| ) |
| |
| self.assertEqual( |
| hasattr(ssvm, 'publicip'), |
| True, |
| "Check whether SSVM has public IP field" |
| ) |
| |
| #Fetch corresponding ip ranges information from listVlanIpRanges |
| ipranges_response = list_vlan_ipranges( |
| self.apiclient, |
| zoneid=ssvm.zoneid |
| ) |
| self.assertEqual( |
| isinstance(ipranges_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| iprange = ipranges_response[0] |
| |
| #Fetch corresponding Physical Network of SSVM's Zone |
| listphyntwk = PhysicalNetwork.list( |
| self.apiclient, |
| zoneid=ssvm.zoneid |
| ) |
| |
| # Execute the following assertion in all zones except EIP-ELB Zones |
| if not (self.zone.networktype.lower() == 'basic' and isinstance(NetScaler.list(self.apiclient,physicalnetworkid=listphyntwk[0].id), list) is True): |
| self.assertEqual( |
| ssvm.gateway, |
| iprange.gateway, |
| "Check gateway with that of corresponding ip range" |
| ) |
| |
| #Fetch corresponding zone information from listZones |
| zone_response = list_zones( |
| self.apiclient, |
| id=ssvm.zoneid |
| ) |
| self.assertEqual( |
| isinstance(zone_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| self.assertEqual( |
| ssvm.dns1, |
| zone_response[0].dns1, |
| "Check DNS1 with that of corresponding zone" |
| ) |
| |
| self.assertEqual( |
| ssvm.dns2, |
| zone_response[0].dns2, |
| "Check DNS2 with that of corresponding zone" |
| ) |
| return |
| |
| def stop_ssvm(self): |
| |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| systemvmtype='secondarystoragevm', |
| state='Running', |
| zoneid=self.zone.id |
| ) |
| self.assertEqual( |
| isinstance(list_ssvm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| ssvm = list_ssvm_response[0] |
| |
| hosts = list_hosts( |
| self.apiclient, |
| id=ssvm.hostid |
| ) |
| self.assertEqual( |
| isinstance(hosts, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| host = hosts[0] |
| |
| self.debug("Stopping SSVM: %s" % ssvm.id) |
| cmd = stopSystemVm.stopSystemVmCmd() |
| cmd.id = ssvm.id |
| self.apiclient.stopSystemVm(cmd) |
| |
| timeout = self.testdata["timeout"] |
| while True: |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| id=ssvm.id |
| ) |
| if isinstance(list_ssvm_response, list): |
| if list_ssvm_response[0].state == 'Running': |
| break |
| if timeout == 0: |
| raise Exception("List SSVM call failed!") |
| |
| time.sleep(self.testdata["sleep"]) |
| timeout = timeout - 1 |
| |
| self.assertEqual( |
| isinstance(list_ssvm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| ssvm_response = list_ssvm_response[0] |
| self.debug("SSVM state after debug: %s" % ssvm_response.state) |
| self.assertEqual( |
| ssvm_response.state, |
| 'Running', |
| "Check whether SSVM is running or not" |
| ) |
| # Wait for the agent to be up |
| self.waitForSystemVMAgent(ssvm_response.name) |
| |
| # Call above tests to ensure SSVM is properly running |
| self.list_sec_storage_vm() |
| |
| def reboot_ssvm(self): |
| |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| systemvmtype='secondarystoragevm', |
| state='Running', |
| zoneid=self.zone.id |
| ) |
| |
| self.assertEqual( |
| isinstance(list_ssvm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| |
| ssvm_response = list_ssvm_response[0] |
| |
| hosts = list_hosts( |
| self.apiclient, |
| id=ssvm_response.hostid |
| ) |
| self.assertEqual( |
| isinstance(hosts, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| host = hosts[0] |
| |
| #Store the public & private IP values before reboot |
| old_public_ip = ssvm_response.publicip |
| old_private_ip = ssvm_response.privateip |
| |
| self.debug("Rebooting SSVM: %s" % ssvm_response.id) |
| cmd = rebootSystemVm.rebootSystemVmCmd() |
| cmd.id = ssvm_response.id |
| self.apiclient.rebootSystemVm(cmd) |
| |
| timeout = self.testdata["timeout"] |
| while True: |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| id=ssvm_response.id |
| ) |
| if isinstance(list_ssvm_response, list): |
| if list_ssvm_response[0].state == 'Running': |
| break |
| if timeout == 0: |
| raise Exception("List SSVM call failed!") |
| |
| time.sleep(self.testdata["sleep"]) |
| timeout = timeout - 1 |
| |
| ssvm_response = list_ssvm_response[0] |
| self.debug("SSVM State: %s" % ssvm_response.state) |
| self.assertEqual( |
| 'Running', |
| str(ssvm_response.state), |
| "Check whether CPVM is running or not" |
| ) |
| |
| self.assertEqual( |
| ssvm_response.publicip, |
| old_public_ip, |
| "Check Public IP after reboot with that of before reboot" |
| ) |
| |
| self.assertEqual( |
| ssvm_response.privateip, |
| old_private_ip, |
| "Check Private IP after reboot with that of before reboot" |
| ) |
| |
| # Wait for the agent to be up |
| self.waitForSystemVMAgent(ssvm_response.name) |
| |
| return |
| |
| def destroy_ssvm(self): |
| |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| systemvmtype='secondarystoragevm', |
| state='Running', |
| zoneid=self.zone.id |
| ) |
| self.assertEqual( |
| isinstance(list_ssvm_response, list), |
| True, |
| "Check list response returns a valid list" |
| ) |
| ssvm_response = list_ssvm_response[0] |
| |
| old_name = ssvm_response.name |
| |
| self.debug("Destroying SSVM: %s" % ssvm_response.id) |
| cmd = destroySystemVm.destroySystemVmCmd() |
| cmd.id = ssvm_response.id |
| self.apiclient.destroySystemVm(cmd) |
| |
| timeout = self.testdata["timeout"] |
| while True: |
| list_ssvm_response = list_ssvms( |
| self.apiclient, |
| zoneid=self.zone.id, |
| systemvmtype='secondarystoragevm' |
| ) |
| if isinstance(list_ssvm_response, list): |
| if list_ssvm_response[0].state == 'Running': |
| break |
| if timeout == 0: |
| raise Exception("List SSVM call failed!") |
| |
| time.sleep(self.testdata["sleep"]) |
| timeout = timeout - 1 |
| |
| ssvm_response = list_ssvm_response[0] |
| |
| # Verify Name, Public IP, Private IP and Link local IP |
| # for newly created SSVM |
| self.assertNotEqual( |
| ssvm_response.name, |
| old_name, |
| "Check SSVM new name with name of destroyed SSVM" |
| ) |
| self.assertEqual( |
| hasattr(ssvm_response, 'privateip'), |
| True, |
| "Check whether SSVM has private IP field" |
| ) |
| |
| self.assertEqual( |
| hasattr(ssvm_response, 'linklocalip'), |
| True, |
| "Check whether SSVM has link local IP field" |
| ) |
| |
| self.assertEqual( |
| hasattr(ssvm_response, 'publicip'), |
| True, |
| "Check whether SSVM has public IP field" |
| ) |
| |
| # Wait for the agent to be up |
| self.waitForSystemVMAgent(ssvm_response.name) |
| |
| return |
| |
| def create_data_volume(self): |
| |
| diskoffering = DiskOffering.list(self.apiclient) |
| self.assertTrue( |
| isinstance( |
| diskoffering, |
| list), |
| msg="DiskOffering list is not a list?") |
| self.assertTrue( |
| len(diskoffering) > 0, |
| "no disk offerings in the deployment") |
| |
| vol = Volume.create( |
| self.apiclient, |
| services=self.testdata["volume"], |
| zoneid=self.zone.id, |
| account=self.account.name, |
| domainid=self.domain.id, |
| diskofferingid=diskoffering[0].id |
| ) |
| self.assertTrue( |
| vol is not None, "volume creation fails in domain %s as user %s" % |
| (self.domain.name, self.account.name)) |
| |
| listed_vol = Volume.list(self.apiclient, id=vol.id) |
| self.assertTrue( |
| listed_vol is not None and isinstance( |
| listed_vol, |
| list), |
| "invalid response from listVolumes for volume %s" % |
| vol.id) |
| self.assertTrue( |
| listed_vol[0].id == vol.id, |
| "Volume returned by list volumes %s not matching with queried\ |
| volume %s in domain %s" % |
| (listed_vol[0].id, |
| vol.id, |
| self.account.name)) |
| return(listed_vol[0]) |
| |
| def attach_data_volume(self,volume,vmdetails): |
| |
| list_volume_response = Volume.list( |
| self.apiclient, |
| id=volume.id |
| ) |
| self.assertNotEqual( |
| list_volume_response, |
| None, |
| "Check if volume exists in ListVolumes" |
| ) |
| self.assertEqual( |
| isinstance(list_volume_response, list), |
| True, |
| "Check list volumes response for valid list" |
| ) |
| volume = list_volume_response[0] |
| |
| self.assertEqual( |
| volume.type, |
| 'DATADISK', |
| "Check volume type from list volume response" |
| ) |
| |
| self.assertEqual( |
| hasattr(volume, 'vmname'), |
| True, |
| "Check whether volume has vmname field" |
| ) |
| self.assertEqual( |
| hasattr(volume, 'virtualmachineid'), |
| True, |
| "Check whether volume has virtualmachineid field" |
| ) |
| |
| # Attach volume to VM |
| self.debug("Attach volume: %s to VM: %s" % ( |
| volume.id, |
| vmdetails.id |
| )) |
| vmdetails.attach_volume(self.apiclient, volume) |
| |
| # Check all volumes attached to same VM |
| list_volume_response = Volume.list( |
| self.apiclient, |
| virtualmachineid=vmdetails.id, |
| type='DATADISK', |
| listall=True |
| ) |
| self.assertNotEqual( |
| list_volume_response, |
| None, |
| "Check if volume exists in ListVolumes" |
| ) |
| self.assertEqual( |
| isinstance(list_volume_response, list), |
| True, |
| "Check list volumes response for valid list" |
| ) |
| volume = list_volume_response[0] |
| self.assertEqual( |
| volume.vmname, |
| vmdetails.name, |
| "Check virtual machine name in list volumes response" |
| ) |
| self.assertEqual( |
| volume.virtualmachineid, |
| vmdetails.id, |
| "Check VM ID in list Volume response" |
| ) |
| return |
| |
| def delete_template(self,templatedetails): |
| |
| list_template_response = Template.list( |
| self.apiclient, |
| templatefilter="all", |
| id=templatedetails.id, |
| zoneid=self.zone.id) |
| |
| if list_template_response is None: |
| self.debug("Template is not available") |
| return |
| |
| cmd = deleteTemplate.deleteTemplateCmd() |
| cmd.id = templatedetails.id |
| self.apiclient.deleteTemplate(cmd) |
| |
| list_template_response = Template.list( |
| self.apiclient, |
| templatefilter="all", |
| id=templatedetails.id, |
| zoneid=self.zone.id |
| ) |
| self.assertEqual( |
| list_template_response, |
| None, |
| "Check template available in List Templates" |
| ) |
| return |
| |
| def detach_data_volume(self,volume,vmdetails): |
| |
| self.debug("Detach volume: %s to VM: %s" % ( |
| volume.id, |
| vmdetails.id |
| )) |
| vmdetails.detach_volume(self.apiclient, volume) |
| |
| # Sleep to ensure the current state will reflected in other calls |
| time.sleep(self.testdata["sleep"]) |
| |
| list_volume_response = Volume.list( |
| self.apiclient, |
| id=volume.id |
| ) |
| self.assertNotEqual( |
| list_volume_response, |
| None, |
| "Check if volume exists in ListVolumes" |
| ) |
| self.assertEqual( |
| isinstance(list_volume_response, list), |
| True, |
| "Check list volumes response for valid list" |
| ) |
| volumelist = list_volume_response[0] |
| self.assertEqual( |
| volumelist.virtualmachineid, |
| None, |
| "Check if volume state (detached) is reflected" |
| ) |
| |
| self.assertEqual( |
| volumelist.vmname, |
| None, |
| "Check if volume state (detached) is reflected" |
| ) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_01_Browser_template_Life_cycle_tpath(self): |
| """ |
| Test Browser_template_Life_cycle |
| """ |
| #try: |
| |
| self.debug("========================= Test 1: Upload Browser based template and validate ========================= ") |
| browseup_template=self.browse_upload_template() |
| |
| self.debug("========================= Test 2: Deploy a VM with uploaded template and validate VM Operations========================= ") |
| |
| vm1details=self.deploy_vm(browseup_template) |
| |
| self.vmoperations(vm1details) |
| |
| self.debug("========================= Test 3: Attach DATA DISK to the VM ") |
| |
| cvolume=self.create_data_volume() |
| self.attach_data_volume(cvolume, vm1details) |
| self.vmoperations(vm1details) |
| |
| self.debug("========================= Test 4: Restore VM created with Uploaded template========================= ") |
| |
| self.restore_vm(vm1details) |
| |
| self.debug("========================= Test 5: Detach DATA DISK to the VM ") |
| |
| self.detach_data_volume(cvolume,vm1details) |
| self.vmoperations(vm1details) |
| |
| self.deletevolume(cvolume.id) |
| |
| |
| self.debug("========================= Test 6: Expunge VM created with Uploaded template========================= ") |
| |
| self.expunge_vm(vm1details) |
| |
| self.debug("========================= Test 7: Destroy VM ========================= ") |
| |
| vm2details=self.deploy_vm(self.template) |
| |
| vm2details=self.deploy_vm(browseup_template) |
| self.destroy_vm(vm2details) |
| |
| self.debug("========================= Test 8: Recover destroyed VM which has Uploaded volumes attached========================= ") |
| |
| self.recover_destroyed_vm(vm2details) |
| self.expunge_vm(vm2details) |
| |
| self.debug("========================= Test 9: Delete the Uploaded Template========================= ") |
| self.debug(browseup_template) |
| self.delete_template(browseup_template) |
| |
| self.debug("========================= Test 10: Upload Multiple templates========================= ") |
| |
| self.multiple_browse_upload_template() |
| |
| # except Exception as e: |
| # self.fail("Exception occurred : %s" % e) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_02_SSVM_Life_Cycle_With_Browser_Template_TPath(self): |
| """ |
| Test SSVM_Life_Cycle_With_Browser_template_TPath |
| """ |
| try: |
| |
| self.debug("========================= Test 11: Stop and Start SSVM and Perform Browser based volume validations ========================= ") |
| |
| self.stop_ssvm() |
| ssvm1browseup_template=self.browse_upload_template() |
| |
| ssvm1vm1details=self.deploy_vm(ssvm1browseup_template) |
| #ssvm1vm1details=self.deploy_vm(self.template) |
| |
| self.vmoperations(ssvm1vm1details) |
| |
| self.expunge_vm(ssvm1vm1details) |
| |
| self.debug("========================= Test 12: Reboot SSVM and Perform Browser based volume validations ========================= ") |
| |
| self.reboot_ssvm() |
| ssvm2browseup_template=self.browse_upload_template() |
| |
| ssvm2vm1details=self.deploy_vm(ssvm2browseup_template) |
| |
| #ssvm2vm1details=self.deploy_vm(self.template) |
| self.vmoperations(ssvm2vm1details) |
| |
| self.expunge_vm(ssvm2vm1details) |
| |
| self.debug("========================= Test 13: Destroy SSVM and Perform Browser based volume validations ========================= ") |
| |
| self.destroy_ssvm() |
| ssvm3browseup_template=self.browse_upload_template() |
| |
| ssvm3vm1details=self.deploy_vm(ssvm3browseup_template) |
| |
| #ssvm2vm1details=self.deploy_vm(self.template) |
| self.vmoperations(ssvm3vm1details) |
| |
| self.expunge_vm(ssvm3vm1details) |
| |
| except Exception as e: |
| self.fail("Exception occurred : %s" % e) |
| return |
| |
| @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") |
| def test_03_Browser_template_upload_multiple_zones(self): |
| """ |
| Test Browser_template_upload_multiple_zones |
| """ |
| |
| cmd = listZones.listZonesCmd() |
| zonelist=self.apiclient.listZones(cmd) |
| if len(zonelist) <2: |
| raise self.skipTest("Only one zone available hence skipping") |
| try: |
| |
| self.debug("========================= Test 14: Upload Browser based template into multiple zones ========================= ") |
| browseup_template=self.browse_upload_template_multiplezones(zonelist) |
| |
| except Exception as e: |
| self.fail("Exception occurred : %s" % e) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_04_Browser_template_ResetVM_With_Deleted_Template(self): |
| """ |
| Test Browser_template_upload_ResetVM_With_Deleted_Template |
| """ |
| try: |
| |
| self.debug("========================= Test 15: Test Browser_template_upload_ResetVM_With_Deleted_Template ========================= ") |
| |
| browseup_template=self.browse_upload_template() |
| |
| vm1details=self.deploy_vm(browseup_template) |
| |
| self.delete_template(browseup_template) |
| |
| self.restore_vm_fail(vm1details) |
| |
| except Exception as e: |
| self.fail("Exception occurred : %s" % e) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_05_Browser_Upload_Template_with_all_API_parameters(self): |
| """ |
| Test Browser_Upload_Template with all API parameters |
| """ |
| try: |
| |
| self.debug("========================= Test 16 & 17 Upload template with account name and domainid========================") |
| |
| browseup_template1=self.browse_upload_template() |
| |
| self.debug("========================= Test 18 Upload template with project id========================") |
| browseup_template2=self.browse_upload_template_with_projectid(self.project.id) |
| |
| self.debug("========================= Test 19 Upload template with out mandatory param zone id ========================") |
| |
| browseup_vol2=self.browse_upload_template_with_out_zoneid() |
| |
| self.debug("========================= Test 20 Upload template with out mandatory param ostypeid ========================") |
| |
| browseup_vol3=self.browse_upload_template_with_out_ostypeid() |
| |
| except Exception as e: |
| self.fail("Exception occurred : %s" % e) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_06_Browser_Upload_template_resource_limits(self): |
| """ |
| Test Browser Upload Template Resource limits |
| """ |
| try: |
| |
| self.debug("========================= Test 21 Upload Template and verify Template limits========================") |
| initialtemplatelimit=self.gettemplatelimts() |
| browseup_template1=self.browse_upload_template() |
| # Adding time for limit to sync in background |
| time.sleep(120) |
| afteruploadtemplatelimit=self.gettemplatelimts() |
| |
| if int(afteruploadtemplatelimit)!=(int(initialtemplatelimit)+1): |
| self.fail("Volume Resource Count is not updated") |
| |
| self.delete_template(browseup_template1) |
| |
| except Exception as e: |
| self.fail("Exception occurred : %s" % e) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_07_Browser_Upload_template_secondary_storage_resource_limits(self): |
| """ |
| Test Browser_Upload_Template Secondary Storage Resource limits |
| """ |
| try: |
| |
| self.debug("========================= Test 22 Upload template and verify secondary storage limits========================") |
| |
| initialsecondarystoragelimit=self.getstoragelimits(11) |
| browseup_template1=self.browse_upload_template() |
| |
| tmpldetails=Template.list( |
| self.apiclient, |
| id=browseup_template1.id, |
| templatefilter="all", |
| zoneid=self.zone.id) |
| |
| |
| afteruploadsecondarystoragelimit=self.getstoragelimits(11) |
| |
| if afteruploadsecondarystoragelimit!=(initialsecondarystoragelimit+tmpldetails[0].size): |
| self.fail("Secondary Storage Resource Count is not updated") |
| |
| self.delete_template(browseup_template1) |
| |
| except Exception as e: |
| self.fail("Exception occurred : %s" % e) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_08_Browser_Upload_template_resource_limits_after_deletion(self): |
| """ |
| Test Browser_Upload_Template Resource limits after template deletion |
| """ |
| try: |
| self.debug("========================= Test 23 Delete Upload template and verify template limits========================") |
| browseup_template1=self.browse_upload_template() |
| initialtemplatelimit=self.gettemplatelimts() |
| |
| self.delete_template(browseup_template1) |
| aftertemplatelimit=self.gettemplatelimts() |
| |
| if aftertemplatelimit!=(initialtemplatelimit-1): |
| self.fail("Template Resource Count is not updated after deletion") |
| |
| except Exception as e: |
| self.fail("Exceptione occurred : %s" % e) |
| return |
| |
| # was tags = ["advanced", "advancedns", "smoke", "basic"] |
| @attr(tags = ["TODO"], required_hardware="true") |
| def test_09_Browser_Upload_Volume_secondary_storage_resource_limits_after_deletion(self): |
| """ |
| Test Browser_Upload_Template Secondary Storage Resource limits after template deletion |
| """ |
| try: |
| self.debug("========================= Test 24 Delete Upload template and verify secondary storage limits========================") |
| |
| browseup_template1=self.browse_upload_template() |
| |
| tmpldetails=Template.list( |
| self.apiclient, |
| id=browseup_template1.id, |
| templatefilter="all", |
| zoneid=self.zone.id) |
| |
| initialuploadprimarystoragelimit=self.getstoragelimits(11) |
| self.delete_template(browseup_template1) |
| |
| afteruploadprimarystoragelimit=self.getstoragelimits(11) |
| |
| if afteruploadprimarystoragelimit!=(initialuploadprimarystoragelimit-tmpldetails[0].size): |
| self.fail("Secondary Storage Resource Count is not updated after deletion") |
| |
| except Exception as e: |
| self.fail("Exception occurred : %s" % e) |
| return |
| |
| # @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") |
| @attr(tags = ["TODO"], required_hardware="false") |
| def test_browser_upload_template_incomplete(self): |
| """ |
| Test browser based incomplete template upload, followed by SSVM destroy. Template should go to UploadAbandoned state and get cleaned up. |
| """ |
| try: |
| self.debug("========================= Test browser based incomplete template upload ========================") |
| |
| #Only register template, without uploading |
| cmd = getUploadParamsForTemplate.getUploadParamsForTemplateCmd() |
| |
| if 'kvm' in self.hypervisor.lower(): |
| cmd.url = 'http://dl.openvm.eu/cloudstack/centos/x86_64/centos-7-kvm.qcow2.bz2' |
| if 'vmware' in self.hypervisor.lower(): |
| cmd.url = 'http://dl.openvm.eu/cloudstack/centos/x86_64/centos-7-vmware.ova' |
| if 'xenserver' in self.hypervisor.lower(): |
| cmd.url = 'http://dl.openvm.eu/cloudstack/centos/x86_64/centos-7-xen.vhd.bz2' |
| |
| cmd.zoneid = self.zone.id |
| cmd.format = self.test_template.format |
| cmd.name=self.test_template.name+self.account.name+(random.choice(string.ascii_uppercase)) |
| cmd.account=self.account.name |
| cmd.domainid=self.domain.id |
| cmd.displaytext=cmd.name |
| cmd.hypervisor=self.test_template.hypervisor |
| cmd.ostypeid=self.test_template.ostypeid |
| template_response=self.apiclient.getUploadParamsForTemplate(cmd) |
| |
| #Destroy SSVM, and wait for new one to start |
| self.destroy_ssvm() |
| |
| #Verify that the template is cleaned up as part of sync-up during new SSVM start |
| list_template_response=Template.list( |
| self.apiclient, |
| id=template_response.id, |
| templatefilter="all", |
| zoneid=self.zone.id) |
| self.assertEqual(list_template_response, None, "Template is not cleaned up, some issue with template sync-up") |
| |
| except Exception as e: |
| self.fail("Exceptione occurred : %s" % e) |
| return |
| |
| @classmethod |
| def tearDownClass(self): |
| super(TestBrowseUploadVolume, self).tearDownClass() |
| |
| def tearDown(self): |
| super(TestBrowseUploadVolume, self).tearDown() |