def check_ext_functions(verify_block): if isinstance(verify_block, list): for vf in verify_block: self.validate_functions.append( get_wrapped_response_function(vf)) elif isinstance(verify_block, dict): self.validate_functions.append( get_wrapped_response_function(verify_block)) elif verify_block is not None: raise exceptions.BadSchemaError( "Badly formatted 'verify_response_with' block")
def __init__(self, session, name, expected, test_block_config): # pylint: disable=unused-argument super(RestResponse, self).__init__() defaults = { 'status_code': 200 } self.name = name body = expected.get("body") or {} if "$ext" in body: self.validate_function = get_wrapped_response_function(body["$ext"]) else: self.validate_function = None self.expected = deep_dict_merge(defaults, expected) self.response = None self.test_block_config = test_block_config self.status_code = None def check_code(code): if code not in _codes: logger.warning("Unexpected status code '%s'", code) if isinstance(self.expected["status_code"], int): check_code(self.expected["status_code"]) else: for code in self.expected["status_code"]: check_code(code)
def __init__(self, session: object, name: Any, expected: Any, test_block_config: Any): # pylint: disable=unused-argument super(RestResponse, self).__init__() defaults = {'status_code': 200} self.name = name body = expected.get("body") or {} if "$ext" in body: self.validate_function = get_wrapped_response_function( body["$ext"]) else: self.validate_function = None self.expected = deep_dict_merge(defaults, expected) self.response = None self.test_block_config = test_block_config self.status_code = None expected_status_code = list() if isinstance(_codes, Iterable): expected_status_code.extend(_codes) else: expected_status_code.append(_codes) if self.expected["status_code"] not in expected_status_code: logger.warning("Unexpected status code '%s'", self.expected["status_code"])
def _save_value(self, save_block): """Save a value in the response for use in future tests Args: to_check (dict): An element of the response from which the given key is extracted key (str): Key to use Returns: dict: dictionary of save_name: value, where save_name is the key we wanted to save this value as """ saved = {} for save_as, joined_key in save_block.items(): try: logger.debug("start format save key:%s", joined_key) val = format_keys(joined_key, self.test_block_config["variables"]) except Exception as e: # pylint: disable=broad-except self._adderr("Format saved value %s for '%s' faild", joined_key, save_as, e=e) else: if save_as == "$ext": ext_fn = get_wrapped_response_function(val) try: to_save = ext_fn(self.response) except Exception as e: # pylint: disable=broad-except self._adderr("Error calling save function '%s':\n%s", ext_fn.func, indent_err_text(traceback.format_exc()), e=e) else: if isinstance(to_save, dict): saved.update(to_save) elif to_save is not None: self._adderr( "Unexpected return value '%s' from $ext save function" ) else: split_keys = save_as.split(".") try: recurse_set_value(saved, split_keys, val) except Exception as e: # pylint: disable=broad-except self._adderr("Set value to '%s' failed", save_as, e=e) return saved
def _validate_block(self, validate_block): """Validate response """ for validator in validate_block: for key, validator_args in validator.items(): try: formatted_validate_args = format_keys( validator_args, self.test_block_config["variables"]) except Exception as e: # pylint: disable=broad-except self._adderr("Format validate args %s for '%s' faild", validator_args, key, e=e) else: if key == "$ext": validate_fn = get_wrapped_response_function( formatted_validate_args) try: validate_fn(self.response) except Exception as e: # pylint: disable=broad-except self._adderr( "Error calling validate function '%s':\n%s", validate_fn.func, indent_err_text(traceback.format_exc()), e=e) else: try: comparator = comparators.get_comparator(key) except Exception as e: # pylint: disable=broad-except self._adderr( "Error getting comparator function '%s'". format, key, e=e) else: kwargs = {} if len(formatted_validate_args) > 2: kwargs = formatted_validate_args.pop() try: comparator(*formatted_validate_args, **kwargs) except Exception as e: # pylint: disable=broad-except self._adderr( "Error calling comparator function '%s':\n%s", key, indent_err_text(traceback.format_exc()), e=e)
def __init__(self, client, name, expected, test_block_config): # pylint: disable=unused-argument super(MQTTResponse, self).__init__() self.name = name payload = expected.get("payload") self.validate_function = None if isinstance(payload, dict): if "$ext" in payload: self.validate_function = get_wrapped_response_function(payload["$ext"]) self.expected = expected self.response = None self._client = client self.received_messages = []
def __init__(self, session, name, expected, test_block_config): # pylint: disable=unused-argument super(RestResponse, self).__init__() defaults = {'status_code': 200} self.name = name body = expected.get("body") or {} if "$ext" in body: self.validate_function = get_wrapped_response_function( body["$ext"]) else: self.validate_function = None self.expected = deep_dict_merge(defaults, expected) self.response = None self.test_block_config = test_block_config self.status_code = None
def maybe_get_save_values_from_ext(self, response, expected): """If there is an $ext function in the save block, call it and save the response Args: expected (dict): the expected response (incl body/json/headers/mqtt topic/etc etc) Actual contents depends on which type of response is being checked response (object): response object. Actual contents depends on which type of response is being checked Returns: dict: mapping of name: value of things to save """ try: wrapped = get_wrapped_response_function(expected["save"]["$ext"]) except KeyError: logger.debug("No save function for this stage") return {} try: to_save = wrapped(response) except Exception as e: # pylint: disable=broad-except self._adderr( "Error calling save function '%s':\n%s", wrapped.func, indent_err_text(traceback.format_exc()), e=e, ) return {} if isinstance(to_save, dict): return to_save elif to_save is not None: self._adderr( "Unexpected return value '%s' from $ext save function", to_save ) return {}
def _check_for_validate_functions(self, payload): if isinstance(payload, dict): if "$ext" in payload: self.validate_function = get_wrapped_response_function( payload["$ext"])
def verify(self, response): """Verify response against expected values and returns any values that we wanted to save for use in future requests There are various ways to 'validate' a block - a specific function, just matching values, validating a schema, etc... Args: response (requests.Response): response object Returns: dict: Any saved values Raises: TestFailError: Something went wrong with validating the response """ self._verbose_log_response(response) self.response = response self.status_code = response.status_code try: body = response.json() except ValueError: body = None self._check_status_code(response.status_code, body) if self.validate_function: try: self.validate_function(response) except Exception as e: # pylint: disable=broad-except self._adderr( "Error calling validate function '%s':\n%s", self.validate_function.func, indent_err_text(traceback.format_exc()), e=e, ) # Get any keys to save saved = {} redirect_query_params = self._get_redirect_query_params(response) saved.update(self._save_value("body", body)) saved.update(self._save_value("headers", response.headers)) saved.update( self._save_value("redirect_query_params", redirect_query_params)) for cookie in self.expected.get("cookies", []): if cookie not in response.cookies: self._adderr("No cookie named '%s' in response", cookie) try: wrapped = get_wrapped_response_function( self.expected["save"]["$ext"]) except KeyError: logger.debug("No save function for this stage") else: try: to_save = wrapped(response) except Exception as e: # pylint: disable=broad-except self._adderr( "Error calling save function '%s':\n%s", wrapped.func, indent_err_text(traceback.format_exc()), e=e, ) else: if isinstance(to_save, dict): saved.update(to_save) elif to_save is not None: self._adderr( "Unexpected return value '%s' from $ext save function") self._validate_block("body", body) self._validate_block("headers", response.headers) self._validate_block("redirect_query_params", redirect_query_params) if self.errors: raise TestFailError( "Test '{:s}' failed:\n{:s}".format(self.name, self._str_errors()), failures=self.errors, ) return saved
def verify(self, response): """Verify response against expected values and returns any values that we wanted to save for use in future requests There are various ways to 'validate' a block - a specific function, just matching values, validating a schema, etc... Args: response (requests.Response): response object Returns: dict: Any saved values Raises: TestFailError: Something went wrong with validating the response """ # pylint: disable=too-many-statements logger.info("Response: '%s' (%s)", response, response.content.decode("utf8")) self.response = response self.status_code = response.status_code try: body = response.json() except ValueError: body = None if response.status_code != self.expected["status_code"]: if 400 <= response.status_code < 500: self._adderr( "Status code was %s, expected %s:\n%s", response.status_code, self.expected["status_code"], indent_err_text(json.dumps(body)), ) else: self._adderr("Status code was %s, expected %s", response.status_code, self.expected["status_code"]) if self.validate_function: try: self.validate_function(response) except Exception as e: #pylint: disable=broad-except self._adderr("Error calling validate function '%s':\n%s", self.validate_function.func, indent_err_text(traceback.format_exc()), e=e) # Get any keys to save saved = {} try: redirect_url = response.headers["location"] except KeyError as e: if "redirect_query_params" in self.expected.get("save", {}): self._adderr( "Wanted to save %s, but there was no redirect url in response", self.expected["save"]["redirect_query_params"], e=e) qp_as_dict = {} else: parsed = urlparse(redirect_url) qp = parsed.query qp_as_dict = {i: j[0] for i, j in parse_qs(qp).items()} saved.update(self._save_value("body", body)) saved.update(self._save_value("headers", response.headers)) saved.update(self._save_value("redirect_query_params", qp_as_dict)) for cookie in self.expected.get("cookies", []): if cookie not in response.cookies: self._adderr("No cookie named '%s' in response", cookie) try: wrapped = get_wrapped_response_function( self.expected["save"]["$ext"]) except KeyError: logger.debug("No save function") else: try: to_save = wrapped(response) except Exception as e: #pylint: disable=broad-except self._adderr("Error calling save function '%s':\n%s", wrapped.func, indent_err_text(traceback.format_exc()), e=e) else: if isinstance(to_save, dict): saved.update(to_save) elif not isinstance(to_save, None): self._adderr( "Unexpected return value '%s' from $ext save function") self._validate_block("body", body) self._validate_block("headers", response.headers) self._validate_block("redirect_query_params", qp_as_dict) if self.errors: raise TestFailError("Test '{:s}' failed:\n{:s}".format( self.name, self._str_errors())) return saved