diff --git a/CHANGELOG.md b/CHANGELOG.md index bb7415b..ba4dc2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] + +## [5.6.4] ### Added - `ErrorPrintingHttpRequest` and `ErrorPrintingAsyncHttpRequest` classes to avoid recursion on ReportPortal logging, by @HardNorth ### Removed diff --git a/reportportal_client/aio/client.py b/reportportal_client/aio/client.py index 467bfa7..3a90a1a 100644 --- a/reportportal_client/aio/client.py +++ b/reportportal_client/aio/client.py @@ -445,10 +445,8 @@ async def finish_launch( ).make() if not response: return None - message = await response.message logger.debug("finish_launch - ID: %s", await await_if_necessary(launch_uuid)) - logger.debug("response message: %s", message) - return message + return None async def update_test_item( self, diff --git a/reportportal_client/client.py b/reportportal_client/client.py index 69d45a3..02247ae 100644 --- a/reportportal_client/client.py +++ b/reportportal_client/client.py @@ -771,12 +771,8 @@ def finish_launch( if not response: return None logger.debug("finish_launch - ID: %s", self.__launch_uuid) - logger.debug("response message: %s", response.message) - message = response.message - else: - message = "" self._log(self._log_batcher.flush()) - return message + return None def update_test_item( self, item_uuid: str, attributes: Optional[Union[list, dict]] = None, description: Optional[str] = None diff --git a/reportportal_client/core/rp_requests.py b/reportportal_client/core/rp_requests.py index 8c5499e..6bfc96f 100644 --- a/reportportal_client/core/rp_requests.py +++ b/reportportal_client/core/rp_requests.py @@ -145,20 +145,20 @@ def make(self) -> Optional[RPResponse]: class ErrorPrintingHttpRequest(HttpRequest): - """This is specific request object which catches any request error and prints it to the "std.err". + """This is specific request object which catches any request error and prints it to the "sys.stderr". The object is supposed to be used in logging methods only to prevent infinite recursion of logging, when logging framework configured to log everything to ReportPortal. In this case if a request to ReportPortal fails, the failure will be logged to ReportPortal once again and, for example, in case of endpoint configuration error, it will also fail and will be logged again. So, the recursion will never end. - This class is used to prevent this situation. It catches any request error and prints it to the "std.err". + This class is used to prevent this situation. It catches any request error and prints it to the "sys.stderr". """ def make(self) -> Optional[RPResponse]: """Make HTTP request to the ReportPortal API. - The method catches any request error and prints it to the "std.err". + The method catches any request error and prints it to the "sys.stderr". :return: wrapped HTTP response or None in case of failure """ @@ -223,20 +223,20 @@ async def make(self) -> Optional[AsyncRPResponse]: class ErrorPrintingAsyncHttpRequest(AsyncHttpRequest): - """This is specific request object which catches any request error and prints it to the "std.err". + """This is specific request object which catches any request error and prints it to the "sys.stderr". The object is supposed to be used in logging methods only to prevent infinite recursion of logging, when logging framework configured to log everything to ReportPortal. In this case if a request to ReportPortal fails, the failure will be logged to ReportPortal once again and, for example, in case of endpoint configuration error, it will also fail and will be logged again. So, the recursion will never end. - This class is used to prevent this situation. It catches any request error and prints it to the "std.err". + This class is used to prevent this situation. It catches any request error and prints it to the "sys.stderr". """ async def make(self) -> Optional[AsyncRPResponse]: """Asynchronously make HTTP request to the ReportPortal API. - The method catches any request error and prints it to the "std.err". + The method catches any request error and prints it to the "sys.stderr". :return: wrapped HTTP response or None in case of failure """ diff --git a/setup.py b/setup.py index c089873..98db5f0 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from setuptools import find_packages, setup -__version__ = "5.6.4" +__version__ = "5.6.5" TYPE_STUBS = ["*.pyi"] diff --git a/tests/aio/test_aio_client.py b/tests/aio/test_aio_client.py index 4697fc4..3bb4a7f 100644 --- a/tests/aio/test_aio_client.py +++ b/tests/aio/test_aio_client.py @@ -646,7 +646,7 @@ async def test_finish_launch(aio_client: Client): attributes = {"attribute_key": "attribute_value", "system": False} result = await aio_client.finish_launch(launch_uuid, end_time, status=status, attributes=attributes) - assert result == RESPONSE_MESSAGE + assert result is None session.put.assert_called_once() call_args = session.put.call_args_list[0] assert expected_uri == call_args[0][0] @@ -671,7 +671,7 @@ async def test_finish_launch_default_values(aio_client: Client): end_time = str(1696921416000) result = await aio_client.finish_launch(launch_uuid, end_time) - assert result == RESPONSE_MESSAGE + assert result is None session.put.assert_called_once() call_args = session.put.call_args_list[0] assert expected_uri == call_args[0][0] diff --git a/tests/aio/test_threaded_client.py b/tests/aio/test_threaded_client.py index 0db80e0..a6ce46a 100644 --- a/tests/aio/test_threaded_client.py +++ b/tests/aio/test_threaded_client.py @@ -12,6 +12,7 @@ # limitations under the License import pickle +import time from unittest import mock # noinspection PyPackageRequirements @@ -46,6 +47,7 @@ def test_clone(): async_client = ThreadedRPClient(*args, **kwargs) task1 = async_client.create_task(__empty_string()) task2 = async_client.create_task(__empty_string()) + time.sleep(0.1) task1.blocking_result() task2.blocking_result() async_client._add_current_item(task1)