OSprofiler support
The OSprofiler is a distributed trace toolkit library. It helps to trace internal calls of Openstack services including RPC, DB and WSGI. This patch integrates OSprofiler in Rally. Rally can trigger the profiling on a per-iteration basis. To do so a secret key (profiler_hmac_key) is stored alongside the credentials and used to initialize the profiler in the constructor of the scenarios. A configuration parameter (enable_profiler) can disabled the profiling. Note that in this patch we don't embed the full osprofiler report but only a trace id. This trace id can be used to retrieve the full trace from the osprofiler tool later. Change-Id: I7602856d094e073fde80d287b4d92b5750aacc3c Co-Authored-By: rcherrueau <Ronan-Alexandre.Cherrueau@inria.fr> Implements: spec osprofiler
This commit is contained in:
parent
2b17411c2e
commit
755af67a02
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -38,3 +38,4 @@ more complicated cases.
|
||||
tutorial/step_8_discovering_more_plugins
|
||||
tutorial/step_9_deploying_openstack
|
||||
tutorial/step_10_verifying_cloud_via_tempest_verifier
|
||||
tutorial/step_11_profiling_openstack_internals
|
||||
|
@ -0,0 +1,84 @@
|
||||
..
|
||||
Copyright 2017 Inria 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.
|
||||
|
||||
.. _tutorial_step_11_profiling_openstack_internals:
|
||||
|
||||
Step 11. Profiling OpenStack Internals
|
||||
======================================
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Rally leverage `OSprofiler <https://github.com/openstack/osprofiler>`_ to
|
||||
generate traces of OpenStack internal calls happening during the run of a
|
||||
scenario. Integration of OSProfiler in Rally can help to dig into concurrency
|
||||
problems of OpenStack which is a huge ecosystem of cooperative services.
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
Enabling the profiler is based on a shared secret between the clients (here
|
||||
Rally) and the various Openstack services : the HMAC key. In the following we
|
||||
assume that your OpenStack services have been configured to enable OSprofiler
|
||||
and that the secret HMAC key is ``SECRET_KEY``. This key is stored alongside
|
||||
the credentials of your deployment. Once Rally is instructed about the HMAC
|
||||
key, a new trace can be initialized for each iteration of the workload. Rally
|
||||
will then store in its reports a profiler trace id. This id can be finally be
|
||||
used to query OSprofiler in order to get the full trace of the iteration.
|
||||
|
||||
Registering the HMAC key
|
||||
------------------------
|
||||
|
||||
You can store your HMAC key in the environment variable
|
||||
``OSPROFILER_HMAC_KEY``. This variable will be loaded if you create your
|
||||
deployment with the ``--from-env`` option.
|
||||
|
||||
Alternatively if you create your deployment using the ``--file`` option you can
|
||||
add the HMAC key with the following :
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"type": "ExistingCloud",
|
||||
"creds": {
|
||||
"openstack": {
|
||||
[...]
|
||||
"profiler_hmac_key": "SECRET_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Getting the full trace
|
||||
----------------------
|
||||
|
||||
A trace id is stored on a per-iteration basis and can be found in the JSON
|
||||
report as-well as the HTML report :
|
||||
|
||||
.. image:: ../../images/Report-Task-Scenario-Data-Per-iteration-profiler.png
|
||||
|
||||
|
||||
OSProfiler can be asked to generate the full trace using this trace id:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
osprofiler trace show --html --out trace.html 941338f6-3d39-4f80-9dba-395d9dbd16bb
|
||||
|
||||
|
||||
Disabling the profiler
|
||||
------------------------
|
||||
|
||||
Setting ``enable_profiler = False`` under the ``benchmark`` group in the
|
||||
configuration file will disabled the profiler.
|
@ -580,6 +580,8 @@
|
||||
# Neutron create loadbalancer poll interval (floating point value)
|
||||
#neutron_create_loadbalancer_poll_interval = 2.0
|
||||
|
||||
# Enable or disable osprofiler to trace the scenarios
|
||||
#enable_profiler = True
|
||||
|
||||
[cleanup]
|
||||
|
||||
|
@ -109,7 +109,8 @@ def get_creds_from_env_vars():
|
||||
"region_name": os.environ.get("OS_REGION_NAME", ""),
|
||||
"https_cacert": os.environ.get("OS_CACERT", ""),
|
||||
"https_insecure": strutils.bool_from_string(
|
||||
os.environ.get("OS_INSECURE"))
|
||||
os.environ.get("OS_INSECURE")),
|
||||
"profiler_hmac_key": os.environ.get("OSPROFILER_HMAC_KEY")
|
||||
}
|
||||
|
||||
user_domain_name = os.environ.get("OS_USER_DOMAIN_NAME")
|
||||
|
@ -152,6 +152,7 @@ class ExistingCloud(engine.Engine):
|
||||
None]},
|
||||
"https_insecure": {"type": "boolean"},
|
||||
"https_cacert": {"type": "string"},
|
||||
"profiler_hmac_key": {"type": ["string", "null"]},
|
||||
"admin": USER_SCHEMA,
|
||||
"users": {"type": "array", "items": USER_SCHEMA},
|
||||
"extra": {"type": "object", "additionalProperties": True}
|
||||
|
@ -25,6 +25,7 @@ from rally.plugins.openstack.cfg import monasca
|
||||
from rally.plugins.openstack.cfg import murano
|
||||
from rally.plugins.openstack.cfg import neutron
|
||||
from rally.plugins.openstack.cfg import nova
|
||||
from rally.plugins.openstack.cfg import profiler
|
||||
from rally.plugins.openstack.cfg import sahara
|
||||
from rally.plugins.openstack.cfg import senlin
|
||||
from rally.plugins.openstack.cfg import vm
|
||||
@ -43,9 +44,10 @@ def list_opts():
|
||||
opts = {}
|
||||
for l_opts in (cinder.OPTS, ec2.OPTS, heat.OPTS, ironic.OPTS, magnum.OPTS,
|
||||
manila.OPTS, mistral.OPTS, monasca.OPTS, murano.OPTS,
|
||||
nova.OPTS, sahara.OPTS, vm.OPTS, glance.OPTS, watcher.OPTS,
|
||||
tempest.OPTS, keystone_roles.OPTS, keystone_users.OPTS,
|
||||
cleanup.OPTS, senlin.OPTS, neutron.OPTS):
|
||||
nova.OPTS, profiler.OPTS, sahara.OPTS, vm.OPTS, glance.OPTS,
|
||||
watcher.OPTS, tempest.OPTS, keystone_roles.OPTS,
|
||||
keystone_users.OPTS, cleanup.OPTS, senlin.OPTS,
|
||||
neutron.OPTS):
|
||||
for category, opt in l_opts.items():
|
||||
opts.setdefault(category, [])
|
||||
opts[category].extend(opt)
|
||||
|
21
rally/plugins/openstack/cfg/profiler.py
Normal file
21
rally/plugins/openstack/cfg/profiler.py
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright 2017: Inria.
|
||||
# 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 oslo_config import cfg
|
||||
|
||||
OPTS = {"benchmark": [
|
||||
cfg.BoolOpt("enable_profiler", default=True,
|
||||
help="Enable or disable osprofiler to trace the scenarios")
|
||||
]}
|
@ -196,7 +196,8 @@ class UserGenerator(context.Context):
|
||||
endpoint_type=self.credential.endpoint_type,
|
||||
https_insecure=self.credential.https_insecure,
|
||||
https_cacert=self.credential.https_cacert,
|
||||
region_name=self.credential.region_name)
|
||||
region_name=self.credential.region_name,
|
||||
profiler_hmac_key=self.credential.profiler_hmac_key)
|
||||
users.append({"id": user.id,
|
||||
"credential": user_credential,
|
||||
"tenant_id": tenant_id})
|
||||
|
@ -32,7 +32,8 @@ class OpenStackCredential(credential.Credential):
|
||||
region_name=None, endpoint_type=None,
|
||||
domain_name=None, endpoint=None, user_domain_name=None,
|
||||
project_domain_name=None,
|
||||
https_insecure=False, https_cacert=None):
|
||||
https_insecure=False, https_cacert=None,
|
||||
profiler_hmac_key=None):
|
||||
self.auth_url = auth_url
|
||||
self.username = username
|
||||
self.password = password
|
||||
@ -46,6 +47,7 @@ class OpenStackCredential(credential.Credential):
|
||||
self.endpoint = endpoint
|
||||
self.https_insecure = https_insecure
|
||||
self.https_cacert = https_cacert
|
||||
self.profiler_hmac_key = profiler_hmac_key
|
||||
|
||||
self._clients_cache = {}
|
||||
|
||||
@ -76,7 +78,8 @@ class OpenStackCredential(credential.Credential):
|
||||
"https_cacert": self.https_cacert,
|
||||
"user_domain_name": self.user_domain_name,
|
||||
"project_domain_name": self.project_domain_name,
|
||||
"permission": self.permission}
|
||||
"permission": self.permission,
|
||||
"profiler_hmac_key": self.profiler_hmac_key}
|
||||
|
||||
def verify_connection(self):
|
||||
from keystoneclient import exceptions as keystone_exceptions
|
||||
@ -152,6 +155,7 @@ class OpenStackCredentialBuilder(credential.CredentialBuilder):
|
||||
None]},
|
||||
"https_insecure": {"type": "boolean"},
|
||||
"https_cacert": {"type": "string"},
|
||||
"profiler_hmac_key": {"type": ["string", "null"]}
|
||||
},
|
||||
"required": ["auth_url", "admin"],
|
||||
"additionalProperties": False
|
||||
@ -171,7 +175,8 @@ class OpenStackCredentialBuilder(credential.CredentialBuilder):
|
||||
user_domain_name=user.get("user_domain_name", None),
|
||||
project_domain_name=user.get("project_domain_name", None),
|
||||
https_insecure=common.get("https_insecure", False),
|
||||
https_cacert=common.get("https_cacert"))
|
||||
https_cacert=common.get("https_cacert"),
|
||||
profiler_hmac_key=common.get("profiler_hmac_key"))
|
||||
return cred.to_dict()
|
||||
|
||||
def build_credentials(self):
|
||||
|
@ -16,11 +16,15 @@
|
||||
import functools
|
||||
import random
|
||||
|
||||
from oslo_config import cfg
|
||||
from osprofiler import profiler
|
||||
from rally import osclients
|
||||
from rally.task import scenario
|
||||
|
||||
configure = functools.partial(scenario.configure, namespace="openstack")
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class OpenStackScenario(scenario.Scenario):
|
||||
"""Base class for all OpenStack scenarios."""
|
||||
@ -54,6 +58,8 @@ class OpenStackScenario(scenario.Scenario):
|
||||
if clients:
|
||||
self._clients = clients
|
||||
|
||||
self._init_profiler(context)
|
||||
|
||||
def _choose_user(self, context):
|
||||
"""Choose one user from users context
|
||||
|
||||
@ -104,3 +110,27 @@ class OpenStackScenario(scenario.Scenario):
|
||||
client = getattr(self._admin_clients, client_type)
|
||||
|
||||
return client(version) if version is not None else client()
|
||||
|
||||
def _init_profiler(self, context):
|
||||
"""Inits the profiler."""
|
||||
if not CONF.benchmark.enable_profiler:
|
||||
return
|
||||
if context is not None:
|
||||
cred = None
|
||||
profiler_hmac_key = None
|
||||
if "admin" in context:
|
||||
cred = context["admin"]["credential"]
|
||||
if cred.profiler_hmac_key is not None:
|
||||
profiler_hmac_key = cred.profiler_hmac_key
|
||||
if "user" in context:
|
||||
cred = context["user"]["credential"]
|
||||
if cred.profiler_hmac_key is not None:
|
||||
profiler_hmac_key = cred.profiler_hmac_key
|
||||
if profiler_hmac_key is None:
|
||||
return
|
||||
profiler.init(profiler_hmac_key)
|
||||
trace_id = profiler.get().get_base_id()
|
||||
self.add_output(complete={
|
||||
"title": "OSProfiler Trace-ID",
|
||||
"chart_plugin": "TextArea",
|
||||
"data": [trace_id]})
|
||||
|
@ -30,6 +30,7 @@ boto>=2.32.1,<=2.46.1 # MIT
|
||||
gnocchiclient>=2.7.0,<=3.1.1 # Apache Software License
|
||||
keystoneauth1==2.20.0 # Apache Software License
|
||||
os-faults>=0.1.5,<=0.1.12 # Apache Software License
|
||||
osprofiler>=1.4.0 # Apache License, Version 2.0
|
||||
python-ceilometerclient>=2.5.0,<=2.8.1 # Apache Software License
|
||||
python-cinderclient==2.0.1 # Apache Software License
|
||||
python-designateclient>=1.5.0,<=2.6.0 # Apache License, Version 2.0
|
||||
|
20
samples/deployments/existing-keystone-v3-osprofiler.json
Normal file
20
samples/deployments/existing-keystone-v3-osprofiler.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"type": "ExistingCloud",
|
||||
"creds": {
|
||||
"openstack": {
|
||||
"auth_url": "http://example.net:5000/v3/",
|
||||
"region_name": "RegionOne",
|
||||
"endpoint_type": "public",
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password": "myadminpass",
|
||||
"user_domain_name": "admin",
|
||||
"project_name": "admin",
|
||||
"project_domain_name": "admin"
|
||||
},
|
||||
"https_insecure": false,
|
||||
"https_cacert": "",
|
||||
"profiler_hmac_key": "SECRET_KEY"
|
||||
}
|
||||
}
|
||||
}
|
@ -54,7 +54,8 @@ class DeploymentCommandsTestCase(test.TestCase):
|
||||
"OS_ENDPOINT": "fake_endpoint",
|
||||
"OS_INSECURE": "True",
|
||||
"OS_CACERT": "fake_cacert",
|
||||
"RALLY_DEPLOYMENT": "fake_deployment_id"})
|
||||
"RALLY_DEPLOYMENT": "fake_deployment_id",
|
||||
"OSPROFILER_HMAC_KEY": "fake_hmac_key"})
|
||||
@mock.patch("rally.cli.commands.deployment.DeploymentCommands.list")
|
||||
def test_createfromenv_keystonev2(self, mock_list):
|
||||
self.deployment.create(self.fake_api, "from_env", True)
|
||||
@ -73,7 +74,8 @@ class DeploymentCommandsTestCase(test.TestCase):
|
||||
"tenant_name": "fake_tenant_name"
|
||||
},
|
||||
"https_insecure": True,
|
||||
"https_cacert": "fake_cacert"
|
||||
"https_cacert": "fake_cacert",
|
||||
"profiler_hmac_key": "fake_hmac_key"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -91,7 +93,8 @@ class DeploymentCommandsTestCase(test.TestCase):
|
||||
"OS_ENDPOINT": "fake_endpoint",
|
||||
"OS_INSECURE": "True",
|
||||
"OS_CACERT": "fake_cacert",
|
||||
"RALLY_DEPLOYMENT": "fake_deployment_id"})
|
||||
"RALLY_DEPLOYMENT": "fake_deployment_id",
|
||||
"OSPROFILER_HMAC_KEY": "fake_hmac_key"})
|
||||
@mock.patch("rally.cli.commands.deployment.DeploymentCommands.list")
|
||||
def test_createfromenv_keystonev3(self, mock_list):
|
||||
self.deployment.create(self.fake_api, "from_env", True)
|
||||
@ -112,7 +115,8 @@ class DeploymentCommandsTestCase(test.TestCase):
|
||||
"project_name": "fake_tenant_name"
|
||||
},
|
||||
"https_insecure": True,
|
||||
"https_cacert": "fake_cacert"
|
||||
"https_cacert": "fake_cacert",
|
||||
"profiler_hmac_key": "fake_hmac_key"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -112,6 +112,7 @@ class EnvUtilsTestCase(test.TestCase):
|
||||
"OS_ENDPOINT_TYPE": "fake_endpoint_typeURL",
|
||||
"OS_ENDPOINT": "fake_endpoint",
|
||||
"OS_INSECURE": "True",
|
||||
"OSPROFILER_HMAC_KEY": "fake_hmac_key",
|
||||
"OS_CACERT": "fake_cacert"})
|
||||
def test_get_creds_from_env_vars_keystone_v2(self):
|
||||
expected_creds = {
|
||||
@ -125,7 +126,8 @@ class EnvUtilsTestCase(test.TestCase):
|
||||
"endpoint": "fake_endpoint",
|
||||
"region_name": "fake_region_name",
|
||||
"https_cacert": "fake_cacert",
|
||||
"https_insecure": True
|
||||
"https_insecure": True,
|
||||
"profiler_hmac_key": "fake_hmac_key"
|
||||
}
|
||||
creds = envutils.get_creds_from_env_vars()
|
||||
self.assertEqual(expected_creds, creds)
|
||||
@ -140,6 +142,7 @@ class EnvUtilsTestCase(test.TestCase):
|
||||
"OS_INSECURE": "True",
|
||||
"OS_PROJECT_DOMAIN_NAME": "fake_pdn",
|
||||
"OS_USER_DOMAIN_NAME": "fake_udn",
|
||||
"OSPROFILER_HMAC_KEY": "fake_hmac_key",
|
||||
"OS_CACERT": "fake_cacert"})
|
||||
def test_get_creds_from_env_vars_keystone_v3(self):
|
||||
expected_creds = {
|
||||
@ -155,7 +158,8 @@ class EnvUtilsTestCase(test.TestCase):
|
||||
"endpoint": "fake_endpoint",
|
||||
"region_name": "fake_region_name",
|
||||
"https_cacert": "fake_cacert",
|
||||
"https_insecure": True
|
||||
"https_insecure": True,
|
||||
"profiler_hmac_key": "fake_hmac_key"
|
||||
}
|
||||
creds = envutils.get_creds_from_env_vars()
|
||||
self.assertEqual(expected_creds, creds)
|
||||
@ -165,6 +169,7 @@ class EnvUtilsTestCase(test.TestCase):
|
||||
"OS_REGION_NAME": "fake_region_name",
|
||||
"OS_ENDPOINT": "fake_endpoint",
|
||||
"OS_INSECURE": "True",
|
||||
"OSPROFILER_HMAC_KEY": "fake_hmac_key",
|
||||
"OS_CACERT": "fake_cacert"})
|
||||
def test_get_creds_from_env_vars_when_required_vars_missing(self):
|
||||
if "OS_USERNAME" in os.environ:
|
||||
|
@ -39,7 +39,8 @@ class CredentialTestCase(test.TestCase):
|
||||
"https_insecure": False,
|
||||
"https_cacert": None,
|
||||
"project_domain_name": None,
|
||||
"user_domain_name": None})
|
||||
"user_domain_name": None,
|
||||
"profiler_hmac_key": None})
|
||||
|
||||
def test_to_dict_with_include_permission(self):
|
||||
credential = objects.Credential(
|
||||
@ -59,7 +60,8 @@ class CredentialTestCase(test.TestCase):
|
||||
"https_insecure": False,
|
||||
"https_cacert": None,
|
||||
"project_domain_name": None,
|
||||
"user_domain_name": None})
|
||||
"user_domain_name": None,
|
||||
"profiler_hmac_key": None})
|
||||
|
||||
def test_to_dict_with_kwarg_credential(self):
|
||||
credential = objects.Credential(
|
||||
@ -80,4 +82,5 @@ class CredentialTestCase(test.TestCase):
|
||||
"https_insecure": False,
|
||||
"https_cacert": None,
|
||||
"project_domain_name": None,
|
||||
"user_domain_name": None})
|
||||
"user_domain_name": None,
|
||||
"profiler_hmac_key": None})
|
||||
|
@ -37,6 +37,7 @@ class TestExistingCloud(test.TestCase):
|
||||
"endpoint_type": consts.EndpointType.INTERNAL,
|
||||
"https_insecure": False,
|
||||
"https_cacert": "cacert",
|
||||
"profiler_hmac_key": None,
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password": "myadminpass",
|
||||
@ -52,6 +53,7 @@ class TestExistingCloud(test.TestCase):
|
||||
"endpoint_type": consts.EndpointType.INTERNAL,
|
||||
"https_insecure": False,
|
||||
"https_cacert": "cacert",
|
||||
"profiler_hmac_key": None,
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password": "myadminpass",
|
||||
@ -72,6 +74,7 @@ class TestExistingCloud(test.TestCase):
|
||||
"endpoint_type": consts.EndpointType.INTERNAL,
|
||||
"https_insecure": False,
|
||||
"https_cacert": "cacert",
|
||||
"profiler_hmac_key": None,
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password": "myadminpass",
|
||||
@ -159,6 +162,7 @@ class TestExistingCloud(test.TestCase):
|
||||
"endpoint_type": "internal",
|
||||
"https_cacert": "cacert",
|
||||
"https_insecure": False,
|
||||
"profiler_hmac_key": None,
|
||||
"password": "myadminpass",
|
||||
"permission": "admin",
|
||||
"project_domain_name": None,
|
||||
|
@ -37,7 +37,7 @@ class EC2ServerGeneratorTestCase(test.TestCase):
|
||||
for tenant_id in tenants.keys():
|
||||
for i in range(users_per_tenant):
|
||||
users.append({"id": i, "tenant_id": tenant_id,
|
||||
"credential": "credential"})
|
||||
"credential": mock.MagicMock()})
|
||||
return tenants, users
|
||||
|
||||
def _get_context(self, users, tenants):
|
||||
|
@ -27,6 +27,8 @@ from tests.unit import test
|
||||
MANILA_UTILS_PATH = ("rally.plugins.openstack.scenarios.manila.utils."
|
||||
"ManilaScenario.")
|
||||
|
||||
MOCK_USER_CREDENTIAL = mock.MagicMock()
|
||||
|
||||
|
||||
class Fake(object):
|
||||
def __init__(self, **kwargs):
|
||||
@ -71,8 +73,9 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
users = []
|
||||
for t_id in tenants.keys():
|
||||
for i in range(self.USERS_PER_TENANT):
|
||||
users.append(
|
||||
{"id": i, "tenant_id": t_id, "credential": "fake"})
|
||||
users.append({
|
||||
"id": i, "tenant_id": t_id,
|
||||
"credential": MOCK_USER_CREDENTIAL})
|
||||
context = {
|
||||
"config": {
|
||||
"users": {
|
||||
@ -123,8 +126,8 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
"tenant_2_id": {"id": "tenant_2_id", "name": "tenant_2_name"},
|
||||
},
|
||||
"users": [
|
||||
{"tenant_id": "tenant_1_id", "credential": {"c1": "foo"}},
|
||||
{"tenant_id": "tenant_2_id", "credential": {"c2": "bar"}},
|
||||
{"tenant_id": "tenant_1_id", "credential": mock.MagicMock()},
|
||||
{"tenant_id": "tenant_2_id", "credential": mock.MagicMock()},
|
||||
],
|
||||
}
|
||||
self.existing_sns = [
|
||||
@ -288,8 +291,8 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
]
|
||||
mock_manila_scenario__create_share_network.assert_has_calls(
|
||||
expected_calls * (self.TENANTS_AMOUNT * networks_per_tenant))
|
||||
mock_clients.assert_has_calls([
|
||||
mock.call("fake", {}) for i in range(self.TENANTS_AMOUNT)])
|
||||
mock_clients.assert_has_calls([mock.call(MOCK_USER_CREDENTIAL, {})
|
||||
for i in range(self.TENANTS_AMOUNT)])
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
@ -326,8 +329,8 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
expected_calls = [mock.call(**sn_args), mock.call().to_dict()]
|
||||
mock_manila_scenario__create_share_network.assert_has_calls(
|
||||
expected_calls * (self.TENANTS_AMOUNT * networks_per_tenant))
|
||||
mock_clients.assert_has_calls([
|
||||
mock.call("fake", {}) for i in range(self.TENANTS_AMOUNT)])
|
||||
mock_clients.assert_has_calls([mock.call(MOCK_USER_CREDENTIAL, {})
|
||||
for i in range(self.TENANTS_AMOUNT)])
|
||||
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
@mock.patch(MANILA_UTILS_PATH + "_create_share_network")
|
||||
@ -351,8 +354,8 @@ class ShareNetworksTestCase(test.TestCase):
|
||||
expected_calls = [mock.call(), mock.call().to_dict()]
|
||||
mock_manila_scenario__create_share_network.assert_has_calls(
|
||||
expected_calls * self.TENANTS_AMOUNT)
|
||||
mock_clients.assert_has_calls([
|
||||
mock.call("fake", {}) for i in range(self.TENANTS_AMOUNT)])
|
||||
mock_clients.assert_has_calls([mock.call(MOCK_USER_CREDENTIAL, {})
|
||||
for i in range(self.TENANTS_AMOUNT)])
|
||||
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
@mock.patch(MANILA_UTILS_PATH + "_delete_share_network")
|
||||
|
@ -56,8 +56,9 @@ class SharesTestCase(test.TestCase):
|
||||
users = []
|
||||
for t_id in sorted(list(tenants.keys())):
|
||||
for i in range(self.USERS_PER_TENANT):
|
||||
users.append(
|
||||
{"id": i, "tenant_id": t_id, "credential": "fake"})
|
||||
users.append({
|
||||
"id": i, "tenant_id": t_id,
|
||||
"credential": mock.MagicMock()})
|
||||
context = {
|
||||
"config": {
|
||||
"users": {
|
||||
|
@ -50,12 +50,12 @@ class MuranoEnvironmentGeneratorTestCase(test.TestCase):
|
||||
{
|
||||
"id": "user_0",
|
||||
"tenant_id": "tenant_0",
|
||||
"credential": "credential"
|
||||
"credential": mock.MagicMock()
|
||||
},
|
||||
{
|
||||
"id": "user_1",
|
||||
"tenant_id": "tenant_1",
|
||||
"credential": "credential"
|
||||
"credential": mock.MagicMock()
|
||||
}
|
||||
],
|
||||
"tenants": {
|
||||
|
@ -41,8 +41,16 @@ class SwiftObjectGeneratorTestCase(test.TestCase):
|
||||
"t2": {"name": "t2_name"}
|
||||
},
|
||||
"users": [
|
||||
{"id": "u1", "tenant_id": "t1", "credential": "c1"},
|
||||
{"id": "u2", "tenant_id": "t2", "credential": "c2"}
|
||||
{
|
||||
"id": "u1",
|
||||
"tenant_id": "t1",
|
||||
"credential": mock.MagicMock()
|
||||
},
|
||||
{
|
||||
"id": "u2",
|
||||
"tenant_id": "t2",
|
||||
"credential": mock.MagicMock()
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@ -122,8 +130,16 @@ class SwiftObjectGeneratorTestCase(test.TestCase):
|
||||
"t2": {"name": "t2_name"}
|
||||
},
|
||||
"users": [
|
||||
{"id": "u1", "tenant_id": "t1", "credential": "c1"},
|
||||
{"id": "u2", "tenant_id": "t2", "credential": "c2"}
|
||||
{
|
||||
"id": "u1",
|
||||
"tenant_id": "t1",
|
||||
"credential": mock.MagicMock()
|
||||
},
|
||||
{
|
||||
"id": "u2",
|
||||
"tenant_id": "t2",
|
||||
"credential": mock.MagicMock()
|
||||
}
|
||||
]
|
||||
})
|
||||
mock_swift = mock_clients.return_value.swift.return_value
|
||||
@ -143,8 +159,16 @@ class SwiftObjectGeneratorTestCase(test.TestCase):
|
||||
"t2": {"name": "t2_name"}
|
||||
},
|
||||
"users": [
|
||||
{"id": "u1", "tenant_id": "t1", "credential": "c1"},
|
||||
{"id": "u2", "tenant_id": "t2", "credential": "c2"}
|
||||
{
|
||||
"id": "u1",
|
||||
"tenant_id": "t1",
|
||||
"credential": mock.MagicMock()
|
||||
},
|
||||
{
|
||||
"id": "u2",
|
||||
"tenant_id": "t2",
|
||||
"credential": mock.MagicMock()
|
||||
}
|
||||
]
|
||||
})
|
||||
mock_swift = mock_clients.return_value.swift.return_value
|
||||
@ -163,7 +187,7 @@ class SwiftObjectGeneratorTestCase(test.TestCase):
|
||||
"name": "t1_name",
|
||||
"containers": [
|
||||
{"user": {"id": "u1", "tenant_id": "t1",
|
||||
"credential": "c1"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "coooon",
|
||||
"objects": []}] * 3
|
||||
}
|
||||
@ -184,7 +208,7 @@ class SwiftObjectGeneratorTestCase(test.TestCase):
|
||||
"name": "t1_name",
|
||||
"containers": [
|
||||
{"user": {"id": "u1", "tenant_id": "t1",
|
||||
"credential": "c1"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "c1",
|
||||
"objects": ["oooo"] * 3}
|
||||
]
|
||||
|
@ -26,14 +26,15 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
tenants = 2
|
||||
containers_per_tenant = 2
|
||||
context = test.get_test_context()
|
||||
c = [mock.MagicMock(), mock.MagicMock()]
|
||||
context.update({
|
||||
"tenants": {
|
||||
"1001": {"name": "t1_name"},
|
||||
"1002": {"name": "t2_name"}
|
||||
},
|
||||
"users": [
|
||||
{"id": "u1", "tenant_id": "1001", "credential": "c1"},
|
||||
{"id": "u2", "tenant_id": "1002", "credential": "c2"}
|
||||
{"id": "u1", "tenant_id": "1001", "credential": c[0]},
|
||||
{"id": "u2", "tenant_id": "1002", "credential": c[1]}
|
||||
]
|
||||
})
|
||||
|
||||
@ -51,7 +52,7 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
self.assertEqual(containers_per_tenant, len(containers))
|
||||
for container in containers:
|
||||
self.assertEqual("u%d" % index, container["user"]["id"])
|
||||
self.assertEqual("c%d" % index,
|
||||
self.assertEqual(c[index - 1],
|
||||
container["user"]["credential"])
|
||||
self.assertEqual(0, len(container["objects"]))
|
||||
|
||||
@ -68,7 +69,7 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
"containers": [
|
||||
{"user": {
|
||||
"id": "u1", "tenant_id": "1001",
|
||||
"credential": "c0"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "c1",
|
||||
"objects": []}
|
||||
]
|
||||
@ -78,7 +79,7 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
"containers": [
|
||||
{"user": {
|
||||
"id": "u2", "tenant_id": "1002",
|
||||
"credential": "c2"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "c2",
|
||||
"objects": []}
|
||||
]
|
||||
@ -114,7 +115,7 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
"containers": [
|
||||
{"user": {
|
||||
"id": "u1", "tenant_id": "1001",
|
||||
"credential": "c1"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "c1",
|
||||
"objects": []}
|
||||
]
|
||||
@ -124,7 +125,7 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
"containers": [
|
||||
{"user": {
|
||||
"id": "u2", "tenant_id": "1002",
|
||||
"credential": "c2"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "c2",
|
||||
"objects": []}
|
||||
]
|
||||
@ -154,7 +155,7 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
"containers": [
|
||||
{"user": {
|
||||
"id": "u1", "tenant_id": "1001",
|
||||
"credential": "c1"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "c1",
|
||||
"objects": ["o1", "o2", "o3"]}
|
||||
]
|
||||
@ -164,7 +165,7 @@ class SwiftObjectMixinTestCase(test.TestCase):
|
||||
"containers": [
|
||||
{"user": {
|
||||
"id": "u2", "tenant_id": "1002",
|
||||
"credential": "c2"},
|
||||
"credential": mock.MagicMock()},
|
||||
"container": "c2",
|
||||
"objects": ["o4", "o5", "o6"]}
|
||||
]
|
||||
|
@ -262,7 +262,7 @@ class VMTasksTestCase(test.ScenarioTestCase):
|
||||
mock_heat.main.Stack.return_value = fake_stack
|
||||
context = {
|
||||
"user": {"keypair": {"name": "name", "private": "pk"},
|
||||
"credential": "ok"},
|
||||
"credential": mock.MagicMock()},
|
||||
"tenant": {"networks": [{"router_id": "1"}]}
|
||||
}
|
||||
scenario = vmtasks.RuncommandHeat(context)
|
||||
|
@ -44,7 +44,9 @@ class OpenStackCredentialTestCase(test.TestCase):
|
||||
"https_insecure": False,
|
||||
"https_cacert": None,
|
||||
"project_domain_name": None,
|
||||
"user_domain_name": None}, self.credential.to_dict())
|
||||
"user_domain_name": None,
|
||||
"profiler_hmac_key": None},
|
||||
self.credential.to_dict())
|
||||
|
||||
@mock.patch("rally.osclients.Clients")
|
||||
def test_verify_connection_admin(self, mock_clients):
|
||||
@ -127,6 +129,7 @@ class OpenStackCredentialBuilderTestCase(test.TestCase):
|
||||
"endpoint_type": consts.EndpointType.INTERNAL,
|
||||
"https_cacert": "cacert",
|
||||
"https_insecure": False,
|
||||
"profiler_hmac_key": None,
|
||||
"project_domain_name": None,
|
||||
"region_name": "RegionOne",
|
||||
"tenant_name": "demo",
|
||||
@ -143,6 +146,7 @@ class OpenStackCredentialBuilderTestCase(test.TestCase):
|
||||
"endpoint_type": consts.EndpointType.INTERNAL,
|
||||
"https_cacert": "cacert",
|
||||
"https_insecure": False,
|
||||
"profiler_hmac_key": None,
|
||||
"project_domain_name": None,
|
||||
"region_name": "RegionOne",
|
||||
"tenant_name": "demo",
|
||||
|
@ -16,11 +16,23 @@
|
||||
import ddt
|
||||
import mock
|
||||
from oslotest import mockpatch
|
||||
|
||||
from rally.plugins.openstack.credential import OpenStackCredential
|
||||
from rally.plugins.openstack import scenario as base_scenario
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
CREDENTIAL_WITHOUT_HMAC = OpenStackCredential(
|
||||
"auth_url",
|
||||
"username",
|
||||
"password")
|
||||
|
||||
CREDENTIAL_WITH_HMAC = OpenStackCredential(
|
||||
"auth_url",
|
||||
"username",
|
||||
"password",
|
||||
profiler_hmac_key="test_profiler_hmac_key")
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class OpenStackScenarioTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
@ -80,6 +92,31 @@ class OpenStackScenarioTestCase(test.TestCase):
|
||||
|
||||
self.assertEqual("foobar", scenario._clients)
|
||||
|
||||
@ddt.data(([], 0),
|
||||
([("admin", CREDENTIAL_WITHOUT_HMAC)], 0),
|
||||
([("user", CREDENTIAL_WITHOUT_HMAC)], 0),
|
||||
([("admin", CREDENTIAL_WITH_HMAC)], 1),
|
||||
([("user", CREDENTIAL_WITH_HMAC)], 1),
|
||||
([("admin", CREDENTIAL_WITH_HMAC),
|
||||
("user", CREDENTIAL_WITH_HMAC)], 1),
|
||||
([("admin", CREDENTIAL_WITHOUT_HMAC),
|
||||
("user", CREDENTIAL_WITH_HMAC)], 1),
|
||||
([("admin", CREDENTIAL_WITH_HMAC),
|
||||
("user", CREDENTIAL_WITHOUT_HMAC)], 1),
|
||||
([("admin", CREDENTIAL_WITHOUT_HMAC),
|
||||
("user", CREDENTIAL_WITHOUT_HMAC)], 0))
|
||||
@ddt.unpack
|
||||
@mock.patch("rally.plugins.openstack.scenario.profiler.init")
|
||||
def test_profiler_init(self, users_credentials,
|
||||
expected_init_call_count,
|
||||
mock_profiler_init):
|
||||
for user, credential in users_credentials:
|
||||
print(user, credential.profiler_hmac_key)
|
||||
self.context.update({user: {"credential": credential}})
|
||||
base_scenario.OpenStackScenario(self.context)
|
||||
self.assertEqual(expected_init_call_count,
|
||||
mock_profiler_init.call_count)
|
||||
|
||||
def test__choose_user_random(self):
|
||||
users = [{"credential": mock.Mock(), "tenant_id": "foo"}
|
||||
for _ in range(5)]
|
||||
|
@ -42,6 +42,7 @@ FAKE_DEPLOYMENT_CONFIG = {
|
||||
"domain_name": None,
|
||||
"project_domain_name": "Default",
|
||||
"user_domain_name": "Default",
|
||||
"profiler_hmac_key": None
|
||||
},
|
||||
"region_name": "RegionOne",
|
||||
"endpoint_type": consts.EndpointType.INTERNAL,
|
||||
|
Loading…
x
Reference in New Issue
Block a user