moto/tests/test_awslambda/test_lambda_layers.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

324 lines
11 KiB
Python
Raw Normal View History

import os
import sys
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
from moto.utilities.distutils_version import LooseVersion
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"
boto3_version = sys.modules["botocore"].__version__
2021-09-21 15:19:49 +00:00
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():
if LooseVersion(boto3_version) < LooseVersion("1.29.0"):
raise SkipTest("Parameters only available in newer versions")
2021-09-21 15:19:49 +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]
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():
if LooseVersion(boto3_version) < LooseVersion("1.29.0"):
raise SkipTest("Parameters only available in newer versions")
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",
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
)