Prepare for real benchmark context support
Move already existing context objects from benchmark.runner to separated modules in benchmark.context module. partial bp benchmark-context Change-Id: Ib00082c521288f358fd8a1cb9fe73c9d74ab145e
This commit is contained in:
parent
30b8b619b2
commit
a3963a0920
0
rally/benchmark/context/__init__.py
Normal file
0
rally/benchmark/context/__init__.py
Normal file
82
rally/benchmark/context/cleaner.py
Normal file
82
rally/benchmark/context/cleaner.py
Normal file
@ -0,0 +1,82 @@
|
||||
# Copyright 2014: 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 functools
|
||||
import itertools
|
||||
import sys
|
||||
|
||||
from rally.benchmark import utils
|
||||
from rally.openstack.common.gettextutils import _
|
||||
from rally.openstack.common import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ResourceCleaner(object):
|
||||
"""Context class for resource cleanup (both admin and non-admin)."""
|
||||
|
||||
def __init__(self, admin=None, users=None):
|
||||
self.admin = admin
|
||||
self.users = users
|
||||
|
||||
def _cleanup_users_resources(self):
|
||||
if not self.users:
|
||||
return
|
||||
|
||||
for user in itertools.imap(utils.create_openstack_clients, self.users):
|
||||
methods = [
|
||||
functools.partial(utils.delete_nova_resources, user["nova"]),
|
||||
functools.partial(utils.delete_glance_resources,
|
||||
user["glance"], user["keystone"]),
|
||||
functools.partial(utils.delete_cinder_resources,
|
||||
user["cinder"])
|
||||
]
|
||||
|
||||
for method in methods:
|
||||
try:
|
||||
method()
|
||||
except Exception as e:
|
||||
LOG.debug(_("Not all resources were cleaned."),
|
||||
exc_info=sys.exc_info())
|
||||
LOG.warning(_('Unable to fully cleanup the cloud: \n%s') %
|
||||
(e.message))
|
||||
|
||||
def _cleanup_admin_resources(self):
|
||||
if not self.admin:
|
||||
return
|
||||
|
||||
try:
|
||||
admin = utils.create_openstack_clients(self.admin)
|
||||
utils.delete_keystone_resources(admin["keystone"])
|
||||
except Exception as e:
|
||||
LOG.debug(_("Not all resources were cleaned."),
|
||||
exc_info=sys.exc_info())
|
||||
LOG.warning(_('Unable to fully cleanup keystone service: %s') %
|
||||
(e.message))
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||
self._cleanup_users_resources()
|
||||
self._cleanup_admin_resources()
|
||||
|
||||
if exc_type:
|
||||
LOG.debug(_("An error occurred while launching "
|
||||
"the benchmark scenario."),
|
||||
exc_info=(exc_type, exc_value, exc_traceback))
|
||||
else:
|
||||
LOG.debug(_("Completed resources cleanup."))
|
88
rally/benchmark/context/users.py
Normal file
88
rally/benchmark/context/users.py
Normal file
@ -0,0 +1,88 @@
|
||||
# Copyright 2014: 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 uuid
|
||||
|
||||
from rally.benchmark import utils
|
||||
from rally import consts
|
||||
from rally.objects import endpoint
|
||||
from rally.openstack.common.gettextutils import _
|
||||
from rally.openstack.common import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UserGenerator(object):
|
||||
"""Context class for generating temporary users/tenants for benchmarks."""
|
||||
|
||||
def __init__(self, admin_endpoints):
|
||||
self.users = []
|
||||
self.tenants = []
|
||||
self.keystone_client = \
|
||||
utils.create_openstack_clients(admin_endpoints)["keystone"]
|
||||
|
||||
def _create_user(self, user_id, tenant_id):
|
||||
pattern = "%(tenant_id)s_user_%(uid)d"
|
||||
name = pattern % {"tenant_id": tenant_id, "uid": user_id}
|
||||
email = "%s@email.me" % name
|
||||
return self.keystone_client.users.create(name, "password",
|
||||
email, tenant_id)
|
||||
|
||||
def _create_tenant(self, run_id, i):
|
||||
pattern = "temp_%(run_id)s_tenant_%(iter)i"
|
||||
return self.keystone_client.tenants.create(pattern % {"run_id": run_id,
|
||||
"iter": i})
|
||||
|
||||
def create_users_and_tenants(self, tenants, users_per_tenant):
|
||||
run_id = str(uuid.uuid4())
|
||||
auth_url = self.keystone_client.auth_url
|
||||
self.tenants = [self._create_tenant(run_id, i)
|
||||
for i in range(tenants)]
|
||||
self.users = []
|
||||
endpoints = []
|
||||
for tenant in self.tenants:
|
||||
for user_id in range(users_per_tenant):
|
||||
user = self._create_user(user_id, tenant.id)
|
||||
self.users.append(user)
|
||||
endpoints.append(endpoint.Endpoint(
|
||||
auth_url, user.name, "password", tenant.name,
|
||||
consts.EndpointPermission.USER))
|
||||
return endpoints
|
||||
|
||||
def _delete_users_and_tenants(self):
|
||||
for user in self.users:
|
||||
try:
|
||||
user.delete()
|
||||
except Exception:
|
||||
LOG.info("Failed to delete user: %s" % user.name)
|
||||
|
||||
for tenant in self.tenants:
|
||||
try:
|
||||
tenant.delete()
|
||||
except Exception:
|
||||
LOG.info("Failed to delete tenant: %s" % tenant.name)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||
self._delete_users_and_tenants()
|
||||
|
||||
if exc_type:
|
||||
LOG.debug(_("Failed to generate temporary users."),
|
||||
exc_info=(exc_type, exc_value, exc_traceback))
|
||||
else:
|
||||
LOG.debug(_("Completed deleting temporary users and tenants."))
|
@ -17,6 +17,7 @@ import json
|
||||
import jsonschema
|
||||
|
||||
from rally.benchmark import base
|
||||
from rally.benchmark.context import users as users_ctx
|
||||
from rally.benchmark import runner
|
||||
from rally.benchmark import utils
|
||||
from rally import consts
|
||||
@ -155,7 +156,7 @@ class BenchmarkEngine(object):
|
||||
if self.admin_endpoint:
|
||||
admin_client = utils.create_openstack_clients(self.admin_endpoint)
|
||||
validate(admin_validators, admin_client)
|
||||
with runner.UserGenerator(self.admin_endpoint) as generator:
|
||||
with users_ctx.UserGenerator(self.admin_endpoint) as generator:
|
||||
temp_user = generator.create_users_and_tenants(1, 1)[0]
|
||||
user_client = utils.create_openstack_clients(temp_user)
|
||||
validate(user_validators, user_client)
|
||||
|
@ -14,18 +14,14 @@
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
import functools
|
||||
import itertools
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from rally.benchmark import base
|
||||
from rally.benchmark.context import cleaner as cleaner_ctx
|
||||
from rally.benchmark.context import users as users_ctx
|
||||
from rally.benchmark import utils
|
||||
from rally import consts
|
||||
from rally.objects import endpoint
|
||||
from rally.openstack.common.gettextutils import _
|
||||
from rally.openstack.common import log as logging
|
||||
from rally import utils as rutils
|
||||
|
||||
@ -63,126 +59,6 @@ def _run_scenario_once(args):
|
||||
"atomic_actions_time": scenario.atomic_actions_time()}
|
||||
|
||||
|
||||
class UserGenerator(object):
|
||||
"""Context class for generating temporary users/tenants for benchmarks."""
|
||||
|
||||
def __init__(self, admin_endpoints):
|
||||
self.users = []
|
||||
self.tenants = []
|
||||
self.keystone_client = \
|
||||
utils.create_openstack_clients(admin_endpoints)["keystone"]
|
||||
|
||||
def _create_user(self, user_id, tenant_id):
|
||||
pattern = "%(tenant_id)s_user_%(uid)d"
|
||||
name = pattern % {"tenant_id": tenant_id, "uid": user_id}
|
||||
email = "%s@email.me" % name
|
||||
return self.keystone_client.users.create(name, "password",
|
||||
email, tenant_id)
|
||||
|
||||
def _create_tenant(self, run_id, i):
|
||||
pattern = "temp_%(run_id)s_tenant_%(iter)i"
|
||||
return self.keystone_client.tenants.create(pattern % {"run_id": run_id,
|
||||
"iter": i})
|
||||
|
||||
def create_users_and_tenants(self, tenants, users_per_tenant):
|
||||
run_id = str(uuid.uuid4())
|
||||
auth_url = self.keystone_client.auth_url
|
||||
self.tenants = [self._create_tenant(run_id, i)
|
||||
for i in range(tenants)]
|
||||
self.users = []
|
||||
endpoints = []
|
||||
for tenant in self.tenants:
|
||||
for user_id in range(users_per_tenant):
|
||||
user = self._create_user(user_id, tenant.id)
|
||||
self.users.append(user)
|
||||
endpoints.append(endpoint.Endpoint(
|
||||
auth_url, user.name, "password", tenant.name,
|
||||
consts.EndpointPermission.USER))
|
||||
return endpoints
|
||||
|
||||
def _delete_users_and_tenants(self):
|
||||
for user in self.users:
|
||||
try:
|
||||
user.delete()
|
||||
except Exception:
|
||||
LOG.info("Failed to delete user: %s" % user.name)
|
||||
|
||||
for tenant in self.tenants:
|
||||
try:
|
||||
tenant.delete()
|
||||
except Exception:
|
||||
LOG.info("Failed to delete tenant: %s" % tenant.name)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||
self._delete_users_and_tenants()
|
||||
|
||||
if exc_type:
|
||||
LOG.debug(_("Failed to generate temporary users."),
|
||||
exc_info=(exc_type, exc_value, exc_traceback))
|
||||
else:
|
||||
LOG.debug(_("Completed deleting temporary users and tenants."))
|
||||
|
||||
|
||||
class ResourceCleaner(object):
|
||||
"""Context class for resource cleanup (both admin and non-admin)."""
|
||||
|
||||
def __init__(self, admin=None, users=None):
|
||||
self.admin = admin
|
||||
self.users = users
|
||||
|
||||
def _cleanup_users_resources(self):
|
||||
if not self.users:
|
||||
return
|
||||
|
||||
for user in itertools.imap(utils.create_openstack_clients, self.users):
|
||||
methods = [
|
||||
functools.partial(utils.delete_nova_resources, user["nova"]),
|
||||
functools.partial(utils.delete_glance_resources,
|
||||
user["glance"], user["keystone"]),
|
||||
functools.partial(utils.delete_cinder_resources,
|
||||
user["cinder"])
|
||||
]
|
||||
|
||||
for method in methods:
|
||||
try:
|
||||
method()
|
||||
except Exception as e:
|
||||
LOG.debug(_("Not all resources were cleaned."),
|
||||
exc_info=sys.exc_info())
|
||||
LOG.warning(_('Unable to fully cleanup the cloud: \n%s') %
|
||||
(e.message))
|
||||
|
||||
def _cleanup_admin_resources(self):
|
||||
if not self.admin:
|
||||
return
|
||||
|
||||
try:
|
||||
admin = utils.create_openstack_clients(self.admin)
|
||||
utils.delete_keystone_resources(admin["keystone"])
|
||||
except Exception as e:
|
||||
LOG.debug(_("Not all resources were cleaned."),
|
||||
exc_info=sys.exc_info())
|
||||
LOG.warning(_('Unable to fully cleanup keystone service: %s') %
|
||||
(e.message))
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||
self._cleanup_users_resources()
|
||||
self._cleanup_admin_resources()
|
||||
|
||||
if exc_type:
|
||||
LOG.debug(_("An error occurred while launching "
|
||||
"the benchmark scenario."),
|
||||
exc_info=(exc_type, exc_value, exc_traceback))
|
||||
else:
|
||||
LOG.debug(_("Completed resources cleanup."))
|
||||
|
||||
|
||||
class ScenarioRunner(object):
|
||||
"""Base class for all scenario runners.
|
||||
|
||||
@ -246,19 +122,19 @@ class ScenarioRunner(object):
|
||||
def _run_as_admin(self, name, kwargs):
|
||||
config = kwargs.get('config', {})
|
||||
|
||||
with UserGenerator(self.admin_user) as generator:
|
||||
with users_ctx.UserGenerator(self.admin_user) as generator:
|
||||
tenants = config.get("tenants", 1)
|
||||
users_per_tenant = config.get("users_per_tenant", 1)
|
||||
self.users = generator.create_users_and_tenants(tenants,
|
||||
users_per_tenant)
|
||||
|
||||
with ResourceCleaner(admin=self.admin_user,
|
||||
users=self.users):
|
||||
with cleaner_ctx.ResourceCleaner(admin=self.admin_user,
|
||||
users=self.users):
|
||||
return self._prepare_and_run_scenario(name, kwargs)
|
||||
|
||||
def _run_as_non_admin(self, name, kwargs):
|
||||
# TODO(boris-42): Somehow setup clients from deployment/config
|
||||
with ResourceCleaner(users=self.users):
|
||||
with cleaner_ctx.ResourceCleaner(users=self.users):
|
||||
return self._prepare_and_run_scenario(name, kwargs)
|
||||
|
||||
def run(self, name, kwargs):
|
||||
|
0
tests/benchmark/context/__init__.py
Normal file
0
tests/benchmark/context/__init__.py
Normal file
94
tests/benchmark/context/test_cleaner.py
Normal file
94
tests/benchmark/context/test_cleaner.py
Normal file
@ -0,0 +1,94 @@
|
||||
# Copyright 2014: 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 rally.benchmark.context import cleaner as cleaner_ctx
|
||||
|
||||
from tests import test
|
||||
|
||||
|
||||
BASE = "rally.benchmark.context.cleaner"
|
||||
|
||||
|
||||
class ResourceCleanerTestCase(test.TestCase):
|
||||
|
||||
def test_with_statement_no_user_no_admin(self):
|
||||
resource_cleaner = cleaner_ctx.ResourceCleaner()
|
||||
with resource_cleaner:
|
||||
pass
|
||||
|
||||
def test_with_statement(self):
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner()
|
||||
|
||||
res_cleaner._cleanup_users_resources = mock.MagicMock()
|
||||
res_cleaner._cleanup_admin_resources = mock.MagicMock()
|
||||
|
||||
with res_cleaner as cleaner:
|
||||
self.assertEqual(res_cleaner, cleaner)
|
||||
|
||||
res_cleaner._cleanup_users_resources.assert_called_once_with()
|
||||
res_cleaner._cleanup_admin_resources.assert_called_once_with()
|
||||
|
||||
@mock.patch("%s.utils.create_openstack_clients" % BASE)
|
||||
@mock.patch("%s.utils.delete_keystone_resources" % BASE)
|
||||
def test_cleaner_admin(self, mock_del_keystone, mock_create_os_clients):
|
||||
|
||||
admin_endpoint = "admin"
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner(admin=admin_endpoint)
|
||||
|
||||
admin_client = mock.MagicMock()
|
||||
admin_client.__getitem__ = mock.MagicMock(return_value="keystone_cl")
|
||||
mock_create_os_clients.return_value = admin_client
|
||||
|
||||
with res_cleaner:
|
||||
pass
|
||||
|
||||
mock_create_os_clients.assert_called_once_with(admin_endpoint)
|
||||
admin_client.__getitem__.assert_called_once_with("keystone")
|
||||
mock_del_keystone.assert_called_once_with("keystone_cl")
|
||||
|
||||
@mock.patch("%s.utils.create_openstack_clients" % BASE)
|
||||
@mock.patch("%s.utils.delete_nova_resources" % BASE)
|
||||
@mock.patch("%s.utils.delete_glance_resources" % BASE)
|
||||
@mock.patch("%s.utils.delete_cinder_resources" % BASE)
|
||||
def test_cleaner_users(self, mock_del_cinder, mock_del_glance,
|
||||
mock_del_nova, mock_create_os_clients):
|
||||
|
||||
users = ["user1", "user2"]
|
||||
res_cleaner = cleaner_ctx.ResourceCleaner(users=users)
|
||||
|
||||
client = mock.MagicMock()
|
||||
client.__getitem__ = mock.MagicMock(side_effect=lambda cl: cl + "_cl")
|
||||
mock_create_os_clients.return_value = client
|
||||
|
||||
with res_cleaner:
|
||||
pass
|
||||
|
||||
os_clients = ["nova", "glance", "keystone", "cinder"]
|
||||
expected = [mock.call("user1"), mock.call("user2")]
|
||||
mock_calls = filter(lambda call: '__getitem__' not in call[0],
|
||||
mock_create_os_clients.mock_calls)
|
||||
self.assertEqual(mock_calls, expected)
|
||||
|
||||
expected = [mock.call(c) for c in os_clients] * len(users)
|
||||
self.assertEqual(client.__getitem__.mock_calls, expected)
|
||||
|
||||
expected = [mock.call("nova_cl")] * len(users)
|
||||
self.assertEqual(mock_del_nova.mock_calls, expected)
|
||||
expected = [mock.call("glance_cl", "keystone_cl")] * len(users)
|
||||
self.assertEqual(mock_del_glance.mock_calls, expected)
|
||||
expected = [mock.call("cinder_cl")] * len(users)
|
||||
self.assertEqual(mock_del_cinder.mock_calls, expected)
|
52
tests/benchmark/context/test_users.py
Normal file
52
tests/benchmark/context/test_users.py
Normal file
@ -0,0 +1,52 @@
|
||||
# Copyright 2014: 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 rally.benchmark.context import users
|
||||
from tests import fakes
|
||||
from tests import test
|
||||
|
||||
|
||||
class UserGeneratorTestCase(test.TestCase):
|
||||
|
||||
@mock.patch("rally.benchmark.context.users.utils.create_openstack_clients")
|
||||
def test_with_statement(self, mock_create_os_clients):
|
||||
admin_endpoint = "admin"
|
||||
with users.UserGenerator(admin_endpoint):
|
||||
pass
|
||||
|
||||
@mock.patch("rally.benchmark.context.users.utils.create_openstack_clients")
|
||||
def test_create_and_delete_users_and_tenants(self, mock_create_os_clients):
|
||||
fc = fakes.FakeClients()
|
||||
# TODO(msdubov): This indicates that osclients.Clients should be
|
||||
# perhaps refactored to support dictionary-like access.
|
||||
mock_create_os_clients.return_value = {
|
||||
"keystone": fc.get_keystone_client()
|
||||
}
|
||||
admin_user = {"username": "admin", "password": "pwd",
|
||||
"tenant_name": "admin", "auth_url": "url"}
|
||||
created_users = []
|
||||
created_tenants = []
|
||||
with users.UserGenerator(admin_user) as generator:
|
||||
tenants = 10
|
||||
users_per_tenant = 5
|
||||
endpoints = generator.create_users_and_tenants(tenants,
|
||||
users_per_tenant)
|
||||
self.assertEqual(len(endpoints), tenants * users_per_tenant)
|
||||
created_users = generator.users
|
||||
created_tenants = generator.tenants
|
||||
self.assertTrue(all(u.status == "DELETED" for u in created_users))
|
||||
self.assertTrue(all(t.status == "DELETED" for t in created_tenants))
|
@ -115,7 +115,7 @@ class BenchmarkEngineTestCase(test.TestCase):
|
||||
mock.MagicMock())
|
||||
|
||||
@mock.patch("rally.benchmark.base.Scenario.get_by_name")
|
||||
@mock.patch("rally.benchmark.runner.UserGenerator."
|
||||
@mock.patch("rally.benchmark.context.users.UserGenerator."
|
||||
"create_users_and_tenants")
|
||||
@mock.patch("rally.benchmark.utils.create_openstack_clients")
|
||||
@mock.patch("rally.benchmark.engine.BenchmarkEngine._validate_config")
|
||||
@ -148,7 +148,7 @@ class BenchmarkEngineTestCase(test.TestCase):
|
||||
mock_create_os_clients.assert_has_calls(expected, any_order=True)
|
||||
|
||||
@mock.patch("rally.benchmark.base.Scenario.get_by_name")
|
||||
@mock.patch("rally.benchmark.runner.UserGenerator."
|
||||
@mock.patch("rally.benchmark.context.users.UserGenerator."
|
||||
"create_users_and_tenants")
|
||||
@mock.patch("rally.benchmark.utils.create_openstack_clients")
|
||||
@mock.patch("rally.benchmark.engine.BenchmarkEngine._validate_config")
|
||||
|
@ -198,105 +198,3 @@ class ScenarioRunnerTestCase(test.TestCase):
|
||||
"tenants": 5, "users_per_tenant": 2})
|
||||
]
|
||||
self.assertEqual(srunner._run_scenario.mock_calls, expected)
|
||||
|
||||
|
||||
class UserGeneratorTestCase(test.TestCase):
|
||||
|
||||
@mock.patch("rally.benchmark.runner.utils.create_openstack_clients")
|
||||
def test_with_statement(self, mock_create_os_clients):
|
||||
admin_endpoint = "admin"
|
||||
with runner.UserGenerator(admin_endpoint):
|
||||
pass
|
||||
|
||||
@mock.patch("rally.benchmark.runner.utils.create_openstack_clients")
|
||||
def test_create_and_delete_users_and_tenants(self, mock_create_os_clients):
|
||||
fc = fakes.FakeClients()
|
||||
# TODO(msdubov): This indicates that osclients.Clients should be
|
||||
# perhaps refactored to support dictionary-like access.
|
||||
mock_create_os_clients.return_value = {
|
||||
"keystone": fc.get_keystone_client()
|
||||
}
|
||||
admin_user = {"username": "admin", "password": "pwd",
|
||||
"tenant_name": "admin", "auth_url": "url"}
|
||||
created_users = []
|
||||
created_tenants = []
|
||||
with runner.UserGenerator(admin_user) as generator:
|
||||
tenants = 10
|
||||
users_per_tenant = 5
|
||||
endpoints = generator.create_users_and_tenants(tenants,
|
||||
users_per_tenant)
|
||||
self.assertEqual(len(endpoints), tenants * users_per_tenant)
|
||||
created_users = generator.users
|
||||
created_tenants = generator.tenants
|
||||
self.assertTrue(all(u.status == "DELETED" for u in created_users))
|
||||
self.assertTrue(all(t.status == "DELETED" for t in created_tenants))
|
||||
|
||||
|
||||
class ResourceCleanerTestCase(test.TestCase):
|
||||
|
||||
def test_with_statement_no_user_no_admin(self):
|
||||
resource_cleaner = runner.ResourceCleaner()
|
||||
with resource_cleaner:
|
||||
pass
|
||||
|
||||
def test_with_statement(self):
|
||||
res_cleaner = runner.ResourceCleaner()
|
||||
res_cleaner._cleanup_users_resources = mock.MagicMock()
|
||||
res_cleaner._cleanup_admin_resources = mock.MagicMock()
|
||||
|
||||
with res_cleaner as cleaner:
|
||||
self.assertEqual(res_cleaner, cleaner)
|
||||
|
||||
res_cleaner._cleanup_users_resources.assert_called_once_with()
|
||||
res_cleaner._cleanup_admin_resources.assert_called_once_with()
|
||||
|
||||
@mock.patch("rally.benchmark.runner.utils.create_openstack_clients")
|
||||
@mock.patch("rally.benchmark.runner.utils.delete_keystone_resources")
|
||||
def test_cleaner_admin(self, mock_del_keystone, mock_create_os_clients):
|
||||
|
||||
admin_endpoint = "admin"
|
||||
res_cleaner = runner.ResourceCleaner(admin=admin_endpoint)
|
||||
|
||||
admin_client = mock.MagicMock()
|
||||
admin_client.__getitem__ = mock.MagicMock(return_value="keystone_cl")
|
||||
mock_create_os_clients.return_value = admin_client
|
||||
|
||||
with res_cleaner:
|
||||
pass
|
||||
|
||||
mock_create_os_clients.assert_called_once_with(admin_endpoint)
|
||||
admin_client.__getitem__.assert_called_once_with("keystone")
|
||||
mock_del_keystone.assert_called_once_with("keystone_cl")
|
||||
|
||||
@mock.patch("rally.benchmark.runner.utils.create_openstack_clients")
|
||||
@mock.patch("rally.benchmark.runner.utils.delete_nova_resources")
|
||||
@mock.patch("rally.benchmark.runner.utils.delete_glance_resources")
|
||||
@mock.patch("rally.benchmark.runner.utils.delete_cinder_resources")
|
||||
def test_cleaner_users(self, mock_del_cinder, mock_del_glance,
|
||||
mock_del_nova, mock_create_os_clients):
|
||||
|
||||
users = ["user1", "user2"]
|
||||
res_cleaner = runner.ResourceCleaner(users=users)
|
||||
|
||||
client = mock.MagicMock()
|
||||
client.__getitem__ = mock.MagicMock(side_effect=lambda cl: cl + "_cl")
|
||||
mock_create_os_clients.return_value = client
|
||||
|
||||
with res_cleaner:
|
||||
pass
|
||||
|
||||
os_clients = ["nova", "glance", "keystone", "cinder"]
|
||||
expected = [mock.call("user1"), mock.call("user2")]
|
||||
mock_calls = filter(lambda call: '__getitem__' not in call[0],
|
||||
mock_create_os_clients.mock_calls)
|
||||
self.assertEqual(mock_calls, expected)
|
||||
|
||||
expected = [mock.call(c) for c in os_clients] * len(users)
|
||||
self.assertEqual(client.__getitem__.mock_calls, expected)
|
||||
|
||||
expected = [mock.call("nova_cl")] * len(users)
|
||||
self.assertEqual(mock_del_nova.mock_calls, expected)
|
||||
expected = [mock.call("glance_cl", "keystone_cl")] * len(users)
|
||||
self.assertEqual(mock_del_glance.mock_calls, expected)
|
||||
expected = [mock.call("cinder_cl")] * len(users)
|
||||
self.assertEqual(mock_del_cinder.mock_calls, expected)
|
||||
|
Loading…
Reference in New Issue
Block a user