# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

""" P1 for VMware DRS testing
"""
#Import Local Modules
import marvin
from nose.plugins.attrib import attr

from marvin.cloudstackTestCase import cloudstackTestCase, unittest

from marvin.integration.lib.base import (Account,
                                         AffinityGroup,
                                         Host,
                                         VirtualMachine,
                                         ServiceOffering)

from marvin.integration.lib.common import (get_zone,
                                           get_template,
                                           get_domain,
                                           get_pod
                                           )

from marvin.integration.lib.utils import (validateList,
                                          cleanup_resources,
                                          random_gen)

from marvin.cloudstackAPI import (prepareHostForMaintenance,
                                  cancelHostMaintenance,
                                  migrateVirtualMachine)

from marvin.codes import PASS


#Import System modules
import time


class Services:
    """Test vmware DRS services
    """

    def __init__(self):
        self.services = {
                "account": {
                    "email": "test@test.com",
                    "firstname": "Test",
                    "lastname": "User",
                    "username": "test",
                    # Random characters are appended in create account to
                    # ensure unique username generated each time
                    "password": "password",
                },
                "virtual_machine":
                {
                    "displayname": "testserver",
                    "username": "root",     # VM creds for SSH
                    "password": "password",
                    "ssh_port": 22,
                    "hypervisor": 'XenServer',
                    "privateport": 22,
                    "publicport": 22,
                    "protocol": 'TCP',
                },
                "service_offering":
                {
                    "name": "Tiny Instance",
                    "displaytext": "Tiny Instance",
                    "cpunumber": 1,
                    "cpuspeed": 100,    # in MHz
                    "memory": 2048,      # In MBs
                },
                "service_offering_max_memory":
                {
                    "name": "Tiny Instance",
                    "displaytext": "Tiny Instance",
                    "cpunumber": 1,
                    "cpuspeed": 100,    # in MHz
                    "memory": 128,      # In MBs
                },
                "host_anti_affinity": {
                    "name": "",
                    "type": "host anti-affinity",
                },
                "host_affinity": {
                    "name": "",
                    "type": "host affinity",
                },
            "sleep": 60,
            "timeout": 10,
            "ostype": 'CentOS 5.3 (64-bit)',
            # CentOS 5.3 (64-bit)
        }

