Skip to content

Commit

Permalink
Logging batch flush on client close
Browse files Browse the repository at this point in the history
  • Loading branch information
HardNorth committed Nov 3, 2023
1 parent 2833c75 commit cd64d72
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions reportportal_client/aio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()


Expand Down Expand Up @@ -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()

Expand Down
1 change: 1 addition & 0 deletions reportportal_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]:
Expand Down
18 changes: 18 additions & 0 deletions tests/aio/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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()
19 changes: 19 additions & 0 deletions tests/aio/test_batched_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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


Expand Down Expand Up @@ -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()
19 changes: 19 additions & 0 deletions tests/aio/test_threaded_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
# 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

import pytest

from reportportal_client.aio import ThreadedRPClient
from reportportal_client.core.rp_requests import AsyncRPRequestLog
from reportportal_client.helpers import timestamp


Expand Down Expand Up @@ -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()
18 changes: 17 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
15 changes: 15 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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()

0 comments on commit cd64d72

Please sign in to comment.