#!/usr/bin/env python
# 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.
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
from marvin.sshClient import SshClient
from nose.plugins.attrib import attr

class Services:
    """Test Account Services
    """

    def __init__(self):
        self.services = {
            "domain": {
                "name": "Domain",
            },
            "account": {
                "email": "newtest@test.com",
                "firstname": "Test",
                "lastname": "User",
                "username": "test",
                # Random characters are appended for unique
                # username
                "password": "password",
            },
            "service_offering": {
                "name": "Tiny Instance",
                "displaytext": "Tiny Instance",
                "cpunumber": 1,
                "cpuspeed": 100,
                # in MHz
                "memory": 64,
                # In MBs
            },
            "ostype": 'CentOS 5.3 (64-bit)',
            "host_anti_affinity": {
                    "name": "",
                    "type": "host anti-affinity",
                },
            "virtual_machine" : {
                "hypervisor" : "KVM",
            },
            "new_domain": {
                "name": "New Domain",
            },
            "new_account": {
                "email": "domain@test.com",
                "firstname": "Domain",
                "lastname": "Admin",
                "username": "do_admin",
                # Random characters are appended for unique
                # username
                "password": "password",
            },
            "new_account1": {
                "email": "user@test.com",
                "firstname": "User",
                "lastname": "User",
                "username": "user",
                # Random characters are appended for unique
                # username
                "password": "password",
            },

        }

class TestCreateAffinityGroup(cloudstackTestCase):
    """
    Test various scenarios for Create Affinity Group API
    """

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(TestCreateAffinityGroup, cls).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.template = get_template(
            cls.api_client,
            cls.zone.id,
            cls.services["ostype"]
        )
        cls.services["virtual_machine"]["zoneid"] = cls.zone.id

        cls.services["template"] = cls.template.id
        cls.services["zoneid"] = cls.zone.id

        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            domainid=cls.domain.id
        )

        cls.services["account"] = cls.account.name
        cls.services["domainid"] = cls.domain.id

        cls.service_offering = ServiceOffering.create(
            cls.api_client,
            cls.services["service_offering"]
        )

        cls._cleanup = [
            cls.service_offering,
            cls.account,
        ]
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []

    def tearDown(self):
        try:
            # Clean up, terminate the created instance, volumes and snapshots
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @classmethod
    def tearDownClass(cls):
        try:
            cls.api_client = super(TestCreateAffinityGroup, cls).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    def create_aff_grp(self, api_client=None, aff_grp=None,
                  acc=None, domainid=None, aff_grp_name=None):

        if not api_client:
            api_client = self.api_client
        if not aff_grp:
            aff_grp = self.services["host_anti_affinity"]
        if not acc:
            acc = self.account.name
        if not domainid:
            domainid = self.domain.id

        if aff_grp_name is None:
            aff_grp["name"] = "aff_grp_" + random_gen(size=6)
        else:
            aff_grp["name"] = aff_grp_name

        try:
            return AffinityGroup.create(api_client, aff_grp, acc, domainid)
        except Exception as e:
            raise Exception("Error: Creation of Affinity Group failed : %s" %e)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_01_admin_create_aff_grp(self):
        """
        Test create affinity group as admin
        @return:
        """

        aff_grp = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
            acc=self.account.name, domainid=self.account.domainid)
        self.debug("Created Affinity Group: %s" % aff_grp.name)
        list_aff_grps = AffinityGroup.list(self.api_client, id=aff_grp.id)
        self.assert_(isinstance(list_aff_grps, list) and len(list_aff_grps) > 0)
        self.assert_(list_aff_grps[0].id == aff_grp.id)
        self.cleanup.append(aff_grp)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_02_doadmin_create_aff_grp(self):
        """
        Test create affinity group as domain admin
        @return:
        """

        self.new_domain = Domain.create(self.api_client, self.services["new_domain"])
        self.do_admin = Account.create(self.api_client, self.services["new_account"],
                                      admin=True, domainid=self.new_domain.id)
        self.cleanup.append(self.do_admin)
        self.cleanup.append(self.new_domain)

        domainapiclient = self.testClient.createUserApiClient(self.do_admin.name, self.new_domain.name, 2)

        aff_grp = self.create_aff_grp(api_client=domainapiclient, aff_grp=self.services["host_anti_affinity"],
                                            acc=self.do_admin.name, domainid=self.new_domain.id)
        aff_grp.delete(domainapiclient)

    #@attr(tags=["simulator", "basic", "advanced"])
    @attr(tags=["vogxn", "simulator", "basic", "advanced"])
    def test_03_user_create_aff_grp(self):
        """
        Test create affinity group as user
        @return:
        """

        self.user = Account.create(self.api_client, self.services["new_account"],
                                  domainid=self.domain.id)

        userapiclient = self.testClient.createUserApiClient(self.user.name, self.domain.name)

        self.cleanup.append(self.user)
        aff_grp = self.create_aff_grp(api_client=userapiclient, aff_grp=self.services["host_anti_affinity"],
                            acc=self.user.name, domainid=self.domain.id)
        aff_grp.delete(userapiclient)


    @attr(tags=["simulator", "basic", "advanced"])
    def test_04_user_create_aff_grp_existing_name(self):
        """
        Test create affinity group that exists (same name)
        @return:
        """

        self.user = Account.create(self.api_client, self.services["new_account"],
                                  domainid=self.domain.id)

        self.cleanup.append(self.user)
        aff_grp = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user.name, domainid=self.domain.id)
        with self.assertRaises(Exception):
            self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user.name, domainid=self.domain.id,
                            aff_grp_name = aff_grp.name)

        self.debug("Deleted Affinity Group: %s" %aff_grp.name)
        aff_grp.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_05_create_aff_grp_same_name_diff_acc(self):
        """
        Test create affinity group with existing name but within different account
        @return:
        """

        self.user = Account.create(self.api_client, self.services["new_account"],
                                  domainid=self.domain.id)

        self.cleanup.append(self.user)
        aff_grp = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user.name, domainid=self.domain.id)

        try:
            self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        except Exception:
            self.debug("Error: Creating affinity group with same name from different account failed.")

        self.debug("Deleted Affinity Group: %s" %aff_grp.name)
        aff_grp.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_06_create_aff_grp_nonexisting_type(self):
        """
        Test create affinity group of non-existing type
        @return:
        """

        self.non_existing_aff_grp = {
                    "name": "TestAffGrp_HA",
                    "type": "Incorrect type",
                }
        with self.assertRaises(Exception):
            self.create_aff_grp(aff_grp=self.non_existing_aff_grp)

