import yaml import json import lollipop.types as lp_types import lollipop.validators as lp_validators from rally import exceptions from rally import plugins from rally.task import context from rally.task import runner from rally.task import scenario from rally.task import sla class RallyPluginExist(lp_validators.Validator): default_error_messages = { "not_found": "Didn't find any plugin with name: {plugin}", "multiple_found": "{error}" } def __init__(self, plugin_base): super(RallyPluginExist, self).__init__() self.plugin_base = plugin_base @plugins.ensure_plugins_are_loaded def __call__(self, data, context=None): try: self.plugin_base.get(data) except exceptions.PluginNotFound: self._fail("not_found", data=data, plugin=data) except exceptions.MultipleMatchesFound as e: self._fail("multiple_found", data=data, error=e.message) class Each(lp_validators.Validator): """Validator that takes a list of validators and applies all of them to each item in collection. :param validators: Validator or list of validators to run against each element of collection. """ default_error_messages = { 'invalid': 'Value should be collection', } def __init__(self, validators, **kwargs): super(Each, self).__init__(**kwargs) if not isinstance(validators, (list, tuple)): validators = [validators] self.validators = validators def __call__(self, value, context=None): if not isinstance(value, (tuple, list, dict)): self._fail('invalid', data=value) error_builder = lp_validators.ValidationErrorBuilder() for idx, item in enumerate(value): for validator in self.validators: try: validator(item) except lp_validators.ValidationError as ve: error_builder.add_errors({idx: ve.messages}) error_builder.raise_errors() def __repr__(self): return "<{klass} {validators!r}>".format( klass=self.__class__.__name__, validators=self.validators, ) def check_plugins(plugin_base, only_one=False): v = [Each(RallyPluginExist(plugin_base))] if only_one: v.append(lp_validators.Length(min=1, max=1)) return v _TagsType = lp_types.Optional( lp_types.List( lp_types.String(validate=[lp_validators.Length(min=1)]), validate=[lp_validators.Unique()]), load_default=[] ) _WorkloadType = lp_types.Object({ "scenario": lp_types.Dict( key_type=lp_types.String(validate=[lp_validators.Regexp(".*")]), validate=check_plugins(scenario.Scenario, only_one=True)), "runner": lp_types.Optional( lp_types.Dict( key_type=lp_types.String(validate=[lp_validators.Regexp(".*")]), validate=check_plugins(runner.ScenarioRunner, only_one=True)), load_default={"serial": {}}), "contexts": lp_types.Optional( lp_types.Dict( key_type=lp_types.String(validate=[lp_validators.Regexp(".*")]), validate=check_plugins(context.Context)), load_default={}, ), "sla": lp_types.Optional( lp_types.Object({}, validate=check_plugins(sla.SLA)), load_default={"failure_rate": {"max": 0}} ), "hooks": lp_types.Optional( lp_types.List(lp_types.Dict()), load_default=[])}, allow_extra_fields=False) def _subtask_load_hint(data): if "workloads" in data: return "MultipleWorkloads" else: return "SingleWorkload" _SubTaskType = lp_types.OneOf({ "SingleWorkload": lp_types.Object( _WorkloadType, { "title": lp_types.Optional( lp_types.String(validate=[lp_validators.Length(min=1)])), "description": lp_types.Optional(lp_types.String(), load_default=""), "group": lp_types.Optional( lp_types.String(validate=[lp_validators.Length(min=1)])), "tags": _TagsType }), "MultipleWorkloads": lp_types.Object({ "title": lp_types.Optional( lp_types.String(validate=[lp_validators.Length(min=1)])), "description": lp_types.Optional(lp_types.String(), load_default=""), "group": lp_types.Optional( lp_types.String(validate=[lp_validators.Length(min=1)])), "tags": _TagsType, "workloads": lp_types.List( _WorkloadType, validate=[lp_validators.Length(min=1)] )}, allow_extra_fields=False, )}, load_hint=_subtask_load_hint ) InputTaskV2Type = lp_types.Object({ "version": lp_types.Optional( lp_types.Integer( validate=[lp_validators.AnyOf([2])], error_messages={ "invalid": "Rally supports only Input Task Format ver. 2"}), load_default=2), "title": lp_types.String(), "description": lp_types.Optional(lp_types.String(), load_default=""), "tags": _TagsType, "subtasks": lp_types.List( _SubTaskType, validate=lp_validators.Length(min=1) ) })