fix lambda endpoint parsing (#1395)

* fix endpoint parsing

* add new unittest

* finish test
This commit is contained in:
Alexander Mohr 2018-03-21 22:14:10 -07:00 committed by Jack Danger
parent 2faffc96de
commit 941d817da4
3 changed files with 80 additions and 9 deletions

View File

@ -603,7 +603,7 @@ class LambdaBackend(BaseBackend):
def list_functions(self): def list_functions(self):
return self._lambdas.all() return self._lambdas.all()
def send_message(self, function_name, message, subject=None): def send_message(self, function_name, message, subject=None, qualifier=None):
event = { event = {
"Records": [ "Records": [
{ {
@ -636,8 +636,8 @@ class LambdaBackend(BaseBackend):
] ]
} }
self._functions[function_name][-1].invoke(json.dumps(event), {}, {}) func = self._lambdas.get_function(function_name, qualifier)
pass func.invoke(json.dumps(event), {}, {})
def list_tags(self, resource): def list_tags(self, resource):
return self.get_function_by_arn(resource).tags return self.get_function_by_arn(resource).tags

View File

@ -100,9 +100,21 @@ class Subscription(BaseModel):
requests.post(self.endpoint, json=post_data) requests.post(self.endpoint, json=post_data)
elif self.protocol == 'lambda': elif self.protocol == 'lambda':
# TODO: support bad function name # TODO: support bad function name
function_name = self.endpoint.split(":")[-1] # http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
region = self.arn.split(':')[3] arr = self.endpoint.split(":")
lambda_backends[region].send_message(function_name, message, subject=subject) region = arr[3]
qualifier = None
if len(arr) == 7:
assert arr[5] == 'function'
function_name = arr[-1]
elif len(arr) == 8:
assert arr[5] == 'function'
qualifier = arr[-1]
function_name = arr[-2]
else:
assert False
lambda_backends[region].send_message(function_name, message, subject=subject, qualifier=qualifier)
def _matches_filter_policy(self, message_attributes): def _matches_filter_policy(self, message_attributes):
# TODO: support Anything-but matching, prefix matching and # TODO: support Anything-but matching, prefix matching and

View File

@ -6,11 +6,12 @@ import boto3
import hashlib import hashlib
import io import io
import json import json
import time
import zipfile import zipfile
import sure # noqa import sure # noqa
from freezegun import freeze_time from freezegun import freeze_time
from moto import mock_lambda, mock_s3, mock_ec2, settings from moto import mock_lambda, mock_s3, mock_ec2, mock_sns, mock_logs, settings
_lambda_region = 'us-west-2' _lambda_region = 'us-west-2'
@ -48,6 +49,15 @@ def lambda_handler(event, context):
return _process_lambda(func_str) return _process_lambda(func_str)
def get_test_zip_file3():
pfunc = """
def lambda_handler(event, context):
print("get_test_zip_file3 success")
return event
"""
return _process_lambda(pfunc)
@mock_lambda @mock_lambda
def test_list_functions(): def test_list_functions():
conn = boto3.client('lambda', 'us-west-2') conn = boto3.client('lambda', 'us-west-2')
@ -160,6 +170,56 @@ if settings.TEST_SERVER_MODE:
payload.should.equal(msg) payload.should.equal(msg)
@mock_logs
@mock_sns
@mock_ec2
@mock_lambda
def test_invoke_function_from_sns():
logs_conn = boto3.client("logs", region_name="us-west-2")
sns_conn = boto3.client("sns", region_name="us-west-2")
sns_conn.create_topic(Name="some-topic")
topics_json = sns_conn.list_topics()
topics = topics_json["Topics"]
topic_arn = topics[0]['TopicArn']
conn = boto3.client('lambda', 'us-west-2')
result = conn.create_function(
FunctionName='testFunction',
Runtime='python2.7',
Role='test-iam-role',
Handler='lambda_function.lambda_handler',
Code={
'ZipFile': get_test_zip_file3(),
},
Description='test lambda function',
Timeout=3,
MemorySize=128,
Publish=True,
)
sns_conn.subscribe(TopicArn=topic_arn, Protocol="lambda", Endpoint=result['FunctionArn'])
result = sns_conn.publish(TopicArn=topic_arn, Message=json.dumps({}))
start = time.time()
while (time.time() - start) < 30:
result = logs_conn.describe_log_streams(logGroupName='/aws/lambda/testFunction')
log_streams = result.get('logStreams')
if not log_streams:
time.sleep(1)
continue
assert len(log_streams) == 1
result = logs_conn.get_log_events(logGroupName='/aws/lambda/testFunction', logStreamName=log_streams[0]['logStreamName'])
for event in result.get('events'):
if event['message'] == 'get_test_zip_file3 success':
return
time.sleep(1)
assert False, "Test Failed"
@mock_lambda @mock_lambda
def test_create_based_on_s3_with_missing_bucket(): def test_create_based_on_s3_with_missing_bucket():
conn = boto3.client('lambda', 'us-west-2') conn = boto3.client('lambda', 'us-west-2')
@ -420,7 +480,6 @@ def test_publish():
function_list['Functions'][0]['FunctionArn'].should.contain('testFunction:$LATEST') function_list['Functions'][0]['FunctionArn'].should.contain('testFunction:$LATEST')
@mock_lambda @mock_lambda
@mock_s3 @mock_s3
@freeze_time('2015-01-01 00:00:00') @freeze_time('2015-01-01 00:00:00')
@ -674,7 +733,7 @@ def test_get_function_created_with_zipfile():
"CodeSha256": hashlib.sha256(zip_content).hexdigest(), "CodeSha256": hashlib.sha256(zip_content).hexdigest(),
"CodeSize": len(zip_content), "CodeSize": len(zip_content),
"Description": "test lambda function", "Description": "test lambda function",
"FunctionArn":'arn:aws:lambda:{}:123456789012:function:testFunction:$LATEST'.format(_lambda_region), "FunctionArn": 'arn:aws:lambda:{}:123456789012:function:testFunction:$LATEST'.format(_lambda_region),
"FunctionName": "testFunction", "FunctionName": "testFunction",
"Handler": "lambda_function.handler", "Handler": "lambda_function.handler",
"MemorySize": 128, "MemorySize": 128,