def get_req_resp_record(self, resp_obj): """ get request and response info from Response() object. """ def log_print(req_resp_dict, r_type): msg = "\n================== {} details ==================\n".format( r_type) for key, value in req_resp_dict[r_type].items(): msg += "{:<16} : {}\n".format(key, repr(value)) logger.log_debug(msg) req_resp_dict = {"request": {}, "response": {}} # record actual request info req_resp_dict["request"]["url"] = resp_obj.request.url req_resp_dict["request"]["headers"] = dict(resp_obj.request.headers) request_body = resp_obj.request.body if request_body: request_content_type = lower_dict_keys( req_resp_dict["request"]["headers"]).get("content-type") if request_content_type and "multipart/form-data" in request_content_type: # upload file type req_resp_dict["request"][ "body"] = "upload file stream (OMITTED)" else: req_resp_dict["request"]["body"] = request_body # log request details in debug mode log_print(req_resp_dict, "request") # record response info req_resp_dict["response"]["ok"] = resp_obj.ok req_resp_dict["response"]["url"] = resp_obj.url req_resp_dict["response"]["status_code"] = resp_obj.status_code req_resp_dict["response"]["reason"] = resp_obj.reason req_resp_dict["response"]["cookies"] = resp_obj.cookies or {} req_resp_dict["response"]["encoding"] = resp_obj.encoding resp_headers = dict(resp_obj.headers) req_resp_dict["response"]["headers"] = resp_headers lower_resp_headers = lower_dict_keys(resp_headers) content_type = lower_resp_headers.get("content-type", "") req_resp_dict["response"]["content_type"] = content_type if "image" in content_type: # response is image type, record bytes content only req_resp_dict["response"]["content"] = resp_obj.content else: try: # try to record json data req_resp_dict["response"]["json"] = resp_obj.json() except ValueError: # only record at most 512 text charactors resp_text = resp_obj.text req_resp_dict["response"]["text"] = omit_long_data(resp_text) # log response details in debug mode log_print(req_resp_dict, "response") return req_resp_dict
def log_req_resp_details(): err_msg = "{} DETAILED REQUEST & RESPONSE {}\n".format("*" * 32, "*" * 32) # log request err_msg += "====== request details ======\n" err_msg += "url: {}\n".format(parsed_url) err_msg += "method: {}\n".format(method) err_msg += "headers: {}\n".format(parsed_test_request.pop("headers", {})) for k, v in parsed_test_request.items(): v = utils.omit_long_data(v) err_msg += "{}: {}\n".format(k, repr(v)) err_msg += "\n" # log response err_msg += "====== response details ======\n" err_msg += "status_code: {}\n".format(resp_obj.status_code) err_msg += "headers: {}\n".format(resp_obj.headers) err_msg += "body: {}\n".format(repr(resp_obj.text)) logger.log_error(err_msg)
def log_req_resp_details(): err_msg = "\n{} DETAILED REQUEST & RESPONSE {}\n".format("*" * 32, "*" * 32) # log request err_msg += "====== request details ======\n" err_msg += f"url: {url}\n" err_msg += f"method: {method}\n" headers = parsed_request_dict.pop("headers", {}) err_msg += f"headers: {headers}\n" for k, v in parsed_request_dict.items(): v = utils.omit_long_data(v) err_msg += f"{k}: {repr(v)}\n" err_msg += "\n" # log response err_msg += "====== response details ======\n" err_msg += f"status_code: {resp.status_code}\n" err_msg += f"headers: {resp.headers}\n" err_msg += f"body: {repr(resp.text)}\n" logger.error(err_msg)
def log_req_resp_details(): err_msg = "{} DETAILED REQUEST & RESPONSE {}\n".format( "*" * 32, "*" * 32) # log request err_msg += "====== request details ======\n" err_msg += "host: {}\n".format(host) err_msg += "port: {}\n".format(port) err_msg += "service: {}\n".format(service) err_msg += "method: {}\n".format(method) err_msg += "params: {}\n".format(params) for k, v in parsed_test_request.items(): v = utils.omit_long_data(v) err_msg += "{}: {}\n".format(k, repr(v)) err_msg += "\n" # log response err_msg += "====== response details ======\n" err_msg += "body: {}\n".format(repr(resp_obj.json)) logger.log_error(err_msg)
def get_req_resp_record(resp_obj: Response) -> ReqRespData: """ get request and response info from Response() object. """ def log_print(req_or_resp, r_type): msg = f"\n================== {r_type} details ==================\n" for key, value in req_or_resp.dict().items(): if isinstance(value, dict): value = json.dumps(value, indent=4) msg += "{:<8} : {}\n".format(key, value) logger.debug(msg) # record actual request info request_headers = dict(resp_obj.request.headers) request_cookies = resp_obj.request._cookies.get_dict() request_body = resp_obj.request.body if request_body is not None: try: request_body = json.loads(request_body) except json.JSONDecodeError: # str: a=1&b=2 pass except UnicodeDecodeError: # bytes/bytearray: request body in protobuf pass except TypeError: # neither str nor bytes/bytearray, e.g. <MultipartEncoder> pass request_content_type = lower_dict_keys(request_headers).get( "content-type") if request_content_type and "multipart/form-data" in request_content_type: # upload file type request_body = "upload file stream (OMITTED)" request_data = RequestData( method=resp_obj.request.method, url=resp_obj.request.url, headers=request_headers, cookies=request_cookies, body=request_body, ) # log request details in debug mode log_print(request_data, "request") # record response info resp_headers = dict(resp_obj.headers) lower_resp_headers = lower_dict_keys(resp_headers) content_type = lower_resp_headers.get("content-type", "") if "image" in content_type: # response is image type, record bytes content only response_body = resp_obj.content else: try: # try to record json data response_body = resp_obj.json() except ValueError: # only record at most 512 text charactors resp_text = resp_obj.text response_body = omit_long_data(resp_text) response_data = ResponseData( status_code=resp_obj.status_code, cookies=resp_obj.cookies or {}, encoding=resp_obj.encoding, headers=resp_headers, content_type=content_type, body=response_body, ) # log response details in debug mode log_print(response_data, "response") req_resp_data = ReqRespData(request=request_data, response=response_data) return req_resp_data
def _run_test(self, test_dict): """ run single teststep. Args: test_dict (dict): teststep info { "name": "teststep description", "skip": "skip this test unconditionally", "times": 3, "variables": [], # optional, override "request": { "url": "http://127.0.0.1:5000/api/users/1000", "method": "POST", "headers": { "Content-Type": "application/json", "authorization": "$authorization", "random": "$random" }, "json": {"name": "user", "password": "******"} }, "extract": {}, # optional "validate": [], # optional "setup_hooks": [], # optional "teardown_hooks": [] # optional } Raises: exceptions.ParamsError exceptions.ValidationFailure exceptions.ExtractFailure """ # clear meta data first to ensure independence for each test self.__clear_test_data() # check skip self._handle_skip_feature(test_dict) # prepare test_dict = utils.lower_test_dict_keys(test_dict) test_variables = test_dict.get("variables", {}) self.session_context.init_test_variables(test_variables) # teststep name test_name = test_dict.get("name", "") # parse test request raw_request = test_dict.get('request', {}) parsed_test_request = self.session_context.eval_content(raw_request) self.session_context.update_test_variables("request", parsed_test_request) # setup hooks setup_hooks = test_dict.get("setup_hooks", []) if setup_hooks: self.do_hook_actions(setup_hooks, "setup") try: url = parsed_test_request.pop('url') method = parsed_test_request.pop('method') parsed_test_request.setdefault("verify", self.verify) group_name = parsed_test_request.pop("group", None) except KeyError: raise exceptions.ParamsError("URL or METHOD missed!") # TODO: move method validation to json schema valid_methods = [ "GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS" ] if method.upper() not in valid_methods: err_msg = u"Invalid HTTP method! => {}\n".format(method) err_msg += "Available HTTP methods: {}".format( "/".join(valid_methods)) logger.log_error(err_msg) raise exceptions.ParamsError(err_msg) logger.log_info("{method} {url}".format(method=method, url=url)) logger.log_debug( "request kwargs(raw): {kwargs}".format(kwargs=parsed_test_request)) # request resp = self.http_client_session.request(method, url, name=(group_name or test_name), **parsed_test_request) resp_obj = response.ResponseObject(resp) # teardown hooks teardown_hooks = test_dict.get("teardown_hooks", []) if teardown_hooks: self.session_context.update_test_variables("response", resp_obj) self.do_hook_actions(teardown_hooks, "teardown") # extract extractors = test_dict.get("extract", {}) extracted_variables_mapping = resp_obj.extract_response(extractors) self.session_context.update_session_variables( extracted_variables_mapping) # validate validators = test_dict.get("validate", []) try: self.session_context.validate(validators, resp_obj) except (exceptions.ParamsError, exceptions.ValidationFailure, exceptions.ExtractFailure): err_msg = "{} DETAILED REQUEST & RESPONSE {}\n".format( "*" * 32, "*" * 32) # log request err_msg += "====== request details ======\n" err_msg += "url: {}\n".format(url) err_msg += "method: {}\n".format(method) err_msg += "headers: {}\n".format( parsed_test_request.pop("headers", {})) for k, v in parsed_test_request.items(): v = utils.omit_long_data(v) err_msg += "{}: {}\n".format(k, repr(v)) err_msg += "\n" # log response err_msg += "====== response details ======\n" err_msg += "status_code: {}\n".format(resp_obj.status_code) err_msg += "headers: {}\n".format(resp_obj.headers) err_msg += "body: {}\n".format(repr(resp_obj.text)) logger.log_error(err_msg) raise finally: self.validation_results = self.session_context.validation_results
def get_req_resp_record(resp_obj): """ get request and response info from Response() object. 从response()对象中获取请求和响应信息 """ def log_print(req_resp_dict, r_type): msg = "\n================== {} details ==================\n".format( r_type) for key, value in req_resp_dict[r_type].items(): msg += "{:<16} : {}\n".format(key, repr(value)) logger.log_debug(msg) req_resp_dict = {"request": {}, "response": {}} # record actual request info记录实际请求信息 req_resp_dict["request"]["url"] = resp_obj.request.url req_resp_dict["request"]["method"] = resp_obj.request.method req_resp_dict["request"]["headers"] = dict(resp_obj.request.headers) request_body = resp_obj.request.body if request_body: request_content_type = lower_dict_keys( req_resp_dict["request"]["headers"]).get("content-type") if request_content_type and "multipart/form-data" in request_content_type: # upload file type上传文件类型:上传文件流(略) req_resp_dict["request"]["body"] = "upload file stream (OMITTED)" else: req_resp_dict["request"]["body"] = request_body # log request details in debug mode在调试模式下记录请求细节 log_print(req_resp_dict, "request") # record response info req_resp_dict["response"]["ok"] = resp_obj.ok req_resp_dict["response"]["url"] = resp_obj.url req_resp_dict["response"]["status_code"] = resp_obj.status_code req_resp_dict["response"]["reason"] = resp_obj.reason req_resp_dict["response"]["cookies"] = resp_obj.cookies or {} req_resp_dict["response"]["encoding"] = resp_obj.encoding resp_headers = dict(resp_obj.headers) req_resp_dict["response"]["headers"] = resp_headers lower_resp_headers = lower_dict_keys(resp_headers) content_type = lower_resp_headers.get("content-type", "") req_resp_dict["response"]["content_type"] = content_type if "image" in content_type: # response is image type, record bytes content only # 响应是图像类型,只记录字节内容 req_resp_dict["response"]["body"] = resp_obj.content else: try: # try to record json data尝试记录json数据 if isinstance(resp_obj, response.ResponseObject): req_resp_dict["response"]["body"] = resp_obj.json else: req_resp_dict["response"]["body"] = resp_obj.json() except ValueError: # only record at most 512 text charactors # 最多只记录512个文本字符 resp_text = resp_obj.text req_resp_dict["response"]["body"] = omit_long_data(resp_text) # log response details in debug mode # 在调试模式下记录响应细节 log_print(req_resp_dict, "response") return req_resp_dict
def get_req_resp_record(resp_obj: Response) -> ReqRespData: """ get request and response info from Response() object. """ def log_print(req_or_resp, r_type): msg = f"\n================== {r_type} details ==================\n" for key, value in req_or_resp.dict().items(): msg += "{:<16} : {}\n".format(key, repr(value)) logger.debug(msg) # record actual request info request_headers = dict(resp_obj.request.headers) request_body = resp_obj.request.body if request_body: request_content_type = lower_dict_keys(request_headers).get("content-type") if request_content_type and "multipart/form-data" in request_content_type: # upload file type request_body = "upload file stream (OMITTED)" request_data = RequestData( method=resp_obj.request.method, url=resp_obj.request.url, headers=request_headers, body=request_body, ) # log request details in debug mode log_print(request_data, "request") # record response info resp_headers = dict(resp_obj.headers) lower_resp_headers = lower_dict_keys(resp_headers) content_type = lower_resp_headers.get("content-type", "") if "image" in content_type: # response is image type, record bytes content only response_body = resp_obj.content else: try: # try to record json data response_body = resp_obj.json() except ValueError: # only record at most 512 text charactors resp_text = resp_obj.text response_body = omit_long_data(resp_text) response_data = ResponseData( status_code=resp_obj.status_code, cookies=resp_obj.cookies or {}, encoding=resp_obj.encoding, headers=resp_headers, content_type=content_type, body=response_body, ) # log response details in debug mode log_print(response_data, "response") req_resp_data = ReqRespData(request=request_data, response=response_data) return req_resp_data