diff --git a/CHANGELOG.md b/CHANGELOG.md index 1990db7..381dd1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [Unreleased] ### Added - Issue [#225](https://github.com/reportportal/client-Python/issues/225): JSON decoding error logging, by @HardNorth +### Fixed +- Issue [#226](https://github.com/reportportal/client-Python/issues/226): Logging batch flush on client close, by @HardNorth ## [5.5.3] ### Fixed diff --git a/reportportal_client/aio/client.py b/reportportal_client/aio/client.py index 800e024..c969460 100644 --- a/reportportal_client/aio/client.py +++ b/reportportal_client/aio/client.py @@ -924,6 +924,7 @@ def clone(self) -> 'AsyncRPClient': async def close(self) -> None: """Close current client connections.""" + await self.__client.log_batch(self._log_batcher.flush()) await self.__client.close() @@ -1307,6 +1308,7 @@ def log(self, time: str, message: str, level: Optional[Union[int, str]] = None, def close(self) -> None: """Close current client connections.""" + self.finish_tasks() if self.own_client: self.create_task(self.__client.close()).blocking_result() diff --git a/reportportal_client/client.py b/reportportal_client/client.py index 64206ee..d832697 100644 --- a/reportportal_client/client.py +++ b/reportportal_client/client.py @@ -886,6 +886,7 @@ def clone(self) -> 'RPClient': def close(self) -> None: """Close current client connections.""" + self._log(self._log_batcher.flush()) self.session.close() def __getstate__(self) -> Dict[str, Any]: diff --git a/tests/aio/test_async_client.py b/tests/aio/test_async_client.py index aa79c8c..dd12bd8 100644 --- a/tests/aio/test_async_client.py +++ b/tests/aio/test_async_client.py @@ -19,6 +19,7 @@ import pytest from reportportal_client.aio import AsyncRPClient +from reportportal_client.core.rp_requests import AsyncRPRequestLog from reportportal_client.helpers import timestamp @@ -171,3 +172,20 @@ async def test_start_item_tracking(async_client: AsyncRPClient): await async_client.finish_test_item(actual_item_id, timestamp()) assert async_client.current_item() is None + + +@pytest.mark.skipif(sys.version_info < (3, 8), + reason='the test requires AsyncMock which was introduced in Python 3.8') +@pytest.mark.asyncio +async def test_logs_flush_on_close(async_client: AsyncRPClient): + # noinspection PyTypeChecker + client: mock.Mock = async_client.client + batcher: mock.Mock = mock.Mock() + batcher.flush.return_value = [AsyncRPRequestLog('test_launch_uuid', timestamp(), message='test_message')] + async_client._log_batcher = batcher + + await async_client.close() + + batcher.flush.assert_called_once() + client.log_batch.assert_called_once() + client.close.assert_called_once() diff --git a/tests/aio/test_batched_client.py b/tests/aio/test_batched_client.py index 9962a11..dd2961f 100644 --- a/tests/aio/test_batched_client.py +++ b/tests/aio/test_batched_client.py @@ -10,6 +10,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License + import pickle import sys from unittest import mock @@ -18,6 +19,7 @@ import pytest from reportportal_client.aio import BatchedRPClient +from reportportal_client.core.rp_requests import AsyncRPRequestLog from reportportal_client.helpers import timestamp @@ -137,3 +139,20 @@ def test_launch_uuid_usage(launch_uuid, method, params): assert args[0].blocking_result() == actual_launch_uuid for i, param in enumerate(params): assert args[i + 1] == param + + +@pytest.mark.skipif(sys.version_info < (3, 8), + reason='the test requires AsyncMock which was introduced in Python 3.8') +def test_logs_flush_on_close(batched_client: BatchedRPClient): + batched_client.own_client = True + # noinspection PyTypeChecker + client: mock.Mock = batched_client.client + batcher: mock.Mock = mock.Mock() + batcher.flush.return_value = [AsyncRPRequestLog('test_launch_uuid', timestamp(), message='test_message')] + batched_client._log_batcher = batcher + + batched_client.close() + + batcher.flush.assert_called_once() + client.log_batch.assert_called_once() + client.close.assert_called_once() diff --git a/tests/aio/test_threaded_client.py b/tests/aio/test_threaded_client.py index 10a9500..25a0cee 100644 --- a/tests/aio/test_threaded_client.py +++ b/tests/aio/test_threaded_client.py @@ -10,6 +10,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License + import pickle import sys from unittest import mock @@ -17,6 +18,7 @@ import pytest from reportportal_client.aio import ThreadedRPClient +from reportportal_client.core.rp_requests import AsyncRPRequestLog from reportportal_client.helpers import timestamp @@ -133,3 +135,20 @@ def test_launch_uuid_usage(launch_uuid, method, params): assert args[0].blocking_result() == actual_launch_uuid for i, param in enumerate(params): assert args[i + 1] == param + + +@pytest.mark.skipif(sys.version_info < (3, 8), + reason='the test requires AsyncMock which was introduced in Python 3.8') +def test_logs_flush_on_close(batched_client: ThreadedRPClient): + batched_client.own_client = True + # noinspection PyTypeChecker + client: mock.Mock = batched_client.client + batcher: mock.Mock = mock.Mock() + batcher.flush.return_value = [AsyncRPRequestLog('test_launch_uuid', timestamp(), message='test_message')] + batched_client._log_batcher = batcher + + batched_client.close() + + batcher.flush.assert_called_once() + client.log_batch.assert_called_once() + client.close.assert_called_once() diff --git a/tests/conftest.py b/tests/conftest.py index 1572a2d..46ef8ae 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,8 +18,8 @@ # noinspection PyPackageRequirements from pytest import fixture +from reportportal_client.aio.client import Client, AsyncRPClient, BatchedRPClient, ThreadedRPClient from reportportal_client.client import RPClient -from reportportal_client.aio.client import Client, AsyncRPClient @fixture @@ -65,3 +65,19 @@ def async_client(): client = AsyncRPClient('http://endpoint', 'project', api_key='api_key', client=mock.AsyncMock()) return client + + +@fixture +def batched_client(): + """Prepare instance of the AsyncRPClient for testing.""" + client = BatchedRPClient('http://endpoint', 'project', api_key='api_key', + client=mock.AsyncMock()) + return client + + +@fixture +def threaded_client(): + """Prepare instance of the AsyncRPClient for testing.""" + client = ThreadedRPClient('http://endpoint', 'project', api_key='api_key', + client=mock.AsyncMock()) + return client diff --git a/tests/test_client.py b/tests/test_client.py index 5345534..d406b3b 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -21,6 +21,7 @@ from requests.exceptions import ReadTimeout from reportportal_client import RPClient +from reportportal_client.core.rp_requests import RPRequestLog from reportportal_client.helpers import timestamp @@ -293,3 +294,17 @@ def test_http_timeout_bypass(method, call_method, arguments): kwargs = getattr(session, call_method).call_args_list[0][1] assert 'timeout' in kwargs assert kwargs['timeout'] == http_timeout + + +def test_logs_flush_on_close(rp_client: RPClient): + # noinspection PyTypeChecker + session: mock.Mock = rp_client.session + batcher: mock.Mock = mock.Mock() + batcher.flush.return_value = [RPRequestLog('test_launch_uuid', timestamp(), message='test_message')] + rp_client._log_batcher = batcher + + rp_client.close() + + batcher.flush.assert_called_once() + session.post.assert_called_once() + session.close.assert_called_once()