class TestListAffinityGroups(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(TestListAffinityGroups, cls).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.template = get_template(
            cls.api_client,
            cls.zone.id,
            cls.services["ostype"]
        )
        cls.services["virtual_machine"]["zoneid"] = cls.zone.id

        cls.services["template"] = cls.template.id
        cls.services["zoneid"] = cls.zone.id

        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            domainid=cls.domain.id
        )

        cls.services["account"] = cls.account.name
        cls.services["domainid"] = cls.domain.id

        cls.service_offering = ServiceOffering.create(
            cls.api_client,
            cls.services["service_offering"]
        )

        cls.__cleanup = [
            cls.service_offering,
            cls.account,
        ]

        # Create multiple Affinity Groups
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.aff_grp = []
        self.cleanup = []

    def tearDown(self):
        try:
            self.api_client = super(TestListAffinityGroups, self).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(self.api_client, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    @classmethod
    def tearDownClass(cls):
        try:
            cls.api_client = super(TestListAffinityGroups, cls).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(cls.api_client, cls.__cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    def create_aff_grp(self, api_client=None, aff_grp=None,
                  acc=None, domainid=None):

        if api_client == None:
            api_client = self.api_client
        if aff_grp == None:
            aff_grp = self.services["host_anti_affinity"]

        aff_grp["name"] = "aff_grp_" + random_gen(size=6)

        try:
            aff_grp = AffinityGroup.create(api_client,
                                           aff_grp, acc, domainid)
            self.aff_grp.append(aff_grp)
            return aff_grp
        except Exception as e:
            raise Exception("Error: Creation of Affinity Group failed : %s" %e)

    def create_vm_in_aff_grps(self, ag_list, account_name=None, domain_id=None):
        if account_name == None:
            account_name = "admin"
        if domain_id == None:
            domain_id = self.domain.id

        self.debug('Creating VM in AffinityGroup=%s' % ag_list[0])
        vm = VirtualMachine.create(
                   self.api_client,
                   self.services["virtual_machine"],
                   accountid=account_name,
                   domainid=domain_id,
                   templateid=self.template.id,
                   serviceofferingid=self.service_offering.id,
                   affinitygroupnames=ag_list
                )
        self.debug('Created VM=%s in Affinity Group=%s' %
               (vm.id, ag_list[0]))

        list_vm = list_virtual_machines(self.api_client, id=vm.id)
        self.assertEqual(isinstance(list_vm, list), True,
                         "Check list response returns a valid list")
        self.assertNotEqual(len(list_vm),0,
                            "Check VM available in List Virtual Machines")
        vm_response = list_vm[0]
        self.assertEqual(vm_response.state, 'Running',
                         msg="VM is not in Running state")
        return vm, vm_response.hostid

    @attr(tags=["simulator", "basic", "advanced"])
    def test_01_list_aff_grps_for_vm(self):
        """
           List affinity group for a vm
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        list_aff_grps = AffinityGroup.list(self.api_client)

        vm, hostid = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)
        list_aff_grps = AffinityGroup.list(self.api_client,
                                           virtualmachineid=vm.id)

        self.assertEqual(list_aff_grps[0].name, self.aff_grp[0].name,
                         "Listing Affinity Group by VM id failed")

        vm.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])

        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_02_list_multiple_aff_grps_for_vm(self):
        """
           List multiple affinity groups associated with a vm
        """

        aff_grp_01 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        aff_grp_02 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        aff_grps_names = [self.aff_grp[0].name, self.aff_grp[1].name]
        vm, hostid = self.create_vm_in_aff_grps(aff_grps_names, account_name=self.account.name, domain_id=self.domain.id)
        list_aff_grps = AffinityGroup.list(self.api_client,
                                           virtualmachineid=vm.id)

        list_aff_grps_names = [list_aff_grps[0].name, list_aff_grps[1].name]

        aff_grps_names.sort()
        list_aff_grps_names.sort()
        self.assertEqual(aff_grps_names, list_aff_grps_names,
                         "One of the Affinity Groups is missing %s"
                         %list_aff_grps_names)

        vm.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])

        aff_grp_01.delete(self.api_client)
        aff_grp_02.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_03_list_aff_grps_by_id(self):
        """
           List affinity groups by id
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        print self.aff_grp[0].__dict__
        list_aff_grps = AffinityGroup.list(self.api_client)
        list_aff_grps = AffinityGroup.list(self.api_client, id=list_aff_grps[0].id)
        self.assertEqual(list_aff_grps[0].name, self.aff_grp[0].name,
                         "Listing Affinity Group by VM id failed")

        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_04_list_aff_grps_by_name(self):
        """
            List Affinity Groups by name
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name=self.aff_grp[0].name)
        self.assertEqual(list_aff_grps[0].name, self.aff_grp[0].name,
                         "Listing Affinity Group by name failed")

        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_05_list_aff_grps_by_non_existing_id(self):
        """
            List Affinity Groups by non-existing id
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        list_aff_grps = AffinityGroup.list(self.api_client,
                                           id=1234)
        self.assertEqual(list_aff_grps, None,
                         "Listing Affinity Group by non-existing id succeeded.")

        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_06_list_aff_grps_by_non_existing_name(self):
        """
            List Affinity Groups by non-existing name
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name="NonexistingName")
        self.assertEqual(list_aff_grps, None,
                         "Listing Affinity Group by non-existing name succeeded.")

        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_07_list_all_vms_in_aff_grp(self):
        """
           List affinity group should list all for a vms associated with that group
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        vm, hostid = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)
        list_aff_grps = AffinityGroup.list(self.api_client, id=self.aff_grp[0].id)

        self.assertEqual(list_aff_grps[0].name, self.aff_grp[0].name,
                         "Listing Affinity Group by id failed")

        self.assertEqual(list_aff_grps[0].virtualmachineIds[0], vm.id,
        "List affinity group response.virtualmachineIds for group: %s doesn't contain hostid : %s associated with the group"
            %(self.aff_grp[0].name, vm.id)
            )


        vm.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])

        self.aff_grp[0].delete(self.api_client)

