From d359b5d074b76ec8b70ca824817900ab8e0bbe63 Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Mon, 5 Dec 2022 09:31:20 -0100 Subject: [PATCH] AWSLambda: Only publish functions when source has changed (#5734) --- moto/awslambda/models.py | 10 ++++++- tests/test_awslambda/test_lambda.py | 33 +++++++++++++++++++++- tests/test_awslambda/test_lambda_policy.py | 6 ++-- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/moto/awslambda/models.py b/moto/awslambda/models.py index 0d344bb3d..e4e5f9246 100644 --- a/moto/awslambda/models.py +++ b/moto/awslambda/models.py @@ -1310,7 +1310,14 @@ class LambdaStorage(object): if not self._functions[name]["latest"]: return None - new_version = len(self._functions[name]["versions"]) + 1 + all_versions = self._functions[name]["versions"] + if all_versions: + latest_published = all_versions[-1] + if latest_published.code_sha_256 == function.code_sha_256: + # Nothing has changed, don't publish + return latest_published + + new_version = len(all_versions) + 1 fn = copy.copy(self._functions[name]["latest"]) fn.set_version(new_version) if description: @@ -1879,6 +1886,7 @@ class LambdaBackend(BaseBackend): self, function_name: str, qualifier: str, body: Dict[str, Any] ) -> Optional[Dict[str, Any]]: fn: LambdaFunction = self.get_function(function_name, qualifier) + fn.update_function_code(body) if body.get("Publish", False): fn = self.publish_function(function_name) # type: ignore[assignment] diff --git a/tests/test_awslambda/test_lambda.py b/tests/test_awslambda/test_lambda.py index 99836cca8..802132728 100644 --- a/tests/test_awslambda/test_lambda.py +++ b/tests/test_awslambda/test_lambda.py @@ -18,7 +18,9 @@ from .utilities import ( get_role_name, get_test_zip_file1, get_test_zip_file2, + get_test_zip_file3, create_invalid_lambda, + _process_lambda, ) _lambda_region = "us-west-2" @@ -870,6 +872,7 @@ def test_list_versions_by_function(): MemorySize=128, Publish=True, ) + conn.update_function_code(FunctionName=function_name, ZipFile=get_test_zip_file1()) res = conn.publish_version(FunctionName=function_name) assert res["ResponseMetadata"]["HTTPStatusCode"] == 201 @@ -1041,12 +1044,14 @@ def test_update_function_zip(key): Publish=True, ) name_or_arn = fxn[key] + first_sha = fxn["CodeSha256"] zip_content_two = get_test_zip_file2() - conn.update_function_code( + update1 = conn.update_function_code( FunctionName=name_or_arn, ZipFile=zip_content_two, Publish=True ) + update1["CodeSha256"].shouldnt.equal(first_sha) response = conn.get_function(FunctionName=function_name, Qualifier="2") @@ -1066,6 +1071,30 @@ def test_update_function_zip(key): config.should.have.key("FunctionName").equals(function_name) config.should.have.key("Version").equals("2") config.should.have.key("LastUpdateStatus").equals("Successful") + config.should.have.key("CodeSha256").equals(update1["CodeSha256"]) + + most_recent_config = conn.get_function(FunctionName=function_name) + most_recent_config["Configuration"]["CodeSha256"].should.equal( + update1["CodeSha256"] + ) + + # Publishing this again, with the same code, gives us the same version + same_update = conn.update_function_code( + FunctionName=name_or_arn, ZipFile=zip_content_two, Publish=True + ) + same_update["FunctionArn"].should.equal( + most_recent_config["Configuration"]["FunctionArn"] + ":2" + ) + same_update["Version"].should.equal("2") + + # Only when updating the code should we have a new version + new_update = conn.update_function_code( + FunctionName=name_or_arn, ZipFile=get_test_zip_file3(), Publish=True + ) + new_update["FunctionArn"].should.equal( + most_recent_config["Configuration"]["FunctionArn"] + ":3" + ) + new_update["Version"].should.equal("3") @mock_lambda @@ -1191,6 +1220,8 @@ def test_multiple_qualifiers(): ) for _ in range(10): + new_zip = _process_lambda(f"func content {_}") + client.update_function_code(FunctionName=fn_name, ZipFile=new_zip) client.publish_version(FunctionName=fn_name) resp = client.list_versions_by_function(FunctionName=fn_name)["Versions"] diff --git a/tests/test_awslambda/test_lambda_policy.py b/tests/test_awslambda/test_lambda_policy.py index b893fd0ba..971764f1e 100644 --- a/tests/test_awslambda/test_lambda_policy.py +++ b/tests/test_awslambda/test_lambda_policy.py @@ -7,7 +7,7 @@ from botocore.exceptions import ClientError from moto import mock_lambda, mock_s3 from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID from uuid import uuid4 -from .utilities import get_role_name, get_test_zip_file1 +from .utilities import get_role_name, get_test_zip_file1, get_test_zip_file2 _lambda_region = "us-west-2" boto3.setup_default_session(region_name=_lambda_region) @@ -139,7 +139,7 @@ def test_get_policy_with_qualifier(): Publish=True, ) - zip_content_two = get_test_zip_file1() + zip_content_two = get_test_zip_file2() conn.update_function_code( FunctionName=function_name, ZipFile=zip_content_two, Publish=True @@ -250,7 +250,7 @@ def test_remove_function_permission__with_qualifier(key): name_or_arn = f[key] # Ensure Qualifier=2 exists - zip_content_two = get_test_zip_file1() + zip_content_two = get_test_zip_file2() conn.update_function_code( FunctionName=function_name, ZipFile=zip_content_two, Publish=True )