def ext_testenv(value, rule_obj, path): if 'host' in value and 'container' in value: raise SchemaError("only one of 'host' and 'container' allowed") if 'host' not in value and 'container' not in value: raise SchemaError("one of 'host' or 'container' required") if 'build' not in value and 'tests' not in value: raise SchemaError("at least one of 'build' or 'tests' required") return True
def _validate_range(self, max_, min_, max_ex, min_ex, errors, value, path, prefix): """ Validate that value is within range values. """ log.debug("Validate range : {} : {} : {} : {} : {} : {}".format( max_, min_, max_ex, min_ex, value, path, )) if max_ is not None: if max_ < value: errors.append( SchemaError.SchemaErrorEntry( msg= "Type '{prefix}' has size of '{value}', greater than max limit '{max_}'. Path: '{path}'", path=path, value=value, prefix=prefix, max_=max_)) if min_ is not None: if min_ > value: errors.append( SchemaError.SchemaErrorEntry( msg= "Type '{prefix}' has size of '{value}', less than min limit '{min_}'. Path: '{path}'", path=path, value=value, prefix=prefix, min_=min_)) if max_ex is not None: if max_ex <= value: errors.append( SchemaError.SchemaErrorEntry( msg= "Type '{prefix}' has size of '{value}', greater than or equals to max limit(exclusive) '{max_ex}'. Path: '{path}'", path=path, value=value, prefix=prefix, max_ex=max_ex)) if min_ex is not None: if min_ex >= value: errors.append( SchemaError.SchemaErrorEntry( msg= "Type '{prefix}' has size of '{value}', less than or equals to min limit(exclusive) '{min_ex}'. Path: '{path}'", path=path, value=value, prefix=prefix, min_ex=min_ex))
def validate(self, raise_exception=True, silent=False): """ """ log.debug(u"starting core") self._start_validate(self.source) self.validation_errors = [unicode(error) for error in self.errors] self.validation_errors_exceptions = self.errors if self.errors is None or len(self.errors) == 0: if not silent: log.info(u"validation.valid") else: if not silent: log.error(u"validation.invalid") log.error(u" --- All found errors ---") log.error(self.validation_errors) if raise_exception: raise SchemaError(u"Schema validation failed:\n - {error_msg}.".format( error_msg=u'.\n - '.join(self.validation_errors))) else: if not silent: log.error(u"Errors found but will not raise exception...") # Return validated data return len(self.errors) == 0
def _validate(self, suite): schema = os.path.join(sys.path[0], "utils/schema.yml") ext = os.path.join(sys.path[0], "utils/ext_schema.py") c = Core(source_data=suite, schema_files=[schema], extensions=[ext]) c.validate() if suite['context'] in self.contexts: raise SchemaError("duplicate 'context' value detected") self.met_required = self.met_required or suite.get('required', False) if suite['context'] == "required" and self.met_required: raise SchemaError('context "required" forbidden when using the ' "'required' key") self.contexts.append(suite['context'])
def _validate(suite, contexts): schema = os.path.join(sys.path[0], "utils/schema.yml") ext = os.path.join(sys.path[0], "utils/ext_schema.py") c = Core(source_data=suite, schema_files=[schema], extensions=[ext]) c.validate() if suite['context'] in contexts: raise SchemaError("duplicate 'context' value detected") contexts.append(suite['context'])
def require_response_keys(responses: List[Dict[Text, Any]], _: Dict, __: Text) -> bool: """Validates that response dicts have either the "text" key or the "custom" key.""" for response in responses: if not isinstance(response, dict): # this is handled by other validation rules continue if response.get("text") is None and not response.get("custom"): raise SchemaError("Missing 'text' or 'custom' key in response.") return True
def _check_trigger_depth(clazz, proj_data, parent, trigger, depth): if depth == 0: path = "triggers/" + trigger["name"] raise SchemaError("Trigger recursion depth exceeded", path=path) for t in proj_data["triggers"]: if t["name"] == trigger["name"]: break for run in t["runs"]: for child in run.get("triggers", []): clazz._check_trigger_depth(proj_data, parent, child, depth - 1) for child in t.get("triggers", []): clazz._check_trigger_depth(proj_data, parent, child, depth - 1)
def parse(self): "Generator of testsuites parsed from the given YAML file." suite = None with open(self.filepath) as f: for idx, raw_yaml in enumerate(yaml.safe_load_all(f.read())): try: suite = self._merge(suite, raw_yaml) self._validate(suite) yield dict(suite) except SchemaError as e: # if it happens on the very first document, let's # just give the exact error directly if idx == 0: raise e raise SchemaError("failed to parse %s testsuite" % common.ordinal(idx + 1)) from e
def load_suites(filepath): "Generator of testsuites parsed from the given YAML file." suite = None contexts = [] with open(filepath) as f: for idx, raw_yaml in enumerate(yaml.safe_load_all(f.read())): try: suite = _merge(suite, raw_yaml) _validate(suite, contexts) yield suite except SchemaError as e: # if it happens on the very first document, let's just give the # exact error directly if idx == 0: raise e msg = "failed to parse %s testsuite" % common.ordinal(idx + 1) raise SchemaError(msg) from e
def validate(self, raise_exception=True): Log.debug("starting core") errors = self._start_validate(self.source) self.validation_errors = errors if errors is None or len(errors) == 0: Log.info("validation.valid") else: Log.error("validation.invalid") Log.error(" --- All found errors ---") Log.error(errors) if raise_exception: raise SchemaError("validation.invalid : {}".format(errors)) else: Log.error("Errors found but will not raise exception...") # Return validated data return self.source
def validate(self, raise_exception=True): log.debug("starting core") errors = self._start_validate(self.source) self.validation_errors = [str(error) for error in errors] self.validation_errors_exceptions = errors if errors is None or len(errors) == 0: log.info("validation.valid") else: log.error("validation.invalid") log.error(" --- All found errors ---") log.error(errors) if raise_exception: raise SchemaError( "Schema validation failed:\n - {error_msg}.".format( error_msg='.\n - '.join(self.validation_errors))) else: log.error("Errors found but will not raise exception...") # Return validated data return self.source
def _expand_run_loops(self): for trigger in self.triggers: for run in trigger["runs"]: loop = run.get("loop-on") index = trigger["runs"].index(run) if loop: names = [x["param"] for x in loop] values = [x["values"] for x in loop] for j, combo in enumerate(itertools.product(*values)): name = "-".join(combo) r = copy.deepcopy(run) r["name"] = run["name"].format(loop=name) del r["loop-on"] params = r.setdefault("params", {}) trigger["runs"].insert(index + j, r) for i, val in enumerate(combo): if names[i] == "host-tag": # this is a special loop-on directive r["host-tag"] = val else: params[names[i]] = val for t in r.get("triggers", []): t["name"] = t["name"].format(loop=name) rname = t.get("run-names") if rname: # put name={name} incase they do: # {name}-{loop} # rather than: # {{name}}-{loop} t["run-names"] = rname.format(name="{name}", loop=name) trigger["runs"].remove(run) path = "triggers/" + trigger["name"] for run in trigger["runs"]: if len(run["name"]) >= 80: msg = "Name of run must be less than 80 characters" raise SchemaError(msg, path=path + "/runs/" + run["name"])