# 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()
