Skip to content

Commit

Permalink
[fix] Fixed mocking of request library in MockRequestPostRunner #360
Browse files Browse the repository at this point in the history
Related to #360
  • Loading branch information
pandafy committed Mar 1, 2024
1 parent 2440f96 commit 6707833
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 15 deletions.
2 changes: 2 additions & 0 deletions openwisp_utils/measurements/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

def post_usage_metrics(events):
try:
print('retrying request')
response = retryable_request(
'post',
url=USER_METRIC_COLLECTION_URL,
Expand All @@ -28,6 +29,7 @@ def post_usage_metrics(events):
},
max_retries=10,
)
print(response.status_code, ' response code from measurement tasks')
assert response.status_code == 204
except Exception as error:
if isinstance(error, AssertionError):
Expand Down
21 changes: 16 additions & 5 deletions openwisp_utils/measurements/tests/runner.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
from unittest.mock import MagicMock
from unittest.mock import patch

import requests
from django.test.runner import DiscoverRunner
from openwisp_utils import utils
from openwisp_utils.tests import TimeLoggingTestRunner

success_response = requests.Response()
success_response.status_code = 204


class MockRequestPostRunner(DiscoverRunner):
class MockRequestPostRunner(TimeLoggingTestRunner):
"""
This runner ensures that usage metrics are
not sent in development when running tests.
"""

pass

def setup_databases(self, **kwargs):
utils.requests.post = MagicMock(return_value=success_response)
return super().setup_databases(**kwargs)
utils.requests.Session._original_post = utils.requests.Session.post
with patch.object(
utils.requests.Session, 'post', return_value=success_response
):
return super().setup_databases(**kwargs)

def run_suite(self, suite, **kwargs):
with patch.object(
utils.requests.Session, 'post', return_value=success_response
):
return super().run_suite(suite)
37 changes: 27 additions & 10 deletions openwisp_utils/measurements/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.db import migrations
from django.test import TestCase, override_settings
from freezegun import freeze_time
from openwisp_utils import utils
from urllib3.response import HTTPResponse

from .. import tasks
Expand Down Expand Up @@ -174,17 +175,20 @@ def test_post_usage_metrics_400_response(self, mocked_error, mocked_warning, *ar
bad_response = requests.Response()
bad_response.status_code = 400
with patch.object(
requests.Session, 'post', return_value=bad_response
) as mocked_post:
tasks, 'retryable_request', return_value=bad_response
) as mocked_retryable_request:
tasks.send_usage_metrics.delay()
mocked_post.assert_called_once()
mocked_retryable_request.assert_called_once()
mocked_warning.assert_not_called()
mocked_error.assert_called_with(
'Collection of usage metrics failed, max retries exceeded.'
' Error: HTTP 400 Response'
)

@patch('urllib3.util.retry.Retry.sleep')
@patch(
'urllib3.connectionpool.HTTPConnection.request',
)
@patch(
'urllib3.connectionpool.HTTPConnection.getresponse',
return_value=HTTPResponse(status=500, version='1.1'),
Expand All @@ -193,7 +197,12 @@ def test_post_usage_metrics_400_response(self, mocked_error, mocked_warning, *ar
def test_post_usage_metrics_500_response(
self, mocked_error, mocked_getResponse, *args
):
tasks.send_usage_metrics.delay()
with patch.object(
utils.requests.Session, 'post', new=utils.requests.Session._original_post
):
# The requests.Session.post is mocked at the test runner level
# in openwisp_utils.measurements.runner.MockedRequestPostRunner
tasks.send_usage_metrics.delay()
self.assertEqual(len(mocked_getResponse.mock_calls), 11)
mocked_error.assert_called_with(
'Collection of usage metrics failed, max retries exceeded.'
Expand All @@ -206,17 +215,20 @@ def test_post_usage_metrics_500_response(
@patch('logging.Logger.warning')
@patch('logging.Logger.error')
def test_post_usage_metrics_204_response(self, mocked_error, mocked_warning, *args):
bad_response = requests.Response()
bad_response.status_code = 204
success_response = requests.Response()
success_response.status_code = 204
with patch.object(
requests.Session, 'post', return_value=bad_response
) as mocked_post:
tasks, 'retryable_request', return_value=success_response
) as mocked_retryable_request:
tasks.send_usage_metrics.delay()
self.assertEqual(len(mocked_post.mock_calls), 1)
self.assertEqual(len(mocked_retryable_request.mock_calls), 1)
mocked_warning.assert_not_called()
mocked_error.assert_not_called()

@patch('urllib3.util.retry.Retry.sleep')
@patch(
'urllib3.connectionpool.HTTPConnection.request',
)
@patch(
'urllib3.connectionpool.HTTPConnectionPool._get_conn',
side_effect=OSError,
Expand All @@ -225,7 +237,12 @@ def test_post_usage_metrics_204_response(self, mocked_error, mocked_warning, *ar
def test_post_usage_metrics_connection_error(
self, mocked_error, mocked_get_conn, *args
):
tasks.send_usage_metrics.delay()
with patch.object(
utils.requests.Session, 'post', new=utils.requests.Session._original_post
):
# The requests.Session.post is mocked at the test runner level
# in openwisp_utils.measurements.runner.MockedRequestPostRunner
tasks.send_usage_metrics.delay()
mocked_error.assert_called_with(
'Collection of usage metrics failed, max retries exceeded.'
' Error: HTTPSConnectionPool(host=\'analytics.openwisp.io\', port=443):'
Expand Down

0 comments on commit 6707833

Please sign in to comment.