adding layers support for lambda backend (#3563)

* adding layers support for lambda backend

* improving lambda layer tests

* adding lambda list_layers and fixing tests

* make format
This commit is contained in:
Erez Freiberger 2021-01-17 17:28:49 +02:00 committed by GitHub
commit 9784e1b487
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 459 additions and 34 deletions

View file

@ -24,6 +24,7 @@ from moto import (
mock_sqs,
)
from moto.sts.models import ACCOUNT_ID
from moto.core.exceptions import RESTError
import pytest
from botocore.exceptions import ClientError
@ -398,6 +399,7 @@ def test_create_function_from_aws_bucket():
},
"ResponseMetadata": {"HTTPStatusCode": 201},
"State": "Active",
"Layers": [],
}
)
@ -442,6 +444,7 @@ def test_create_function_from_zipfile():
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"ResponseMetadata": {"HTTPStatusCode": 201},
"State": "Active",
"Layers": [],
}
)
@ -786,6 +789,7 @@ def test_list_create_list_get_delete_list():
"Version": "$LATEST",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
"Layers": [],
},
"ResponseMetadata": {"HTTPStatusCode": 200},
}
@ -988,6 +992,7 @@ def test_get_function_created_with_zipfile():
"Version": "$LATEST",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
"Layers": [],
}
)
@ -1678,6 +1683,7 @@ def test_update_function_zip():
"Version": "2",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
"Layers": [],
}
)
@ -1744,6 +1750,7 @@ def test_update_function_s3():
"Version": "2",
"VpcConfig": {"SecurityGroupIds": [], "SubnetIds": []},
"State": "Active",
"Layers": [],
}
)
@ -1886,6 +1893,113 @@ def test_get_function_concurrency():
result["ReservedConcurrentExecutions"].should.equal(expected_concurrency)
@mock_lambda
@mock_s3
@freeze_time("2015-01-01 00:00:00")
def test_get_lambda_layers():
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket="test-bucket",
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file1()
s3_conn.put_object(Bucket="test-bucket", Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
with pytest.raises((RESTError, ClientError)):
conn.publish_layer_version(
LayerName="testLayer",
Content={},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
conn.publish_layer_version(
LayerName="testLayer",
Content={"ZipFile": get_test_zip_file1()},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
conn.publish_layer_version(
LayerName="testLayer",
Content={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
result = conn.list_layer_versions(LayerName="testLayer")
for version in result["LayerVersions"]:
version.pop("CreatedDate")
result["LayerVersions"].sort(key=lambda x: x["Version"])
expected_arn = "arn:aws:lambda:{0}:{1}:layer:testLayer:".format(
_lambda_region, ACCOUNT_ID
)
result["LayerVersions"].should.equal(
[
{
"Version": 1,
"LayerVersionArn": expected_arn + "1",
"CompatibleRuntimes": ["python3.6"],
"Description": "",
"LicenseInfo": "MIT",
},
{
"Version": 2,
"LayerVersionArn": expected_arn + "2",
"CompatibleRuntimes": ["python3.6"],
"Description": "",
"LicenseInfo": "MIT",
},
]
)
conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
Environment={"Variables": {"test_variable": "test_value"}},
Layers=[(expected_arn + "1")],
)
result = conn.get_function_configuration(FunctionName="testFunction")
result["Layers"].should.equal(
[{"Arn": (expected_arn + "1"), "CodeSize": len(zip_content)}]
)
result = conn.update_function_configuration(
FunctionName="testFunction", Layers=[(expected_arn + "2")]
)
result["Layers"].should.equal(
[{"Arn": (expected_arn + "2"), "CodeSize": len(zip_content)}]
)
# Test get layer versions for non existant layer
result = conn.list_layer_versions(LayerName="testLayer2")
result["LayerVersions"].should.equal([])
# Test create function with non existant layer version
with pytest.raises((ValueError, ClientError)):
conn.create_function(
FunctionName="testFunction",
Runtime="python2.7",
Role=get_role_name(),
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": "test-bucket", "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
Environment={"Variables": {"test_variable": "test_value"}},
Layers=[(expected_arn + "3")],
)
def create_invalid_lambda(role):
conn = boto3.client("lambda", _lambda_region)
zip_content = get_test_zip_file1()

View file

@ -1,5 +1,7 @@
from __future__ import unicode_literals
import json
import io
import zipfile
from decimal import Decimal
@ -1819,6 +1821,71 @@ def lambda_handler(event, context):
result["Concurrency"]["ReservedConcurrentExecutions"].should.equal(10)
def _make_zipfile(func_str):
zip_output = io.BytesIO()
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()
@mock_cloudformation
@mock_s3
@mock_lambda
def test_lambda_layer():
# switch this to python as backend lambda only supports python execution.
layer_code = """
def lambda_handler(event, context):
return (event, context)
"""
region = "us-east-1"
bucket_name = "test_bucket"
s3_conn = boto3.client("s3", region)
s3_conn.create_bucket(Bucket=bucket_name)
zip_content = _make_zipfile(layer_code)
s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"lambdaTest": {
"Type": "AWS::Lambda::LayerVersion",
"Properties": {
"Content": {"S3Bucket": bucket_name, "S3Key": "test.zip",},
"LayerName": "testLayer",
"Description": "Test Layer",
"CompatibleRuntimes": ["python2.7", "python3.6"],
"LicenseInfo": "MIT",
},
},
},
}
template_json = json.dumps(template)
cf_conn = boto3.client("cloudformation", region)
cf_conn.create_stack(StackName="test_stack", TemplateBody=template_json)
lambda_conn = boto3.client("lambda", region)
result = lambda_conn.list_layers()
layer_name = result["Layers"][0]["LayerName"]
result = lambda_conn.list_layer_versions(LayerName=layer_name)
result["LayerVersions"][0].pop("CreatedDate")
result["LayerVersions"].should.equal(
[
{
"Version": 1,
"LayerVersionArn": "arn:aws:lambda:{}:{}:layer:{}:1".format(
region, ACCOUNT_ID, layer_name
),
"CompatibleRuntimes": ["python2.7", "python3.6"],
"Description": "Test Layer",
"LicenseInfo": "MIT",
}
]
)
@mock_cloudformation
@mock_ec2
def test_nat_gateway():