10000 Cfn/fix lambda update (#11802) · localstack/localstack@0896c3c · GitHub
[go: up one dir, main page]

Skip to content

Commit 0896c3c

Browse files
authored
Cfn/fix lambda update (#11802)
1 parent 0c04ec3 commit 0896c3c

File tree

8 files changed

+173
-8
lines changed

8 files changed

+173
-8
lines changed

localstack-core/localstack/services/lambda_/resource_providers/aws_lambda_function.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ def update(
463463
# TODO: handle defaults properly
464464
old_name = request.previous_state["FunctionName"]
465465
new_name = request.desired_state.get("FunctionName")
466-
if old_name != new_name:
466+
if new_name and old_name != new_name:
467467
# replacement (!) => shouldn't be handled here but in the engine
468468
self.delete(request)
469469
return self.create(request)

tests/aws/services/cloudformation/resources/test_apigateway.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,47 @@ def test_update_usage_plan(deploy_cfn_template, aws_client, snapshot):
440440
assert usage_plan["quota"]["limit"] == 7000
441441

442442

443+
@markers.snapshot.skip_snapshot_verify(
444+
paths=["$..createdDate", "$..description", "$..lastUpdatedDate", "$..tags"]
445+
)
446+
@markers.aws.validated
447+
def test_update_apigateway_stage(deploy_cfn_template, snapshot, aws_client):
448+
snapshot.add_transformers_list(
449+
[
450+
snapshot.transform.key_value("deploymentId"),
451+
snapshot.transform.key_value("aws:cloudformation:stack-name"),
452+
snapshot.transform.resource_name(),
453+
]
454+
)
455+
456+
api_name = f"api-{short_uid()}"
457+
stack = deploy_cfn_template(
458+
template_path=os.path.join(
459+
os.path.dirname(__file__), "../../../templates/apigateway_update_stage.yml"
460+
),
461+
parameters={"RestApiName": api_name},
462+
)
463+
api_id = stack.outputs["RestApiId"]
464+
stage = aws_client.apigateway.get_stage(stageName="dev", restApiId=api_id)
465+
snapshot.match("created-stage", stage)
466+
467+
deploy_cfn_template(
468+
is_update=True,
469+
stack_name=stack.stack_name,
470+
template_path=os.path.join(
471+
os.path.dirname(__file__), "../../../templates/apigateway_update_stage.yml"
472+
),
473+
parameters={
474+
"Description": "updated-description",
475+
"Method": "POST",
476+
"RestApiName": api_name,
477+
},
478+
)
479+
# Changes to the stage or one of the methods it depends on does not trigger a redeployment
480+
stage = aws_client.apigateway.get_stage(stageName="dev", restApiId=api_id)
481+
snapshot.match("updated-stage", stage)
482+
483+
443484
@markers.aws.validated
444485
def test_api_gateway_with_policy_as_dict(deploy_cfn_template, snapshot, aws_client):
445486
template = """

tests/aws/services/cloudformation/resources/test_apigateway.snapshot.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,5 +626,48 @@
626626
}
627627
}
628628
}
629+
},
630+
"tests/aws/services/cloudformation/resources/test_apigateway.py::test_update_apigateway_stage": {
631+
"recorded-date": "07-11-2024, 05:35:20",
632+
"recorded-content": {
633+
"created-stage": {
634+
"cacheClusterEnabled": false,
635+
"cacheClusterStatus": "NOT_AVAILABLE",
636+
"createdDate": "datetime",
637+
"deploymentId": "<deployment-id:1>",
638+
"lastUpdatedDate": "datetime",
639+
"methodSettings": {},
640+
"stageName": "dev",
641+
"tags": {
642+
"aws:cloudformation:logical-id": "Stage",
643+
"aws:cloudformation:stack-id": "arn:<partiti F438 on>:cloudformation:<region>:111111111111:stack/<aws:cloudformation:stack-name:1>/<resource:1>",
644+
"aws:cloudformation:stack-name": "<aws:cloudformation:stack-name:1>"
645+
},
646+
"tracingEnabled": false,
647+
"ResponseMetadata": {
648+
"HTTPHeaders": {},
649+
"HTTPStatusCode": 200
650+
}
651+
},
652+
"updated-stage": {
653+
"cacheClusterEnabled": false,
654+
"cacheClusterStatus": "NOT_AVAILABLE",
655+
"createdDate": "datetime",
656+
"deploymentId": "<deployment-id:1>",
657+
"lastUpdatedDate": "datetime",
658+
"methodSettings": {},
659+
"stageName": "dev",
660+
"tags": {
661+
"aws:cloudformation:logical-id": "Stage",
662+
"aws:cloudformation:stack-id": "arn:<partition>:cloudformation:<region>:111111111111:stack/<aws:cloudformation:stack-name:1>/<resource:1>",
663+
"aws:cloudformation:stack-name": "<aws:cloudformation:stack-name:1>"
664+
},
665+
"tracingEnabled": false,
666+
"ResponseMetadata": {
667+
"HTTPHeaders": {},
668+
"HTTPStatusCode": 200
669+
}
670+
}
671+
}
629672
}
630673
}

tests/aws/services/cloudformation/resources/test_apigateway.validation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
"tests/aws/services/cloudformation/resources/test_apigateway.py::test_rest_api_serverless_ref_resolving": {
2424
"last_validated_date": "2023-07-06T19:01:08+00:00"
2525
},
26+
"tests/aws/services/cloudformation/resources/test_apigateway.py::test_update_apigateway_stage": {
27+
"last_validated_date": "2024-11-07T05:35:20+00:00"
28+
},
2629
"tests/aws/services/cloudformation/resources/test_apigateway.py::test_update_usage_plan": {
2730
"last_validated_date": "2024-09-13T09:57:21+00:00"
2831
}

tests/aws/services/cloudformation/resources/test_lambda.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,19 +101,16 @@ def test_lambda_w_dynamodb_event_filter_update(deploy_cfn_template, snapshot, aw
101101
snapshot.match("updated_source_mappings", source_mappings)
102102

103103

104-
@pytest.mark.skip(
105-
reason="fails/times out. Provider not able to update lambda function environment variables"
106-
)
107104
@markers.aws.validated
108105
def test_update_lambda_function(s3_create_bucket, deploy_cfn_template, aws_client):
106+
function_name = f"lambda-{short_uid()}"
109107
stack = deploy_cfn_template(
110108
template_path=os.path.join(
111109
os.path.dirname(__file__), "../../../templates/lambda_function_update.yml"
112110
),
113-
parameters={"Environment": "ORIGINAL"},
111+
parameters={"Environment": "ORIGINAL", "FunctionName": function_name},
114112
)
115113

116-
function_name = stack.outputs["LambdaName"]
117114
response = aws_client.lambda_.get_function(FunctionName=function_name)
118115
assert response["Configuration"]["Environment"]["Variables"]["TEST"] == "ORIGINAL"
119116

@@ -123,13 +120,42 @@ def test_update_lambda_function(s3_create_bucket, deploy_cfn_template, aws_clien
123120
template_path=os.path.join(
124121
os.path.dirname(__file__), "../../../templates/lambda_function_update.yml"
125122
),
126-
parameters={"Environment": "UPDATED"},
123+
parameters={"Environment": "UPDATED", "FunctionName": function_name},
127124
)
128125

129126
response = aws_client.lambda_.get_function(FunctionName=function_name)
130127
assert response["Configuration"]["Environment"]["Variables"]["TEST"] == "UPDATED"
131128

132129

130+
@markers.aws.validated
131+
def test_update_lambda_function_name(s3_create_bucket, deploy_cfn_template, aws_client):
132+
function_name_1 = f"lambda-{short_uid()}"
133+
function_name_2 = f"lambda-{short_uid()}"
134+
stack = deploy_cfn_template(
135+
template_path=os.path.join(
136+
os.path.dirname(__file__), "../../../templates/lambda_function_update.yml"
137+
),
138+
parameters={"FunctionName": function_name_1},
139+
)
140+
141+
function_name = stack.outputs["LambdaName"]
142+
response = aws_client.lambda_.get_function(FunctionName=function_name_1)
143+
assert response["Configuration"]["Environment"]["Variables"]["TEST"] == "ORIGINAL"
144+
145+
deploy_cfn_template(
146+
stack_name=stack.stack_name,
147+
is_update=True,
148+
template_path=os.path.join(
149+
os.path.dirname(__file__), "../../../templates/lambda_function_update.yml"
150+
),
151+< A851 div class="diff-text-inner"> parameters={"FunctionName": function_name_2},
152+
)
153+
with pytest.raises(aws_client.lambda_.exceptions.ResourceNotFoundException):
154+
aws_client.lambda_.get_function(FunctionName=function_name)
155+
156+
aws_client.lambda_.get_function(FunctionName=function_name_2)
157+
158+
133159
@markers.snapshot.skip_snapshot_verify(
134160
paths=[
135161
"$..Metadata",

tests/aws/services/cloudformation/resources/test_lambda.validation.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@
4848
"last_validated_date": "2024-04-09T07:38:32+00:00"
4949
},
5050
"tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_function": {
51-
"last_validated_date": "2024-06-20T15:49:50+00:00"
51+
"last_validated_date": "2024-11-07T03:16:40+00:00"
52+
},
53+
"tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_function_name": {
54+
"last_validated_date": "2024-11-07T03:10:48+00:00"
5255
},
5356
"tests/aws/services/cloudformation/resources/test_lambda.py::test_update_lambda_permissions": {
5457
"last_validated_date": "2024-04-09T07:23:41+00:00"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Parameters:
2+
Description:
3+
Type: String
4+
Default: "Original description"
5+
Method:
6+
Type: String
7+
Default: GET
8+
RestApiName:
9+
Type: String
10+
11+
Resources:
12+
RestApi:
13+
Type: AWS::ApiGateway::RestApi
14+
Properties:
15+
Name: !Ref RestApiName
16+
Stage:
17+
Type: AWS::ApiGateway::Stage
18+
Properties:
19+
RestApiId:
20+
Ref: RestApi
21+
DeploymentId:
22+
Ref: ApiDeployment
23+
StageName: dev
24+
MockMethod:
25+
Type: 'AWS::ApiGateway::Method'
26+
Properties:
27+
RestApiId: !Ref RestApi
28+
ResourceId: !GetAtt
29+
- RestApi
30+
- RootResourceId
31+
HttpMethod: !Ref Method
32+
AuthorizationType: NONE
33+
Integration:
34+
Type: MOCK
35+
ApiDeployment:
36+
Type: AWS::ApiGateway::Deployment
37+
Properties:
38+
RestApiId:
39+
Ref: RestApi
40+
Description: !Ref Description
41+
DependsOn:
42+
- MockMethod
43+
44+
Outputs:
45+
RestApiId:
46+
Value: !GetAtt RestApi.RestApiId

tests/aws/templates/lambda_function_update.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Parameters:
66
AllowedValues:
77
- 'ORIGINAL'
88
- 'UPDATED'
9+
FunctionName:
10+
Type: String
911

1012
Resources:
1113
PullMarketsRole:
@@ -47,6 +49,7 @@ Resources:
4749
- Arn
4850
Runtime: nodejs18.x
4951
Timeout: 6
52+
FunctionName: !Ref FunctionName
5053
Environment:
5154
Variables:
5255
TEST: !Ref Environment

0 commit comments

Comments
 (0)
0