moto/tests/test_awslambda/test_lambda_layers.py

316 lines
10 KiB
Python
Raw Normal View History

import os
from unittest import SkipTest, mock
from uuid import uuid4
2021-09-21 15:19:49 +00:00
import boto3
import pytest
2021-09-21 15:19:49 +00:00
from botocore.exceptions import ClientError
from freezegun import freeze_time
2024-01-07 12:03:33 +00:00
from moto import mock_aws, settings
2022-08-13 09:49:43 +00:00
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
2021-09-21 15:19:49 +00:00
from .utilities import get_role_name, get_test_zip_file1
PYTHON_VERSION = "python3.11"
2021-09-21 15:19:49 +00:00
_lambda_region = "us-west-2"
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-17 12:32:31 +00:00
def test_publish_lambda_layers__without_content():
conn = boto3.client("lambda", _lambda_region)
layer_name = str(uuid4())[0:6]
with pytest.raises(ClientError) as exc:
conn.publish_layer_version(
LayerName=layer_name,
Content={},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
err = exc.value.response["Error"]
assert err["Code"] == "InvalidParameterValueException"
assert err["Message"] == "Missing Content"
2022-03-17 12:32:31 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
@mock.patch.dict(os.environ, {"VALIDATE_LAMBDA_S3": "false"})
def test_publish_layer_with_unknown_s3_file():
if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can only set env var in DecoratorMode")
conn = boto3.client("lambda", _lambda_region)
content = conn.publish_layer_version(
LayerName=str(uuid4())[0:6],
Content=dict(S3Bucket="my-bucket", S3Key="my-key.zip"),
)["Content"]
assert content["CodeSha256"] == ""
assert content["CodeSize"] == 0
2024-01-07 12:03:33 +00:00
@mock_aws
2021-09-21 15:19:49 +00:00
@freeze_time("2015-01-01 00:00:00")
def test_get_lambda_layers():
bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket=bucket_name,
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file1()
s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
layer_name = str(uuid4())[0:6]
conn.publish_layer_version(
LayerName=layer_name,
Content={"ZipFile": get_test_zip_file1()},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
conn.publish_layer_version(
LayerName=layer_name,
Content={"S3Bucket": bucket_name, "S3Key": "test.zip"},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
result = conn.list_layer_versions(LayerName=layer_name)
for version in result["LayerVersions"]:
version.pop("CreatedDate")
result["LayerVersions"].sort(key=lambda x: x["Version"])
expected_arn = f"arn:aws:lambda:{_lambda_region}:{ACCOUNT_ID}:layer:{layer_name}:"
assert result["LayerVersions"] == [
{
"Version": 1,
"LayerVersionArn": expected_arn + "1",
"CompatibleRuntimes": ["python3.6"],
"Description": "",
"LicenseInfo": "MIT",
"CompatibleArchitectures": [],
},
{
"Version": 2,
"LayerVersionArn": expected_arn + "2",
"CompatibleRuntimes": ["python3.6"],
"Description": "",
"LicenseInfo": "MIT",
"CompatibleArchitectures": [],
},
]
2021-09-21 15:19:49 +00:00
function_name = str(uuid4())[0:6]
conn.create_function(
FunctionName=function_name,
Runtime=PYTHON_VERSION,
2021-09-21 15:19:49 +00:00
Role=get_role_name(),
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": bucket_name, "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=function_name)
assert result["Layers"] == [
{"Arn": (expected_arn + "1"), "CodeSize": len(zip_content)}
]
2021-09-21 15:19:49 +00:00
result = conn.update_function_configuration(
FunctionName=function_name, Layers=[(expected_arn + "2")]
)
assert result["Layers"] == [
{"Arn": (expected_arn + "2"), "CodeSize": len(zip_content)}
]
2021-09-21 15:19:49 +00:00
# Test get layer versions for non existant layer
result = conn.list_layer_versions(LayerName=f"{layer_name}2")
assert result["LayerVersions"] == []
2021-09-21 15:19:49 +00:00
# Test create function with non existant layer version
function_name = str(uuid4())[0:6] # Must be different than above
with pytest.raises(ClientError) as exc:
2021-09-21 15:19:49 +00:00
conn.create_function(
FunctionName=function_name,
Runtime=PYTHON_VERSION,
2021-09-21 15:19:49 +00:00
Role=get_role_name(),
Handler="lambda_function.lambda_handler",
Code={"S3Bucket": bucket_name, "S3Key": "test.zip"},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
Environment={"Variables": {"test_variable": "test_value"}},
Layers=[(expected_arn + "3")],
)
err = exc.value.response["Error"]
assert err["Code"] == "ResourceNotFoundException"
2022-03-17 12:32:31 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-17 12:32:31 +00:00
def test_get_layer_version():
bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket=bucket_name,
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file1()
s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
layer_name = str(uuid4())[0:6]
resp = conn.publish_layer_version(
LayerName=layer_name,
Content={"ZipFile": get_test_zip_file1()},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
2022-05-19 11:08:02 +00:00
CompatibleArchitectures=["x86_64"],
2022-03-17 12:32:31 +00:00
)
layer_version = resp["Version"]
resp = conn.get_layer_version(LayerName=layer_name, VersionNumber=layer_version)
assert resp["Description"] == ""
assert resp["Version"] == 1
assert resp["CompatibleArchitectures"] == ["x86_64"]
assert resp["CompatibleRuntimes"] == ["python3.6"]
assert resp["LicenseInfo"] == "MIT"
2022-03-17 12:32:31 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-17 12:32:31 +00:00
def test_get_layer_version__unknown():
bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket=bucket_name,
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file1()
s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
layer_name = str(uuid4())[0:6]
# Delete Layer that never existed
with pytest.raises(ClientError) as exc:
conn.get_layer_version(LayerName=layer_name, VersionNumber=1)
err = exc.value.response["Error"]
assert err["Code"] == "ResourceNotFoundException"
2022-03-17 12:32:31 +00:00
conn.publish_layer_version(
LayerName=layer_name,
Content={"ZipFile": get_test_zip_file1()},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
# Delete Version that never existed
with pytest.raises(ClientError) as exc:
conn.get_layer_version(LayerName=layer_name, VersionNumber=999)
err = exc.value.response["Error"]
assert err["Code"] == "ResourceNotFoundException"
2022-03-17 12:32:31 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
@pytest.mark.parametrize("use_arn", [True, False])
def test_delete_layer_version(use_arn):
2022-03-17 12:32:31 +00:00
bucket_name = str(uuid4())
s3_conn = boto3.client("s3", _lambda_region)
s3_conn.create_bucket(
Bucket=bucket_name,
CreateBucketConfiguration={"LocationConstraint": _lambda_region},
)
zip_content = get_test_zip_file1()
s3_conn.put_object(Bucket=bucket_name, Key="test.zip", Body=zip_content)
conn = boto3.client("lambda", _lambda_region)
layer_name = str(uuid4())[0:6]
resp = conn.publish_layer_version(
LayerName=layer_name,
Content={"ZipFile": get_test_zip_file1()},
CompatibleRuntimes=["python3.6"],
LicenseInfo="MIT",
)
layer_arn = resp["LayerArn"]
2022-03-17 12:32:31 +00:00
layer_version = resp["Version"]
if use_arn:
conn.get_layer_version(LayerName=layer_arn, VersionNumber=layer_version)
conn.delete_layer_version(LayerName=layer_arn, VersionNumber=layer_version)
else:
conn.get_layer_version(LayerName=layer_name, VersionNumber=layer_version)
conn.delete_layer_version(LayerName=layer_name, VersionNumber=layer_version)
2022-03-17 12:32:31 +00:00
result = conn.list_layer_versions(LayerName=layer_name)["LayerVersions"]
assert result == []
2024-01-07 12:03:33 +00:00
@mock_aws
def test_get_layer_with_no_layer_versions():
def get_layer_by_layer_name_from_list_of_layer_dicts(layer_name, layer_list):
for layer in layer_list:
if layer["LayerName"] == layer_name:
return layer
return None
conn = boto3.client("lambda", _lambda_region)
layer_name = str(uuid4())[0:6]
# Publish a new Layer and assert Layer exists and only version 1 is there
conn.publish_layer_version(
LayerName=layer_name,
Content={"ZipFile": get_test_zip_file1()},
)
assert (
get_layer_by_layer_name_from_list_of_layer_dicts(
layer_name, conn.list_layers()["Layers"]
)["LatestMatchingVersion"]["Version"]
== 1
)
# Add a new version of that Layer then delete that version
conn.publish_layer_version(
LayerName=layer_name,
Content={"ZipFile": get_test_zip_file1()},
)
assert (
get_layer_by_layer_name_from_list_of_layer_dicts(
layer_name, conn.list_layers()["Layers"]
)["LatestMatchingVersion"]["Version"]
== 2
)
conn.delete_layer_version(LayerName=layer_name, VersionNumber=2)
assert (
get_layer_by_layer_name_from_list_of_layer_dicts(
layer_name, conn.list_layers()["Layers"]
)["LatestMatchingVersion"]["Version"]
== 1
)
# Delete the last layer_version and check that the Layer is still in the LayerStorage
conn.delete_layer_version(LayerName=layer_name, VersionNumber=1)
assert (
get_layer_by_layer_name_from_list_of_layer_dicts(
layer_name, conn.list_layers()["Layers"]
)
is None
)
# Assert _latest_version didn't decrement
conn.publish_layer_version(
LayerName=layer_name,
Content={"ZipFile": get_test_zip_file1()},
)
assert (
get_layer_by_layer_name_from_list_of_layer_dicts(
layer_name, conn.list_layers()["Layers"]
)["LatestMatchingVersion"]["Version"]
== 3
)