#!/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 import remoteSSHClient
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)
