Merge "Refactored cleaner and added cleanup/utils"
This commit is contained in:
0
rally/benchmark/context/cleanup/__init__.py
Normal file
0
rally/benchmark/context/cleanup/__init__.py
Normal file
@@ -17,7 +17,7 @@ import functools
|
||||
import sys
|
||||
|
||||
from rally.benchmark.context import base
|
||||
from rally.benchmark import utils
|
||||
from rally.benchmark.context.cleanup import utils
|
||||
from rally.openstack.common.gettextutils import _
|
||||
from rally.openstack.common import log as logging
|
||||
from rally import osclients
|
||||
@@ -100,17 +100,3 @@ class ResourceCleaner(base.Context):
|
||||
self._cleanup_users_resources()
|
||||
if self.admin:
|
||||
self._cleanup_admin_resources()
|
||||
|
||||
|
||||
def cleanup(services):
|
||||
"""Decorates scenario methods requiring a cleanup of resources.
|
||||
|
||||
If a scenario method is not decorated by @cleanup all the resources
|
||||
(nova, glance and cinder) will be cleaned.
|
||||
|
||||
:param services: list of services which will be cleaned.
|
||||
"""
|
||||
def wrap(func):
|
||||
func.cleanup_services = services
|
||||
return func
|
||||
return wrap
|
123
rally/benchmark/context/cleanup/utils.py
Normal file
123
rally/benchmark/context/cleanup/utils.py
Normal file
@@ -0,0 +1,123 @@
|
||||
# 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 logging
|
||||
|
||||
from rally.benchmark.scenarios.keystone import utils as kutils
|
||||
from rally.benchmark import utils as bench_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def delete_cinder_resources(cinder):
|
||||
delete_volume_transfers(cinder)
|
||||
delete_volumes(cinder)
|
||||
delete_volume_snapshots(cinder)
|
||||
delete_volume_backups(cinder)
|
||||
|
||||
|
||||
def delete_glance_resources(glance, project_uuid):
|
||||
delete_images(glance, project_uuid)
|
||||
|
||||
|
||||
def delete_keystone_resources(keystone):
|
||||
for resource in ["users", "tenants", "services", "roles"]:
|
||||
_delete_single_keystone_resource_type(keystone, resource)
|
||||
|
||||
|
||||
def _delete_single_keystone_resource_type(keystone, resource_name):
|
||||
for resource in getattr(keystone, resource_name).list():
|
||||
if kutils.is_temporary(resource):
|
||||
resource.delete()
|
||||
|
||||
|
||||
def delete_images(glance, project_uuid):
|
||||
for image in glance.images.list(owner=project_uuid):
|
||||
image.delete()
|
||||
_wait_for_list_statuses(glance.images, statuses=["DELETED"],
|
||||
list_query={'owner': project_uuid},
|
||||
timeout=600, check_interval=3)
|
||||
|
||||
|
||||
def delete_quotas(admin_clients, project_uuid):
|
||||
# TODO(yingjun): We need to add the cinder part for deleting
|
||||
# quotas when the new cinderclient released.
|
||||
admin_clients.nova().quotas.delete(project_uuid)
|
||||
|
||||
|
||||
def delete_volumes(cinder):
|
||||
for vol in cinder.volumes.list():
|
||||
vol.delete()
|
||||
_wait_for_empty_list(cinder.volumes, timeout=120)
|
||||
|
||||
|
||||
def delete_volume_transfers(cinder):
|
||||
for transfer in cinder.transfers.list():
|
||||
transfer.delete()
|
||||
_wait_for_empty_list(cinder.transfers)
|
||||
|
||||
|
||||
def delete_volume_snapshots(cinder):
|
||||
for snapshot in cinder.volume_snapshots.list():
|
||||
snapshot.delete()
|
||||
_wait_for_empty_list(cinder.volume_snapshots, timeout=240)
|
||||
|
||||
|
||||
def delete_volume_backups(cinder):
|
||||
for backup in cinder.backups.list():
|
||||
backup.delete()
|
||||
_wait_for_empty_list(cinder.backups, timeout=240)
|
||||
|
||||
|
||||
def delete_nova_resources(nova):
|
||||
delete_servers(nova)
|
||||
delete_keypairs(nova)
|
||||
|
||||
|
||||
def delete_servers(nova):
|
||||
for server in nova.servers.list():
|
||||
server.delete()
|
||||
_wait_for_empty_list(nova.servers, timeout=600, check_interval=3)
|
||||
|
||||
|
||||
def delete_keypairs(nova):
|
||||
for keypair in nova.keypairs.list():
|
||||
keypair.delete()
|
||||
_wait_for_empty_list(nova.keypairs)
|
||||
|
||||
|
||||
def _wait_for_empty_list(mgr, timeout=10, check_interval=1):
|
||||
_wait_for_list_size(mgr, sizes=[0], timeout=timeout,
|
||||
check_interval=check_interval)
|
||||
|
||||
|
||||
def _wait_for_list_size(mgr, sizes=[0], timeout=10, check_interval=1):
|
||||
bench_utils.wait_for(mgr, is_ready=bench_utils.manager_list_size(sizes),
|
||||
update_resource=None, timeout=timeout,
|
||||
check_interval=check_interval)
|
||||
|
||||
|
||||
def _wait_for_list_statuses(mgr, statuses, list_query=None,
|
||||
timeout=10, check_interval=1):
|
||||
list_query = list_query or {}
|
||||
|
||||
def _list_statuses(mgr):
|
||||
for resource in mgr.list(**list_query):
|
||||
if resource.status not in statuses:
|
||||
return False
|
||||
return True
|
||||
|
||||
bench_utils.wait_for(mgr, is_ready=_list_statuses, update_resource=None,
|
||||
timeout=timeout, check_interval=check_interval)
|
@@ -15,7 +15,6 @@
|
||||
|
||||
import json
|
||||
|
||||
from rally.benchmark.context import cleaner as context_cleaner
|
||||
from rally.benchmark.scenarios import base
|
||||
from rally.benchmark.scenarios.nova import utils as nova_utils
|
||||
from rally.benchmark.scenarios.vm import utils as vm_utils
|
||||
@@ -32,7 +31,6 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(VMTasks, self).__init__(*args, **kwargs)
|
||||
|
||||
@context_cleaner.cleanup(['nova'])
|
||||
@valid.add_validator(valid.image_valid_on_flavor("flavor_id", "image_id"))
|
||||
@valid.add_validator(valid.file_exists("script"))
|
||||
@valid.add_validator(valid.number("port", minval=1, maxval=65535,
|
||||
|
@@ -20,7 +20,6 @@ import time
|
||||
import traceback
|
||||
|
||||
from novaclient.v1_1 import servers
|
||||
from rally.benchmark.scenarios.keystone import utils as kutils
|
||||
from rally import exceptions
|
||||
|
||||
|
||||
@@ -113,33 +112,9 @@ def wait_for(resource, is_ready, update_resource=None, timeout=60,
|
||||
return resource
|
||||
|
||||
|
||||
def _wait_for_list_statuses(mgr, statuses, list_query=None,
|
||||
timeout=10, check_interval=1):
|
||||
list_query = list_query or {}
|
||||
|
||||
def _list_statuses(mgr):
|
||||
for resource in mgr.list(**list_query):
|
||||
if resource.status not in statuses:
|
||||
return False
|
||||
return True
|
||||
|
||||
wait_for(mgr, is_ready=_list_statuses, update_resource=None,
|
||||
timeout=timeout, check_interval=check_interval)
|
||||
|
||||
|
||||
def _wait_for_empty_list(mgr, timeout=10, check_interval=1):
|
||||
_wait_for_list_size(mgr, sizes=[0], timeout=timeout,
|
||||
check_interval=check_interval)
|
||||
|
||||
|
||||
def _wait_for_list_size(mgr, sizes=[0], timeout=10, check_interval=1):
|
||||
wait_for(mgr, is_ready=manager_list_size(sizes), update_resource=None,
|
||||
timeout=timeout, check_interval=check_interval)
|
||||
|
||||
|
||||
def wait_for_delete(resource, update_resource=None, timeout=60,
|
||||
check_interval=1):
|
||||
"""Waits for the full deletion of resource.
|
||||
"""Wait for the full deletion of resource.
|
||||
|
||||
:param update_resource: Function that should take the resource object
|
||||
and return an 'updated' resource, or raise
|
||||
@@ -186,80 +161,3 @@ def run_concurrent(concurrent, fn, fn_args):
|
||||
pool.join()
|
||||
|
||||
return iterator
|
||||
|
||||
|
||||
def delete_servers(nova):
|
||||
for server in nova.servers.list():
|
||||
server.delete()
|
||||
_wait_for_empty_list(nova.servers, timeout=600, check_interval=3)
|
||||
|
||||
|
||||
def delete_keypairs(nova):
|
||||
for keypair in nova.keypairs.list():
|
||||
keypair.delete()
|
||||
_wait_for_empty_list(nova.keypairs)
|
||||
|
||||
|
||||
def delete_images(glance, project_uuid):
|
||||
for image in glance.images.list(owner=project_uuid):
|
||||
image.delete()
|
||||
_wait_for_list_statuses(glance.images, statuses=["DELETED"],
|
||||
list_query={'owner': project_uuid},
|
||||
timeout=600, check_interval=3)
|
||||
|
||||
|
||||
def delete_volumes(cinder):
|
||||
for vol in cinder.volumes.list():
|
||||
vol.delete()
|
||||
_wait_for_empty_list(cinder.volumes, timeout=120)
|
||||
|
||||
|
||||
def delete_volume_transfers(cinder):
|
||||
for transfer in cinder.transfers.list():
|
||||
transfer.delete()
|
||||
_wait_for_empty_list(cinder.transfers)
|
||||
|
||||
|
||||
def delete_volume_snapshots(cinder):
|
||||
for snapshot in cinder.volume_snapshots.list():
|
||||
snapshot.delete()
|
||||
_wait_for_empty_list(cinder.volume_snapshots, timeout=240)
|
||||
|
||||
|
||||
def delete_volume_backups(cinder):
|
||||
for backup in cinder.backups.list():
|
||||
backup.delete()
|
||||
_wait_for_empty_list(cinder.backups, timeout=240)
|
||||
|
||||
|
||||
def delete_keystone_resources(keystone):
|
||||
for resource in ["users", "tenants", "services", "roles"]:
|
||||
_delete_single_keystone_resource_type(keystone, resource)
|
||||
|
||||
|
||||
def _delete_single_keystone_resource_type(keystone, resource_name):
|
||||
for resource in getattr(keystone, resource_name).list():
|
||||
if kutils.is_temporary(resource):
|
||||
resource.delete()
|
||||
|
||||
|
||||
def delete_nova_resources(nova):
|
||||
delete_servers(nova)
|
||||
delete_keypairs(nova)
|
||||
|
||||
|
||||
def delete_cinder_resources(cinder):
|
||||
delete_volume_transfers(cinder)
|
||||
delete_volumes(cinder)
|
||||
delete_volume_snapshots(cinder)
|
||||
delete_volume_backups(cinder)
|
||||
|
||||
|
||||
def delete_glance_resources(glance, project_uuid):
|
||||
delete_images(glance, project_uuid)
|
||||
|
||||
|
||||
def delete_quotas(admin_clients, project_uuid):
|
||||
# TODO(yingjun): We need to add the cinder part for deleting
|
||||
# quotas when the new cinderclient released.
|
||||
admin_clients.nova().quotas.delete(project_uuid)
|
||||
|
0
tests/benchmark/context/cleanup/__init__.py
Normal file
0
tests/benchmark/context/cleanup/__init__.py
Normal file
@@ -15,13 +15,13 @@
|
||||
|
||||
import mock
|
||||
|
||||
from rally.benchmark.context import cleaner as cleaner_ctx
|
||||
from rally.benchmark.context.cleanup import cleanup as cleanup_ctx
|
||||
|
||||
from tests import fakes
|
||||
from tests import test
|
||||
|
||||
|
||||
BASE = "rally.benchmark.context.cleaner"
|
||||
BASE = "rally.benchmark.context.cleanup.cleanup"
|
||||
|
||||
|
||||
class ResourceCleanerTestCase(test.TestCase):
|
||||
@@ -33,14 +33,14 @@ class ResourceCleanerTestCase(test.TestCase):
|
||||
"users": [],
|
||||
"tenants": [],
|
||||
}
|
||||
resource_cleaner = cleaner_ctx.ResourceCleaner(context)
|
||||
resource_cleaner = cleanup_ctx.ResourceCleaner(context)
|
||||
with resource_cleaner:
|
||||
resource_cleaner.setup()
|
||||
|
||||
def test_with_statement(self):
|
||||
fake_user_ctx = fakes.FakeUserContext({}).context
|
||||
fake_user_ctx["config"] = {"cleanup": ["nova"]}
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner(fake_user_ctx)
|
||||
res_cleaner = cleanup_ctx.ResourceCleaner(fake_user_ctx)
|
||||
res_cleaner.setup()
|
||||
|
||||
res_cleaner._cleanup_users_resources = mock.MagicMock()
|
||||
@@ -60,7 +60,7 @@ class ResourceCleanerTestCase(test.TestCase):
|
||||
"config": {"cleanup": ["cinder", "nova"]},
|
||||
"admin": {"endpoint": mock.MagicMock()},
|
||||
}
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner(context)
|
||||
res_cleaner = cleanup_ctx.ResourceCleaner(context)
|
||||
|
||||
mock_clients.return_value.keystone.return_value = 'keystone'
|
||||
|
||||
@@ -85,7 +85,7 @@ class ResourceCleanerTestCase(test.TestCase):
|
||||
"config": {"cleanup": ["cinder", "nova", "glance"]},
|
||||
"tenants": [mock.MagicMock()]
|
||||
}
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner(context)
|
||||
res_cleaner = cleanup_ctx.ResourceCleaner(context)
|
||||
|
||||
with res_cleaner:
|
||||
res_cleaner.setup()
|
||||
@@ -105,7 +105,7 @@ class ResourceCleanerTestCase(test.TestCase):
|
||||
"users": [{"endpoint": mock.MagicMock()},
|
||||
{"endpoint": mock.MagicMock()}],
|
||||
}
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner(context)
|
||||
res_cleaner = cleanup_ctx.ResourceCleaner(context)
|
||||
|
||||
with res_cleaner:
|
||||
res_cleaner.setup()
|
||||
@@ -125,7 +125,7 @@ class ResourceCleanerTestCase(test.TestCase):
|
||||
"config": {"cleanup": ["cinder", "nova"]},
|
||||
"tenants": [mock.MagicMock()]
|
||||
}
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner(context)
|
||||
res_cleaner = cleanup_ctx.ResourceCleaner(context)
|
||||
|
||||
with res_cleaner:
|
||||
res_cleaner.setup()
|
@@ -114,7 +114,7 @@ class WaitForTestCase(test.TestCase):
|
||||
self.resource = object()
|
||||
self.load_secs = 0.01
|
||||
self.fake_checker_delayed = self.get_fake_checker_delayed(
|
||||
seconds=self.load_secs)
|
||||
seconds=self.load_secs)
|
||||
|
||||
def get_fake_checker_delayed(self, **delay):
|
||||
deadline = datetime.datetime.now() + datetime.timedelta(**delay)
|
||||
|
Reference in New Issue
Block a user