class TestVMPlacement(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(
                               TestVMPlacement,
                               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.pod = get_pod(
                          cls.api_client,
                          zoneid=cls.zone.id,
                          services=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["virtual_machine"]["template"] = cls.template.id

        cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.services["service_offering"],
                                            offerha=True
                                            )
        cls._cleanup = [
                        cls.service_offering,
                        ]
        return

    @classmethod
    def tearDownClass(cls):
        try:
            #Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.account = Account.create(
                                     self.apiclient,
                                     self.services["account"],
                                     admin=True,
                                     domainid=self.domain.id
                                     )
        self.cleanup = [self.account]
        return

    def tearDown(self):
        try:
            #Clean up, terminate the created accounts, domains etc
            cleanup_resources(self.apiclient, self.cleanup)
            #self.testClient.close()
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @attr(tags = ["advanced", "vmware", "multihost"])
    def test_vm_creation_in_fully_automated_mode(self):
        """ Test VM Creation in  automation mode = Fully automated
            This test requires following preconditions:
                - DRS Cluster is configured in "Fully automated" mode
        """
        # Validate the following
        # 1. Create a new VM in a host which is almost fully utilized
        # 2 Automatically places VM on the other host
        # 3. VM state is running after deployment

        hosts = Host.list(
                          self.apiclient,
                          zoneid=self.zone.id,
                          resourcestate='Enabled',
                          type='Routing'
                          )
        self.assertEqual(
                         isinstance(hosts, list),
                         True,
                         "List hosts should return valid host response"
                         )
        self.assertGreaterEqual(
                         len(hosts),
                         2,
                         "There must be two hosts present in a cluster"
                        )

        host_1 = hosts[0]

        #Convert available memory( Keep some margin) into MBs and assign to service offering
        self.services["service_offering_max_memory"]["memory"] = int((int(hosts[0].memorytotal) - int(hosts[0].memoryused))/1048576 - 1024)

        self.debug("max memory: %s" % self.services["service_offering_max_memory"]["memory"])

        service_offering_max_memory = ServiceOffering.create(
                                            self.apiclient,
                                            self.services["service_offering_max_memory"]
                                            )

        VirtualMachine.create(
                              self.apiclient,
                              self.services["virtual_machine"],
                              accountid=self.account.name,
                              domainid=self.account.domainid,
                              serviceofferingid=service_offering_max_memory.id,
                              hostid = host_1.id
                              )

        # Host 1 has only 1024 MB memory available now after deploying the instance
        # We are trying to deploy an instance with 2048 MB memory, this should automatically
        # get deployed on other host which has the enough capacity

        self.debug("Trying to deploy instance with memory requirement more than that is available on\
                     the first host")

        self.debug("Deploying VM in account: %s" % self.account.name)
        # Spawn an instance in that network
        virtual_machine = VirtualMachine.create(
                                  self.apiclient,
                                  self.services["virtual_machine"],
                                  accountid=self.account.name,
                                  domainid=self.account.domainid,
                                  serviceofferingid=self.service_offering.id
                                  )
        vms = VirtualMachine.list(
                                  self.apiclient,
                                  id=virtual_machine.id,
                                  listall=True
                                  )
        self.assertEqual(
                    isinstance(vms, list),
                    True,
                    "List VMs should return valid response for deployed VM"
                    )
        self.assertNotEqual(
                    len(vms),
                    0,
                    "List VMs should return valid response for deployed VM"
                    )
        vm = vms[0]
        self.assertEqual(
                         vm.state,
                         "Running",
                         "Deployed VM should be in RUnning state"
                         )
        self.assertNotEqual(
                    vm.hostid,
                    host_1.id,
                    "Host Ids of two should not match as one host is full"
                    )

        self.debug("The host ids of two virtual machines are different as expected\
                    they are %s and %s" % (vm.hostid, host_1.id))
        return

@unittest.skip("Skipping... Not tested due to unavailibility of multihosts setup - 3 hosts in a cluster")
class TestAntiAffinityRules(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(
                               TestAntiAffinityRules,
                               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["virtual_machine"]["template"] = cls.template.id

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

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

    @classmethod
    def tearDownClass(cls):
        try:
            #Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

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

    def tearDown(self):
        try:
            #Clean up, terminate the created accounts, domains etc
            cleanup_resources(self.apiclient, self.cleanup)
            #self.testClient.close()
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

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

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

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

    @attr(tags = ["advanced", "vmware", "multihost"])
    def test_vmware_anti_affinity(self):
        """ Test Set up anti-affinity rules

            The test requires following pre-requisites
            - VMWare cluster configured in fully automated mode
        """

        # Validate the following
        # 1. Deploy VMs on host 1 and 2
        # 2. Enable maintenance mode for host 1
        # 3. VM should be migrated to 3rd host

        hosts = Host.list(
                          self.apiclient,
                          zoneid=self.zone.id,
                          resourcestate='Enabled',
                          type='Routing'
                          )
        self.assertEqual(
                         isinstance(hosts, list),
                         True,
                         "List hosts should return valid host response"
                         )

        self.debug(len(hosts))

        self.assertGreaterEqual(
                         len(hosts),
                         3,
                         "There must be at least 3 hosts present in a cluster"
                        )

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

        vm_1 = VirtualMachine.create(
                              self.apiclient,
                              self.services["virtual_machine"],
                              accountid=self.account.name,
                              domainid=self.domain.id,
                              serviceofferingid=self.service_offering.id,
                              affinitygroupnames=[aff_grp.name]
                             )

        vm_2 = VirtualMachine.create(
                              self.apiclient,
                              self.services["virtual_machine"],
                              accountid=self.account.name,
                              domainid=self.domain.id,
                              serviceofferingid=self.service_offering.id,
                              affinitygroupnames=[aff_grp.name]
                             )

        host_1 = vm_1.hostid

        host_2 = vm_2.hostid

        vms = VirtualMachine.list(
                                  self.apiclient,
                                  id=vm_1.id,
                                  listall=True
                                  )
        vm_list_validation_result = validateList(vms)

        self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" %
                         vm_list_validation_result[1])

        virtual_machine_1 = vm_list_validation_result[1]

        self.debug("VM State: %s" % virtual_machine_1.state)
        self.assertEqual(
                         virtual_machine_1.state,
                         "Running",
                         "Deployed VM should be in RUnning state"
                         )

        vms = VirtualMachine.list(
                                  self.apiclient,
                                  id=vm_2.id,
                                  listall=True
                                  )
        vm_list_validation_result = validateList(vms)

        self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" %
                         vm_list_validation_result[1])

        virtual_machine_2 = vm_list_validation_result[1]

        self.debug("VM %s  State: %s" % (
                                         virtual_machine_2.name,
                                         virtual_machine_2.state
                                         ))
        self.assertEqual(
                         virtual_machine_2.state,
                         "Running",
                         "Deployed VM should be in RUnning state"
                         )
        self.debug("Enabling maintenance mode on host_1: %s" % host_1)

        cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
        cmd.id = host_1
        self.apiclient.prepareHostForMaintenance(cmd)

        timeout = self.services["timeout"]
        while True:
            hosts = Host.list(
                          self.apiclient,
                          zoneid=self.zone.id,
                          type='Routing',
                          id=host_1
                          )
            host_list_validation_result = validateList(hosts)

            self.assertEqual(host_list_validation_result[0], PASS, "host list validation failed due to %s"
                            % host_list_validation_result[2])

            host = host_list_validation_result[1]

            if host.resourcestate == 'Maintenance':
                break
            elif timeout == 0:
                self.fail("Failed to put host: %s in maintenance mode" % host.name)

            time.sleep(self.services["sleep"])
            timeout = timeout - 1

        vms = VirtualMachine.list(
                                  self.apiclient,
                                  id=virtual_machine_1.id,
                                  listall=True
                                  )
        vm_list_validation_result = validateList(vms)

        self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" %
                         vm_list_validation_result[2])

        vm = vm_list_validation_result[0]

        self.assertEqual(
                         vm.state,
                         "Running",
                         "Deployed VM should be in RUnning state"
                         )
        self.assertNotEqual(
                         vm.hostid,
                         host_2,
                         "The host name should not match with second host name"
                         )

        self.debug("Canceling host maintenance for ID: %s" % host_1.id)
        cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
        cmd.id = host_1.id
        self.apiclient.cancelHostMaintenance(cmd)
        self.debug("Maintenance mode canceled for host: %s" % host_1.id)

        return

