Skip to content

Commit 44934cc

Browse files
committed
add invoke method, utilize in tests
1 parent 25d1dbc commit 44934cc

3 files changed

Lines changed: 70 additions & 35 deletions

File tree

aws_lambda/aws_lambda.py

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,22 @@ def update_function(cfg, path_to_zip_file, extra_config=None):
286286
client.update_function_configuration(**lambda_update_config)
287287

288288

289-
def function_exists(cfg, function_name):
290-
"""Check whether a function exists or not"""
291-
289+
def _client_from_cfg(cfg):
290+
"""
291+
Helper method for the below methods that sets up a lambda client given
292+
a config dictionary containing the relevant AWS key.
293+
"""
292294
aws_access_key_id = cfg.get('aws_access_key_id')
293295
aws_secret_access_key = cfg.get('aws_secret_access_key')
294-
client = get_client('lambda', aws_access_key_id, aws_secret_access_key,
296+
region = cfg.get('region', 'us-east-1')
297+
return get_client('lambda', aws_access_key_id, aws_secret_access_key,
295298
cfg.get('region'))
299+
300+
301+
def function_exists(cfg, function_name):
302+
"""Check whether a function exists or not"""
303+
304+
client = _client_from_cfg(cfg)
296305
try:
297306
client.get_function(FunctionName=function_name)
298307
except:
@@ -306,13 +315,42 @@ def delete_function(cfg, function_name):
306315
Returns True in success, False otherwise
307316
"""
308317

309-
aws_access_key_id = cfg.get('aws_access_key_id')
310-
aws_secret_access_key = cfg.get('aws_secret_access_key')
311-
client = get_client('lambda', aws_access_key_id, aws_secret_access_key,
312-
cfg.get('region'))
318+
client = _client_from_cfg(cfg)
313319
try:
314320
client.get_function(FunctionName=function_name)
315321
client.delete_function(FunctionName=function_name)
316322
except:
317323
return False
318324
return True
325+
326+
def invoke_function(cfg, function_name, invocation_type='RequestResponse', event={}):
327+
"""
328+
Invokes the given lambda function using the given client.
329+
330+
invocation_type is one of 'Event'|'RequestResponse'|'DryRun'. The default
331+
is RequestResponse, which will cause this function to hang until the lambda
332+
is completed. 'Event' triggers the lambda asynchronously. 'DryRun' just
333+
validates paremeters/permissions.
334+
335+
event is a dictionary containing the arguments needed for this lambda. For
336+
example if your lambda is expecting fields 'a' and 'b' in the 'event' that is
337+
passed to it from AWS, you would pass in:
338+
339+
event = {'a': 5, 'b': 13}
340+
341+
to this function. This information is serialized into JSON and passed to Boto3
342+
343+
Returns decoded response in success, None otherwise
344+
"""
345+
346+
import json
347+
client = _client_from_cfg(cfg)
348+
try:
349+
resp = client.invoke(FunctionName=function_name,
350+
InvocationType=invocation_type,
351+
Payload=json.dumps(event))
352+
except:
353+
log.error('Failed to execute lambda fxn: %s with arguments: \n %s \n %s'
354+
% (function_name, invocation_type, event))
355+
return None
356+
return resp['Payload'].read().decode('utf-8')

conftest.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@
22
import pytest
33
from aws_lambda.aws_lambda import (
44
deploy_function,
5-
_install_packages,
6-
pip_install_to_target,
75
get_role_name,
86
get_account_id,
97
get_client,
10-
create_function,
11-
update_function,
128
function_exists,
13-
delete_function
9+
delete_function,
10+
invoke_function
1411
)

tests/test_aws_lambda.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ def cfg(aws_keys):
2929
return conf
3030

3131

32-
@pytest.fixture
33-
def lambda_client(aws_keys):
34-
key_id, secret = aws_keys
35-
return get_client('lambda', key_id, secret, region='us-east-1')
36-
37-
3832
class TestPythonLambdaUnit():
3933
""" Class containing unit (non-integration) tests for Python-Lambda """
4034

@@ -75,7 +69,7 @@ class TestPythonLambdaIntegration():
7569

7670
pytestmark = [pytest.mark.integration]
7771

78-
def test_deploy_lambda(self, cfg, lambda_client):
72+
def test_deploy_lambda(self, cfg):
7973
"""
8074
Deploys a lambda function, tests that we can see/use it
8175
Updates that same function with different config, invokes to verify the
@@ -85,15 +79,15 @@ def test_deploy_lambda(self, cfg, lambda_client):
8579
full_name = example_function.config['function_name'] + '_' + suff
8680
deploy_function(example_function, function_name_suffix=suff)
8781
assert function_exists(cfg, full_name)
88-
resp = lambda_client.invoke(FunctionName=full_name, InvocationType='RequestResponse')
89-
assert resp['Payload'].read().decode('utf-8') == '"Hello! My input event is {}"'
82+
resp = invoke_function(cfg, full_name)
83+
assert resp == '"Hello! My input event is {}"'
9084
deploy_function(example_function_update, function_name_suffix=suff)
91-
resp = lambda_client.invoke(FunctionName=full_name, InvocationType='RequestResponse')
92-
assert resp['Payload'].read().decode('utf-8') == '"Hello! I have been updated! My input event is {}"'
85+
resp = invoke_function(cfg, full_name)
86+
assert resp == '"Hello! I have been updated! My input event is {}"'
9387
assert delete_function(cfg, full_name)
9488
assert not delete_function(cfg, full_name)
9589

96-
def test_deploy_lambda_with_requirements(self, cfg, lambda_client):
90+
def test_deploy_lambda_with_requirements(self, cfg):
9791
"""
9892
Deploys and invokes a lambda that has requirements, this time with no suffix
9993
Also passes an argument that is checked
@@ -103,24 +97,22 @@ def test_deploy_lambda_with_requirements(self, cfg, lambda_client):
10397
req_fpath = './tests/test_lambdas/requirements.txt'
10498
deploy_function(function_with_requirements, requirements_fpath=req_fpath)
10599
assert function_exists(cfg, full_name)
106-
resp = lambda_client.invoke(FunctionName=full_name,
107-
InvocationType='RequestResponse',
108-
Payload=json.dumps({'magic': 17}))
109-
assert resp['Payload'].read().decode('utf-8') == '"I successfully imported pytest! Magic: 17"'
100+
resp = invoke_function(cfg, full_name, event={'magic': 17})
101+
assert resp == '"I successfully imported pytest! Magic: 17"'
110102
assert delete_function(cfg, full_name)
111103

112-
def test_deploy_lambda_with_package(self, cfg, lambda_client):
104+
def test_deploy_lambda_with_package(self, cfg):
113105
"""
114106
Deploys and invokes a lambda that has package based dependencies
115107
"""
116108
full_name = function_with_package.config['function_name']
117109
deploy_function(function_with_package, package_objects=[package])
118110
assert function_exists(cfg, full_name)
119-
resp = lambda_client.invoke(FunctionName=full_name, InvocationType='RequestResponse')
120-
assert resp['Payload'].read().decode('utf-8') == '"I successfully called magic_function: 21"'
111+
resp = invoke_function(cfg, full_name)
112+
assert resp == '"I successfully called magic_function: 21"'
121113
assert delete_function(cfg, full_name)
122114

123-
def test_deploy_lambda_with_package_and_requirements(self, cfg, lambda_client):
115+
def test_deploy_lambda_with_package_and_requirements(self, cfg):
124116
"""
125117
Deploys and invokes a lambda that uses both an independently packaged
126118
dependency and one given from requirements.
@@ -130,6 +122,14 @@ def test_deploy_lambda_with_package_and_requirements(self, cfg, lambda_client):
130122
deploy_function(function_with_req_pack, requirements_fpath=req_fpath,
131123
package_objects=[package])
132124
assert function_exists(cfg, full_name)
133-
resp = lambda_client.invoke(FunctionName=full_name, InvocationType='RequestResponse')
134-
assert resp['Payload'].read().decode('utf-8') == '"Imported pytest, magic_function: 21"'
125+
resp = invoke_function(cfg, full_name)
126+
assert resp == '"Imported pytest, magic_function: 21"'
135127
assert delete_function(cfg, full_name)
128+
129+
def test_invoke_invalid_lambda(self, cfg):
130+
"""
131+
Tries to execute an invalid lambda. Should fail
132+
"""
133+
full_name = 'not_a_lambda_name'
134+
resp = invoke_function(cfg, full_name)
135+
assert resp is None

0 commit comments

Comments
 (0)