moto/tests/test_awslambda/test_lambda.py

1854 lines
59 KiB
Python
Raw Normal View History

from __future__ import unicode_literals
2016-10-06 09:52:23 +00:00
import base64
import uuid
import botocore.client
import boto3
import hashlib
import io
import json
import time
import zipfile
import sure # noqa
from freezegun import freeze_time
2019-10-31 15:44:26 +00:00
from moto import (
mock_dynamodb2,
mock_lambda,
mock_iam,
2019-10-31 15:44:26 +00:00
mock_s3,
mock_ec2,
mock_sns,
mock_logs,
settings,
mock_sqs,
)
from moto.sts.models import ACCOUNT_ID
import pytest
2019-02-18 04:32:39 +00:00
from botocore.exceptions import ClientError
2019-10-31 15:44:26 +00:00
_lambda_region = "us-west-2"
boto3.setup_default_session(region_name=_lambda_region)
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
def _process_lambda(func_str):
zip_output = io.BytesIO()
2019-10-31 15:44:26 +00:00
zip_file = zipfile.ZipFile(zip_output, "w", zipfile.ZIP_DEFLATED)
zip_file.writestr("lambda_function.py", func_str)
zip_file.close()
zip_output.seek(0)
return zip_output.read()
2016-10-06 09:52:23 +00:00
def get_test_zip_file1():
pfunc = """
2016-10-06 09:52:23 +00:00
def lambda_handler(event, context):
print("custom log event")
return event
2016-10-06 09:52:23 +00:00
"""
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
return _process_lambda(pfunc)
2016-10-06 09:52:23 +00:00
def get_test_zip_file2():
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
func_str = """
import boto3
2016-10-06 09:52:23 +00:00
def lambda_handler(event, context):
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
ec2 = boto3.resource('ec2', region_name='us-west-2', endpoint_url='http://{base_url}')
2016-10-06 09:52:23 +00:00
volume_id = event.get('volume_id')
vol = ec2.Volume(volume_id)
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
return {{'id': vol.id, 'state': vol.state, 'size': vol.size}}
2019-10-31 15:44:26 +00:00
""".format(
base_url="motoserver:5000"
if settings.TEST_SERVER_MODE
else "ec2.us-west-2.amazonaws.com"
)
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
return _process_lambda(func_str)
2016-10-06 09:52:23 +00:00
def get_test_zip_file3():
pfunc = """
def lambda_handler(event, context):
print("Nr_of_records("+str(len(event['Records']))+")")
print("get_test_zip_file3 success")
return event
"""
return _process_lambda(pfunc)
2019-10-31 15:44:26 +00:00
def get_test_zip_file4():
pfunc = """
def lambda_handler(event, context):
raise Exception('I failed!')
"""
return _process_lambda(pfunc)
@pytest.mark.parametrize("region", ["us-west-2", "cn-northwest-1"])
@mock_lambda
def test_lambda_regions(region):
client = boto3.client("lambda", region_name=region)
resp = client.list_functions()
resp["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
@mock_lambda
def test_list_functions():
conn = boto3.client("lambda", _lambda_region)
result = conn.list_functions()
2019-10-31 15:44:26 +00:00
result["Functions"].should.have.length_of(0)
2020-10-06 09:51:29 +00:00
@pytest.mark.network
2016-06-22 19:24:46 +00:00
@mock_lambda
def test_invoke_requestresponse_function():
conn = boto3.client("lambda", _lambda_region)
2016-06-22 19:24:46 +00:00
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file1()},
Description="test lambda function",
2016-06-22 19:24:46 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-10-31 15:44:26 +00:00
in_data = {"msg": "So long and thanks for all the fish"}
success_result = conn.invoke(
FunctionName="testFunction",
InvocationType="RequestResponse",
Payload=json.dumps(in_data),
2020-05-07 11:29:18 +00:00
LogType="Tail",
2019-10-31 15:44:26 +00:00
)
2016-06-22 19:24:46 +00:00
success_result["StatusCode"].should.equal(200)
logs = base64.b64decode(success_result["LogResult"]).decode("utf-8")
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
logs.should.contain("START RequestId:")
logs.should.contain("custom log event")
logs.should.contain("END RequestId:")
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
2019-10-31 15:44:26 +00:00
payload = success_result["Payload"].read().decode("utf-8")
json.loads(payload).should.equal(in_data)
# Logs should not be returned by default, only when the LogType-param is supplied
success_result = conn.invoke(
FunctionName="testFunction",
InvocationType="RequestResponse",
Payload=json.dumps(in_data),
)
success_result["StatusCode"].should.equal(200)
assert "LogResult" not in success_result
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_lambda
def test_invoke_requestresponse_function_with_arn():
from moto.awslambda.models import ACCOUNT_ID
conn = boto3.client("lambda", "us-west-2")
conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file1()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
in_data = {"msg": "So long and thanks for all the fish"}
success_result = conn.invoke(
FunctionName="arn:aws:lambda:us-west-2:{}:function:testFunction".format(
ACCOUNT_ID
),
InvocationType="RequestResponse",
Payload=json.dumps(in_data),
)
success_result["StatusCode"].should.equal(200)
payload = success_result["Payload"].read().decode("utf-8")
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
json.loads(payload).should.equal(in_data)
2016-06-22 19:24:46 +00:00
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_lambda
def test_invoke_event_function():
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file1()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
conn.invoke.when.called_with(
2019-10-31 15:44:26 +00:00
FunctionName="notAFunction", InvocationType="Event", Payload="{}"
).should.throw(botocore.client.ClientError)
2019-10-31 15:44:26 +00:00
in_data = {"msg": "So long and thanks for all the fish"}
2017-02-24 02:37:43 +00:00
success_result = conn.invoke(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction", InvocationType="Event", Payload=json.dumps(in_data)
)
2016-10-06 09:52:23 +00:00
success_result["StatusCode"].should.equal(202)
2020-01-24 16:11:44 +00:00
json.loads(success_result["Payload"].read().decode("utf-8")).should.equal(in_data)
2016-10-06 09:52:23 +00:00
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_lambda
def test_invoke_dryrun_function():
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
2020-01-24 09:08:48 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2020-01-24 09:08:48 +00:00
Handler="lambda_function.lambda_handler",
2020-11-11 15:55:37 +00:00
Code={"ZipFile": get_test_zip_file1(),},
2020-01-24 09:08:48 +00:00
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
conn.invoke.when.called_with(
2020-01-24 09:08:48 +00:00
FunctionName="notAFunction", InvocationType="Event", Payload="{}"
).should.throw(botocore.client.ClientError)
2020-01-24 09:08:48 +00:00
in_data = {"msg": "So long and thanks for all the fish"}
success_result = conn.invoke(
2020-01-24 09:08:48 +00:00
FunctionName="testFunction",
InvocationType="DryRun",
Payload=json.dumps(in_data),
)
success_result["StatusCode"].should.equal(204)
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
if settings.TEST_SERVER_MODE:
2019-10-31 15:44:26 +00:00
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
@mock_ec2
@mock_lambda
def test_invoke_function_get_ec2_volume():
conn = boto3.resource("ec2", _lambda_region)
vol = conn.create_volume(Size=99, AvailabilityZone=_lambda_region)
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
vol = conn.Volume(vol.id)
conn = boto3.client("lambda", _lambda_region)
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python3.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file2()},
Description="test lambda function",
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
2016-10-06 09:52:23 +00:00
2019-10-31 15:44:26 +00:00
in_data = {"volume_id": vol.id}
result = conn.invoke(
FunctionName="testFunction",
InvocationType="RequestResponse",
Payload=json.dumps(in_data),
)
result["StatusCode"].should.equal(200)
2020-01-09 10:08:35 +00:00
actual_payload = json.loads(result["Payload"].read().decode("utf-8"))
expected_payload = {"id": vol.id, "state": vol.state, "size": vol.size}
actual_payload.should.equal(expected_payload)
2016-06-22 19:24:46 +00:00
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_logs
@mock_sns
@mock_ec2
@mock_lambda
def test_invoke_function_from_sns():
logs_conn = boto3.client("logs", region_name=_lambda_region)
sns_conn = boto3.client("sns", region_name=_lambda_region)
sns_conn.create_topic(Name="some-topic")
topics_json = sns_conn.list_topics()
topics = topics_json["Topics"]
2019-10-31 15:44:26 +00:00
topic_arn = topics[0]["TopicArn"]
conn = boto3.client("lambda", _lambda_region)
result = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-10-31 15:44:26 +00:00
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:
2019-10-31 15:44:26 +00:00
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
2019-10-31 15:44:26 +00:00
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
def test_create_based_on_s3_with_missing_bucket():
conn = boto3.client("lambda", _lambda_region)
conn.create_function.when.called_with(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "this-bucket-does-not-exist", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
2019-10-31 15:44:26 +00:00
VpcConfig={"SecurityGroupIds": ["sg-123abc"], "SubnetIds": ["subnet-123abc"]},
).should.throw(botocore.client.ClientError)
@mock_lambda
@mock_s3
2019-10-31 15:44:26 +00:00
@freeze_time("2015-01-01 00:00:00")
def test_create_function_from_aws_bucket():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
2016-10-06 09:52:23 +00:00
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
result = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
2019-10-31 15:44:26 +00:00
VpcConfig={"SecurityGroupIds": ["sg-123abc"], "SubnetIds": ["subnet-123abc"]},
)
2017-02-24 02:37:43 +00:00
# this is hard to match against, so remove it
2019-10-31 15:44:26 +00:00
result["ResponseMetadata"].pop("HTTPHeaders", None)
2017-02-24 02:37:43 +00:00
# Botocore inserts retry attempts not seen in Python27
2019-10-31 15:44:26 +00:00
result["ResponseMetadata"].pop("RetryAttempts", None)
result.pop("LastModified")
result.should.equal(
{
"FunctionName": "testFunction",
"FunctionArn": "arn:aws:lambda:{}:{}:function:testFunction".format(
_lambda_region, ACCOUNT_ID
2019-10-31 15:44:26 +00:00
),
"Runtime": "python2.7",
"Role": result["Role"],
2019-10-31 15:44:26 +00:00
"Handler": "lambda_function.lambda_handler",
"CodeSha256": hashlib.sha256(zip_content).hexdigest(),
"CodeSize": len(zip_content),
"Description": "test lambda function",
"Timeout": 3,
"MemorySize": 128,
"Version": "1",
"VpcConfig": {
"SecurityGroupIds": ["sg-123abc"],
"SubnetIds": ["subnet-123abc"],
"VpcId": "vpc-123abc",
},
"ResponseMetadata": {"HTTPStatusCode": 201},
"State": "Active",
2019-10-31 15:44:26 +00:00
}
)
@mock_lambda
2019-10-31 15:44:26 +00:00
@freeze_time("2015-01-01 00:00:00")
def test_create_function_from_zipfile():
conn = boto3.client("lambda", _lambda_region)
2016-10-06 09:52:23 +00:00
zip_content = get_test_zip_file1()
result = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": zip_content},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
2017-02-24 02:37:43 +00:00
# this is hard to match against, so remove it
2019-10-31 15:44:26 +00:00
result["ResponseMetadata"].pop("HTTPHeaders", None)
2017-02-24 02:37:43 +00:00
# Botocore inserts retry attempts not seen in Python27
2019-10-31 15:44:26 +00:00
result["ResponseMetadata"].pop("RetryAttempts", None)
result.pop("LastModified")
2019-10-31 15:44:26 +00:00
result.should.equal(
{
"FunctionName": "testFunction",
"FunctionArn": "arn:aws:lambda:{}:{}:function:testFunction".format(
_lambda_region, ACCOUNT_ID
2019-10-31 15:44:26 +00:00
),
"Runtime": "python2.7",
"Role": result["Role"],
2019-10-31 15:44:26 +00:00
"Handler": "lambda_function.lambda_handler",
"CodeSize": len(zip_content),
"Description": "test lambda function",
"Timeout": 3,
"MemorySize": 128,
"CodeSha256": hashlib.sha256(zip_content).hexdigest(),
"Version": "1",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"ResponseMetadata": {"HTTPStatusCode": 201},
"State": "Active",
2019-10-31 15:44:26 +00:00
}
)
@mock_lambda
@mock_s3
2019-10-31 15:44:26 +00:00
@freeze_time("2015-01-01 00:00:00")
def test_get_function():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
2016-10-06 09:52:23 +00:00
zip_content = get_test_zip_file1()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
2019-11-04 15:22:03 +00:00
Environment={"Variables": {"test_variable": "test_value"}},
)
2019-10-31 15:44:26 +00:00
result = conn.get_function(FunctionName="testFunction")
2017-02-24 02:37:43 +00:00
# this is hard to match against, so remove it
2019-10-31 15:44:26 +00:00
result["ResponseMetadata"].pop("HTTPHeaders", None)
2017-02-24 02:37:43 +00:00
# Botocore inserts retry attempts not seen in Python27
2019-10-31 15:44:26 +00:00
result["ResponseMetadata"].pop("RetryAttempts", None)
result["Configuration"].pop("LastModified")
2019-10-31 15:44:26 +00:00
result["Code"]["Location"].should.equal(
"s3://awslambda-{0}-tasks.s3-{0}.amazonaws.com/test.zip".format(_lambda_region)
)
result["Code"]["RepositoryType"].should.equal("S3")
2019-10-31 15:44:26 +00:00
result["Configuration"]["CodeSha256"].should.equal(
hashlib.sha256(zip_content).hexdigest()
)
result["Configuration"]["CodeSize"].should.equal(len(zip_content))
result["Configuration"]["Description"].should.equal("test lambda function")
result["Configuration"].should.contain("FunctionArn")
result["Configuration"]["FunctionName"].should.equal("testFunction")
result["Configuration"]["Handler"].should.equal("lambda_function.lambda_handler")
result["Configuration"]["MemorySize"].should.equal(128)
result["Configuration"]["Role"].should.equal(get_role_name())
2019-10-31 15:44:26 +00:00
result["Configuration"]["Runtime"].should.equal("python2.7")
result["Configuration"]["Timeout"].should.equal(3)
result["Configuration"]["Version"].should.equal("$LATEST")
result["Configuration"].should.contain("VpcConfig")
2019-11-04 15:22:03 +00:00
result["Configuration"].should.contain("Environment")
result["Configuration"]["Environment"].should.contain("Variables")
result["Configuration"]["Environment"]["Variables"].should.equal(
{"test_variable": "test_value"}
)
# Test get function with qualifier
2019-10-31 15:44:26 +00:00
result = conn.get_function(FunctionName="testFunction", Qualifier="$LATEST")
result["Configuration"]["Version"].should.equal("$LATEST")
result["Configuration"]["FunctionArn"].should.equal(
"arn:aws:lambda:us-west-2:{}:function:testFunction:$LATEST".format(ACCOUNT_ID)
2019-10-31 15:44:26 +00:00
)
2019-02-18 04:32:39 +00:00
# Test get function when can't find function name
with pytest.raises(conn.exceptions.ResourceNotFoundException):
2019-10-31 15:44:26 +00:00
conn.get_function(FunctionName="junk", Qualifier="$LATEST")
2019-02-18 04:32:39 +00:00
2019-11-04 15:22:03 +00:00
@mock_lambda
@mock_s3
def test_get_function_by_arn():
2019-11-04 15:22:03 +00:00
bucket_name = "test-bucket"
s3_conn = boto3.client("s3", "us-east-1")
s3_conn.create_bucket(
Bucket=bucket_name,
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file2()
2019-11-04 15:22:03 +00:00
s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", "us-east-1")
2019-11-04 15:22:03 +00:00
fnc = conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-11-04 15:22:03 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": bucket_name, "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-11-04 15:22:03 +00:00
result = conn.get_function(FunctionName=fnc["FunctionArn"])
result["Configuration"]["FunctionName"].should.equal("testFunction")
2019-02-18 04:32:39 +00:00
@mock_lambda
@mock_s3
def test_delete_function():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
2016-10-06 09:52:23 +00:00
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-10-31 15:44:26 +00:00
success_result = conn.delete_function(FunctionName="testFunction")
2017-02-24 02:37:43 +00:00
# this is hard to match against, so remove it
2019-10-31 15:44:26 +00:00
success_result["ResponseMetadata"].pop("HTTPHeaders", None)
2017-02-24 02:37:43 +00:00
# Botocore inserts retry attempts not seen in Python27
2019-10-31 15:44:26 +00:00
success_result["ResponseMetadata"].pop("RetryAttempts", None)
2019-10-31 15:44:26 +00:00
success_result.should.equal({"ResponseMetadata": {"HTTPStatusCode": 204}})
function_list = conn.list_functions()
2019-10-31 15:44:26 +00:00
function_list["Functions"].should.have.length_of(0)
@mock_lambda
@mock_s3
def test_delete_function_by_arn():
2019-10-31 15:44:26 +00:00
bucket_name = "test-bucket"
s3_conn = boto3.client("s3", "us-east-1")
s3_conn.create_bucket(
Bucket=bucket_name,
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", "us-east-1")
fnc = conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": bucket_name, "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-10-31 15:44:26 +00:00
conn.delete_function(FunctionName=fnc["FunctionArn"])
function_list = conn.list_functions()
2019-10-31 15:44:26 +00:00
function_list["Functions"].should.have.length_of(0)
@mock_lambda
def test_delete_unknown_function():
conn = boto3.client("lambda", _lambda_region)
2017-02-24 02:37:43 +00:00
conn.delete_function.when.called_with(
2019-10-31 15:44:26 +00:00
FunctionName="testFunctionThatDoesntExist"
).should.throw(botocore.client.ClientError)
@mock_lambda
@mock_s3
def test_publish():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=False,
)
function_list = conn.list_functions()
2019-10-31 15:44:26 +00:00
function_list["Functions"].should.have.length_of(1)
latest_arn = function_list["Functions"][0]["FunctionArn"]
2019-10-31 15:44:26 +00:00
res = conn.publish_version(FunctionName="testFunction")
assert res["ResponseMetadata"]["HTTPStatusCode"] == 201
function_list = conn.list_functions()
2019-10-31 15:44:26 +00:00
function_list["Functions"].should.have.length_of(2)
# #SetComprehension ;-)
2019-10-31 15:44:26 +00:00
published_arn = list(
{f["FunctionArn"] for f in function_list["Functions"]} - {latest_arn}
)[0]
published_arn.should.contain("testFunction:1")
2019-10-31 15:44:26 +00:00
conn.delete_function(FunctionName="testFunction", Qualifier="1")
function_list = conn.list_functions()
2019-10-31 15:44:26 +00:00
function_list["Functions"].should.have.length_of(1)
function_list["Functions"][0]["FunctionArn"].should.contain("testFunction")
@mock_lambda
@mock_s3
2019-10-31 15:44:26 +00:00
@freeze_time("2015-01-01 00:00:00")
def test_list_create_list_get_delete_list():
"""
test `list -> create -> list -> get -> delete -> list` integration
"""
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
2016-10-06 09:52:23 +00:00
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
2019-10-31 15:44:26 +00:00
conn.list_functions()["Functions"].should.have.length_of(0)
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
expected_function_result = {
"Code": {
2019-10-31 15:44:26 +00:00
"Location": "s3://awslambda-{0}-tasks.s3-{0}.amazonaws.com/test.zip".format(
_lambda_region
),
"RepositoryType": "S3",
},
"Configuration": {
"CodeSha256": hashlib.sha256(zip_content).hexdigest(),
"CodeSize": len(zip_content),
"Description": "test lambda function",
"FunctionArn": "arn:aws:lambda:{}:{}:function:testFunction".format(
_lambda_region, ACCOUNT_ID
2019-10-31 15:44:26 +00:00
),
"FunctionName": "testFunction",
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
"Handler": "lambda_function.lambda_handler",
"MemorySize": 128,
"Role": get_role_name(),
"Runtime": "python2.7",
"Timeout": 3,
2019-10-31 15:44:26 +00:00
"Version": "$LATEST",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
},
2019-10-31 15:44:26 +00:00
"ResponseMetadata": {"HTTPStatusCode": 200},
}
2019-10-31 15:44:26 +00:00
func = conn.list_functions()["Functions"][0]
func.pop("LastModified")
func.should.equal(expected_function_result["Configuration"])
2019-10-31 15:44:26 +00:00
func = conn.get_function(FunctionName="testFunction")
2017-02-24 02:37:43 +00:00
# this is hard to match against, so remove it
2019-10-31 15:44:26 +00:00
func["ResponseMetadata"].pop("HTTPHeaders", None)
2017-02-24 02:37:43 +00:00
# Botocore inserts retry attempts not seen in Python27
2019-10-31 15:44:26 +00:00
func["ResponseMetadata"].pop("RetryAttempts", None)
func["Configuration"].pop("LastModified")
func.should.equal(expected_function_result)
2019-10-31 15:44:26 +00:00
conn.delete_function(FunctionName="testFunction")
2019-10-31 15:44:26 +00:00
conn.list_functions()["Functions"].should.have.length_of(0)
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_lambda
def test_invoke_lambda_error():
lambda_fx = """
lambda + SNS enhancements (#1048) * updates - support lambda messages from SNS - run lambda in docker container * decode output * populate timeout * simplify * whoops * skeletons of cloudwatchlogs * impl filter log streams * fix logging * PEP fixes * PEP fixes * fix reset * fix reset * add new endpoint * fix region name * add docker * try to fix tests * try to fix travis issue with boto * fix escaping in urls * fix environment variables * fix PEP * more pep * switch back to precise * another fix attempt * fix typo * fix lambda invoke * fix more unittests * work on getting this to work in new scheme * fix py2 * fix error * fix tests when running in server mode * more lambda fixes * try running with latest docker adapted from aiodocker * switch to docker python client * pep fixes * switch to docker volume * fix unittest * fix invoke from sns * fix zip2tar * add hack impl for get_function with zip * try fix * fix for py < 3.6 * add volume refcount * try to fix travis * docker test * fix yaml * try fix * update endpoints * fix * another attempt * try again * fix recursive import * refactor fix * revert changes with better fix * more reverts * wait for service to come up * add back detached mode * sleep and add another exception type * put this back for logging * put back with note * whoops :) * docker in docker! * fix invalid url * hopefully last fix! * fix lambda regions * fix protocol * travis!!!! * just run lambda test for now * use one print * fix escaping * another attempt * yet another * re-enable all tests * fixes * fix for py2 * revert change * fix for py2.7 * fix output ordering * remove this given there's a new unittest that covers it * changes based on review - add skeleton logs test file - switch to docker image that matches test env - fix mock_logs import * add readme entry
2017-09-27 23:04:58 +00:00
def lambda_handler(event, context):
raise Exception('failsauce')
"""
zip_output = io.BytesIO()
2019-10-31 15:44:26 +00:00
zip_file = zipfile.ZipFile(zip_output, "w", zipfile.ZIP_DEFLATED)
zip_file.writestr("lambda_function.py", lambda_fx)
zip_file.close()
zip_output.seek(0)
2019-10-31 15:44:26 +00:00
client = boto3.client("lambda", region_name="us-east-1")
client.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="test-lambda-fx",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
2019-10-31 15:44:26 +00:00
Code={"ZipFile": zip_output.read()},
)
result = client.invoke(
2019-10-31 15:44:26 +00:00
FunctionName="test-lambda-fx", InvocationType="RequestResponse", LogType="Tail"
)
2019-10-31 15:44:26 +00:00
assert "FunctionError" in result
assert result["FunctionError"] == "Handled"
2017-09-13 04:44:22 +00:00
2017-10-25 19:04:00 +00:00
@mock_lambda
@mock_s3
def test_tags():
"""
test list_tags -> tag_resource -> list_tags -> tag_resource -> list_tags -> untag_resource -> list_tags integration
"""
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
function = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
# List tags when there are none
2019-10-31 15:44:26 +00:00
conn.list_tags(Resource=function["FunctionArn"])["Tags"].should.equal(dict())
# List tags when there is one
2019-10-31 15:44:26 +00:00
conn.tag_resource(Resource=function["FunctionArn"], Tags=dict(spam="eggs"))[
"ResponseMetadata"
]["HTTPStatusCode"].should.equal(200)
conn.list_tags(Resource=function["FunctionArn"])["Tags"].should.equal(
dict(spam="eggs")
)
# List tags when another has been added
2019-10-31 15:44:26 +00:00
conn.tag_resource(Resource=function["FunctionArn"], Tags=dict(foo="bar"))[
"ResponseMetadata"
]["HTTPStatusCode"].should.equal(200)
conn.list_tags(Resource=function["FunctionArn"])["Tags"].should.equal(
dict(spam="eggs", foo="bar")
)
# Untag resource
2019-10-31 15:44:26 +00:00
conn.untag_resource(Resource=function["FunctionArn"], TagKeys=["spam", "trolls"])[
"ResponseMetadata"
]["HTTPStatusCode"].should.equal(204)
conn.list_tags(Resource=function["FunctionArn"])["Tags"].should.equal(
dict(foo="bar")
)
# Untag a tag that does not exist (no error and no change)
2019-10-31 15:44:26 +00:00
conn.untag_resource(Resource=function["FunctionArn"], TagKeys=["spam"])[
"ResponseMetadata"
]["HTTPStatusCode"].should.equal(204)
2017-10-25 19:04:00 +00:00
@mock_lambda
def test_tags_not_found():
"""
Test list_tags and tag_resource when the lambda with the given arn does not exist
"""
conn = boto3.client("lambda", _lambda_region)
conn.list_tags.when.called_with(
Resource="arn:aws:lambda:{}:function:not-found".format(ACCOUNT_ID)
).should.throw(botocore.client.ClientError)
conn.tag_resource.when.called_with(
Resource="arn:aws:lambda:{}:function:not-found".format(ACCOUNT_ID),
2019-10-31 15:44:26 +00:00
Tags=dict(spam="eggs"),
).should.throw(botocore.client.ClientError)
conn.untag_resource.when.called_with(
2019-12-17 02:25:20 +00:00
Resource="arn:aws:lambda:{}:function:not-found".format(ACCOUNT_ID),
TagKeys=["spam"],
).should.throw(botocore.client.ClientError)
2017-09-14 02:06:05 +00:00
2017-10-25 19:04:00 +00:00
2020-10-06 09:51:29 +00:00
@pytest.mark.network
2017-09-13 04:44:22 +00:00
@mock_lambda
def test_invoke_async_function():
conn = boto3.client("lambda", _lambda_region)
2017-09-13 04:44:22 +00:00
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file1()},
Description="test lambda function",
2017-09-13 04:44:22 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
success_result = conn.invoke_async(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction", InvokeArgs=json.dumps({"test": "event"})
)
2017-09-13 04:44:22 +00:00
2019-10-31 15:44:26 +00:00
success_result["Status"].should.equal(202)
2017-10-25 19:04:00 +00:00
@mock_lambda
2019-10-31 15:44:26 +00:00
@freeze_time("2015-01-01 00:00:00")
def test_get_function_created_with_zipfile():
conn = boto3.client("lambda", _lambda_region)
zip_content = get_test_zip_file1()
result = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.handler",
Code={"ZipFile": zip_content},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-10-31 15:44:26 +00:00
response = conn.get_function(FunctionName="testFunction")
response["Configuration"].pop("LastModified")
2019-10-31 15:44:26 +00:00
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
assert len(response["Code"]) == 2
assert response["Code"]["RepositoryType"] == "S3"
assert response["Code"]["Location"].startswith(
"s3://awslambda-{0}-tasks.s3-{0}.amazonaws.com".format(_lambda_region)
)
response["Configuration"].should.equal(
{
"CodeSha256": hashlib.sha256(zip_content).hexdigest(),
"CodeSize": len(zip_content),
"Description": "test lambda function",
"FunctionArn": "arn:aws:lambda:{}:{}:function:testFunction".format(
_lambda_region, ACCOUNT_ID
2019-10-31 15:44:26 +00:00
),
"FunctionName": "testFunction",
"Handler": "lambda_function.handler",
"MemorySize": 128,
"Role": get_role_name(),
"Runtime": "python2.7",
"Timeout": 3,
2019-10-31 15:44:26 +00:00
"Version": "$LATEST",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
2019-10-31 15:44:26 +00:00
}
2017-09-15 03:07:02 +00:00
)
2017-10-03 00:33:50 +00:00
2017-10-25 19:04:00 +00:00
2017-10-03 02:23:00 +00:00
@mock_lambda
def test_add_function_permission():
conn = boto3.client("lambda", _lambda_region)
2017-10-03 02:23:00 +00:00
zip_content = get_test_zip_file1()
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=(get_role_name()),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.handler",
Code={"ZipFile": zip_content},
Description="test lambda function",
2017-10-03 02:23:00 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.add_permission(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
StatementId="1",
2017-10-03 02:23:00 +00:00
Action="lambda:InvokeFunction",
2019-10-31 15:44:26 +00:00
Principal="432143214321",
2017-10-03 02:23:00 +00:00
SourceArn="arn:aws:lambda:us-west-2:account-id:function:helloworld",
2019-10-31 15:44:26 +00:00
SourceAccount="123412341234",
EventSourceToken="blah",
Qualifier="2",
2017-10-03 02:23:00 +00:00
)
2019-10-31 15:44:26 +00:00
assert "Statement" in response
res = json.loads(response["Statement"])
assert res["Action"] == "lambda:InvokeFunction"
2017-10-03 02:23:00 +00:00
2017-10-03 00:33:50 +00:00
@mock_lambda
def test_get_function_policy():
conn = boto3.client("lambda", _lambda_region)
2017-10-03 00:33:50 +00:00
zip_content = get_test_zip_file1()
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.handler",
Code={"ZipFile": zip_content},
Description="test lambda function",
2017-10-03 00:33:50 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
2017-10-03 02:23:00 +00:00
response = conn.add_permission(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
StatementId="1",
2017-10-03 02:23:00 +00:00
Action="lambda:InvokeFunction",
2019-10-31 15:44:26 +00:00
Principal="432143214321",
2017-10-03 02:23:00 +00:00
SourceArn="arn:aws:lambda:us-west-2:account-id:function:helloworld",
2019-10-31 15:44:26 +00:00
SourceAccount="123412341234",
EventSourceToken="blah",
Qualifier="2",
2017-10-03 02:23:00 +00:00
)
2019-10-31 15:44:26 +00:00
response = conn.get_policy(FunctionName="testFunction")
2017-10-03 00:54:37 +00:00
2019-10-31 15:44:26 +00:00
assert "Policy" in response
res = json.loads(response["Policy"])
assert res["Statement"][0]["Action"] == "lambda:InvokeFunction"
@mock_lambda
@mock_s3
def test_list_versions_by_function():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-10-31 15:44:26 +00:00
res = conn.publish_version(FunctionName="testFunction")
assert res["ResponseMetadata"]["HTTPStatusCode"] == 201
versions = conn.list_versions_by_function(FunctionName="testFunction")
assert len(versions["Versions"]) == 3
2019-12-17 02:25:20 +00:00
assert versions["Versions"][0][
"FunctionArn"
] == "arn:aws:lambda:us-west-2:{}:function:testFunction:$LATEST".format(ACCOUNT_ID)
assert versions["Versions"][1][
"FunctionArn"
] == "arn:aws:lambda:us-west-2:{}:function:testFunction:1".format(ACCOUNT_ID)
assert versions["Versions"][2][
"FunctionArn"
] == "arn:aws:lambda:us-west-2:{}:function:testFunction:2".format(ACCOUNT_ID)
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction_2",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=False,
)
2019-10-31 15:44:26 +00:00
versions = conn.list_versions_by_function(FunctionName="testFunction_2")
assert len(versions["Versions"]) == 1
2019-12-17 02:25:20 +00:00
assert versions["Versions"][0][
"FunctionArn"
] == "arn:aws:lambda:us-west-2:{}:function:testFunction_2:$LATEST".format(
ACCOUNT_ID
2019-10-31 15:44:26 +00:00
)
2019-02-16 18:37:46 +00:00
@mock_lambda
@mock_s3
def test_create_function_with_already_exists():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
2019-02-16 18:37:46 +00:00
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
2019-02-16 18:37:46 +00:00
conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
2019-02-16 18:37:46 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
2019-02-16 18:37:46 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
2019-10-31 15:44:26 +00:00
assert response["FunctionName"] == "testFunction"
2019-02-16 18:37:46 +00:00
@mock_lambda
@mock_s3
def test_list_versions_by_function_for_nonexistent_function():
conn = boto3.client("lambda", _lambda_region)
2019-10-31 15:44:26 +00:00
versions = conn.list_versions_by_function(FunctionName="testFunction")
2019-02-16 18:37:46 +00:00
2019-10-31 15:44:26 +00:00
assert len(versions["Versions"]) == 0
@mock_logs
@mock_lambda
@mock_sqs
def test_create_event_source_mapping():
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-sqs-queue1")
conn = boto3.client("lambda", region_name="us-east-1")
func = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=queue.attributes["QueueArn"], FunctionName=func["FunctionArn"]
)
2019-10-31 15:44:26 +00:00
assert response["EventSourceArn"] == queue.attributes["QueueArn"]
assert response["FunctionArn"] == func["FunctionArn"]
assert response["State"] == "Enabled"
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_logs
@mock_lambda
@mock_sqs
def test_invoke_function_from_sqs():
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-sqs-queue1")
conn = boto3.client("lambda", region_name="us-east-1")
func = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=queue.attributes["QueueArn"], FunctionName=func["FunctionArn"]
)
2019-10-31 15:44:26 +00:00
assert response["EventSourceArn"] == queue.attributes["QueueArn"]
assert response["State"] == "Enabled"
sqs_client = boto3.client("sqs", region_name="us-east-1")
2019-10-31 15:44:26 +00:00
sqs_client.send_message(QueueUrl=queue.url, MessageBody="test")
expected_msg = "get_test_zip_file3 success"
log_group = "/aws/lambda/testFunction"
msg_showed_up, all_logs = wait_for_log_msg(expected_msg, log_group)
assert msg_showed_up, (
expected_msg
+ " was not found after sending an SQS message. All logs: "
+ all_logs
)
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_logs
@mock_lambda
@mock_dynamodb2
def test_invoke_function_from_dynamodb_put():
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
2019-10-31 15:44:26 +00:00
table_name = "table_with_stream"
table = dynamodb.create_table(
TableName=table_name,
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
StreamSpecification={
"StreamEnabled": True,
"StreamViewType": "NEW_AND_OLD_IMAGES",
},
)
conn = boto3.client("lambda", region_name="us-east-1")
2019-10-31 15:44:26 +00:00
func = conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function executed after a DynamoDB table is updated",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=table["TableDescription"]["LatestStreamArn"],
FunctionName=func["FunctionArn"],
)
2019-10-31 15:44:26 +00:00
assert response["EventSourceArn"] == table["TableDescription"]["LatestStreamArn"]
assert response["State"] == "Enabled"
2019-10-31 15:44:26 +00:00
dynamodb.put_item(TableName=table_name, Item={"id": {"S": "item 1"}})
expected_msg = "get_test_zip_file3 success"
log_group = "/aws/lambda/testFunction"
msg_showed_up, all_logs = wait_for_log_msg(expected_msg, log_group)
assert msg_showed_up, (
expected_msg + " was not found after a DDB insert. All logs: " + all_logs
)
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_logs
@mock_lambda
@mock_dynamodb2
def test_invoke_function_from_dynamodb_update():
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
table_name = "table_with_stream"
table = dynamodb.create_table(
TableName=table_name,
KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}],
StreamSpecification={
"StreamEnabled": True,
"StreamViewType": "NEW_AND_OLD_IMAGES",
},
)
conn = boto3.client("lambda", region_name="us-east-1")
func = conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function executed after a DynamoDB table is updated",
Timeout=3,
MemorySize=128,
Publish=True,
)
conn.create_event_source_mapping(
EventSourceArn=table["TableDescription"]["LatestStreamArn"],
FunctionName=func["FunctionArn"],
)
dynamodb.put_item(TableName=table_name, Item={"id": {"S": "item 1"}})
log_group = "/aws/lambda/testFunction"
expected_msg = "get_test_zip_file3 success"
msg_showed_up, all_logs = wait_for_log_msg(expected_msg, log_group)
assert "Nr_of_records(1)" in all_logs, "Only one item should be inserted"
2020-02-18 12:34:24 +00:00
dynamodb.update_item(
TableName=table_name,
Key={"id": {"S": "item 1"}},
UpdateExpression="set #attr = :val",
ExpressionAttributeNames={"#attr": "new_attr"},
ExpressionAttributeValues={":val": {"S": "new_val"}},
)
msg_showed_up, all_logs = wait_for_log_msg(expected_msg, log_group)
assert msg_showed_up, (
expected_msg + " was not found after updating DDB. All logs: " + str(all_logs)
)
assert "Nr_of_records(1)" in all_logs, "Only one item should be updated"
assert (
"Nr_of_records(2)" not in all_logs
), "The inserted item should not show up again"
def wait_for_log_msg(expected_msg, log_group):
logs_conn = boto3.client("logs", region_name="us-east-1")
received_messages = []
start = time.time()
while (time.time() - start) < 10:
result = logs_conn.describe_log_streams(logGroupName=log_group)
log_streams = result.get("logStreams")
if not log_streams:
time.sleep(1)
continue
for log_stream in log_streams:
result = logs_conn.get_log_events(
2020-11-11 15:55:37 +00:00
logGroupName=log_group, logStreamName=log_stream["logStreamName"],
)
received_messages.extend(
[event["message"] for event in result.get("events")]
)
if expected_msg in received_messages:
return True, received_messages
time.sleep(1)
return False, received_messages
2020-10-06 09:51:29 +00:00
@pytest.mark.network
@mock_logs
@mock_lambda
@mock_sqs
def test_invoke_function_from_sqs_exception():
logs_conn = boto3.client("logs", region_name="us-east-1")
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-sqs-queue1")
conn = boto3.client("lambda", region_name="us-east-1")
func = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file4()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=queue.attributes["QueueArn"], FunctionName=func["FunctionArn"]
)
2019-10-31 15:44:26 +00:00
assert response["EventSourceArn"] == queue.attributes["QueueArn"]
assert response["State"] == "Enabled"
entries = []
for i in range(3):
2019-10-31 15:44:26 +00:00
body = {"uuid": str(uuid.uuid4()), "test": "test_{}".format(i)}
entry = {"Id": str(i), "MessageBody": json.dumps(body)}
entries.append(entry)
queue.send_messages(Entries=entries)
start = time.time()
while (time.time() - start) < 30:
2019-10-31 15:44:26 +00:00
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
2019-10-31 15:44:26 +00:00
result = logs_conn.get_log_events(
logGroupName="/aws/lambda/testFunction",
logStreamName=log_streams[0]["logStreamName"],
)
for event in result.get("events"):
if "I failed!" in event["message"]:
messages = queue.receive_messages(MaxNumberOfMessages=10)
# Verify messages are still visible and unprocessed
assert len(messages) == 3
return
time.sleep(1)
assert False, "Test Failed"
@mock_logs
@mock_lambda
@mock_sqs
def test_list_event_source_mappings():
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-sqs-queue1")
conn = boto3.client("lambda", region_name="us-east-1")
func = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=queue.attributes["QueueArn"], FunctionName=func["FunctionArn"]
)
2019-10-31 15:44:26 +00:00
mappings = conn.list_event_source_mappings(EventSourceArn="123")
assert len(mappings["EventSourceMappings"]) == 0
2019-10-31 15:44:26 +00:00
mappings = conn.list_event_source_mappings(
EventSourceArn=queue.attributes["QueueArn"]
)
assert len(mappings["EventSourceMappings"]) == 1
assert mappings["EventSourceMappings"][0]["UUID"] == response["UUID"]
assert mappings["EventSourceMappings"][0]["FunctionArn"] == func["FunctionArn"]
@mock_lambda
@mock_sqs
def test_get_event_source_mapping():
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-sqs-queue1")
conn = boto3.client("lambda", region_name="us-east-1")
func = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=queue.attributes["QueueArn"], FunctionName=func["FunctionArn"]
)
2019-10-31 15:44:26 +00:00
mapping = conn.get_event_source_mapping(UUID=response["UUID"])
assert mapping["UUID"] == response["UUID"]
assert mapping["FunctionArn"] == func["FunctionArn"]
2019-10-31 15:44:26 +00:00
conn.get_event_source_mapping.when.called_with(UUID="1").should.throw(
botocore.client.ClientError
)
@mock_lambda
@mock_sqs
def test_update_event_source_mapping():
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-sqs-queue1")
conn = boto3.client("lambda", region_name="us-east-1")
func1 = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
func2 = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction2",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=queue.attributes["QueueArn"], FunctionName=func1["FunctionArn"]
)
2019-10-31 15:44:26 +00:00
assert response["FunctionArn"] == func1["FunctionArn"]
assert response["BatchSize"] == 10
assert response["State"] == "Enabled"
mapping = conn.update_event_source_mapping(
UUID=response["UUID"], Enabled=False, BatchSize=2, FunctionName="testFunction2"
)
2019-10-31 15:44:26 +00:00
assert mapping["UUID"] == response["UUID"]
assert mapping["FunctionArn"] == func2["FunctionArn"]
assert mapping["State"] == "Disabled"
assert mapping["BatchSize"] == 2
@mock_lambda
@mock_sqs
def test_delete_event_source_mapping():
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-sqs-queue1")
conn = boto3.client("lambda", region_name="us-east-1")
func1 = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": get_test_zip_file3()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
response = conn.create_event_source_mapping(
2019-10-31 15:44:26 +00:00
EventSourceArn=queue.attributes["QueueArn"], FunctionName=func1["FunctionArn"]
)
2019-10-31 15:44:26 +00:00
assert response["FunctionArn"] == func1["FunctionArn"]
assert response["BatchSize"] == 10
assert response["State"] == "Enabled"
2019-10-31 15:44:26 +00:00
response = conn.delete_event_source_mapping(UUID=response["UUID"])
2019-10-31 15:44:26 +00:00
assert response["State"] == "Deleting"
conn.get_event_source_mapping.when.called_with(UUID=response["UUID"]).should.throw(
botocore.client.ClientError
)
@mock_lambda
@mock_s3
def test_update_configuration():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
fxn = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
2019-11-04 15:22:03 +00:00
Environment={"Variables": {"test_old_environment": "test_old_value"}},
)
2019-10-31 15:44:26 +00:00
assert fxn["Description"] == "test lambda function"
assert fxn["Handler"] == "lambda_function.lambda_handler"
assert fxn["MemorySize"] == 128
assert fxn["Runtime"] == "python2.7"
assert fxn["Timeout"] == 3
updated_config = conn.update_function_configuration(
2019-10-31 15:44:26 +00:00
FunctionName="testFunction",
Description="updated test lambda function",
Handler="lambda_function.new_lambda_handler",
Runtime="python3.6",
Timeout=7,
VpcConfig={"SecurityGroupIds": ["sg-123abc"], "SubnetIds": ["subnet-123abc"]},
2019-11-04 15:22:03 +00:00
Environment={"Variables": {"test_environment": "test_value"}},
)
2019-10-31 15:44:26 +00:00
assert updated_config["ResponseMetadata"]["HTTPStatusCode"] == 200
assert updated_config["Description"] == "updated test lambda function"
assert updated_config["Handler"] == "lambda_function.new_lambda_handler"
assert updated_config["MemorySize"] == 128
assert updated_config["Runtime"] == "python3.6"
assert updated_config["Timeout"] == 7
2019-11-04 15:22:03 +00:00
assert updated_config["Environment"]["Variables"] == {
"test_environment": "test_value"
}
assert updated_config["VpcConfig"] == {
"SecurityGroupIds": ["sg-123abc"],
"SubnetIds": ["subnet-123abc"],
"VpcId": "vpc-123abc",
}
@mock_lambda
2019-10-09 21:20:49 +00:00
def test_update_function_zip():
conn = boto3.client("lambda", _lambda_region)
zip_content_one = get_test_zip_file1()
fxn = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunctionZip",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"ZipFile": zip_content_one},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
zip_content_two = get_test_zip_file2()
2019-10-09 20:15:10 +00:00
fxn_updated = conn.update_function_code(
2019-10-31 15:44:26 +00:00
FunctionName="testFunctionZip", ZipFile=zip_content_two, Publish=True
)
2019-10-31 15:44:26 +00:00
response = conn.get_function(FunctionName="testFunctionZip", Qualifier="2")
response["Configuration"].pop("LastModified")
2019-10-31 15:44:26 +00:00
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
assert len(response["Code"]) == 2
assert response["Code"]["RepositoryType"] == "S3"
assert response["Code"]["Location"].startswith(
"s3://awslambda-{0}-tasks.s3-{0}.amazonaws.com".format(_lambda_region)
)
response["Configuration"].should.equal(
{
"CodeSha256": hashlib.sha256(zip_content_two).hexdigest(),
"CodeSize": len(zip_content_two),
"Description": "test lambda function",
"FunctionArn": "arn:aws:lambda:{}:{}:function:testFunctionZip:2".format(
_lambda_region, ACCOUNT_ID
2019-10-31 15:44:26 +00:00
),
2019-10-09 21:20:49 +00:00
"FunctionName": "testFunctionZip",
"Handler": "lambda_function.lambda_handler",
"MemorySize": 128,
"Role": fxn["Role"],
"Runtime": "python2.7",
"Timeout": 3,
2019-10-31 15:44:26 +00:00
"Version": "2",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
2019-10-31 15:44:26 +00:00
}
2019-10-09 21:20:49 +00:00
)
2019-10-31 15:44:26 +00:00
2019-10-09 21:20:49 +00:00
@mock_lambda
@mock_s3
def test_update_function_s3():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
2019-10-09 21:20:49 +00:00
zip_content = get_test_zip_file1()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
2019-10-09 21:20:49 +00:00
conn = boto3.client("lambda", _lambda_region)
2019-10-09 21:20:49 +00:00
fxn = conn.create_function(
2019-10-31 15:44:26 +00:00
FunctionName="testFunctionS3",
Runtime="python2.7",
Role=get_role_name(),
2019-10-31 15:44:26 +00:00
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
2019-10-09 21:20:49 +00:00
Timeout=3,
MemorySize=128,
Publish=True,
)
zip_content_two = get_test_zip_file2()
2019-10-31 15:44:26 +00:00
s3_conn.put_object(Bucket="test-bucket", Key="test2.zip", Body=zip_content_two)
2019-10-09 21:20:49 +00:00
fxn_updated = conn.update_function_code(
2019-10-31 15:44:26 +00:00
FunctionName="testFunctionS3",
S3Bucket="test-bucket",
S3Key="test2.zip",
Publish=True,
2019-10-09 21:20:49 +00:00
)
2019-10-31 15:44:26 +00:00
response = conn.get_function(FunctionName="testFunctionS3", Qualifier="2")
response["Configuration"].pop("LastModified")
2019-10-09 21:20:49 +00:00
2019-10-31 15:44:26 +00:00
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
assert len(response["Code"]) == 2
assert response["Code"]["RepositoryType"] == "S3"
assert response["Code"]["Location"].startswith(
"s3://awslambda-{0}-tasks.s3-{0}.amazonaws.com".format(_lambda_region)
)
response["Configuration"].should.equal(
2019-10-09 21:20:49 +00:00
{
"CodeSha256": hashlib.sha256(zip_content_two).hexdigest(),
"CodeSize": len(zip_content_two),
"Description": "test lambda function",
"FunctionArn": "arn:aws:lambda:{}:{}:function:testFunctionS3:2".format(
_lambda_region, ACCOUNT_ID
2019-10-31 15:44:26 +00:00
),
2019-10-09 21:20:49 +00:00
"FunctionName": "testFunctionS3",
"Handler": "lambda_function.lambda_handler",
"MemorySize": 128,
"Role": fxn["Role"],
2019-10-09 21:20:49 +00:00
"Runtime": "python2.7",
"Timeout": 3,
2019-10-31 15:44:26 +00:00
"Version": "2",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
2019-10-31 15:44:26 +00:00
}
)
@mock_lambda
def test_create_function_with_invalid_arn():
err = create_invalid_lambda("test-iam-role")
2020-10-06 06:04:09 +00:00
err.value.response["Error"]["Message"].should.equal(
r"1 validation error detected: Value 'test-iam-role' at 'role' failed to satisfy constraint: Member must satisfy regular expression pattern: arn:(aws[a-zA-Z-]*)?:iam::(\d{12}):role/?[a-zA-Z_0-9+=,.@\-_/]+"
)
@mock_lambda
def test_create_function_with_arn_from_different_account():
err = create_invalid_lambda("arn:aws:iam::000000000000:role/example_role")
2020-10-06 06:04:09 +00:00
err.value.response["Error"]["Message"].should.equal(
"Cross-account pass role is not allowed."
)
@mock_lambda
def test_create_function_with_unknown_arn():
err = create_invalid_lambda(
"arn:aws:iam::" + str(ACCOUNT_ID) + ":role/service-role/unknown_role"
)
2020-10-06 06:04:09 +00:00
err.value.response["Error"]["Message"].should.equal(
"The role defined for the function cannot be assumed by Lambda."
)
@mock_lambda
def test_remove_function_permission():
conn = boto3.client("lambda", _lambda_region)
zip_content = get_test_zip_file1()
conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=(get_role_name()),
Handler="lambda_function.handler",
Code={"ZipFile": zip_content},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
conn.add_permission(
FunctionName="testFunction",
StatementId="1",
Action="lambda:InvokeFunction",
Principal="432143214321",
SourceArn="arn:aws:lambda:us-west-2:account-id:function:helloworld",
SourceAccount="123412341234",
EventSourceToken="blah",
Qualifier="2",
)
remove = conn.remove_permission(
2020-11-11 15:55:37 +00:00
FunctionName="testFunction", StatementId="1", Qualifier="2",
)
remove["ResponseMetadata"]["HTTPStatusCode"].should.equal(204)
policy = conn.get_policy(FunctionName="testFunction", Qualifier="2")["Policy"]
policy = json.loads(policy)
policy["Statement"].should.equal([])
@mock_lambda
def test_put_function_concurrency():
expected_concurrency = 15
function_name = "test"
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
FunctionName=function_name,
Runtime="python3.8",
Role=(get_role_name()),
Handler="lambda_function.handler",
Code={"ZipFile": get_test_zip_file1()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
result = conn.put_function_concurrency(
FunctionName=function_name, ReservedConcurrentExecutions=expected_concurrency
)
result["ReservedConcurrentExecutions"].should.equal(expected_concurrency)
@mock_lambda
def test_delete_function_concurrency():
function_name = "test"
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
FunctionName=function_name,
Runtime="python3.8",
Role=(get_role_name()),
Handler="lambda_function.handler",
Code={"ZipFile": get_test_zip_file1()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
conn.put_function_concurrency(
FunctionName=function_name, ReservedConcurrentExecutions=15
)
conn.delete_function_concurrency(FunctionName=function_name)
result = conn.get_function(FunctionName=function_name)
result.doesnt.have.key("Concurrency")
@mock_lambda
def test_get_function_concurrency():
expected_concurrency = 15
function_name = "test"
conn = boto3.client("lambda", _lambda_region)
conn.create_function(
FunctionName=function_name,
Runtime="python3.8",
Role=(get_role_name()),
Handler="lambda_function.handler",
Code={"ZipFile": get_test_zip_file1()},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
conn.put_function_concurrency(
FunctionName=function_name, ReservedConcurrentExecutions=expected_concurrency
)
result = conn.get_function_concurrency(FunctionName=function_name)
result["ReservedConcurrentExecutions"].should.equal(expected_concurrency)
def create_invalid_lambda(role):
conn = boto3.client("lambda", _lambda_region)
zip_content = get_test_zip_file1()
with pytest.raises(ClientError) as err:
conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=role,
Handler="lambda_function.handler",
Code={"ZipFile": zip_content},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
)
return err
def get_role_name():
with mock_iam():
iam = boto3.client("iam", region_name=_lambda_region)
try:
return iam.get_role(RoleName="my-role")["Role"]["Arn"]
except ClientError:
return iam.create_role(
RoleName="my-role",
AssumeRolePolicyDocument="some policy",
Path="/my-path/",
)["Role"]["Arn"]