diff --git a/app/clients/cbc_proxy.py b/app/clients/cbc_proxy.py index 8d2a65d12..57296fa03 100644 --- a/app/clients/cbc_proxy.py +++ b/app/clients/cbc_proxy.py @@ -26,6 +26,12 @@ class CBCProxyNoopClient: def init_app(self, app): pass + def send_canary( + self, + identifier, + ): + pass + def create_and_send_broadcast( self, identifier, headline, description, areas @@ -57,6 +63,26 @@ class CBCProxyClient: aws_secret_access_key=app.config['CBC_PROXY_AWS_SECRET_ACCESS_KEY'], ) + def send_canary( + self, + identifier, + ): + payload_bytes = bytes(json.dumps({ + 'identifier': identifier, + }), encoding='utf8') + + result = self._lambda_client.invoke( + FunctionName='canary', + InvocationType='RequestResponse', + Payload=payload_bytes, + ) + + if result['StatusCode'] > 299: + raise Exception('Could not invoke lambda') + + if 'FunctionError' in result: + raise Exception('Function exited with unhandled exception') + def create_and_send_broadcast( self, identifier, headline, description, areas, diff --git a/tests/app/clients/test_cbc_proxy.py b/tests/app/clients/test_cbc_proxy.py index febcc26a4..8368180c7 100644 --- a/tests/app/clients/test_cbc_proxy.py +++ b/tests/app/clients/test_cbc_proxy.py @@ -1,4 +1,5 @@ import json +import uuid import pytest @@ -165,3 +166,88 @@ def test_cbc_proxy_create_and_send_handles_function_error(mocker, cbc_proxy): InvocationType='RequestResponse', Payload=mocker.ANY, ) + + +def test_cbc_proxy_send_canary_invokes_function(mocker, cbc_proxy): + identifier = str(uuid.uuid4()) + + ld_client_mock = mocker.patch.object( + cbc_proxy, + '_lambda_client', + create=True, + ) + + ld_client_mock.invoke.return_value = { + 'StatusCode': 200, + } + + cbc_proxy.send_canary( + identifier=identifier, + ) + + ld_client_mock.invoke.assert_called_once_with( + FunctionName='canary', + InvocationType='RequestResponse', + Payload=mocker.ANY, + ) + + kwargs = ld_client_mock.invoke.mock_calls[0][-1] + payload_bytes = kwargs['Payload'] + payload = json.loads(payload_bytes) + + assert payload['identifier'] == identifier + + +def test_cbc_proxy_send_canary_handles_invoke_error(mocker, cbc_proxy): + identifier = str(uuid.uuid4()) + + ld_client_mock = mocker.patch.object( + cbc_proxy, + '_lambda_client', + create=True, + ) + + ld_client_mock.invoke.return_value = { + 'StatusCode': 400, + } + + with pytest.raises(Exception) as e: + cbc_proxy.send_canary( + identifier=identifier, + ) + + assert e.match('Function exited with unhandled exception') + + ld_client_mock.invoke.assert_called_once_with( + FunctionName='canary', + InvocationType='RequestResponse', + Payload=mocker.ANY, + ) + + +def test_cbc_proxy_send_canary_handles_function_error(mocker, cbc_proxy): + identifier = str(uuid.uuid4()) + + ld_client_mock = mocker.patch.object( + cbc_proxy, + '_lambda_client', + create=True, + ) + + ld_client_mock.invoke.return_value = { + 'StatusCode': 200, + 'FunctionError': 'something', + } + + with pytest.raises(Exception) as e: + cbc_proxy.send_canary( + identifier=identifier, + ) + + assert e.match('Could not invoke lambda') + + ld_client_mock.invoke.assert_called_once_with( + FunctionName='canary', + InvocationType='RequestResponse', + Payload=mocker.ANY, + )