# 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
import unittest

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

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

from marvin.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.testClient = super(TestVMPlacement, cls).getClsTestClient()
        if cls.testClient.getHypervisorInfo().lower() != "vmware":
            raise unittest.SkipTest("VMWare tests only valid on VMWare hypervisor")
        cls.api_client = cls.testClient.getApiClient()

        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client)
        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
        cls.pod = get_pod(
                          cls.api_client,
                          zone_id=cls.zone.id)
        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

    @unittest.skip("Test case is not testable as the VM is being deployed with\
    too high memory - above account capacity")
    @attr(tags=["invalid"], required_hardware="true")
    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.testClient = super(TestAntiAffinityRules, cls).getClsTestClient()
        if cls.testClient.getHypervisorInfo().lower() != "vmware":
            raise unittest.SkipTest("VMWare tests only valid on VMWare hypervisor")
        cls.api_client = cls.testClient.getApiClient()

        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client)
        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
        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"], required_hardware="true")
    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.testClient = super(TestAffinityRules, cls).getClsTestClient()
        if cls.testClient.getHypervisorInfo().lower() != "vmware":
            raise unittest.SkipTest("VMWare tests only valid on VMWare hypervisor")
        cls.api_client = cls.testClient.getApiClient()

        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client)
        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
        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"], required_hardware="true")
    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
