Merge "[validators] Port validators to use context object"

This commit is contained in:
Jenkins 2017-09-25 12:23:24 +00:00 committed by Gerrit Code Review
commit 3eda923a3a
16 changed files with 242 additions and 262 deletions

View File

@ -46,10 +46,10 @@ class Validator(plugin.Plugin):
pass
@abc.abstractmethod
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
"""Method that validates something.
:param credentials: credentials dict for all platforms
:param context: a validation context
:param config: dict, configuration of workload
:param plugin_cls: plugin class
:param plugin_cfg: dict, with exact configuration of the plugin
@ -73,6 +73,8 @@ class Validator(plugin.Plugin):
return doc
# TODO(andreykurilin): Get rid of hardcode to "admin"/"users" properties as
# soon as we finish "Platforms" work.
@configure(name="required_platform")
class RequiredPlatformValidator(Validator):
@ -94,18 +96,18 @@ class RequiredPlatformValidator(Validator):
self.admin = admin
self.users = users
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
if not (self.admin or self.users):
self.fail("You should specify admin=True or users=True or both.")
if credentials is None:
credentials = {}
credentials = credentials.get(self.platform, {})
if context is None:
context = {"platforms": {}}
context = context["platforms"].get(self.platform, {})
if self.admin and credentials.get("admin") is None:
if self.admin and context.get("admin") is None:
self.fail("No admin credential for %s" % self.platform)
if self.users and len(credentials.get("users", ())) == 0:
if credentials.get("admin") is None:
if self.users and len(context.get("users", ())) == 0:
if context.get("admin") is None:
self.fail("No user credentials for %s" % self.platform)
else:
# NOTE(andreykurilin): It is a case when the plugin requires
@ -176,7 +178,7 @@ class ValidatablePluginMixin(object):
for name, args, kwargs in validators]
@classmethod
def validate(cls, name, credentials, config, plugin_cfg,
def validate(cls, name, context, config, plugin_cfg,
allow_hidden=False, vtype=None):
"""Execute all validators stored in meta of plugin.
@ -185,7 +187,7 @@ class ValidatablePluginMixin(object):
to the list.
:param name: full name of the plugin to validate
:param credentials: credentials dict for all platforms
:param context: a validation context
:param config: dict with configuration of specified workload
:param plugin_cfg: dict, with exact configuration of the plugin
:param allow_hidden: do not ignore hidden plugins
@ -243,7 +245,7 @@ class ValidatablePluginMixin(object):
validator = validator_cls(*args, **kwargs)
result = None
try:
validator.validate(credentials=credentials,
validator.validate(context=context,
config=config,
plugin_cls=plugin,
plugin_cfg=plugin_cfg)

View File

@ -120,7 +120,7 @@ def _worker_process(queue, iteration_gen, timeout, concurrency, times,
class CheckConstantValidator(validation.Validator):
"""Additional schema validation for constant runner"""
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
if plugin_cfg.get("concurrency", 1) > plugin_cfg.get("times", 1):
return self.fail(
"Parameter 'concurrency' means a number of parallel executions"

View File

@ -125,7 +125,7 @@ def _worker_process(queue, iteration_gen, timeout, times, max_concurrent,
class CheckPRSValidator(validation.Validator):
"""Additional schema validation for rps runner"""
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
if isinstance(plugin_cfg["rps"], dict):
if plugin_cfg["rps"]["end"] < plugin_cfg["rps"]["start"]:
msg = "rps end value must not be less than rps start value."

View File

@ -28,7 +28,7 @@ LOG = logging.getLogger(__name__)
class JsonSchemaValidator(validation.Validator):
"""JSON schema validator"""
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
try:
jsonschema.validate(plugin_cfg, plugin_cls.CONFIG_SCHEMA)
except jsonschema.ValidationError as err:
@ -39,7 +39,7 @@ class JsonSchemaValidator(validation.Validator):
class ArgsValidator(validation.Validator):
"""Scenario arguments validator"""
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
scenario = plugin_cls
name = scenario.get_name()
namespace = scenario.get_platform()
@ -87,7 +87,7 @@ class RequiredParameterValidator(validation.Validator):
self.subdict = subdict
self.params = params
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
missing = []
args = config.get("args", {})
if self.subdict:
@ -133,7 +133,7 @@ class NumberValidator(validation.Validator):
self.nullable = nullable
self.integer_only = integer_only
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
value = config.get("args", {}).get(self.param_name)
@ -195,7 +195,7 @@ class EnumValidator(validation.Validator):
else:
self.values = values
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
value = config.get("args", {}).get(self.param_name)
if value:
if self.case_insensitive:
@ -230,7 +230,7 @@ class RestrictedParametersValidator(validation.Validator):
self.params = [param_names]
self.subdict = subdict
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
restricted_params = []
for param_name in self.params:
args = config.get("args", {})
@ -268,18 +268,18 @@ class RequiredContextsValidator(validation.Validator):
self.contexts = [contexts]
self.contexts.extend(args)
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
missing_contexts = []
context = config.get("context", {})
input_context = config.get("context", {})
for name in self.contexts:
if isinstance(name, tuple):
if not set(name) & set(context):
if not set(name) & set(input_context):
# formatted string like: 'foo or bar or baz'
formatted_names = "'{}'".format(" or ".join(name))
missing_contexts.append(formatted_names)
else:
if name not in context:
if name not in input_context:
missing_contexts.append(name)
if missing_contexts:
@ -300,7 +300,7 @@ class RequiredParamOrContextValidator(validation.Validator):
self.param_name = param_name
self.ctx_name = ctx_name
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
msg = ("You should specify either scenario argument {} or"
" use context {}.").format(self.param_name,
self.ctx_name)
@ -349,7 +349,7 @@ class FileExistsValidator(validation.Validator):
"mode": mode,
"param_name": param_name})
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
self._file_access_ok(config.get("args", {}).get(self.param_name),
self.mode, self.param_name, self.required)

View File

@ -24,7 +24,7 @@ from rally.task import context
class CheckOpenStackAPIVersionsValidator(validation.Validator):
"""Additional validation for api_versions context"""
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
for client in plugin_cfg:
client_cls = osclients.OSClient.get(client)
try:

View File

@ -29,7 +29,7 @@ class CheckCleanupResourcesValidator(validation.Validator):
super(CheckCleanupResourcesValidator, self).__init__()
self.admin_required = admin_required
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
missing = set(plugin_cfg)
missing -= manager.list_resource_names(
admin_required=self.admin_required)

View File

@ -99,7 +99,7 @@ class ValidCommandValidator(validators.FileExistsValidator):
"Unexpected command parameters: %s" % ", ".join(
unexpected_keys))
def validate(self, config, credentials, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
command = config.get("args", {}).get(self.param_name)
if command is None and not self.required:
return

View File

@ -48,7 +48,7 @@ class ImageExistsValidator(validation.Validator):
self.param_name = param_name
self.nullable = nullable
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
image_args = config.get("args", {}).get(self.param_name)
@ -70,8 +70,8 @@ class ImageExistsValidator(validation.Validator):
"regex" in image_args and match):
return
try:
for user in credentials["openstack"]["users"]:
clients = user.get("credential", {}).clients()
for user in context["users"]:
clients = user["credential"].clients()
image_id = openstack_types.GlanceImage.transform(
clients=clients, resource_config=image_args)
clients.glance().images.get(image_id)
@ -91,15 +91,14 @@ class ExternalNetworkExistsValidator(validation.Validator):
super(ExternalNetworkExistsValidator, self).__init__()
self.param_name = param_name
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
ext_network = config.get("args", {}).get(self.param_name)
if not ext_network:
return
users = credentials["openstack"]["users"]
result = []
for user in users:
for user in context["users"]:
creds = user["credential"]
networks = creds.clients().neutron().list_networks()["networks"]
@ -139,8 +138,8 @@ class RequiredNeutronExtensionsValidator(validation.Validator):
self.req_ext = [extensions]
self.req_ext.extend(args)
def validate(self, credentials, config, plugin_cls, plugin_cfg):
clients = credentials["openstack"]["users"][0]["credential"].clients()
def validate(self, context, config, plugin_cls, plugin_cfg):
clients = context["users"][0]["credential"].clients()
extensions = clients.neutron().list_extensions()["extensions"]
aliases = [x["alias"] for x in extensions]
for extension in self.req_ext:
@ -190,11 +189,10 @@ class FlavorExistsValidator(validation.Validator):
pass
self.fail("Flavor '%s' not found" % flavor_value)
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
# flavors do not depend on user or tenant, so checking for one user
# should be enough
user = credentials["openstack"]["users"][0]
clients = user["credential"].clients()
clients = context["users"][0]["credential"].clients()
self._get_validated_flavor(config=config,
clients=clients,
param_name=self.param_name)
@ -265,10 +263,10 @@ class ImageValidOnFlavorValidator(FlavorExistsValidator):
except (glance_exc.HTTPNotFound, exceptions.InvalidScenarioArgument):
self.fail("Image '%s' not found" % image_args)
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
flavor = None
for user in credentials["openstack"]["users"]:
for user in context["users"]:
clients = user["credential"].clients()
if not flavor:
@ -335,7 +333,7 @@ class RequiredClientsValidator(validation.Validator):
"Client for {0} is not installed. To install it run "
"`pip install python-{0}client`".format(client_component))
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
LOG.warning("The validator 'required_clients' is deprecated since "
"Rally 0.10.0. If you are interested in it, please "
"contact Rally team via E-mail, IRC or Gitter (see "
@ -343,10 +341,10 @@ class RequiredClientsValidator(validation.Validator):
"/index.html#where-can-i-discuss-and-propose-changes for "
"more details).")
if self.options.get("admin", False):
clients = credentials["openstack"]["admin"].clients()
clients = context["admin"]["credential"].clients()
self._check_component(clients)
else:
for user in credentials["openstack"]["users"]:
for user in context["users"]:
clients = user["credential"].clients()
self._check_component(clients)
break
@ -376,9 +374,9 @@ class RequiredServicesValidator(validation.Validator):
self.services = [services]
self.services.extend(args)
def validate(self, credentials, config, plugin_cls, plugin_cfg):
creds = (credentials["openstack"].get("admin")
or credentials["openstack"]["users"][0]["credential"])
def validate(self, context, config, plugin_cls, plugin_cfg):
creds = (context.get("admin", {}).get("credential", None)
or context["users"][0]["credential"])
available_services = creds.clients().services().values()
if consts.Service.NOVA_NET in self.services:
@ -425,7 +423,7 @@ class ValidateHeatTemplateValidator(validation.Validator):
self.params = [params]
self.params.extend(args)
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
for param_name in self.params:
template_path = config.get("args", {}).get(param_name)
@ -440,7 +438,7 @@ class ValidateHeatTemplateValidator(validation.Validator):
self.fail("No file found by the given path %s" % template_path)
with open(template_path, "r") as f:
try:
for user in credentials["openstack"]["users"]:
for user in context["users"]:
clients = user["credential"].clients()
clients.heat().stacks.validate(template=f.read())
except Exception as e:
@ -464,10 +462,10 @@ class RequiredCinderServicesValidator(validation.Validator):
super(RequiredCinderServicesValidator, self).__init__()
self.services = services
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
clients = credentials["openstack"]["admin"].clients().cinder()
for service in clients.services.list():
clients = context["admin"]["credential"].clients()
for service in clients.cinder().services.list():
if (service.binary == six.text_type(self.services)
and service.state == six.text_type("up")):
return
@ -489,13 +487,13 @@ class RequiredAPIVersionsValidator(validation.Validator):
self.component = component
self.versions = versions
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
versions = [str(v) for v in self.versions]
versions_str = ", ".join(versions)
msg = ("Task was designed to be used with %(component)s "
"V%(version)s, but V%(found_version)s is "
"selected.")
for user in credentials["openstack"]["users"]:
for user in context["users"]:
clients = user["credential"].clients()
if self.component == "keystone":
if "2.0" not in versions and hasattr(
@ -539,27 +537,27 @@ class VolumeTypeExistsValidator(validation.Validator):
self.param = param_name
self.nullable = nullable
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
volume_type = config.get("args", {}).get(self.param, False)
if not volume_type and self.nullable:
return
if volume_type:
for user in credentials["openstack"]["users"]:
clients = user["credential"].clients()
vt_names = [vt.name for vt in
clients.cinder().volume_types.list()]
ctx = config.get("context", {}).get("volume_types", [])
vt_names += ctx
if volume_type not in vt_names:
self.fail("Specified volume type %s not found for user %s."
" List of available types: %s" %
(volume_type, user, vt_names))
else:
if not volume_type:
self.fail("The parameter '%s' is required and should not be empty."
% self.param)
for user in context["users"]:
clients = user["credential"].clients()
vt_names = [vt.name for vt in
clients.cinder().volume_types.list()]
ctx = config.get("context", {}).get("volume_types", [])
vt_names += ctx
if volume_type not in vt_names:
self.fail("Specified volume type %s not found for user %s."
" List of available types: %s" %
(volume_type, user, vt_names))
@validation.configure(name="workbook_contains_workflow", platform="openstack")
class WorkbookContainsWorkflowValidator(validators.FileExistsValidator):
@ -574,7 +572,7 @@ class WorkbookContainsWorkflowValidator(validators.FileExistsValidator):
self.workbook = workbook_param
self.workflow = workflow_param
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
wf_name = config.get("args", {}).get(self.workflow)
if wf_name:
wb_path = config.get("args", {}).get(self.workbook)

View File

@ -260,14 +260,20 @@ class TaskEngine(object):
self.deployment = deployment
self.abort_on_sla_failure = abort_on_sla_failure
def _validate_workload(self, workload, credentials=None, vtype=None):
def _validate_workload(self, workload, vcontext=None, vtype=None):
"""Validate a workload.
:param workload: a workload configuration
:param vcontext: a validation context
:param vtype: a type of validation (platform, syntax or semantic)
"""
scenario_cls = scenario.Scenario.get(workload["name"])
scenario_context = copy.deepcopy(scenario_cls.get_default_context())
results = []
results.extend(scenario.Scenario.validate(
name=workload["name"],
credentials=credentials,
context=vcontext,
config=workload,
plugin_cfg=None,
vtype=vtype))
@ -275,7 +281,7 @@ class TaskEngine(object):
if workload["runner"]:
results.extend(runner.ScenarioRunner.validate(
name=workload["runner"]["type"],
credentials=credentials,
context=vcontext,
config=None,
plugin_cfg=workload["runner"],
vtype=vtype))
@ -283,7 +289,7 @@ class TaskEngine(object):
for context_name, context_conf in workload["context"].items():
results.extend(context.Context.validate(
name=context_name,
credentials=credentials,
context=vcontext,
config=None,
plugin_cfg=context_conf,
vtype=vtype))
@ -291,7 +297,7 @@ class TaskEngine(object):
for context_name, context_conf in scenario_context.items():
results.extend(context.Context.validate(
name=context_name,
credentials=credentials,
context=vcontext,
config=None,
plugin_cfg=context_conf,
allow_hidden=True,
@ -300,7 +306,7 @@ class TaskEngine(object):
for sla_name, sla_conf in workload["sla"].items():
results.extend(sla.SLA.validate(
name=sla_name,
credentials=credentials,
context=vcontext,
config=None,
plugin_cfg=sla_conf,
vtype=vtype))
@ -308,7 +314,7 @@ class TaskEngine(object):
for hook_conf in workload["hooks"]:
results.extend(hook.Hook.validate(
name=hook_conf["config"]["name"],
credentials=credentials,
context=vcontext,
config=None,
plugin_cfg=hook_conf["config"]["args"],
vtype=vtype))
@ -316,7 +322,7 @@ class TaskEngine(object):
trigger_conf = hook_conf["config"]["trigger"]
results.extend(trigger.Trigger.validate(
name=trigger_conf["name"],
credentials=credentials,
context=vcontext,
config=None,
plugin_cfg=trigger_conf["args"],
vtype=vtype))
@ -340,12 +346,15 @@ class TaskEngine(object):
@logging.log_task_wrapper(LOG.info, _("Task validation of required "
"platforms."))
def _validate_config_platforms(self, config):
# FIXME(andreykurilin): prepare the similar context object to others
credentials = self.deployment.get_all_credentials()
credentials = dict((p, creds[0]) for p, creds in credentials.items())
ctx = {"task": self.task,
"platforms": dict((p, creds[0])
for p, creds in credentials.items())}
for subtask in config.subtasks:
for workload in subtask["workloads"]:
self._validate_workload(
workload, credentials=credentials, vtype="platform")
workload, vcontext=ctx, vtype="platform")
@logging.log_task_wrapper(LOG.info, _("Task validation of semantic."))
def _validate_config_semantic(self, config):
@ -353,24 +362,10 @@ class TaskEngine(object):
validation_ctx = self.deployment.get_validation_context()
ctx_obj = {"task": self.task, "config": validation_ctx}
with context.ContextManager(ctx_obj):
# TODO(boris-42): Temporary adapter for current validators
# validators are going to accept completely
# context object instead of credentials,
# which unifies it to how scenarios works.
if "users@openstack" in validation_ctx:
credentials = {
"openstack": {
"admin": ctx_obj.get("admin", {}).get("credential"),
"users": ctx_obj["users"]
}
}
else:
credentials = {}
for subtask in config.subtasks:
for workload in subtask["workloads"]:
self._validate_workload(
workload, credentials, vtype="semantic")
workload, vcontext=ctx_obj, vtype="semantic")
@logging.log_task_wrapper(LOG.info, _("Task validation."))
def validate(self, only_syntax=False):

View File

@ -46,7 +46,12 @@ class ValidationResult(object):
class OldValidator(validation.Validator):
class Deployment(object):
pass
def __init__(self, ctx):
self.ctx = ctx
def get_credentials_for(self, platform):
return {"admin": self.ctx["admin"]["credential"],
"users": [u["credential"] for u in self.ctx["users"]]}
def __init__(self, fn, *args, **kwargs):
"""Legacy validator for OpenStack scenarios
@ -57,12 +62,10 @@ class OldValidator(validation.Validator):
self.args = args
self.kwargs = kwargs
def validate(self, credentials, config, plugin_cls, plugin_cfg):
creds = credentials.get("openstack", {})
users = creds.get("users", [])
def validate(self, context, config, plugin_cls, plugin_cfg):
users = context["users"]
deployment = self.Deployment()
deployment.get_credentials_for = credentials.get
deployment = self.Deployment(context)
if users:
users = [user["credential"].clients() for user in users]

View File

@ -51,7 +51,7 @@ class DummyValidator(validation.Validator):
super(DummyValidator, self).__init__()
self.foo = foo
def validate(self, credentials, config, plugin_cls, plugin_cfg):
def validate(self, context, config, plugin_cls, plugin_cfg):
if self.foo not in config:
raise Exception("foo")
@ -70,14 +70,15 @@ class ValidatorTestCase(test.TestCase):
class DummyPlugin(DummyPluginBase):
pass
creds = {"foo": {"admin": "fake_admin", "users": ["fake_user"]}}
ctx = {"platforms": {
"foo": {"admin": "fake_admin", "users": ["fake_user"]}}}
result = DummyPluginBase.validate(
name="dummy_plugin", credentials=creds,
name="dummy_plugin", context=ctx,
config={"bar": 1}, plugin_cfg={})
self.assertEqual(0, len(result))
self.assertEqual(0, len(result), result)
result = DummyPluginBase.validate(
name="dummy_plugin", credentials=creds, config={}, plugin_cfg={})
name="dummy_plugin", context=ctx, config={}, plugin_cfg={})
self.assertEqual(1, len(result))
self.assertIn("raise Exception(\"foo\")", result[0])
@ -100,36 +101,36 @@ class RequiredPlatformValidatorTestCase(test.TestCase):
@ddt.data(
{"kwargs": {"platform": "foo", "admin": True},
"credentials": {"foo": {"admin": "fake_admin"}}},
"context": {"platforms": {"foo": {"admin": "fake_admin"}}}},
{"kwargs": {"platform": "foo", "admin": True, "users": True},
"credentials": {"foo": {"admin": "fake_admin"}}},
"context": {"platforms": {"foo": {"admin": "fake_admin"}}}},
{"kwargs": {"platform": "foo", "admin": True, "users": True},
"credentials": {"foo": {"admin": "fake_admin",
"users": ["fake_user"]}}}
"context": {"platforms": {"foo": {"admin": "fake_admin",
"users": ["fake_user"]}}}}
)
@ddt.unpack
def test_validator(self, kwargs, credentials):
def test_validator(self, kwargs, context):
validator = validation.RequiredPlatformValidator(**kwargs)
validator.validate(credentials, None, None, None)
validator.validate(context, None, None, None)
@ddt.data(
{"kwargs": {"platform": "foo"},
"credentials": {},
"context": {},
"error_msg": "You should specify admin=True or users=True or both."},
{"kwargs": {"platform": "foo", "admin": True},
"credentials": None,
"context": {"platforms": {}},
"error_msg": "No admin credential for foo"},
{"kwargs": {"platform": "foo", "admin": True, "users": True},
"credentials": {"foo": {"users": ["fake_user"]}},
"context": {"platforms": {"foo": {"users": ["fake_user"]}}},
"error_msg": "No admin credential for foo"},
{"kwargs": {"platform": "foo", "users": True},
"credentials": {"foo": {}},
"context": {"platforms": {"foo": {}}},
"error_msg": "No user credentials for foo"}
)
@ddt.unpack
def test_validator_failed(self, kwargs, credentials, error_msg=False):
def test_validator_failed(self, kwargs, context, error_msg=False):
validator = validation.RequiredPlatformValidator(**kwargs)
e = self.assertRaises(
validation.ValidationError,
validator.validate, credentials, None, None, None)
validator.validate, context, None, None, None)
self.assertEqual(error_msg, e.message)

View File

@ -294,8 +294,8 @@ class ValidCommandValidatorTestCase(test.TestCase):
def setUp(self):
super(ValidCommandValidatorTestCase, self).setUp()
self.credentials = dict(openstack={"admin": mock.MagicMock(),
"users": [mock.MagicMock()], })
self.context = {"admin": {"credential": mock.MagicMock()},
"users": [{"credential": mock.MagicMock()}]}
@ddt.data({"command": {"script_inline": "foobar",
"interpreter": ["ENV=bar", "/bin/foo"],
@ -341,8 +341,8 @@ class ValidCommandValidatorTestCase(test.TestCase):
required=True)
mock__file_access_ok.return_value = None
command = {"script_file": "foobar", "interpreter": "foo"}
result = validator.validate({"args": {"p": command}},
self.credentials, None, None)
result = validator.validate(self.context, {"args": {"p": command}},
None, None)
self.assertIsNone(result)
mock__file_access_ok.assert_called_once_with(
filename="foobar", mode=os.R_OK, param_name="p",
@ -351,8 +351,8 @@ class ValidCommandValidatorTestCase(test.TestCase):
def test_valid_command_not_required(self):
validator = vmtasks.ValidCommandValidator(param_name="p",
required=False)
result = validator.validate({"args": {"p": None}},
self.credentials, None, None)
result = validator.validate(self.context, {"args": {"p": None}},
None, None)
self.assertIsNone(result)
def test_valid_command_required(self):
@ -362,7 +362,7 @@ class ValidCommandValidatorTestCase(test.TestCase):
e = self.assertRaises(
validation.ValidationError,
validator.validate, {"args": {"p": None}},
self.credentials, None, None)
self.context, None, None)
self.assertEqual("Command must be a dictionary", e.message)
@mock.patch("rally.plugins.common.validators.FileExistsValidator"
@ -376,8 +376,8 @@ class ValidCommandValidatorTestCase(test.TestCase):
command = {"script_file": "foobar", "interpreter": "foo"}
e = self.assertRaises(
validation.ValidationError,
validator.validate, {"args": {"p": command}},
self.credentials, None, None)
validator.validate, self.context, {"args": {"p": command}},
None, None)
self.assertEqual("O_o", e.message)
@mock.patch("%s.ValidCommandValidator.check_command_dict" % BASE)
@ -391,7 +391,7 @@ class ValidCommandValidatorTestCase(test.TestCase):
e = self.assertRaises(
validation.ValidationError,
validator.validate, {"args": {"p": {"foo": "bar"}}},
self.credentials, None, None)
self.context, None, None)
self.assertEqual("foobar", e.message)
def test_valid_command_script_inline(self):
@ -399,7 +399,7 @@ class ValidCommandValidatorTestCase(test.TestCase):
required=True)
command = {"script_inline": "bar", "interpreter": "/bin/sh"}
result = validator.validate({"args": {"p": command}}, self.credentials,
result = validator.validate(self.context, {"args": {"p": command}},
None, None)
self.assertIsNone(result)
@ -414,7 +414,7 @@ class ValidCommandValidatorTestCase(test.TestCase):
command = {"remote_path": "bar", "local_path": "foobar"}
self.assertRaises(
validation.ValidationError,
validator.validate, {"args": {"p": command}}, self.credentials,
validator.validate, self.context, {"args": {"p": command}},
None, None)
mock__file_access_ok.assert_called_once_with(
filename="foobar", mode=os.R_OK, param_name="p",

View File

@ -29,11 +29,9 @@ from tests.unit import test
PATH = "rally.plugins.openstack.validators"
credentials = {
"openstack": {
"admin": mock.MagicMock(),
"users": [mock.MagicMock()],
}
context = {
"admin": mock.MagicMock(),
"users": [mock.MagicMock()],
}
config = dict(args={"image": {"id": "fake_id",
@ -57,7 +55,7 @@ class ImageExistsValidatorTestCase(test.TestCase):
super(ImageExistsValidatorTestCase, self).setUp()
self.validator = validators.ImageExistsValidator("image", True)
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
@ddt.unpack
@ddt.data(
@ -70,8 +68,7 @@ class ImageExistsValidatorTestCase(test.TestCase):
validator = validators.ImageExistsValidator(param_name,
nullable)
clients = self.credentials[
"openstack"]["users"][0].clients.return_value
clients = self.context["users"][0].clients.return_value
clients.glance().images.get = mock.Mock()
if ex:
@ -80,10 +77,10 @@ class ImageExistsValidatorTestCase(test.TestCase):
if err_msg:
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
self.assertEqual(err_msg, e.message)
else:
result = validator.validate(self.config, self.credentials, None,
result = validator.validate(self.config, self.context, None,
None)
self.assertIsNone(result)
@ -93,7 +90,7 @@ class ImageExistsValidatorTestCase(test.TestCase):
"images": {
"image_name": "foo"}}}
self.validator.validate(self.credentials, config, None, None)
self.validator.validate(self.context, config, None, None)
@mock.patch("%s.openstack_types.GlanceImage.transform" % PATH,
return_value="image_id")
@ -103,11 +100,11 @@ class ImageExistsValidatorTestCase(test.TestCase):
"images": {
"fake_image_name": "foo"}}}
clients = self.credentials[
"openstack"]["users"][0].get.return_value.clients.return_value
clients = self.context[
"users"][0]["credential"].clients.return_value
clients.glance().images.get = mock.Mock()
result = self.validator.validate(self.credentials, config, None, None)
result = self.validator.validate(self.context, config, None, None)
self.assertIsNone(result)
mock_glance_image_transform.assert_called_once_with(
@ -121,7 +118,7 @@ class ImageExistsValidatorTestCase(test.TestCase):
e = self.assertRaises(
validators.validation.ValidationError,
self.validator.validate, self.credentials, config, None, None)
self.validator.validate, self.context, config, None, None)
self.assertEqual("Image 'fake_image' not found", e.message)
@ -133,7 +130,7 @@ class ExternalNetworkExistsValidatorTestCase(test.TestCase):
super(ExternalNetworkExistsValidatorTestCase, self).setUp()
self.validator = validators.ExternalNetworkExistsValidator("net")
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
@ddt.unpack
@ddt.data(
@ -153,7 +150,7 @@ class ExternalNetworkExistsValidatorTestCase(test.TestCase):
def test_validator(self, foo_conf, net1_name="public", net2_name="custom",
err_msg=""):
user = self.credentials["openstack"]["users"][0]
user = self.context["users"][0]
net1 = {"name": net1_name, "router:external": True}
net2 = {"name": net2_name, "router:external": True}
@ -163,13 +160,13 @@ class ExternalNetworkExistsValidatorTestCase(test.TestCase):
if err_msg:
e = self.assertRaises(
validators.validation.ValidationError,
self.validator.validate, self.credentials, foo_conf,
self.validator.validate, self.context, foo_conf,
None, None)
self.assertEqual(
err_msg.format(user["credential"].username, net1, net2),
e.message)
else:
result = self.validator.validate(self.credentials, foo_conf,
result = self.validator.validate(self.context, foo_conf,
None, None)
self.assertIsNone(result, "Unexpected result '%s'" % result)
@ -180,32 +177,30 @@ class RequiredNeutronExtensionsValidatorTestCase(test.TestCase):
def setUp(self):
super(RequiredNeutronExtensionsValidatorTestCase, self).setUp()
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
def test_validator(self):
validator = validators.RequiredNeutronExtensionsValidator(
"existing_extension")
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.neutron().list_extensions.return_value = {
"extensions": [{"alias": "existing_extension"}]}
validator.validate(self.credentials, {}, None, None)
validator.validate(self.context, {}, None, None)
def test_validator_failed(self):
err_msg = "Neutron extension absent_extension is not configured"
validator = validators.RequiredNeutronExtensionsValidator(
"absent_extension")
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.neutron().list_extensions.return_value = {
"extensions": [{"alias": "existing_extension"}]}
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, {}, None, None)
validator.validate, self.context, {}, None, None)
self.assertEqual(err_msg, e.message)
@ -216,13 +211,13 @@ class FlavorExistsValidatorTestCase(test.TestCase):
self.validator = validators.FlavorExistsValidator(
param_name="foo_flavor")
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
def test__get_validated_flavor_wrong_value_in_config(self):
e = self.assertRaises(
validators.validation.ValidationError,
self.validator._get_validated_flavor, self.config,
self.credentials, "foo_flavor")
mock.MagicMock(), "foo_flavor")
self.assertEqual("Parameter foo_flavor is not specified.",
e.message)
@ -290,14 +285,14 @@ class FlavorExistsValidatorTestCase(test.TestCase):
side_effect=expected_e)
config = mock.Mock()
creds = mock.MagicMock()
ctx = mock.MagicMock()
actual_e = self.assertRaises(
validators.validation.ValidationError,
self.validator.validate, creds, config, None, None)
self.validator.validate, ctx, config, None, None)
self.assertEqual(expected_e, actual_e)
self.validator._get_validated_flavor.assert_called_once_with(
config=config,
clients=creds["openstack"]["users"][0]["credential"].clients(),
clients=ctx["users"][0]["credential"].clients(),
param_name=self.validator.param_name)
@ -309,7 +304,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
self.validator = validators.ImageValidOnFlavorValidator("foo_flavor",
"image")
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
@ddt.data(
{"validate_disk": True, "flavor_disk": True},
@ -339,20 +334,19 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
# case 1: no image, but it is ok, since fail_on_404_image is False
validator._get_validated_image = mock.Mock(
side_effect=validators.validation.ValidationError("!!!"))
validator.validate(self.credentials, {}, None, None)
validator.validate(self.context, {}, None, None)
# case 2: there is an image
validator._get_validated_image = mock.Mock(
return_value=fake_image)
validator.validate(self.credentials, {}, None, None)
validator.validate(self.context, {}, None, None)
# case 3: check caching of the flavor
user = self.credentials["openstack"]["users"][0]
self.credentials["openstack"]["users"].append(user)
self.context["users"].append(self.context["users"][0])
validator._get_validated_image.reset_mock()
validator._get_validated_flavor.reset_mock()
validator.validate(self.credentials, {}, None, None)
validator.validate(self.context, {}, None, None)
self.assertEqual(1, validator._get_validated_flavor.call_count)
self.assertEqual(2, validator._get_validated_image.call_count)
@ -378,7 +372,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
side_effect=expected_e)
actual_e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, {}, None, None
validator.validate, self.context, {}, None, None
)
self.assertEqual(expected_e, actual_e)
@ -387,7 +381,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
validator._get_validated_flavor.side_effect = expected_e
actual_e = self.assertRaises(
KeyError,
validator.validate, self.credentials, {}, None, None
validator.validate, self.context, {}, None, None
)
self.assertEqual(expected_e, actual_e)
@ -400,7 +394,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
return_value=fake_image)
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, {}, None, None
validator.validate, self.context, {}, None, None
)
self.assertEqual(
"The memory size for flavor 'flavor_id' is too small for "
@ -414,7 +408,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
return_value=fake_image)
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, {}, None, None
validator.validate, self.context, {}, None, None
)
self.assertEqual(
"The disk size for flavor 'flavor_id' is too small for "
@ -429,7 +423,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
return_value=fake_image)
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, {}, None, None
validator.validate, self.context, {}, None, None
)
self.assertEqual(
"The minimal disk size for flavor 'flavor_id' is too small for "
@ -449,7 +443,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
actual_e = self.assertRaises(
KeyError,
validator.validate, self.credentials, {}, None, None
validator.validate, self.context, {}, None, None
)
self.assertEqual(expected_e, actual_e)
@ -467,7 +461,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
"image": {"regex": r"^foo$"}}, "context": {
"images": {
"image_name": "foo"}
}}, self.credentials, "image")
}}, mock.Mock(), "image")
self.assertEqual(image, result)
clients = mock.Mock()
@ -491,7 +485,7 @@ class ImageValidOnFlavorValidatorTestCase(test.TestCase):
e = self.assertRaises(
validators.validation.ValidationError,
self.validator._get_validated_image, self.config,
self.credentials, "fake_param")
mock.Mock(), "fake_param")
self.assertEqual("Parameter fake_param is not specified.",
e.message)
@ -546,21 +540,20 @@ class RequiredClientsValidatorTestCase(test.TestCase):
def setUp(self):
super(RequiredClientsValidatorTestCase, self).setUp()
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
def test_validate(self):
validator = validators.RequiredClientsValidator(components=["keystone",
"nova"])
clients = self.credentials[
"openstack"]["users"][0]["credential"].clients.return_value
clients = self.context["users"][0]["credential"].clients.return_value
result = validator.validate(self.credentials, self.config, None, None)
result = validator.validate(self.context, self.config, None, None)
self.assertIsNone(result)
clients.nova.side_effect = ImportError
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
self.assertEqual("Client for nova is not installed. To install it "
"run `pip install python-novaclient`", e.message)
@ -568,15 +561,14 @@ class RequiredClientsValidatorTestCase(test.TestCase):
validator = validators.RequiredClientsValidator(components=["keystone",
"nova"],
admin=True)
clients = self.credentials[
"openstack"]["admin"].clients.return_value
result = validator.validate(self.credentials, self.config, None, None)
clients = self.context["admin"]["credential"].clients.return_value
result = validator.validate(self.context, self.config, None, None)
self.assertIsNone(result)
clients.keystone.side_effect = ImportError
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
self.assertEqual("Client for keystone is not installed. To install it "
"run `pip install python-keystoneclient`", e.message)
@ -590,33 +582,33 @@ class RequiredServicesValidatorTestCase(test.TestCase):
consts.Service.NOVA,
consts.Service.NOVA_NET])
self.config = config
self.credentials = credentials
self.context = context
def test_validator(self):
self.config["context"]["api_versions@openstack"].get = mock.Mock(
return_value={consts.Service.KEYSTONE: "service_type"})
clients = self.credentials["openstack"]["admin"].clients()
clients = self.context["admin"].get("credential").clients()
clients.services().values.return_value = [
consts.Service.KEYSTONE, consts.Service.NOVA,
consts.Service.NOVA_NET]
fake_service = mock.Mock(binary="nova-network", status="enabled")
clients.nova.services.list.return_value = [fake_service]
result = self.validator.validate(self.credentials, self.config,
result = self.validator.validate(self.context, self.config,
None, None)
self.assertIsNone(result)
fake_service = mock.Mock(binary="keystone", status="enabled")
clients.nova.services.list.return_value = [fake_service]
result = self.validator.validate(self.credentials, self.config,
result = self.validator.validate(self.context, self.config,
None, None)
self.assertIsNone(result)
fake_service = mock.Mock(binary="nova-network", status="disabled")
clients.nova.services.list.return_value = [fake_service]
result = self.validator.validate(self.credentials, self.config,
result = self.validator.validate(self.context, self.config,
None, None)
self.assertIsNone(result)
@ -626,7 +618,7 @@ class RequiredServicesValidatorTestCase(test.TestCase):
return_value={consts.Service.KEYSTONE: "service_type",
consts.Service.NOVA: "service_name"})
clients = self.credentials["openstack"]["admin"].clients()
clients = self.context["admin"].get("credential").clients()
clients.services().values.return_value = [
consts.Service.KEYSTONE, consts.Service.NOVA]
@ -636,7 +628,7 @@ class RequiredServicesValidatorTestCase(test.TestCase):
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, {}, None, None)
validator.validate, self.context, {}, None, None)
expected_msg = ("'{0}' service is not available. Hint: If '{0}'"
" service has non-default service_type, try to setup"
" it via 'api_versions' context.").format("lol")
@ -651,7 +643,7 @@ class ValidateHeatTemplateValidatorTestCase(test.TestCase):
self.validator = validators.ValidateHeatTemplateValidator(
"template_path1", "template_path2")
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
@ddt.data(
{"exception_msg": "Heat template validation failed on fake_path1. "
@ -664,8 +656,7 @@ class ValidateHeatTemplateValidatorTestCase(test.TestCase):
@mock.patch("rally.plugins.openstack.validators.open",
side_effect=mock.mock_open(), create=True)
def test_validate(self, mock_open, mock_exists, exception_msg):
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
mock_open().__enter__().read.side_effect = ["fake_template1",
"fake_template2"]
heat_validator = mock.MagicMock()
@ -675,8 +666,7 @@ class ValidateHeatTemplateValidatorTestCase(test.TestCase):
context = {"args": {"template_path1": "fake_path1",
"template_path2": "fake_path2"}}
if not exception_msg:
result = self.validator.validate(self.credentials, context, None,
None)
result = self.validator.validate(self.context, context, None, None)
heat_validator.assert_has_calls([
mock.call(template="fake_template1"),
@ -690,7 +680,7 @@ class ValidateHeatTemplateValidatorTestCase(test.TestCase):
else:
e = self.assertRaises(
validators.validation.ValidationError,
self.validator.validate, self.credentials, context, None, None)
self.validator.validate, self.context, context, None, None)
heat_validator.assert_called_once_with(
template="fake_template1")
self.assertEqual(
@ -703,7 +693,7 @@ class ValidateHeatTemplateValidatorTestCase(test.TestCase):
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
expected_msg = ("Path to heat template is not specified. Its needed "
"for heat template validation. Please check the "
@ -713,11 +703,11 @@ class ValidateHeatTemplateValidatorTestCase(test.TestCase):
@mock.patch("%s.os.path.exists" % PATH,
return_value=False)
def test_validate_file_not_found(self, mock_exists):
context = {"args": {"template_path1": "fake_path1",
"template_path2": "fake_path2"}}
config = {"args": {"template_path1": "fake_path1",
"template_path2": "fake_path2"}}
e = self.assertRaises(
validators.validation.ValidationError,
self.validator.validate, self.credentials, context, None, None)
self.validator.validate, self.context, config, None, None)
expected_msg = "No file found by the given path fake_path1"
self.assertEqual(expected_msg, e.message)
@ -726,7 +716,7 @@ class RequiredCinderServicesValidatorTestCase(test.TestCase):
def setUp(self):
super(RequiredCinderServicesValidatorTestCase, self).setUp()
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
self.config = copy.deepcopy(config)
def test_validate(self):
@ -734,15 +724,15 @@ class RequiredCinderServicesValidatorTestCase(test.TestCase):
"cinder_service")
fake_service = mock.Mock(binary="cinder_service", state="up")
clients = self.credentials["openstack"]["admin"].clients()
clients = self.context["admin"]["credential"].clients()
clients.cinder().services.list.return_value = [fake_service]
result = validator.validate(self.credentials, self.config, None, None)
result = validator.validate(self.context, self.config, None, None)
self.assertIsNone(result)
fake_service.state = "down"
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
self.assertEqual("cinder_service service is not available",
e.message)
@ -753,7 +743,7 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
def setUp(self):
super(RequiredAPIVersionsValidatorTestCase, self).setUp()
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
def _get_keystone_v2_mock_client(self):
keystone = mock.Mock()
@ -771,28 +761,26 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
validator = validators.RequiredAPIVersionsValidator("keystone",
[2.0, 3])
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.keystone.return_value = self._get_keystone_v3_mock_client()
validator.validate(self.credentials, self.config, None, None)
validator.validate(self.context, self.config, None, None)
clients.keystone.return_value = self._get_keystone_v2_mock_client()
validator.validate(self.credentials, self.config, None, None)
validator.validate(self.context, self.config, None, None)
def test_validate_with_keystone_v2(self):
validator = validators.RequiredAPIVersionsValidator("keystone",
[2.0])
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.keystone.return_value = self._get_keystone_v2_mock_client()
validator.validate(self.credentials, self.config, None, None)
validator.validate(self.context, self.config, None, None)
clients.keystone.return_value = self._get_keystone_v3_mock_client()
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
self.assertEqual("Task was designed to be used with keystone V2.0, "
"but V3 is selected.", e.message)
@ -800,15 +788,14 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
validator = validators.RequiredAPIVersionsValidator("keystone",
[3])
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.keystone.return_value = self._get_keystone_v3_mock_client()
validator.validate(self.credentials, self.config, None, None)
validator.validate(self.context, self.config, None, None)
clients.keystone.return_value = self._get_keystone_v2_mock_client()
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
self.assertEqual("Task was designed to be used with keystone V3, "
"but V2.0 is selected.", e.message)
@ -829,8 +816,7 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
validator = validators.RequiredAPIVersionsValidator("nova",
versions)
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.nova.choose_version.return_value = nova
config = {"context": {"api_versions@openstack": {}}}
@ -838,10 +824,10 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
if err_msg:
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, config, None, None)
validator.validate, self.context, config, None, None)
self.assertEqual(err_msg, e.message)
else:
result = validator.validate(self.credentials, config, None, None)
result = validator.validate(self.context, config, None, None)
self.assertIsNone(result)
@ddt.unpack
@ -858,10 +844,10 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
if err_msg:
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, config, None, None)
validator.validate, self.context, config, None, None)
self.assertEqual(err_msg, e.message)
else:
result = validator.validate(self.credentials, config, None, None)
result = validator.validate(self.context, config, None, None)
self.assertIsNone(result)
@ -872,70 +858,61 @@ class VolumeTypeExistsValidatorTestCase(test.TestCase):
self.validator = validators.VolumeTypeExistsValidator("volume_type",
True)
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
self.context = copy.deepcopy(context)
def test_validator_without_ctx(self):
validator = validators.VolumeTypeExistsValidator("fake_param",
nullable=True)
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.cinder().volume_types.list.return_value = [mock.MagicMock()]
result = validator.validate(self.credentials, self.config, None, None)
result = validator.validate(self.context, self.config, None, None)
self.assertIsNone(result, "Unexpected result")
def test_validator_without_ctx_failed(self):
validator = validators.VolumeTypeExistsValidator("fake_param",
nullable=False)
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.cinder().volume_types.list.return_value = [mock.MagicMock()]
e = self.assertRaises(
validators.validation.ValidationError,
validator.validate, self.credentials, self.config, None, None)
validator.validate, self.context, self.config, None, None)
self.assertEqual(
"The parameter 'fake_param' is required and should not be empty.",
e.message)
def test_validate_with_ctx(self):
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.cinder().volume_types.list.return_value = []
ctx = {"args": {"volume_type": "fake_type"},
"context": {"volume_types": ["fake_type"]}}
result = self.validator.validate(self.credentials, ctx, None, None)
result = self.validator.validate(self.context, ctx, None, None)
self.assertIsNone(result)
def test_validate_with_ctx_failed(self):
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients = self.context["users"][0]["credential"].clients()
clients.cinder().volume_types.list.return_value = []
ctx = {"args": {"volume_type": "fake_type"},
"context": {"volume_types": ["fake_type_2"]}}
config = {"args": {"volume_type": "fake_type"},
"context": {"volume_types": ["fake_type_2"]}}
e = self.assertRaises(
validators.validation.ValidationError,
self.validator.validate, self.credentials, ctx, None, None)
self.validator.validate, self.context, config, None, None)
err_msg = ("Specified volume type fake_type not found for user {}. "
"List of available types: ['fake_type_2']")
fake_user = self.credentials["openstack"]["users"][0]
fake_user = self.context["users"][0]
self.assertEqual(err_msg.format(fake_user), e.message)
@ddt.ddt
class WorkbookContainsWorkflowValidatorTestCase(test.TestCase):
def setUp(self):
super(WorkbookContainsWorkflowValidatorTestCase, self).setUp()
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
@mock.patch("rally.common.yamlutils.safe_load")
@mock.patch("%s.os.access" % PATH)
@mock.patch("%s.open" % PATH)
@ -957,14 +934,14 @@ class WorkbookContainsWorkflowValidatorTestCase(test.TestCase):
validator = validators.WorkbookContainsWorkflowValidator(
workbook_param="definition", workflow_param="workflow_name")
context = {
config = {
"args": {
"definition": "fake_path1",
"workflow_name": "wf1"
}
}
result = validator.validate(None, context, None, None)
result = validator.validate(None, config, None, None)
self.assertIsNone(result)
self.assertEqual(1, mock_open.called)

View File

@ -169,28 +169,28 @@ class TaskEngineTestCase(test.TestCase):
eng._validate_workload(workload)
mock_scenario_runner_validate.assert_called_once_with(
name=runner_type, credentials=None, config=None,
name=runner_type, context=None, config=None,
plugin_cfg={"type": runner_type}, vtype=None)
self.assertEqual([mock.call(name="a",
credentials=None,
context=None,
config=None,
plugin_cfg="a_conf",
vtype=None),
mock.call(name="foo",
credentials=None,
context=None,
config=None,
plugin_cfg="foo_conf",
allow_hidden=True,
vtype=None)],
mock_context_validate.call_args_list)
mock_sla_validate.assert_called_once_with(
config=None, credentials=None,
config=None, context=None,
name="foo_sla", plugin_cfg="sla_conf", vtype=None)
mock_hook_validate.assert_called_once_with(
config=None, credentials=None, name="c", plugin_cfg="c_args",
config=None, context=None, name="c", plugin_cfg="c_args",
vtype=None)
mock_trigger_validate.assert_called_once_with(
config=None, credentials=None, name="d", plugin_cfg="d_args",
config=None, context=None, name="d", plugin_cfg="d_args",
vtype=None)
@mock.patch("rally.task.engine.json.dumps")
@ -394,7 +394,9 @@ class TaskEngineTestCase(test.TestCase):
eng._validate_config_platforms(config)
self.assertEqual(
[mock.call(w, vtype="platform", credentials={"foo": foo_cred1})
[mock.call(w, vtype="platform",
vcontext={"platforms": {"foo": foo_cred1},
"task": eng.task})
for w in (workload1, workload2)],
mock__validate_workload.call_args_list)
deployment.get_all_credentials.assert_called_once_with()

View File

@ -89,7 +89,7 @@ class ScenarioTestCase(test.TestCase):
for context_name, context_conf in s.get_default_context().items():
results.extend(context.Context.validate(
name=context_name,
credentials=None,
context=None,
config=None,
plugin_cfg=context_conf,
allow_hidden=True,

View File

@ -49,8 +49,8 @@ class ValidationUtilsTestCase(test.TestCase):
validator_cls = common_validation.Validator.get(vname)
validator_inst = validator_cls(*args, **kwargs)
fake_admin = fakes.fake_credential()
credentials = {"openstack": {"admin": fake_admin, "users": []}}
result = validator_inst.validate(credentials, {}, None, None)
ctx = {"admin": {"credential": fake_admin}, "users": []}
result = validator_inst.validate(ctx, {}, None, None)
self.assertIsNone(result)
validator_func.assert_called_once_with(
@ -77,8 +77,8 @@ class ValidationUtilsTestCase(test.TestCase):
fake_users1 = fakes.fake_credential()
fake_users2 = fakes.fake_credential()
users = [{"credential": fake_users1}, {"credential": fake_users2}]
credentials = {"openstack": {"admin": fake_admin, "users": users}}
result = validator_inst.validate(credentials, {}, None, None)
ctx = {"admin": {"credential": fake_admin}, "users": users}
result = validator_inst.validate(ctx, {}, None, None)
self.assertIsNone(result)
fake_users1.clients.assert_called_once_with()
@ -91,7 +91,8 @@ class ValidationUtilsTestCase(test.TestCase):
))
for args in validator_func.call_args:
deployment = validator_func.call_args[0][2]
self.assertEqual({"admin": fake_admin, "users": users},
self.assertEqual({"admin": fake_admin,
"users": [fake_users1, fake_users2]},
deployment.get_credentials_for("openstack"))
def test_old_validator_users_error(self):
@ -112,10 +113,10 @@ class ValidationUtilsTestCase(test.TestCase):
fake_users1 = fakes.fake_credential()
fake_users2 = fakes.fake_credential()
users = [{"credential": fake_users1}, {"credential": fake_users2}]
credentials = {"openstack": {"admin": fake_admin, "users": users}}
ctx = {"admin": {"credential": fake_admin}, "users": users}
self.assertRaises(
common_validation.ValidationError,
validator_inst.validate, credentials, {}, None, None)
validator_inst.validate, ctx, {}, None, None)
fake_users1.clients.assert_called_once_with()
fake_users2.clients.assert_called_once_with()
@ -123,7 +124,8 @@ class ValidationUtilsTestCase(test.TestCase):
{}, fake_users1.clients.return_value, mock.ANY,
"a", "b", "c", d=1)
deployment = validator_func.call_args[0][2]
self.assertEqual({"admin": fake_admin, "users": users},
self.assertEqual({"admin": fake_admin,
"users": [fake_users1, fake_users2]},
deployment.get_credentials_for("openstack"))
@mock.patch("rally.task.validation.LOG.warning")