Fix benchmark.utils.get_from_manager()
* get_from_manager() method should raise exception in case of unexisting resources. So we will be able to handle this in proper way and avoid __getitem__ exception. * Add rally.utils.wait_for_delete() that will update resource unit it raise excetpion (not found). * Use rally.utils.wait_for_delete() in all methods that delete resources * Add part of missing tests for benchmark.utils methods Change-Id: If9fed2418c61de9f18023b2d2cc1fd81673d9379 Closes-Bug: #1269307
This commit is contained in:
@@ -71,6 +71,6 @@ class CinderScenario(base.Scenario):
|
||||
:param volume: volume object
|
||||
"""
|
||||
volume.delete()
|
||||
utils.wait_for(volume, is_ready=bench_utils.is_none,
|
||||
update_resource=bench_utils.get_from_manager(),
|
||||
timeout=600, check_interval=2)
|
||||
utils.wait_for_delete(volume,
|
||||
update_resource=bench_utils.get_from_manager(),
|
||||
timeout=600, check_interval=2)
|
||||
|
@@ -155,9 +155,9 @@ class NovaScenario(base.Scenario):
|
||||
:param server: Server object
|
||||
"""
|
||||
server.delete()
|
||||
utils.wait_for(server, is_ready=bench_utils.is_none,
|
||||
update_resource=bench_utils.get_from_manager(),
|
||||
timeout=600, check_interval=3)
|
||||
utils.wait_for_delete(server,
|
||||
update_resource=bench_utils.get_from_manager(),
|
||||
timeout=600, check_interval=3)
|
||||
|
||||
@scenario_utils.atomic_action_timer('nova.delete_all_servers')
|
||||
def _delete_all_servers(self):
|
||||
@@ -175,9 +175,9 @@ class NovaScenario(base.Scenario):
|
||||
:param image: Image object
|
||||
"""
|
||||
image.delete()
|
||||
utils.wait_for(image, is_ready=bench_utils.resource_is("DELETED"),
|
||||
update_resource=bench_utils.get_from_manager(),
|
||||
timeout=600, check_interval=3)
|
||||
utils.wait_for_delete(image,
|
||||
update_resource=bench_utils.get_from_manager(),
|
||||
timeout=600, check_interval=3)
|
||||
|
||||
@scenario_utils.atomic_action_timer('nova.create_image')
|
||||
def _create_image(self, server):
|
||||
|
@@ -39,11 +39,14 @@ def get_from_manager(error_statuses=None):
|
||||
try:
|
||||
resource = resource.manager.get(resource.id)
|
||||
except Exception as e:
|
||||
if getattr(e, 'http_status', 400) == 404:
|
||||
return None
|
||||
raise e
|
||||
if resource.status.upper() in error_statuses:
|
||||
raise rally_exceptions.GetResourceFailure(status=resource.status)
|
||||
if getattr(e, 'code', 400) == 404:
|
||||
raise rally_exceptions.GetResourceNotFound(status="404")
|
||||
raise rally_exceptions.GetResourceFailure(status=e)
|
||||
status = resource.status.upper()
|
||||
if status == "DELETED":
|
||||
raise rally_exceptions.GetResourceNotFound(status="404")
|
||||
if status in error_statuses:
|
||||
raise rally_exceptions.GetResourceErrorStatus(status=status)
|
||||
return resource
|
||||
|
||||
return _get_from_manager
|
||||
|
@@ -136,8 +136,15 @@ class TimeoutException(RallyException):
|
||||
|
||||
|
||||
class GetResourceFailure(RallyException):
|
||||
msg_fmt = _("Failed to get the resource due to invalid status:"
|
||||
"`%(status)s`")
|
||||
msg_fmt = _("Failed to get the resource: '`%(status)s`'")
|
||||
|
||||
|
||||
class GetResourceNotFound(GetResourceFailure):
|
||||
msg_fmt = _("Resource not found: `%(status)s`")
|
||||
|
||||
|
||||
class GetResourceErrorStatus(GetResourceFailure):
|
||||
msg_fmt = _("Resouce has invalid status: `%(status)s`")
|
||||
|
||||
|
||||
class SSHError(RallyException):
|
||||
|
@@ -158,6 +158,31 @@ def wait_for(resource, is_ready, update_resource=None, timeout=60,
|
||||
return resource
|
||||
|
||||
|
||||
def wait_for_delete(resource, update_resource=None, timeout=60,
|
||||
check_interval=1):
|
||||
"""Waits for the full deletion of resource.
|
||||
|
||||
:param update_resource: Function that should take the resource object
|
||||
and return an 'updated' resource, or raise
|
||||
exception rally.exceptions.GetResourceNotFound
|
||||
that means that resource is deleted.
|
||||
|
||||
:param timeout: Timeout in seconds after which a TimeoutException will be
|
||||
raised
|
||||
:param check_interval: Interval in seconds between the two consecutive
|
||||
readiness checks
|
||||
"""
|
||||
start = time.time()
|
||||
while True:
|
||||
try:
|
||||
resource = update_resource(resource)
|
||||
except exceptions.GetResourceNotFound:
|
||||
break
|
||||
time.sleep(check_interval)
|
||||
if time.time() - start > timeout:
|
||||
raise exceptions.TimeoutException()
|
||||
|
||||
|
||||
def log_task_wrapper(log, msg, **kw):
|
||||
"""A logging wrapper for any method of a class.
|
||||
|
||||
|
@@ -37,6 +37,9 @@ class NovaScenarioTestCase(test.TestCase):
|
||||
self.res_is = mockpatch.Patch(BM_UTILS + ".resource_is")
|
||||
self.get_fm = mockpatch.Patch(BM_UTILS + '.get_from_manager')
|
||||
self.wait_for = mockpatch.Patch(NOVA_UTILS + ".utils.wait_for")
|
||||
self.wait_for_delete = mockpatch.Patch(NOVA_UTILS +
|
||||
".utils.wait_for_delete")
|
||||
self.useFixture(self.wait_for_delete)
|
||||
self.useFixture(self.wait_for)
|
||||
self.useFixture(self.res_is)
|
||||
self.useFixture(self.get_fm)
|
||||
@@ -111,11 +114,10 @@ class NovaScenarioTestCase(test.TestCase):
|
||||
nova_scenario = utils.NovaScenario()
|
||||
nova_scenario._delete_server(self.server)
|
||||
self.server.delete.assert_called_once_with()
|
||||
self.wait_for.mock.assert_called_once_with(self.server,
|
||||
is_ready=mock_isnone,
|
||||
update_resource=self.gfm(),
|
||||
check_interval=3,
|
||||
timeout=600)
|
||||
self.wait_for_delete.mock.assert_called_once_with(
|
||||
self.server,
|
||||
update_resource=self.gfm(),
|
||||
check_interval=3, timeout=600)
|
||||
self._test_atomic_action_timer(nova_scenario.atomic_actions_time(),
|
||||
'nova.delete_server')
|
||||
|
||||
@@ -192,14 +194,12 @@ class NovaScenarioTestCase(test.TestCase):
|
||||
nova_scenario = utils.NovaScenario()
|
||||
nova_scenario._delete_all_servers()
|
||||
expected = [
|
||||
mock.call(self.server, is_ready=mock_isnone,
|
||||
update_resource=self.gfm(),
|
||||
mock.call(self.server, update_resource=self.gfm(),
|
||||
check_interval=3, timeout=600),
|
||||
mock.call(self.server1, is_ready=mock_isnone,
|
||||
update_resource=self.gfm(),
|
||||
mock.call(self.server1, update_resource=self.gfm(),
|
||||
check_interval=3, timeout=600)
|
||||
]
|
||||
self.assertEqual(expected, self.wait_for.mock.mock_calls)
|
||||
self.assertEqual(expected, self.wait_for_delete.mock.mock_calls)
|
||||
self._test_atomic_action_timer(nova_scenario.atomic_actions_time(),
|
||||
'nova.delete_all_servers')
|
||||
|
||||
@@ -207,12 +207,9 @@ class NovaScenarioTestCase(test.TestCase):
|
||||
nova_scenario = utils.NovaScenario()
|
||||
nova_scenario._delete_image(self.image)
|
||||
self.image.delete.assert_called_once_with()
|
||||
self.wait_for.mock.assert_called_once_with(self.image,
|
||||
update_resource=self.gfm(),
|
||||
is_ready=self.res_is.mock(),
|
||||
check_interval=3,
|
||||
timeout=600)
|
||||
self.res_is.mock.assert_has_calls(mock.call('DELETED'))
|
||||
self.wait_for_delete.mock.assert_called_once_with(
|
||||
self.image, update_resource=self.gfm(),
|
||||
check_interval=3, timeout=600)
|
||||
self._test_atomic_action_timer(nova_scenario.atomic_actions_time(),
|
||||
'nova.delete_image')
|
||||
|
||||
|
109
tests/benchmark/test_utils.py
Normal file
109
tests/benchmark/test_utils.py
Normal file
@@ -0,0 +1,109 @@
|
||||
# Copyright 2013: Mirantis Inc.
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from tests import fakes
|
||||
from tests import test
|
||||
|
||||
from rally.benchmark import utils
|
||||
from rally import exceptions
|
||||
|
||||
|
||||
class BenchmarkUtilsTestCase(test.TestCase):
|
||||
|
||||
def test_resource_is(self):
|
||||
is_active = utils.resource_is("ACTIVE")
|
||||
self.assertTrue(is_active(fakes.FakeResource(status="active")))
|
||||
self.assertTrue(is_active(fakes.FakeResource(status="aCtIvE")))
|
||||
self.assertFalse(is_active(fakes.FakeResource(status="ERROR")))
|
||||
|
||||
def test_is_none(self):
|
||||
self.assertTrue(utils.is_none(None))
|
||||
self.assertFalse(utils.is_none(0))
|
||||
self.assertFalse(utils.is_none(""))
|
||||
self.assertFalse(utils.is_none("afafa"))
|
||||
|
||||
def test_false(self):
|
||||
self.assertFalse(utils.false(None))
|
||||
|
||||
def test_async_clenaup(self):
|
||||
cls = mock.MagicMock()
|
||||
indicies = {}
|
||||
utils.async_cleanup(cls, indicies)
|
||||
cls._cleanup_with_clients.assert_called_once_with(indicies)
|
||||
|
||||
def test_infinite_run_args(self):
|
||||
args = ("a", "b", "c", "d", 123)
|
||||
for i, real_args in enumerate(utils.infinite_run_args(args)):
|
||||
self.assertEqual((i,) + args, real_args)
|
||||
if i == 10:
|
||||
break
|
||||
|
||||
def test_create_openstack_clients(self):
|
||||
#TODO(boris-42): Implement this method
|
||||
pass
|
||||
|
||||
def test_manager_list_sizes(self):
|
||||
manager = fakes.FakeManager()
|
||||
|
||||
def lst():
|
||||
return [1] * 10
|
||||
|
||||
manager.list = lst
|
||||
manager_list_size = utils.manager_list_size([5])
|
||||
self.assertFalse(manager_list_size(manager))
|
||||
|
||||
manager_list_size = utils.manager_list_size([10])
|
||||
self.assertTrue(manager_list_size(manager))
|
||||
|
||||
def test_get_from_manager(self):
|
||||
get_from_manager = utils.get_from_manager()
|
||||
manager = fakes.FakeManager()
|
||||
resource = fakes.FakeResource(manager=manager)
|
||||
manager._cache(resource)
|
||||
self.assertEqual(get_from_manager(resource), resource)
|
||||
|
||||
def test_get_from_manager_in_error_state(self):
|
||||
get_from_manager = utils.get_from_manager()
|
||||
manager = fakes.FakeManager()
|
||||
resource = fakes.FakeResource(manager=manager, status="ERROR")
|
||||
manager._cache(resource)
|
||||
self.assertRaises(exceptions.GetResourceFailure,
|
||||
get_from_manager, resource)
|
||||
|
||||
def test_get_from_manager_not_found(self):
|
||||
get_from_manager = utils.get_from_manager()
|
||||
manager = mock.MagicMock()
|
||||
resource = fakes.FakeResource(manager=manager, status="ERROR")
|
||||
|
||||
class NotFoundException(Exception):
|
||||
http_status = 404
|
||||
|
||||
manager.get = mock.MagicMock(side_effect=NotFoundException)
|
||||
self.assertRaises(exceptions.GetResourceFailure,
|
||||
get_from_manager, resource)
|
||||
|
||||
def test_get_from_manager_http_exception(self):
|
||||
get_from_manager = utils.get_from_manager()
|
||||
manager = mock.MagicMock()
|
||||
resource = fakes.FakeResource(manager=manager, status="ERROR")
|
||||
|
||||
class HTTPException(Exception):
|
||||
pass
|
||||
|
||||
manager.get = mock.MagicMock(side_effect=HTTPException)
|
||||
self.assertRaises(exceptions.GetResourceFailure,
|
||||
get_from_manager, resource)
|
@@ -22,9 +22,9 @@ from rally import utils as rally_utils
|
||||
|
||||
class FakeResource(object):
|
||||
|
||||
def __init__(self, manager=None, name=None):
|
||||
def __init__(self, manager=None, name=None, status="ACTIVE"):
|
||||
self.name = name or uuid.uuid4()
|
||||
self.status = "ACTIVE"
|
||||
self.status = status
|
||||
self.manager = manager
|
||||
self.uuid = uuid.uuid4()
|
||||
self.id = self.uuid
|
||||
|
Reference in New Issue
Block a user