# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack, LLC
# All Rights Reserved.
#
#    Licensed 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 tempest import exceptions
from tempest.test import attr
from tempest.tests.identity.base import BaseIdentityAdminTest
from tempest.whitebox import manager


@attr(type='whitebox')
class ServersWhiteboxTest(manager.ComputeWhiteboxTest):
    _interface = 'json'

    @classmethod
    def setUpClass(cls):
        raise cls.skipException("Until Bug 1034129 is fixed")
        super(ServersWhiteboxTest, cls).setUpClass()
        #NOTE(afazekas): Strange relationship
        BaseIdentityAdminTest.setUpClass()
        cls.client = cls.servers_client
        cls.img_client = cls.images_client
        cls.admin_client = BaseIdentityAdminTest.client

        cls.connection, cls.meta = cls.get_db_handle_and_meta()

        resp, tenants = cls.admin_client.list_tenants()
        cls.tenant_id = [
            tnt['id']
            for tnt in tenants if tnt['name'] == cls.config.compute.tenant_name
        ][0]

        cls.shared_server = cls.create_server()

    def tearDown(cls):
        for server in cls.servers:
            try:
                cls.client.delete_server(server['id'])
            except exceptions.NotFound:
                continue

    def test_create_server_vcpu_quota_full(self):
        # Disallow server creation when tenant's vcpu quota is full
        quotas = self.meta.tables['quotas']
        stmt = (quotas.select().
                where(quotas.c.project_id == self.tenant_id).
                where(quotas.c.resource == 'cores'))
        result = self.connection.execute(stmt).first()

        # Set vcpu quota for tenant if not already set
        if not result:
            cores_hard_limit = 2
            stmt = quotas.insert().values(deleted=0,
                                          project_id=self.tenant_id,
                                          resource='cores',
                                          hard_limit=cores_hard_limit)

            self.connection.execute(stmt, autocommit=True)
        else:
            cores_hard_limit = result.hard_limit

        # Create servers assuming 1 VCPU per instance i.e flavor_id=1
        try:
            for count in range(cores_hard_limit + 1):
                self.create_server()
        except exceptions.OverLimit:
            pass
        else:
            self.fail("Could create servers over the VCPU quota limit")
        finally:
            stmt = quotas.delete()
            self.connection.execute(stmt, autocommit=True)

    def test_create_server_memory_quota_full(self):
        # Disallow server creation when tenant's memory quota is full
        quotas = self.meta.tables['quotas']
        stmt = (quotas.select().
                where(quotas.c.project_id == self.tenant_id).
                where(quotas.c.resource == 'ram'))
        result = self.connection.execute(stmt).first()

        # Set memory quota for tenant if not already set
        if not result:
            ram_hard_limit = 1024
            stmt = quotas.insert().values(deleted=0,
                                          project_id=self.tenant_id,
                                          resource='ram',
                                          hard_limit=ram_hard_limit)

            self.connection.execute(stmt, autocommit=True)
        else:
            ram_hard_limit = result.hard_limit

        try:
            # Set a hard range of 3 servers for reaching the RAM quota
            for count in range(3):
                self.create_server()
        except exceptions.OverLimit:
            pass
        else:
            self.fail("Could create servers over the RAM quota limit")
        finally:
            stmt = quotas.delete()
            self.connection.execute(stmt, autocommit=True)

    def update_state(self, server_id, vm_state, task_state, deleted=0):
        """Update states of an instance in database for validation."""
        if not task_state:
            task_state = 'NULL'

        instances = self.meta.tables['instances']
        stmt = instances.update().where(instances.c.uuid == server_id).values(
            deleted=deleted,
            vm_state=vm_state,
            task_state=task_state)
        self.connection.execute(stmt, autocommit=True)

    def _test_delete_server_base(self, vm_state, task_state):
        """
        Base method for delete server tests based on vm and task states.
        Validates for successful server termination.
        """
        try:
            server = self.create_server()
            self.update_state(server['id'], vm_state, task_state)

            resp, body = self.client.delete_server(server['id'])
            self.assertEqual('204', resp['status'])
            self.client.wait_for_server_termination(server['id'],
                                                    ignore_error=True)

            instances = self.meta.tables['instances']
            stmt = instances.select().where(instances.c.uuid == server['id'])
            result = self.connection.execute(stmt).first()

            self.assertEqual(1, result.deleted)
            self.assertEqual('deleted', result.vm_state)
            self.assertEqual(None, result.task_state)
        except Exception:
            self.fail("Should be able to delete a server when vm_state=%s and "
                      "task_state=%s" % (vm_state, task_state))

    def _test_delete_server_403_base(self, vm_state, task_state):
        """
        Base method for delete server tests based on vm and task states.
        Validates for 403 error code.
        """
        try:
            self.update_state(self.shared_server['id'], vm_state, task_state)

            self.assertRaises(exceptions.Unauthorized,
                              self.client.delete_server,
                              self.shared_server['id'])
        except Exception:
            self.fail("Should not allow delete server when vm_state=%s and "
                      "task_state=%s" % (vm_state, task_state))
        finally:
            self.update_state(self.shared_server['id'], 'active', None)

    def test_delete_server_when_vm_eq_building_task_eq_networking(self):
        # Delete server when instance states are building,networking
        self._test_delete_server_base('building', 'networking')

    def test_delete_server_when_vm_eq_building_task_eq_bdm(self):
        # Delete server when instance states are building,block device mapping
        self._test_delete_server_base('building', 'block_device_mapping')

    def test_delete_server_when_vm_eq_building_task_eq_spawning(self):
        # Delete server when instance states are building,spawning
        self._test_delete_server_base('building', 'spawning')

    def test_delete_server_when_vm_eq_active_task_eq_image_backup(self):
        # Delete server when instance states are active,image_backup
        self._test_delete_server_base('active', 'image_backup')

    def test_delete_server_when_vm_eq_active_task_eq_rebuilding(self):
        # Delete server when instance states are active,rebuilding
        self._test_delete_server_base('active', 'rebuilding')

    def test_delete_server_when_vm_eq_error_task_eq_spawning(self):
        # Delete server when instance states are error,spawning
        self._test_delete_server_base('error', 'spawning')

    def test_delete_server_when_vm_eq_resized_task_eq_resize_prep(self):
        # Delete server when instance states are resized,resize_prep
        self._test_delete_server_403_base('resized', 'resize_prep')

    def test_delete_server_when_vm_eq_resized_task_eq_resize_migrating(self):
        # Delete server when instance states are resized,resize_migrating
        self._test_delete_server_403_base('resized', 'resize_migrating')

    def test_delete_server_when_vm_eq_resized_task_eq_resize_migrated(self):
        # Delete server when instance states are resized,resize_migrated
        self._test_delete_server_403_base('resized', 'resize_migrated')

    def test_delete_server_when_vm_eq_resized_task_eq_resize_finish(self):
        # Delete server when instance states are resized,resize_finish
        self._test_delete_server_403_base('resized', 'resize_finish')

    def test_delete_server_when_vm_eq_resized_task_eq_resize_reverting(self):
        # Delete server when instance states are resized,resize_reverting
        self._test_delete_server_403_base('resized', 'resize_reverting')

    def test_delete_server_when_vm_eq_resized_task_eq_resize_confirming(self):
        # Delete server when instance states are resized,resize_confirming
        self._test_delete_server_403_base('resized', 'resize_confirming')

    def test_delete_server_when_vm_eq_active_task_eq_resize_verify(self):
        # Delete server when instance states are active,resize_verify
        self._test_delete_server_base('active', 'resize_verify')

    def test_delete_server_when_vm_eq_active_task_eq_rebooting(self):
        # Delete server when instance states are active,rebooting
        self._test_delete_server_base('active', 'rebooting')

    def test_delete_server_when_vm_eq_building_task_eq_deleting(self):
        # Delete server when instance states are building,deleting
        self._test_delete_server_base('building', 'deleting')

    def test_delete_server_when_vm_eq_active_task_eq_deleting(self):
        # Delete server when instance states are active,deleting
        self._test_delete_server_base('active', 'deleting')

    def test_delete_server_when_vm_eq_error_task_eq_none(self):
        # Delete server when instance states are error,None
        self._test_delete_server_base('error', None)

    def test_delete_server_when_vm_eq_resized_task_eq_none(self):
        # Delete server when instance states are resized,None
        self._test_delete_server_403_base('resized', None)

    def test_delete_server_when_vm_eq_error_task_eq_resize_prep(self):
        # Delete server when instance states are error,resize_prep
        self._test_delete_server_base('error', 'resize_prep')

    def test_delete_server_when_vm_eq_error_task_eq_error(self):
        # Delete server when instance states are error,error
        self._test_delete_server_base('error', 'error')