class TestDeleteAffinityGroups(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(TestDeleteAffinityGroups, cls).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.template = get_template(
            cls.api_client,
            cls.zone.id,
            cls.services["ostype"]
        )
        cls.services["virtual_machine"]["zoneid"] = cls.zone.id

        cls.services["template"] = cls.template.id
        cls.services["zoneid"] = cls.zone.id

        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            domainid=cls.domain.id
        )

        cls.services["account"] = cls.account.name
        cls.services["domainid"] = cls.domain.id

        cls.service_offering = ServiceOffering.create(
            cls.api_client,
            cls.services["service_offering"]
        )

        cls.__cleanup = [
            cls.service_offering,
            cls.account,
        ]

        # Create multiple Affinity Groups
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.aff_grp = []
        self.cleanup = []

    def tearDown(self):
        try:
            self.api_client = super(TestDeleteAffinityGroups,self).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(self.api_client, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    @classmethod
    def tearDownClass(cls):

        try:
            cls.api_client = super(TestDeleteAffinityGroups, cls).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(cls.api_client, cls.__cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    def create_aff_grp(self, api_client=None, aff_grp=None,
                  acc=None, domainid=None):

        if api_client == None:
            api_client = self.api_client
        if aff_grp == None:
            aff_grp = self.services["host_anti_affinity"]

        aff_grp["name"] = "aff_grp_" + random_gen(size=6)

        try:
            return AffinityGroup.create(api_client, aff_grp, acc, domainid)
        except Exception as e:
            raise Exception("Error: Creation of Affinity Group failed : %s" %e)

    def create_vm_in_aff_grps(self, ag_list, account_name=None, domain_id=None):
        if account_name == None:
            account_name = "admin"
        if domain_id == None:
            domain_id = self.domain.id
        self.debug('Creating VM in AffinityGroup=%s' % ag_list[0])
        vm = VirtualMachine.create(
                   self.api_client,
                   self.services["virtual_machine"],
                   accountid=account_name,
                   domainid=domain_id,
                   templateid=self.template.id,
                   serviceofferingid=self.service_offering.id,
                   affinitygroupnames=ag_list
                )
        self.debug('Created VM=%s in Affinity Group=%s' %
               (vm.id, ag_list[0]))

        list_vm = list_virtual_machines(self.api_client, id=vm.id)

        self.assertEqual(isinstance(list_vm, list), True,
                         "Check list response returns a valid list")
        self.assertNotEqual(len(list_vm),0,
                            "Check VM available in Delete Virtual Machines")

        vm_response = list_vm[0]
        self.assertEqual(vm_response.state, 'Running',
                         msg="VM is not in Running state")

        return vm, vm_response.hostid

    def delete_aff_group(self, apiclient, **kwargs):
        cmd = deleteAffinityGroup.deleteAffinityGroupCmd()
        [setattr(cmd, k, v) for k, v in kwargs.items()]
        return apiclient.deleteAffinityGroup(cmd)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_01_delete_aff_grp_by_name(self):
        """
            Delete Affinity Group by name
        """

        aff_0 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        AffinityGroup.list(self.api_client, name=aff_0.name)
        self.delete_aff_group(self.api_client, name=aff_0.name)
        self.assert_(AffinityGroup.list(self.api_client, name=aff_0.name) is None)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_02_delete_aff_grp_for_acc(self):
        """
            Delete Affinity Group as admin for an account
        """

        aff_0 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.account.name, domainid=self.domain.id)
        aff_1 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.account.name, domainid=self.domain.id)

        aff_0.delete(self.api_client)
        with self.assertRaises(Exception):
            self.create_vm_in_aff_grps([aff_0.name], account_name=self.account.name, domain_id=self.domain.id)
        aff_1.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_03_delete_aff_grp_with_vms(self):
        """
            Delete Affinity Group which has vms in it
        """

        aff_0 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        aff_1 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        vm, hostid = self.create_vm_in_aff_grps([aff_0.name, aff_1.name], account_name=self.account.name, domain_id=self.domain.id)
        aff_0.delete(self.api_client)
        vm_list = list_virtual_machines(self.apiclient, id=vm.id)
        self.assert_(vm_list is not None)
        vm.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        aff_1.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_05_delete_aff_grp_id(self):
        """
            Delete Affinity Group with id which does not belong to this user
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        aff_0 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user1.name,
                            domainid=self.domain.id)

        self.user2 = Account.create(self.apiclient, self.services["new_account1"])
        self.cleanup.append(self.user2)

        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user2.name,
                                        DomainName=self.user2.domain,
                                        acctType=0)

        aff_1 = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name=aff_0.name)

        # Delete Affinity group belonging to different user by id
        with self.assertRaises(Exception):
            self.delete_aff_group(userapiclient, name=list_aff_grps.id)

        #Cleanup
        aff_0.delete(self.api_client)
        aff_1.delete(userapiclient)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_06_delete_aff_grp_name(self):
        """
            Delete Affinity Group by name which does not belong to this user
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        aff_0 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user1.name,
                            domainid=self.domain.id)

        self.user2 = Account.create(self.apiclient, self.services["new_account1"])
        self.cleanup.append(self.user2)

        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user2.name,
                                        DomainName=self.user2.domain,
                                        acctType=0)

        aff_1 = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name=aff_0.name)

        # Delete Affinity group belonging to different user by name
        with self.assertRaises(Exception):
            self.delete_aff_group(userapiclient, name=list_aff_grps.name)

        #Cleanup
        aff_0.delete(self.api_client)
        aff_1.delete(userapiclient)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_08_delete_aff_grp_by_id(self):
        """
            Delete Affinity Group by id.
        """

        aff_grp_1 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        aff_grp_2 = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])

        aff_grp_1.delete(self.api_client)
        aff_grp_2.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_09_delete_aff_grp_root_admin(self):
        """
            Root admin should be able to delete affinity group of other users
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        user1apiclient = self.testClient.createUserApiClient(
                                        UserName=self.user1.name,
                                        DomainName=self.user1.domain,
                                        acctType=0)

        aff_grp = self.create_aff_grp(api_client=user1apiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(self.api_client)
        self.assertNotEqual(list_aff_grps, [], "Admin not able to list Affinity "
                         "Groups of users")

        aff_grp.delete(self.api_client)

class TestUpdateVMAffinityGroups(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(TestUpdateVMAffinityGroups, cls).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.template = get_template(
            cls.api_client,
            cls.zone.id,
            cls.services["ostype"]
        )
        cls.services["virtual_machine"]["zoneid"] = cls.zone.id

        cls.services["template"] = cls.template.id
        cls.services["zoneid"] = cls.zone.id

        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            domainid=cls.domain.id
        )

        cls.services["account"] = cls.account.name
        cls.services["domainid"] = cls.domain.id

        cls.service_offering = ServiceOffering.create(
            cls.api_client,
            cls.services["service_offering"]
        )

        cls.__cleanup = [
            cls.service_offering,
            cls.account,
        ]

        # Create multiple Affinity Groups
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.aff_grp = []
        self.cleanup = []

    def tearDown(self):
        try:
            self.api_client = super(TestUpdateVMAffinityGroups,self).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(self.api_client, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    @classmethod
    def tearDownClass(cls):

        try:
            cls.api_client = super(TestUpdateVMAffinityGroups, cls).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(cls.api_client, cls.__cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    def create_aff_grp(self, api_client=None, aff_grp=None,
                  acc=None, domainid=None):

        if api_client == None:
            api_client = self.api_client
        if aff_grp == None:
            aff_grp = self.services["host_anti_affinity"]

        aff_grp["name"] = "aff_grp_" + random_gen(size=6)

        try:
            self.aff_grp.append(AffinityGroup.create(api_client,
                                                     aff_grp, acc, domainid))
        except Exception as e:
            raise Exception("Error: Creation of Affinity Group failed : %s" %e)

    def create_vm_in_aff_grps(self, ag_list, account_name=None, domain_id=None):
        if account_name == None:
            account_name = "admin"
        if domain_id == None:
            domain_id = self.domain.id
        self.debug('Creating VM in AffinityGroup=%s' % ag_list)

        vm = VirtualMachine.create(
               self.api_client,
               self.services["virtual_machine"],
               accountid=account_name,
               domainid=domain_id,
               templateid=self.template.id,
               serviceofferingid=self.service_offering.id,
               affinitygroupnames=ag_list
            )
        self.debug('Created VM=%s in Affinity Group=%s' %
                   (vm.id, ag_list))

        list_vm = list_virtual_machines(self.api_client, id=vm.id)

        self.assertEqual(isinstance(list_vm, list), True,
                         "Check list response returns a valid list")
        self.assertNotEqual(len(list_vm),0,
                            "Check VM available in Delete Virtual Machines")

        vm_response = list_vm[0]
        self.assertEqual(vm_response.state, 'Running',
                         msg="VM is not in Running state")

        return vm, vm_response.hostid

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_01_update_aff_grp_by_ids(self):
        """
            Update the list of affinityGroups by using affinity groupids

        """
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        vm1, hostid1 = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)
        vm2, hostid2 = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)

        vm1.stop(self.api_client)

        list_aff_grps = AffinityGroup.list(self.api_client, account=self.account.name, domainid=self.domain.id)

        self.assertEqual(len(list_aff_grps), 2 , "2 affinity groups should be present")

        vm1.update_affinity_group(self.api_client,
                                  affinitygroupids=[list_aff_grps[0].id,
                                                    list_aff_grps[1].id])

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           virtualmachineid=vm1.id)

        list_aff_grps_names = [list_aff_grps[0].name, list_aff_grps[1].name]

        aff_grps_names = [self.aff_grp[0].name, self.aff_grp[1].name]
        aff_grps_names.sort()
        list_aff_grps_names.sort()
        self.assertEqual(aff_grps_names, list_aff_grps_names,
                         "One of the Affinity Groups is missing %s"
                         %list_aff_grps_names)

        vm1.start(self.api_client)

        vm_status = VirtualMachine.list(self.api_client, id=vm1.id)
        self.assertNotEqual(vm_status[0].hostid, hostid2, "The virtual machine "
                         "started on host %s violating the host anti-affinity"
                         "rule" %vm_status[0].hostid)

        vm1.delete(self.api_client)
        vm2.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        for aff_grp in self.aff_grp:
            aff_grp.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_02_update_aff_grp_by_names(self):
        """
            Update the list of affinityGroups by using affinity groupnames

        """
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        vm1, hostid1 = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)
        vm2, hostid2 = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)

        vm1.stop(self.api_client)

        vm1.update_affinity_group(self.api_client,
                                  affinitygroupnames=[self.aff_grp[0].name,
                                                    self.aff_grp[1].name])

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           virtualmachineid=vm1.id)

        list_aff_grps_names = [list_aff_grps[0].name, list_aff_grps[1].name]

        aff_grps_names = [self.aff_grp[0].name, self.aff_grp[1].name]
        aff_grps_names.sort()
        list_aff_grps_names.sort()
        self.assertEqual(aff_grps_names, list_aff_grps_names,
                         "One of the Affinity Groups is missing %s"
                         %list_aff_grps_names)

        vm1.start(self.api_client)

        vm_status = VirtualMachine.list(self.api_client, id=vm1.id)
        self.assertNotEqual(vm_status[0].hostid, hostid2, "The virtual machine "
                         "started on host %s violating the host anti-affinity"
                         "rule" %vm_status[0].hostid)

        vm1.delete(self.api_client)
        vm2.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        for aff_grp in self.aff_grp:
            aff_grp.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_03_update_aff_grp_for_vm_with_no_aff_grp(self):
        """
            Update the list of affinityGroups for vm which is not associated
            with any affinity groups.

        """
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        vm1, hostid1 = self.create_vm_in_aff_grps([], account_name=self.account.name, domain_id=self.domain.id)
        vm2, hostid2 = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)

        vm1.stop(self.api_client)

        vm1.update_affinity_group(self.api_client,
                                  affinitygroupnames=[self.aff_grp[0].name])

        vm1.start(self.api_client)

        vm_status = VirtualMachine.list(self.api_client, id=vm1.id)
        self.assertNotEqual(vm_status[0].hostid, hostid2, "The virtual machine "
                         "started on host %s violating the host anti-affinity"
                         "rule" %vm_status[0].hostid)

        vm1.delete(self.api_client)
        vm2.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        aff_grps = [self.aff_grp[0], self.aff_grp[1]]
        for aff_grp in aff_grps:
            aff_grp.delete(self.api_client)

    @unittest.skip("Skip - Failing - work in progress")
    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_04_update_aff_grp_remove_all(self):
        """
            Update the list of Affinity Groups to empty list
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"])
        vm1, hostid1 = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)

        aff_grps = [self.aff_grp[0], self.aff_grp[1]]
        vm1.stop(self.api_client)

        vm1.update_affinity_group(self.api_client, affinitygroupids = [])

        vm1.start(self.api_client)
        list_aff_grps = AffinityGroup.list(self.api_client,
                                           virtualmachineid=vm1.id)
        self.assertEqual(list_aff_grps, [], "The affinity groups list is not empyty")

        vm1.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        for aff_grp in aff_grps:
            aff_grp.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_05_update_aff_grp_on_running_vm(self):
        """
            Update the list of Affinity Groups on running vm
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        vm1, hostid1 = self.create_vm_in_aff_grps([self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)

        aff_grps = [self.aff_grp[0], self.aff_grp[1]]
        with self.assertRaises(Exception):
            vm1.update_affinity_group(self.api_client, affinitygroupnames=[])

        vm1.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        for aff_grp in aff_grps:
            aff_grp.delete(self.api_client)

class TestDeployVMAffinityGroups(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(TestDeployVMAffinityGroups, cls).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.template = get_template(
            cls.api_client,
            cls.zone.id,
            cls.services["ostype"]
        )
        cls.services["virtual_machine"]["zoneid"] = cls.zone.id

        cls.services["template"] = cls.template.id
        cls.services["zoneid"] = cls.zone.id

        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            domainid=cls.domain.id
        )

        cls.services["account"] = cls.account.name
        cls.services["domainid"] = cls.domain.id

        cls.service_offering = ServiceOffering.create(
            cls.api_client,
            cls.services["service_offering"]
        )

        cls.__cleanup = [
            cls.service_offering,
            cls.account,
        ]

        # Create multiple Affinity Groups
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.aff_grp = []
        self.cleanup = []

    def tearDown(self):
        try:
            self.api_client = super(TestDeployVMAffinityGroups,self).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(self.api_client, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    @classmethod
    def tearDownClass(cls):

        try:
            cls.api_client = super(TestDeployVMAffinityGroups, cls).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(cls.api_client, cls.__cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    def create_aff_grp(self, api_client=None, aff_grp=None,
                  acc=None, domainid=None):

        if api_client == None:
            api_client = self.api_client
        if aff_grp == None:
            aff_grp = self.services["host_anti_affinity"]

        aff_grp["name"] = "aff_grp_" + random_gen(size=6)

        try:
            self.aff_grp.append(AffinityGroup.create(api_client,
                                                     aff_grp, acc, domainid))
        except Exception as e:
            raise Exception("Error: Creation of Affinity Group failed : %s" %e)

    def create_vm_in_aff_grps(self, api_client=None, ag_list=None, ag_ids=None, account_name=None, domain_id=None):
        if account_name == None:
            account_name = "admin"
        if domain_id == None:
            domain_id = self.domain.id
        if api_client == None:
            api_client = self.api_client
        self.debug('Creating VM in AffinityGroup=%s' % ag_list)
        vm = VirtualMachine.create(
               api_client,
               self.services["virtual_machine"],
               accountid=account_name,
               domainid=domain_id,
               templateid=self.template.id,
               serviceofferingid=self.service_offering.id,
               affinitygroupnames=ag_list,
               affinitygroupids=ag_ids
            )
        self.debug('Created VM=%s in Affinity Group=%s' %
                    (vm.id, ag_list))

        list_vm = list_virtual_machines(self.api_client, id=vm.id)

        self.assertEqual(isinstance(list_vm, list), True,
                         "Check list response returns a valid list")
        self.assertNotEqual(len(list_vm),0,
                            "Check VM available in Delete Virtual Machines")

        vm_response = list_vm[0]
        self.assertEqual(vm_response.state, 'Running',
                         msg="VM is not in Running state")

        return vm, vm_response.hostid

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_01_deploy_vm_without_aff_grp(self):
        """
            Deploy VM without affinity group
        """
        vm1, hostid1 = self.create_vm_in_aff_grps(account_name=self.account.name, domain_id=self.domain.id)

        vm1.delete(self.api_client)
        #Wait for expunge interval to cleanup VM
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_02_deploy_vm_by_aff_grp_name(self):
        """
            Deploy VM by aff grp name
        """
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        vm1, hostid1 = self.create_vm_in_aff_grps(ag_list=[self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)

        vm1.delete(self.api_client)
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_03_deploy_vm_by_aff_grp_id(self):
        """
            Deploy VM by aff grp id
        """
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name=self.aff_grp[0].name, account=self.account.name, domainid=self.domain.id)

        vm1, hostid1 = self.create_vm_in_aff_grps(ag_ids=[list_aff_grps[0].id], account_name=self.account.name, domain_id=self.domain.id)

        vm1.delete(self.api_client)
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_04_deploy_vm_anti_affinity_group(self):
        """
        test DeployVM in anti-affinity groups

        deploy VM1 and VM2 in the same host-anti-affinity groups
        Verify that the vms are deployed on separate hosts
        """
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        vm1, hostid1 = self.create_vm_in_aff_grps(ag_list=[self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)
        vm2, hostid2 = self.create_vm_in_aff_grps(ag_list=[self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)

        self.assertNotEqual(hostid1, hostid2,
            msg="Both VMs of affinity group %s are on the same host"
            % self.aff_grp[0].name)

        vm1.delete(self.api_client)
        vm2.delete(self.api_client)
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_05_deploy_vm_by_id(self):
        """
            Deploy vms by affinity group id
        """
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name=self.aff_grp[0].name, acc=self.account.name, domainid=self.domain.id)

        vm1, hostid1 = self.create_vm_in_aff_grps(ag_ids=[list_aff_grps[0].id], account_name=self.account.name, domain_id=self.domain.id)
        vm2, hostid2 = self.create_vm_in_aff_grps(ag_ids=[list_aff_grps[0].id], account_name=self.account.name, domain_id=self.domain.id)

        self.assertNotEqual(hostid1, hostid2,
            msg="Both VMs of affinity group %s are on the same host"
            % self.aff_grp[0].name)

        vm1.delete(self.api_client)
        vm2.delete(self.api_client)
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        self.aff_grp[0].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_06_deploy_vm_aff_grp_of_other_user_by_name(self):
        """
            Deploy vm in affinity group of another user by name
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user1.name,
                            domainid=self.domain.id)

        self.user2 = Account.create(self.apiclient, self.services["new_account1"])
        self.cleanup.append(self.user2)

        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user2.name,
                                        DomainName=self.user2.domain,
                                        acctType=0)

        self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        with self.assertRaises(Exception):
            vm1, hostid1 = self.create_vm_in_aff_grps(api_client=userapiclient,
                                                  ag_list=[self.aff_grp[0].name], account_name=self.account.name, domain_id=self.domain.id)


        self.aff_grp[0].delete(self.api_client)
        self.aff_grp[1].delete(userapiclient)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_07_deploy_vm_aff_grp_of_other_user_by_id(self):
        """
            Deploy vm in affinity group of another user by id
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user1.name,
                            domainid=self.domain.id)

        self.user2 = Account.create(self.apiclient, self.services["new_account1"])
        self.cleanup.append(self.user2)

        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user2.name,
                                        DomainName=self.user2.domain,
                                        acctType=0)

        self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name=self.aff_grp[0].name)

        # Deploy VM in Affinity group belonging to different user by id
        with self.assertRaises(Exception):
            vm1, hostid1 = self.create_vm_in_aff_grps(api_client=userapiclient,
                                                  ag_ids=[list_aff_grps[0].id], account_name=self.account.name, domain_id=self.domain.id)

        self.aff_grp[0].delete(self.api_client)
        self.aff_grp[1].delete(userapiclient)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_08_deploy_vm_multiple_aff_grps(self):
        """
            Deploy vm in multiple affinity groups
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        vm1, hostid1 = self.create_vm_in_aff_grps(ag_list=[self.aff_grp[0].name,
                                                   self.aff_grp[1].name], account_name=self.account.name, domain_id=self.domain.id)

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           virtualmachineid=vm1.id)

        aff_grps_names = [self.aff_grp[0].name, self.aff_grp[1].name]
        list_aff_grps_names = [list_aff_grps[0].name, list_aff_grps[1].name]

        aff_grps_names.sort()
        list_aff_grps_names.sort()
        self.assertEqual(aff_grps_names, list_aff_grps_names,
                         "One of the Affinity Groups is missing %s"
                         %list_aff_grps_names)

        vm1.delete(self.api_client)
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])
        self.aff_grp[0].delete(self.api_client)
        self.aff_grp[1].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_09_deploy_vm_multiple_aff_grps(self):
        """
            Deploy multiple vms in multiple affinity groups
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)
        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        vm1, hostid1 = self.create_vm_in_aff_grps(ag_list=[self.aff_grp[0].name,
                                                   self.aff_grp[1].name], account_name=self.account.name, domain_id=self.domain.id)
        vm2, hostid2 = self.create_vm_in_aff_grps(ag_list=[self.aff_grp[0].name,
                                                   self.aff_grp[1].name], account_name=self.account.name, domain_id=self.domain.id)

        aff_grps_names = [self.aff_grp[0].name, self.aff_grp[1].name]
        aff_grps_names.sort()

        for vm in [vm1, vm2]:
            list_aff_grps = AffinityGroup.list(self.api_client,
                                           virtualmachineid=vm.id)

            list_aff_grps_names = [list_aff_grps[0].name, list_aff_grps[1].name]

            list_aff_grps_names.sort()
            self.assertEqual(aff_grps_names, list_aff_grps_names,
                         "One of the Affinity Groups is missing %s"
                         %list_aff_grps_names)

        vm1.delete(self.api_client)
        vm2.delete(self.api_client)
        wait_for_cleanup(self.apiclient, ["expunge.delay", "expunge.interval"])

        self.aff_grp[0].delete(self.api_client)
        self.aff_grp[1].delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_10_deploy_vm_by_aff_grp_name_and_id(self):
        """
            Deploy VM by aff grp name and id
        """

        self.create_aff_grp(aff_grp=self.services["host_anti_affinity"], acc=self.account.name, domainid=self.domain.id)

        list_aff_grps = AffinityGroup.list(self.api_client,
                                           name=self.aff_grp[0].name)

        with self.assertRaises(Exception):
            vm1, hostid1 = self.create_vm_in_aff_grps(ag_list=[self.aff_grp[0].name],
                                                  ag_ids=[list_aff_grps[0].id], account_name=self.account.name, domain_id=self.domain.id)

        self.aff_grp[0].delete(self.api_client)

class TestAffinityGroupsAdminUser(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(TestAffinityGroupsAdminUser, cls).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.template = get_template(
            cls.api_client,
            cls.zone.id,
            cls.services["ostype"]
        )
        cls.services["virtual_machine"]["zoneid"] = cls.zone.id

        cls.services["template"] = cls.template.id
        cls.services["zoneid"] = cls.zone.id

        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            domainid=cls.domain.id
        )

        cls.services["account"] = cls.account.name
        cls.services["domainid"] = cls.domain.id

        cls.service_offering = ServiceOffering.create(
            cls.api_client,
            cls.services["service_offering"]
        )

        cls.__cleanup = [
            cls.service_offering,
            cls.account,
        ]

        # Create multiple Affinity Groups
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.aff_grp = []
        self.cleanup = []

    def tearDown(self):
        try:
            self.api_client = super(TestAffinityGroupsAdminUser,self).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(self.api_client, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    @classmethod
    def tearDownClass(cls):

        try:
            cls.api_client = super(TestAffinityGroupsAdminUser, cls).getClsTestClient().getApiClient()
            #Clean up, terminate the created templates
            cleanup_resources(cls.api_client, cls.__cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    def create_aff_grp(self, api_client=None, aff_grp=None,
                  acc=None, domainid=None):

        if api_client == None:
            api_client = self.api_client
        if aff_grp == None:
            aff_grp = self.services["host_anti_affinity"]

        aff_grp["name"] = "aff_grp_" + random_gen(size=6)

        try:
            return AffinityGroup.create(api_client, aff_grp, acc, domainid)
        except Exception as e:
            raise Exception("Error: Creation of Affinity Group failed : %s" %e)

    def create_vm_in_aff_grps(self, api_client=None, ag_list=None, ag_ids=None, account_name=None, domain_id=None):
        if account_name == None:
            account_name = "admin"
        if domain_id == None:
            domain_id = self.domain.id
        if api_client == None:
            api_client = self.api_client
        self.debug('Creating VM in AffinityGroup=%s' % ag_list)
        vm = VirtualMachine.create(
               api_client,
               self.services["virtual_machine"],
               templateid=self.template.id,
               serviceofferingid=self.service_offering.id,
               affinitygroupnames=ag_list,
               affinitygroupids=ag_ids
            )
        self.debug('Created VM=%s in Affinity Group=%s' %
                   (vm.id, ag_list))

        list_vm = list_virtual_machines(self.api_client, id=vm.id)

        self.assertEqual(isinstance(list_vm, list), True,
                         "Check list response returns a valid list")
        self.assertNotEqual(len(list_vm),0,
                            "Check VM available in Delete Virtual Machines")

        vm_response = list_vm[0]
        self.assertEqual(vm_response.state, 'Running',
                         msg="VM is not in Running state")

        return vm, vm_response.hostid

    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_01_deploy_vm_another_user(self):
        """
            Deploy vm as Admin in Affinity Group belonging to regular user (should fail)
        """
        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user1.name,
                                        DomainName=self.user1.domain,
                                        acctType=0)

        aff_grp = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        with self.assertRaises(Exception):
            self.create_vm_in_aff_grps(api_client=self.apiclient, ag_list=[self.aff_grp[0].name])

        aff_grp.delete(userapiclient)

    @attr(tags=["simulator", "basic", "advanced", "multihost"])

    def test_02_create_aff_grp_user(self):
        """
            Create Affinity Group as admin for regular user
        """

        self.user = Account.create(self.api_client, self.services["new_account"],
                                  domainid=self.domain.id)

        self.cleanup.append(self.user)
        aff_grp = self.create_aff_grp(aff_grp=self.services["host_anti_affinity"],
                            acc=self.user.name, domainid=self.domain.id)
        aff_grp.delete(self.apiclient)


    @attr(tags=["simulator", "basic", "advanced", "multihost"])
    def test_03_list_aff_grp_all_users(self):
        """
            List Affinity Groups as admin for all the users
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user1.name,
                                        DomainName=self.user1.domain,
                                        acctType=0)

        aff_grp = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(self.api_client)
        self.assertNotEqual(list_aff_grps, [], "Admin not able to list Affinity "
                         "Groups of users")
        aff_grp.delete(userapiclient)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_04_list_all_admin_aff_grp(self):
        """
            List Affinity Groups belonging to admin user
        """

        aff_grp1 = self.create_aff_grp(api_client=self.api_client,
                            aff_grp=self.services["host_anti_affinity"])
        aff_grp2 = self.create_aff_grp(api_client=self.api_client,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(self.api_client)

        self.assertNotEqual(list_aff_grps, [], "Admin not able to list Affinity "
                         "Groups belonging to him")
        grp_names = [aff_grp1.name, aff_grp2.name]
        list_names = []
        for grp in list_aff_grps:
            list_names.append(grp.name)

        for name in grp_names:
            self.assertTrue(name in list_names,
                        "Listing affinity groups belonging to Admin didn't return group %s" %(name))

        aff_grp1.delete(self.api_client)
        aff_grp2.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_05_list_all_users_aff_grp(self):
        """
            List Affinity Groups belonging to regular user passing account id and domain id
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user1.name,
                                        DomainName=self.user1.domain,
                                        acctType=0)

        aff_grp1 = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])
        aff_grp2 = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(self.api_client, accountId=self.user1.id, domainId=self.user1.domainid)

        self.assertNotEqual(list_aff_grps, [], "Admin not able to list Affinity "
                         "Groups of users")
        grp_names = [aff_grp1.name, aff_grp2.name]
        list_names = []
        for grp in list_aff_grps:
            list_names.append(grp.name)

        for name in grp_names:
            self.assertTrue(name in list_names,
                        "Missing Group %s from listing" %(name))

        aff_grp1.delete(self.api_client)
        aff_grp2.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_06_list_all_users_aff_grp_by_id(self):
        """
            List Affinity Groups belonging to regular user passing group id
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user1.name,
                                        DomainName=self.user1.domain,
                                        acctType=0)

        aff_grp = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(userapiclient)
        aff_grp_by_id = AffinityGroup.list(self.api_client, id=list_aff_grps[0].id)

        self.assertNotEqual(aff_grp_by_id, [], "Admin not able to list Affinity "
                         "Groups of users")
        self.assertEqual(len(aff_grp_by_id), 1, "%s affinity groups listed by admin with id %s. Expected 1"
                                                %(len(aff_grp_by_id), list_aff_grps[0].id))
        self.assertEqual(aff_grp_by_id[0].name, aff_grp.name,
                "Incorrect name returned when listing user affinity groups as admin by id Expected : %s Got: %s"
                %(aff_grp.name, aff_grp_by_id[0].name )
            )

        aff_grp.delete(self.api_client)

    @attr(tags=["simulator", "basic", "advanced"])
    def test_07_delete_aff_grp_of_other_user(self):
        """
            Delete Affinity Group belonging to regular user
        """

        self.user1 = Account.create(self.api_client,
                                       self.services["new_account"])

        self.cleanup.append(self.user1)
        userapiclient = self.testClient.createUserApiClient(
                                        UserName=self.user1.name,
                                        DomainName=self.user1.domain,
                                        acctType=0)

        aff_grp = self.create_aff_grp(api_client=userapiclient,
                            aff_grp=self.services["host_anti_affinity"])

        list_aff_grps = AffinityGroup.list(userapiclient)
        aff_grp_by_id = AffinityGroup.list(self.api_client, id=list_aff_grps[0].id)

        self.assertNotEqual(aff_grp_by_id, [], "Admin not able to list Affinity "
                         "Groups of users")
        self.assertEqual(len(aff_grp_by_id), 1, "%s affinity groups listed by admin with id %s. Expected 1"
                                                %(len(aff_grp_by_id), list_aff_grps[0].id))
        self.assertEqual(aff_grp_by_id[0].name, aff_grp.name,
                "Incorrect name returned when listing user affinity groups as admin by id Expected : %s Got: %s"
                %(aff_grp.name, aff_grp_by_id[0].name )
            )

        aff_grp.delete(self.api_client)
