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.

322 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
from moto import mock_lambda, mock_s3, 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"
boto3.setup_default_session(region_name=_lambda_region)
2022-03-17 12:32:31 +00:00
@mock_lambda
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
@mock_lambda
@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
2021-09-21 15:19:49 +00:00
@mock_lambda
@mock_s3
@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
@mock_lambda
@mock_s3
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
@mock_lambda
@mock_s3
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
@mock_lambda
@mock_s3
@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 == []
@mock_lambda
@mock_s3
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
)