def validate(config): """Validates runner's part of task config.""" super(RPSScenarioRunner, RPSScenarioRunner).validate(config) if isinstance(config["rps"], dict): if config["rps"]["end"] < config["rps"]["start"]: msg = "rps end value must not be less than rps start value." raise exceptions.InvalidTaskException(msg)
def test_validate_invalid(self, mock__load_and_validate_task): exc = exceptions.InvalidTaskException("foo") self.fake_api.task.validate.side_effect = exc self.assertRaises(exceptions.InvalidTaskException, self.task.validate, self.fake_api, "path_to_task", "deployment") self.fake_api.task.validate.assert_called_once_with( "deployment", mock__load_and_validate_task.return_value)
def validate(self): """Perform full task configuration validation.""" self.task.update_status(consts.TaskStatus.VERIFYING) try: self._validate_config_scenarios_name(self.config) self._validate_config_syntax(self.config) self._validate_config_semantic(self.config) except Exception as e: log = [str(type(e)), str(e), json.dumps(traceback.format_exc())] self.task.set_failed(log=log) raise exceptions.InvalidTaskException(str(e))
def validate(self): """Perform full task configuration validation.""" self.task.update_status(consts.TaskStatus.VERIFYING) try: self._validate_config_scenarios_name(self.config) self._validate_config_syntax(self.config) self._validate_config_semantic(self.config) except Exception as e: exception_info = json.dumps(traceback.format_exc(), indent=2) self.task.set_failed(type(e).__name__, str(e), exception_info) LOG.debug(exception_info) raise exceptions.InvalidTaskException(str(e))
def validate(self): """Perform full task configuration validation.""" self.task.update_status(consts.TaskStatus.VALIDATING) try: self._validate_config_scenarios_name(self.config) self._validate_config_syntax(self.config) self._validate_config_semantic(self.config) except Exception as e: exception_info = json.dumps(traceback.format_exc(), indent=2, separators=(",", ": ")) self.task.set_failed(type(e).__name__, str(e), exception_info) if logging.is_debug(): LOG.exception(e) raise exceptions.InvalidTaskException(str(e))
def _process_1(self, config): try: jsonschema.validate(config, self.CONFIG_SCHEMA_V1) except jsonschema.ValidationError as e: raise exceptions.InvalidTaskException(str(e)) subtasks = [] for name, v1_workloads in config.items(): workloads = [] for v1_workload in v1_workloads: v2_workload = copy.deepcopy(v1_workload) v2_workload["scenario"] = {name: v2_workload.pop("args", {})} v2_workload["contexts"] = v2_workload.pop("context", {}) if "runner" in v2_workload: runner_type = v2_workload["runner"].pop("type") v2_workload["runner"] = { runner_type: v2_workload["runner"] } if "hooks" in v2_workload: hooks = v2_workload["hooks"] v2_workload["hooks"] = [] for hook_cfg in hooks: trigger_cfg = hook_cfg["trigger"] v2_workload["hooks"].append({ "description": hook_cfg.get("description"), "action": { hook_cfg["name"]: hook_cfg["args"] }, "trigger": { trigger_cfg["name"]: trigger_cfg["args"] } }) workloads.append(v2_workload) subtasks.append({ "title": name, "workloads": workloads, }) return { "title": "Task (adopted from task format v1)", "subtasks": subtasks }
def validate(self, only_syntax=False): """Perform full task configuration validation. :param only_syntax: Check only syntax of task configuration """ self.task.update_status(consts.TaskStatus.VALIDATING) try: self._validate_config_syntax(self.config) if only_syntax: return self._validate_config_platforms(self.config) self._validate_config_semantic(self.config) except Exception as e: exception_info = json.dumps(traceback.format_exc(), indent=2, separators=(",", ": ")) self.task.set_failed(type(e).__name__, str(e), exception_info) if (logging.is_debug() and not isinstance(e, exceptions.InvalidTaskConfig)): LOG.exception("Invalid Task") raise exceptions.InvalidTaskException(str(e))
def __init__(self, config, task, deployment, abort_on_sla_failure=False): """TaskEngine constructor. :param config: Dict with configuration of specified benchmark scenarios :param task: Instance of Task, the current task which is being performed :param deployment: Instance of Deployment, :param abort_on_sla_failure: True if the execution should be stopped when some SLA check fails """ try: self.config = TaskConfig(config) except Exception as e: task.set_failed( type(e).__name__, str(e), json.dumps(traceback.format_exc())) if logging.is_debug(): LOG.exception(e) raise exceptions.InvalidTaskException(str(e)) self.task = task self.deployment = deployment self.abort_on_sla_failure = abort_on_sla_failure
def __init__(self, config, task, admin=None, users=None, abort_on_sla_failure=False): """TaskEngine constructor. :param config: Dict with configuration of specified benchmark scenarios :param task: Instance of Task, the current task which is being performed :param admin: Dict with admin credentials :param users: List of dicts with user credentials :param abort_on_sla_failure: True if the execution should be stopped when some SLA check fails """ try: self.config = TaskConfig(config) except Exception as e: log = [str(type(e)), str(e), json.dumps(traceback.format_exc())] task.set_failed(log=log) raise exceptions.InvalidTaskException(str(e)) self.task = task self.admin = admin and objects.Credential(**admin) or None self.existing_users = users or [] self.abort_on_sla_failure = abort_on_sla_failure
def _validate_json(self, config): try: jsonschema.validate(config, self.CONFIG_SCHEMAS[self.version]) except Exception as e: raise exceptions.InvalidTaskException(str(e))
def _validate_version(self): if self.version not in self.CONFIG_SCHEMAS: allowed = ", ".join([str(k) for k in self.CONFIG_SCHEMAS]) msg = (_("Task configuration version {0} is not supported. " "Supported versions: {1}")).format(self.version, allowed) raise exceptions.InvalidTaskException(msg)
def __init__(self, config): """TaskConfig constructor. Validates and represents different versions of task configuration in unified form. :param config: Dict with configuration of specified task :raises InvalidTaskException: in case of validation error :raises Exception: in case of some unexpected things """ if config is None: raise exceptions.InvalidTaskException("It is empty") elif not isinstance(config, dict): raise exceptions.InvalidTaskException("It is not a dict") self.version = str(config.get("version", 1)) processors = {} for name in dir(self): if not name.startswith("_process_"): continue method = getattr(self, name) if callable(method): version = name[9:].replace("_", ".") processors[version] = method if self.version not in processors: msg = ("Task configuration version %s is not supported. " "Supported versions: %s" % (self.version, ", ".join(processors))) raise exceptions.InvalidTaskException(msg) config = processors[self.version](config) self.title = config.get("title", "Task") self.tags = config.get("tags", []) self.description = config.get("description", "") self.subtasks = [] for sconf in config["subtasks"]: sconf = copy.deepcopy(sconf) # fill all missed properties of a SubTask sconf.setdefault("tags", []) sconf.setdefault("description", "") # it is not supported feature yet, but the code expects this # variable sconf.setdefault("contexts", {}) workloads = [] for position, wconf in enumerate(sconf["workloads"]): # fill all missed properties of a Workload wconf["name"], wconf["args"] = list( wconf["scenario"].items())[0] del wconf["scenario"] wconf["position"] = position if not wconf.get("description", ""): try: wconf["description"] = scenario.Scenario.get( wconf["name"]).get_info()["title"] except (exceptions.PluginNotFound, exceptions.MultiplePluginsFound): # let's fail an issue with loading plugin at a # validation step pass wconf.setdefault("contexts", {}) if "runner" in wconf: runner = list(wconf["runner"].items())[0] wconf["runner_type"], wconf["runner"] = runner else: wconf["runner_type"] = "serial" wconf["runner"] = {} wconf.setdefault("sla", {"failure_rate": {"max": 0}}) hooks = wconf.get("hooks", []) wconf["hooks"] = [] for hook_cfg in hooks: hook_cfg["action"] = list(hook_cfg["action"].items())[0] hook_cfg["trigger"] = list(hook_cfg["trigger"].items())[0] wconf["hooks"].append(hook_cfg) workloads.append(wconf) sconf["workloads"] = workloads self.subtasks.append(sconf)