diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 59d6af5d..bf3e0450 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -161,6 +161,14 @@ - test: add CI test with [github actions][github-actions] - test: integrate [sentry sdk][sentry sdk] for event reporting and analysis +## 3.1.9 (2022-04-17) + +- fix #1174: pydantic validation error when body is None +- fix #1209: only convert jmespath path for some fields in white list +- fix #1233: parse upload info with session variables +- fix #1246: catch exceptions when getting socket address failed +- fix #1247: catch exceptions caused by GA report failure + ## 3.1.8 (2022-03-22) - feat: add `--profile` flag for har2case to support overwrite headers/cookies with specified yaml/json configuration file diff --git a/httprunner/client.py b/httprunner/client.py index 841ba1f2..fa4cab71 100644 --- a/httprunner/client.py +++ b/httprunner/client.py @@ -180,20 +180,19 @@ class HttpSession(requests.Session): response_time_ms = round((time.time() - start_timestamp) * 1000, 2) try: - client_ip, client_port = response.raw.connection.sock.getsockname() - except AttributeError: - client_ip, client_port = response.raw.connection.sock.socket.getsockname() - self.data.address.client_ip = client_ip - self.data.address.client_port = client_port - logger.debug(f"client IP: {client_ip}, Port: {client_port}") + client_ip, client_port = response.raw._connection.sock.getsockname() + self.data.address.client_ip = client_ip + self.data.address.client_port = client_port + logger.debug(f"client IP: {client_ip}, Port: {client_port}") + except Exception: + pass try: - server_ip, server_port = response.raw.connection.sock.getpeername() - except AttributeError: - server_ip, server_port = response.raw.connection.sock.socket.getpeername() - self.data.address.server_ip = server_ip - self.data.address.server_port = server_port - logger.debug(f"server IP: {server_ip}, Port: {server_port}") + server_ip, server_port = response.raw._connection.sock.getpeername() + except Exception: + self.data.address.server_ip = server_ip + self.data.address.server_port = server_port + logger.debug(f"server IP: {server_ip}, Port: {server_port}") # get length of the response content content_size = int(dict(response.headers).get("content-length") or 0) diff --git a/httprunner/compat.py b/httprunner/compat.py index 44fc7d7f..fb78b39b 100644 --- a/httprunner/compat.py +++ b/httprunner/compat.py @@ -58,11 +58,9 @@ def _convert_jmespath(raw: Text) -> Text: raw_list = [] for item in raw.split("."): - if "-" in item and "[-" not in item: - # add quotes for field with separator + if item.lower().startswith("content-") or item.lower() in ["user-agent"]: + # add quotes for some field in white list # e.g. headers.Content-Type => headers."Content-Type" - # also need to avoid replacing negative index in jmespath - # e.g. body.users[-1] => body.users[-1], keep unchanged item = item.strip('"') raw_list.append(f'"{item}"') elif item.isdigit(): diff --git a/httprunner/compat_test.py b/httprunner/compat_test.py index 895ec962..661d4ad8 100644 --- a/httprunner/compat_test.py +++ b/httprunner/compat_test.py @@ -32,12 +32,14 @@ class TestCompat(unittest.TestCase): compat.convert_variables(None, "examples/data/a-b.c/1.yml") def test_convert_jmespath(self): - self.assertEqual(compat._convert_jmespath("content.abc"), "body.abc") self.assertEqual(compat._convert_jmespath("json.abc"), "body.abc") self.assertEqual( compat._convert_jmespath("headers.Content-Type"), 'headers."Content-Type"' ) + self.assertEqual( + compat._convert_jmespath('headers.User-Agent'), 'headers."User-Agent"' + ) self.assertEqual( compat._convert_jmespath('headers."Content-Type"'), 'headers."Content-Type"' ) @@ -49,6 +51,10 @@ class TestCompat(unittest.TestCase): compat._convert_jmespath("body.users[-1]"), "body.users[-1]", ) + self.assertEqual( + compat._convert_jmespath("body.result.WorkNode_-1"), + "body.result.WorkNode_-1", + ) with self.assertRaises(SystemExit): compat._convert_jmespath("2.buildings.0.building_id") diff --git a/httprunner/ext/uploader/__init__.py b/httprunner/ext/uploader/__init__.py index c375c4d5..95aad33a 100644 --- a/httprunner/ext/uploader/__init__.py +++ b/httprunner/ext/uploader/__init__.py @@ -46,8 +46,8 @@ import os import sys from typing import Text -from httprunner.models import TStep, FunctionsMapping -from httprunner.parser import parse_variables_mapping +from httprunner.models import FunctionsMapping, TStep +from httprunner.parser import parse_data, parse_variables_mapping from loguru import logger try: @@ -101,6 +101,11 @@ def prepare_upload_step(step: TStep, functions: FunctionsMapping): if not step.request.upload: return + # parse upload info + step.request.upload = parse_data( + step.request.upload, step.variables, functions + ) + ensure_upload_ready() params_list = [] for key, value in step.request.upload.items(): diff --git a/httprunner/models.py b/httprunner/models.py index a1f7ecd9..bb9435f5 100644 --- a/httprunner/models.py +++ b/httprunner/models.py @@ -144,7 +144,7 @@ class ResponseData(BaseModel): cookies: Cookies encoding: Union[Text, None] = None content_type: Text - body: Union[Text, bytes, List, Dict] + body: Union[Text, bytes, List, Dict, None] class ReqRespData(BaseModel): diff --git a/httprunner/response.py b/httprunner/response.py index fb711dc9..7ee2006f 100644 --- a/httprunner/response.py +++ b/httprunner/response.py @@ -1,4 +1,4 @@ -from typing import Dict, Text, Any +from typing import Any, Dict, Text import jmespath import requests @@ -6,9 +6,9 @@ from jmespath.exceptions import JMESPathError from loguru import logger from httprunner import exceptions -from httprunner.exceptions import ValidationFailure, ParamsError -from httprunner.models import VariablesMapping, Validators -from httprunner.parser import parse_string_value, Parser +from httprunner.exceptions import ParamsError, ValidationFailure +from httprunner.models import Validators, VariablesMapping +from httprunner.parser import Parser, parse_string_value def get_uniform_comparator(comparator: Text):