| # 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.api.identity.base import BaseIdentityAdminTest |
| from tempest import exceptions |
| from tempest.whitebox import manager |
| |
| |
| 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') |