Skip to content

Commit 5de9b33

Browse files
authored
Merge pull request #42 from open-mpic/ds-dcv-async-bug-fix
added missing initialization for dcv checker
2 parents 422152e + 9fe1119 commit 5de9b33

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

src/aws_lambda_mpic/mpic_dcv_checker_lambda/mpic_dcv_checker_lambda_function.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ def __init__(self):
1212
self.perspective_code = os.environ['AWS_REGION']
1313
self.dcv_checker = MpicDcvChecker(self.perspective_code)
1414

15+
async def initialize(self):
16+
await self.dcv_checker.initialize()
17+
1518
def process_invocation(self, dcv_request: DcvCheckRequest):
1619
try:
1720
event_loop = asyncio.get_running_loop()
@@ -39,13 +42,26 @@ def process_invocation(self, dcv_request: DcvCheckRequest):
3942
_handler = None
4043

4144

45+
async def initialize_handler() -> MpicDcvCheckerLambdaHandler:
46+
handler = MpicDcvCheckerLambdaHandler()
47+
await handler.initialize()
48+
return handler
49+
50+
4251
def get_handler() -> MpicDcvCheckerLambdaHandler:
4352
"""
4453
Singleton pattern to avoid recreating the handler on every Lambda invocation
4554
"""
4655
global _handler
4756
if _handler is None:
48-
_handler = MpicDcvCheckerLambdaHandler()
57+
try:
58+
event_loop = asyncio.get_running_loop()
59+
except RuntimeError:
60+
# No running event loop, create a new one
61+
event_loop = asyncio.new_event_loop()
62+
asyncio.set_event_loop(event_loop)
63+
64+
_handler = event_loop.run_until_complete(initialize_handler())
4965
return _handler
5066

5167

tests/unit/aws_lambda_mpic/test_dcv_checker_lambda.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import asyncio
12
import time
3+
from asyncio import StreamReader
4+
from unittest.mock import MagicMock, AsyncMock
5+
26
import pytest
7+
from aiohttp import ClientResponse
8+
from multidict import CIMultiDictProxy, CIMultiDict
9+
from yarl import URL
310

411
import aws_lambda_mpic.mpic_dcv_checker_lambda.mpic_dcv_checker_lambda_function as mpic_dcv_checker_lambda_function
512
from open_mpic_core.common_domain.validation_error import MpicValidationError
@@ -9,6 +16,7 @@
916
from open_mpic_core_test.test_util.valid_check_creator import ValidCheckCreator
1017

1118

19+
# noinspection PyMethodMayBeStatic
1220
class TestDcvCheckerLambda:
1321
@staticmethod
1422
@pytest.fixture(scope='class')
@@ -53,6 +61,31 @@ def lambda_handler__should_return_appropriate_status_code_given_errors_in_respon
5361
result = mpic_dcv_checker_lambda_function.lambda_handler(dcv_check_request, None)
5462
assert result == mock_return_value
5563

64+
def lambda_handler__should_ensure_dcv_checker_is_fully_initialized_to_perform_http_based_checks(self, set_env_variables, mocker):
65+
dcv_check_request = ValidCheckCreator.create_valid_http_check_request()
66+
expected_challenge_value = dcv_check_request.dcv_check_parameters.validation_details.challenge_value
67+
68+
# this test requires getting pretty far into the Dcv Checker execution; need to mock an aiohttp.ClientResponse
69+
event_loop = asyncio.get_event_loop()
70+
response = ClientResponse(
71+
method='GET', url=URL('http://example.com'), writer=MagicMock(), continue100=None,
72+
timer=AsyncMock(), request_info=AsyncMock(), traces=[], loop=event_loop, session=AsyncMock()
73+
)
74+
response.status = 200
75+
response.content = StreamReader(loop=event_loop)
76+
response.content.feed_data(bytes(expected_challenge_value.encode('utf-8')))
77+
response.content.feed_eof()
78+
response._headers = CIMultiDictProxy(CIMultiDict({
79+
'Content-Type': 'text/plain; charset=utf-8', 'Content-Length': str(len(expected_challenge_value))
80+
}))
81+
82+
mocker.patch(
83+
'aiohttp.ClientSession.get',
84+
side_effect=lambda *args, **kwargs: AsyncMock(__aenter__=AsyncMock(return_value=response))
85+
)
86+
result = mpic_dcv_checker_lambda_function.lambda_handler(dcv_check_request, None)
87+
assert result['statusCode'] == 200
88+
5689
@staticmethod
5790
def create_dcv_check_response():
5891
return DcvCheckResponse(perspective_code='us-east-1', check_passed=True,

0 commit comments

Comments
 (0)