def test_query_json_content_is_text(self): json_content = "" query = "key" with self.assertRaises(exception.ResponseError): utils.query_json(json_content, query) json_content = "<html><body>content</body></html>" query = "key" with self.assertRaises(exception.ParseResponseError): utils.query_json(json_content, query)
def extract_field(self, field, delimiter='.'): """ extract field from requests.Response @param (str) field of requests.Response object, and may be joined by delimiter "status_code" "content" "headers.content-type" "content.person.name.first_name" """ try: field += "." # string.split(sep=None, maxsplit=-1) -> list of strings # e.g. "content.person.name" => ["content", "person.name"] top_query, sub_query = field.split(delimiter, 1) if top_query in ["body", "content", "text"]: json_content = self.parsed_body() else: json_content = getattr(self.resp_obj, top_query) if sub_query: # e.g. key: resp_headers_content_type, sub_query = "content-type" return utils.query_json(json_content, sub_query) else: # e.g. key: resp_status_code, resp_content return json_content except AttributeError: raise exception.ParseResponseError("failed to extract bind variable in response!")
def test_query_json(self): json_content = { "ids": [1, 2, 3, 4], "person": { "name": { "first_name": "Leo", "last_name": "Lee", }, "age": 29, "cities": ["Guangzhou", "Shenzhen"] } } query = "ids.2" result = utils.query_json(json_content, query) self.assertEqual(result, 3) query = "ids.str_key" with self.assertRaises(exception.ParamsError): utils.query_json(json_content, query) query = "ids.5" with self.assertRaises(exception.ParamsError): utils.query_json(json_content, query) query = "person.age" result = utils.query_json(json_content, query) self.assertEqual(result, 29) query = "person.not_exist_key" with self.assertRaises(exception.ParamsError): utils.query_json(json_content, query) query = "person.cities.0" result = utils.query_json(json_content, query) self.assertEqual(result, "Guangzhou") query = "person.name.first_name" result = utils.query_json(json_content, query) self.assertEqual(result, "Leo")
def test_query_json(self): json_content = { "ids": [1, 2, 3, 4], "person": { "name": { "first_name": "Leo", "last_name": "Lee", }, "age": 29, "cities": ["Guangzhou", "Shenzhen"] } } query = "ids.2" result = utils.query_json(json_content, query) self.assertEqual(result, 3) query = "ids.str_key" with self.assertRaises(exception.ParseResponseError): utils.query_json(json_content, query) query = "ids.5" with self.assertRaises(exception.ParseResponseError): utils.query_json(json_content, query) query = "person.age" result = utils.query_json(json_content, query) self.assertEqual(result, 29) query = "person.not_exist_key" with self.assertRaises(exception.ParseResponseError): utils.query_json(json_content, query) query = "person.cities.0" result = utils.query_json(json_content, query) self.assertEqual(result, "Guangzhou") query = "person.name.first_name" result = utils.query_json(json_content, query) self.assertEqual(result, "Leo")
def _extract_field_with_delimiter(self, field): """ response content could be json or html text. @param (str) field should be string joined by delimiter. e.g. "status_code" "content" "headers.content-type" "content.person.name.first_name" """ try: # string.split(sep=None, maxsplit=-1) -> list of strings # e.g. "content.person.name" => ["content", "person.name"] try: top_query, sub_query = field.split('.', 1) except ValueError: top_query = field sub_query = None if top_query in ["body", "content", "text"]: top_query_content = self.parsed_body() else: top_query_content = getattr(self.resp_obj, top_query) if sub_query: if not isinstance(top_query_content, (dict, CaseInsensitiveDict, list)): err_msg = u"Extractor error: failed to extract data with regex!\n" err_msg += u"response: {}\n".format(self.parsed_dict()) err_msg += u"regex: {}\n".format(field) logging.error(err_msg) raise exception.ParamsError(err_msg) # e.g. key: resp_headers_content_type, sub_query = "content-type" return utils.query_json(top_query_content, sub_query) else: # e.g. key: resp_status_code, resp_content return top_query_content except AttributeError: err_msg = u"Failed to extract value from response!\n" err_msg += u"response: {}\n".format(self.parsed_dict()) err_msg += u"extract field: {}\n".format(field) logging.error(err_msg) raise exception.ParamsError(err_msg)
def extract_response(self, extract_binds, delimiter='.'): """ extract content from requests.Response @param (dict) extract_binds { "resp_status_code": "status_code", "resp_headers_content_type": "headers.content-type", "resp_content": "content", "resp_content_person_first_name": "content.person.name.first_name" } """ extract_binds_dict = {} for key, value in extract_binds.items(): if not isinstance(value, utils.string_type): raise exception.ParamsError("invalid extract_binds!") try: value += "." # string.split(sep=None, maxsplit=-1) -> list of strings # e.g. "content.person.name" => ["content", "person.name"] top_query, sub_query = value.split(delimiter, 1) if top_query in ["body", "content", "text"]: json_content = self.parsed_body() else: json_content = getattr(self.resp_obj, top_query) if sub_query: # e.g. key: resp_headers_content_type, sub_query = "content-type" answer = utils.query_json(json_content, sub_query) extract_binds_dict[key] = answer else: # e.g. key: resp_status_code, resp_content extract_binds_dict[key] = json_content except AttributeError: raise exception.ParamsError("invalid extract_binds!") return extract_binds_dict
def extract_response(resp_obj, context, delimiter='.'): """ extract content from requests.Response, and bind extracted value to context.extractors @param (requests.Response instance) resp_obj @param (ate.context.Context instance) context context.extractors: { "resp_status_code": "status_code", "resp_headers_content_type": "headers.content-type", "resp_content": "content", "resp_content_person_first_name": "content.person.name.first_name" } """ for key, value in context.extractors.items(): try: if isinstance(value, str): value += "." # string.split(sep=None, maxsplit=-1) -> list of strings # e.g. "content.person.name" => ["content", "person.name"] top_query, sub_query = value.split(delimiter, 1) if top_query in ["body", "content", "text"]: json_content = parse_response_body(resp_obj) else: json_content = getattr(resp_obj, top_query) if sub_query: # e.g. key: resp_headers_content_type, sub_query = "content-type" answer = utils.query_json(json_content, sub_query) context.extractors[key] = answer else: # e.g. key: resp_status_code, resp_content context.extractors[key] = json_content else: raise NotImplementedError("TODO: support template.") except AttributeError: raise exception.ParamsError("invalid extract_binds!")