@unittest.skip("Skipping...Host Affinity feature not available yet in cloudstack")
class TestAffinityRules(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.api_client = super(
                               TestAffinityRules,
                               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["virtual_machine"]["template"] = cls.template.id

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

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

    @classmethod
    def tearDownClass(cls):
        try:
            #Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

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

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

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

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

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

    @attr(tags = ["advanced", "vmware", "multihost"])
    def test_vmware_affinity(self):
        """ Test Set up affinity rules

            The test requires following pre-requisites
            - VMWare cluster configured in fully automated mode
        """

        # Validate the following
        # 1. Deploy 2 VMs on same hosts
        # 2. Migrate one VM from one host to another
        # 3. The second VM should also get migrated

        hosts = Host.list(
                          self.apiclient,
                          zoneid=self.zone.id,
                          resourcestate='Enabled',
                          type='Routing'
                          )
        self.assertEqual(
                         isinstance(hosts, list),
                         True,
                         "List hosts should return valid host response"
                         )
        self.assertGreaterEqual(
                         len(hosts),
                         2,
                         "There must be two hosts present in a cluster"
                        )

        host_1 = hosts[0].id

        host_2 = hosts[1].id

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

        vm_1 = VirtualMachine.create(
                              self.apiclient,
                              self.services["virtual_machine"],
                              accountid=self.account.name,
                              domainid=self.domain.id,
                              serviceofferingid=self.service_offering.id,
                              affinitygroupnames=[aff_grp.name],
                              hostid = host_1
                             )

        vm_2 = VirtualMachine.create(
                              self.apiclient,
                              self.services["virtual_machine"],
                              accountid=self.account.name,
                              domainid=self.domain.id,
                              serviceofferingid=self.service_offering.id,
                              affinitygroupnames=[aff_grp.name]
                             )

        vms = VirtualMachine.list(
                                  self.apiclient,
                                  id= vm_1.id,
                                  listall=True
                                  )

        vm_list_validation_result = validateList(vms)

        self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" %
                         vm_list_validation_result[2])

        virtual_machine_1 = vm_list_validation_result[1]

        self.assertEqual(
                         virtual_machine_1.state,
                         "Running",
                         "Deployed VM should be in RUnning state"
                         )

        self.debug("Deploying VM on account: %s" % self.account.name)

        vms = VirtualMachine.list(
                                  self.apiclient,
                                  id=vm_2.id,
                                  listall=True
                                  )
        vm_list_validation_result = validateList(vms)

        self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" %
                         vm_list_validation_result[2])

        virtual_machine_2 = vm_list_validation_result[1]

        self.assertEqual(
                         virtual_machine_2.state,
                         "Running",
                         "Deployed VM should be in RUnning state"
                         )

        self.debug("Migrate VM from host_1 to host_2")
        cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
        cmd.virtualmachineid = virtual_machine_2.id
        cmd.hostid = host_2
        self.apiclient.migrateVirtualMachine(cmd)
        self.debug("Migrated VM from host_1 to host_2")

        vms = VirtualMachine.list(
                                  self.apiclient,
                                  hostid=host_2,
                                  listall=True
                                  )
        vm_list_validation_result = validateList(vms)

        self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" %
                         vm_list_validation_result[2])

        vmids = [vm.id for vm in vms]

        self.assertIn(
                      virtual_machine_1.id,
                      vmids,
                      "VM 1 should be successfully migrated to host 2"
                      )
        self.assertIn(
                      virtual_machine_2.id,
                      vmids,
                      "VM 2 should be automatically migrated to host 2"
                      )
        return
