From d2fdfa69f893b40281de32ce7f996098f72e4f7c Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 09:54:11 -0600 Subject: [PATCH 01/12] validated `test_domain_validation` and added snapshot --- tests/aws/services/acm/test_acm.py | 18 ++++++-- tests/aws/services/acm/test_acm.snapshot.json | 41 +++++++++++++++++++ .../aws/services/acm/test_acm.validation.json | 3 ++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/tests/aws/services/acm/test_acm.py b/tests/aws/services/acm/test_acm.py index fba50b6f63e91..f26980b382048 100644 --- a/tests/aws/services/acm/test_acm.py +++ b/tests/aws/services/acm/test_acm.py @@ -61,12 +61,22 @@ def _certificate_present(): snapshot.match("describe-certificate-response", describe_res) - @markers.aws.unknown - def test_domain_validation(self, acm_request_certificate, aws_client): + @markers.snapshot.skip_snapshot_verify( + paths=[ + "$..ResourceRecord", # Added by LS but not in aws response + "$..ValidationEmails", # Not in LS response + ] + ) + @markers.aws.validated + def test_domain_validation(self, acm_request_certificate, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("CertificateArn")) + snapshot.add_transformer(snapshot.transform.key_value("DomainName")) + snapshot.add_transformer(snapshot.transform.key_value("ValidationMethod")) + snapshot.add_transformer(snapshot.transform.key_value("SignatureAlgorithm")) + certificate_arn = acm_request_certificate()["CertificateArn"] result = aws_client.acm.describe_certificate(CertificateArn=certificate_arn) - options = result["Certificate"]["DomainValidationOptions"] - assert len(options) == 1 + snapshot.match("describe-certificate", result) @markers.aws.unknown def test_boto_wait_for_certificate_validation( diff --git a/tests/aws/services/acm/test_acm.snapshot.json b/tests/aws/services/acm/test_acm.snapshot.json index d1aa096b73d47..ae7623aa0cb72 100644 --- a/tests/aws/services/acm/test_acm.snapshot.json +++ b/tests/aws/services/acm/test_acm.snapshot.json @@ -291,5 +291,46 @@ } } } + }, + "tests/aws/services/acm/test_acm.py::TestACM::test_domain_validation": { + "recorded-date": "12-04-2024, 15:36:37", + "recorded-content": { + "describe-certificate": { + "Certificate": { + "CertificateArn": "", + "CreatedAt": "datetime", + "DomainName": "", + "DomainValidationOptions": [ + { + "DomainName": "", + "ValidationDomain": "", + "ValidationEmails": [], + "ValidationMethod": "", + "ValidationStatus": "PENDING_VALIDATION" + } + ], + "ExtendedKeyUsages": [], + "InUseBy": [], + "Issuer": "Amazon", + "KeyAlgorithm": "RSA-2048", + "KeyUsages": [], + "Options": { + "CertificateTransparencyLoggingPreference": "ENABLED" + }, + "RenewalEligibility": "INELIGIBLE", + "SignatureAlgorithm": "", + "Status": "PENDING_VALIDATION", + "Subject": "CN=", + "SubjectAlternativeNames": [ + "" + ], + "Type": "AMAZON_ISSUED" + }, + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } } } diff --git a/tests/aws/services/acm/test_acm.validation.json b/tests/aws/services/acm/test_acm.validation.json index 5591990ba15d8..8201f405c3e71 100644 --- a/tests/aws/services/acm/test_acm.validation.json +++ b/tests/aws/services/acm/test_acm.validation.json @@ -5,6 +5,9 @@ "tests/aws/services/acm/test_acm.py::TestACM::test_create_certificate_for_multiple_alternative_domains": { "last_validated_date": "2024-01-09T14:58:14+00:00" }, + "tests/aws/services/acm/test_acm.py::TestACM::test_domain_validation": { + "last_validated_date": "2024-04-12T15:36:37+00:00" + }, "tests/aws/services/acm/test_acm.py::TestACM::test_import_certificate": { "last_validated_date": "2024-02-22T17:41:15+00:00" } From 5402bd1ba0add0aadf1e0c538e25433f8a7e92a1 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 10:11:18 -0600 Subject: [PATCH 02/12] Marked test_boto_wait_for_certificate_validation as need_fixing --- tests/aws/services/acm/test_acm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/aws/services/acm/test_acm.py b/tests/aws/services/acm/test_acm.py index f26980b382048..c670414034501 100644 --- a/tests/aws/services/acm/test_acm.py +++ b/tests/aws/services/acm/test_acm.py @@ -78,7 +78,7 @@ def test_domain_validation(self, acm_request_certificate, aws_client, snapshot): result = aws_client.acm.describe_certificate(CertificateArn=certificate_arn) snapshot.match("describe-certificate", result) - @markers.aws.unknown + @markers.aws.needs_fixing def test_boto_wait_for_certificate_validation( self, acm_request_certificate, aws_client, monkeypatch ): From 6535d730e112efeaba9580439ec000e696be8b29 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 14:50:34 -0600 Subject: [PATCH 03/12] Add `needs_fixing` to `test_create_rest_api_with_custom_id`. --- tests/aws/services/apigateway/test_apigateway_basic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index 947f8e4d90a9c..110de0fb2c2bf 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -157,7 +157,8 @@ def test_delete_rest_api_with_invalid_id(self, aws_client): assert "foobar" in e.value.response["Error"]["Message"] @pytest.mark.parametrize("url_function", [path_based_url, host_based_url]) - @markers.aws.unknown + @markers.aws.needs_fixing + # This is not a possible feature on aws. Is there a reason for us to add that support? def test_create_rest_api_with_custom_id(self, create_rest_apigw, url_function, aws_client): apigw_name = f"gw-{short_uid()}" test_id = "testId123" From 9ad09af8bc033cbdec3631dd5b6479ea2e12d77c Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 15:26:50 -0600 Subject: [PATCH 04/12] Updated fixture to enable a more consistent resource deletion --- localstack/testing/pytest/fixtures.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/localstack/testing/pytest/fixtures.py b/localstack/testing/pytest/fixtures.py index 163a130684551..1ef78774a7279 100644 --- a/localstack/testing/pytest/fixtures.py +++ b/localstack/testing/pytest/fixtures.py @@ -1940,7 +1940,15 @@ def create_rest_apigw(aws_client_factory): def _create_apigateway_function(**kwargs): region_name = kwargs.pop("region_name", None) - apigateway_client = aws_client_factory(region_name=region_name).apigateway + client_config = None + if is_aws_cloud(): + client_config = botocore.config.Config( + # Api gateway can throttle requests pretty heavily. Leading to potentially undeleted apis + retries={"max_attempts": 10, "mode": "adaptive"} + ) + apigateway_client = aws_client_factory( + region_name=region_name, config=client_config + ).apigateway kwargs.setdefault("name", f"api-{short_uid()}") response = apigateway_client.create_rest_api(**kwargs) From bc04875cafd785262db9049247f99dc5e61d70cf Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 15:27:48 -0600 Subject: [PATCH 05/12] updated `test_update_rest_api_deployment` with snapshot --- .../services/apigateway/test_apigateway_basic.py | 8 +++++--- .../apigateway/test_apigateway_basic.snapshot.json | 14 ++++++++++++++ .../test_apigateway_basic.validation.json | 5 ++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index 110de0fb2c2bf..b6851dbad9361 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -178,8 +178,10 @@ def test_create_rest_api_with_custom_id(self, create_rest_apigw, url_function, a assert response.ok assert response._content == b'{"echo": "foobar", "response": "mocked"}' - @markers.aws.unknown - def test_update_rest_api_deployment(self, create_rest_apigw, aws_client): + @markers.aws.validated + def test_update_rest_api_deployment(self, create_rest_apigw, aws_client, snapshot): + snapshot.add_transformer(snapshot.transform.key_value("id")) + api_id, _, root = create_rest_apigw(name="test_gateway5") create_rest_resource_method( @@ -219,7 +221,7 @@ def test_update_rest_api_deployment(self, create_rest_apigw, aws_client): deploymentId=deployment_id, patchOperations=patch_operations, ) - assert deployment["description"] == "new-description" + snapshot.match("after-update", deployment) @markers.aws.validated def test_api_gateway_lambda_integration_aws_type( diff --git a/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json b/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json index 0102e87e8feb9..94cb62de7f442 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json +++ b/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json @@ -72,5 +72,19 @@ } } } + }, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_update_rest_api_deployment": { + "recorded-date": "12-04-2024, 21:24:49", + "recorded-content": { + "after-update": { + "createdDate": "datetime", + "description": "new-description", + "id": "", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 200 + } + } + } } } diff --git a/tests/aws/services/apigateway/test_apigateway_basic.validation.json b/tests/aws/services/apigateway/test_apigateway_basic.validation.json index cfcf95656b62e..e1c60dd8c3ece 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.validation.json +++ b/tests/aws/services/apigateway/test_apigateway_basic.validation.json @@ -7,5 +7,8 @@ }, "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigw_test_invoke_method_api": { "last_validated_date": "2024-02-04T18:48:24+00:00" + }, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_update_rest_api_deployment": { + "last_validated_date": "2024-04-12T21:24:49+00:00" } -} \ No newline at end of file +} From 8863b6e39c590d8c1cfa9ab92f4eff16ff6ffeb5 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 15:57:57 -0600 Subject: [PATCH 06/12] Added comment for `test_api_gateway_lambda_proxy_integration` --- tests/aws/services/apigateway/test_apigateway_basic.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index b6851dbad9361..4f26c2f39e612 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -358,7 +358,9 @@ def test_invoke_endpoint_cors_headers( assert response.status_code == 200 assert "http://test.com" in response.headers["Access-Control-Allow-Origin"] - @markers.aws.unknown + # This test fails as it tries to create a lambda locally? + # It then leaves some resources behind, apigateway and policies + @markers.aws.needs_fixing @pytest.mark.parametrize( "api_path", [API_PATH_LAMBDA_PROXY_BACKEND, API_PATH_LAMBDA_PROXY_BACKEND_WITH_PATH_PARAM] ) From f43e5f9f3f62ec1136aa1420a214d81f49e621ed Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 16:05:35 -0600 Subject: [PATCH 07/12] added comments for `test_api_gateway_lambda_proxy_integration_with_is_base_64_encoded` --- tests/aws/services/apigateway/test_apigateway_basic.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index 4f26c2f39e612..eaf0cd90daf34 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -381,7 +381,9 @@ def test_api_gateway_lambda_proxy_integration( aws_client.apigateway, ) - @markers.aws.unknown + # This test fails as it tries to create a lambda locally? + # It then leaves some resources behind, apigateway and policies + @markers.aws.needs_fixing def test_api_gateway_lambda_proxy_integration_with_is_base_64_encoded( self, integration_lambda, aws_client, create_iam_role_with_policy ): From 2269ca91e29a6c0cb2da1c467790f14029395747 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 16:16:01 -0600 Subject: [PATCH 08/12] Adde comment for `test_api_gateway_lambda_proxy_integration_any_method` --- tests/aws/services/apigateway/test_apigateway_basic.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index eaf0cd90daf34..157195026f093 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -637,7 +637,9 @@ def test_api_gateway_authorizer_crud(self, aws_client): restApiId=get_api_gateway_id, authorizerId=authorizer_id ) - @markers.aws.unknown + # This test fails as it tries to create a lambda locally? + # It then leaves some resources behind, apigateway and policies + @markers.aws.needs_fixing def test_malformed_response_apigw_invocation( self, create_lambda_function, aws_client, region_name ): From 12af0abc468311d2d049238777a565fa9b372673 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 16:17:57 -0600 Subject: [PATCH 09/12] added comment for `test_api_gateway_handle_domain_name` --- tests/aws/services/apigateway/test_apigateway_basic.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index 157195026f093..7c8eff27be1ca 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -669,7 +669,9 @@ def test_malformed_response_apigw_invocation( assert result.headers.get("Content-Type") == "application/json" assert json.loads(result.content)["message"] == "Internal server error" - @markers.aws.unknown + # Missing certificate creation to create a domain + # this might end up being a bigger issue to fix until we have a validated certificate we can use + @markers.aws.needs_fixing def test_api_gateway_handle_domain_name(self, aws_client): domain_name = f"{short_uid()}.example.com" apigw_client = aws_client.apigateway From 406dde0352765d649ae636598ead3e3880c45de6 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 16:32:46 -0600 Subject: [PATCH 10/12] Added snapshot testing for `test_apigateway_with_custom_authorization_method` --- .../apigateway/test_apigateway_basic.py | 18 ++++++++--- .../test_apigateway_basic.snapshot.json | 30 +++++++++++++++++++ .../test_apigateway_basic.validation.json | 3 ++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index 7c8eff27be1ca..896922b17803f 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -710,15 +710,25 @@ def _test_api_gateway_lambda_proxy_integration_any_method(self, fn_name, path): else: assert 204 == result.status_code - @markers.aws.unknown + @markers.snapshot.skip_snapshot_verify( + paths=[ + "$..authType", # Not added by LS + "$..authorizerResultTtlInSeconds", # Exists in LS but not in AWS + ] + ) + @markers.aws.validated def test_apigateway_with_custom_authorization_method( - self, create_rest_apigw, aws_client, account_id, region_name, integration_lambda + self, create_rest_apigw, aws_client, account_id, region_name, integration_lambda, snapshot ): + snapshot.add_transformer(snapshot.transform.key_value("api_id")) + snapshot.add_transformer(snapshot.transform.key_value("authorizerUri")) + snapshot.add_transformer(snapshot.transform.key_value("id")) # create Lambda function lambda_uri = arns.lambda_function_arn(integration_lambda, account_id, region_name) # create REST API api_id, _, _ = create_rest_apigw(name="test-api") + snapshot.match("api-id", {"api_id": api_id}) root_res_id = aws_client.apigateway.get_resources(restApiId=api_id)["items"][0]["id"] # create authorizer at root resource @@ -730,6 +740,7 @@ def test_apigateway_with_custom_authorization_method( 2015-03-31/functions/{}/invocations".format(lambda_uri), identitySource="method.request.header.Auth", ) + snapshot.match("authorizer", authorizer) # create method with custom authorizer is_api_key_required = True @@ -741,8 +752,7 @@ def test_apigateway_with_custom_authorization_method( authorizerId=authorizer["id"], apiKeyRequired=is_api_key_required, ) - - assert authorizer["id"] == method_response["authorizerId"] + snapshot.match("put-method-response", method_response) @markers.aws.unknown def test_base_path_mapping(self, create_rest_apigw, aws_client): diff --git a/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json b/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json index 94cb62de7f442..65bc69da07608 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json +++ b/tests/aws/services/apigateway/test_apigateway_basic.snapshot.json @@ -86,5 +86,35 @@ } } } + }, + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigateway_with_custom_authorization_method": { + "recorded-date": "12-04-2024, 22:31:50", + "recorded-content": { + "api-id": { + "api_id": "" + }, + "authorizer": { + "authType": "custom", + "authorizerUri": "", + "id": "", + "identitySource": "method.request.header.Auth", + "name": "lambda_authorizer", + "type": "TOKEN", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + }, + "put-method-response": { + "apiKeyRequired": true, + "authorizationType": "CUSTOM", + "authorizerId": "", + "httpMethod": "GET", + "ResponseMetadata": { + "HTTPHeaders": {}, + "HTTPStatusCode": 201 + } + } + } } } diff --git a/tests/aws/services/apigateway/test_apigateway_basic.validation.json b/tests/aws/services/apigateway/test_apigateway_basic.validation.json index e1c60dd8c3ece..cb9d50ad20e38 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.validation.json +++ b/tests/aws/services/apigateway/test_apigateway_basic.validation.json @@ -1,4 +1,7 @@ { + "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigateway_with_custom_authorization_method": { + "last_validated_date": "2024-04-12T22:31:50+00:00" + }, "tests/aws/services/apigateway/test_apigateway_basic.py::TestAPIGateway::test_apigateway_with_step_function_integration[DeleteStateMachine]": { "last_validated_date": "2023-09-07T20:40:38+00:00" }, From 2b06001970743b95c54fb5d069a2d6bcc565ea0a Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Fri, 12 Apr 2024 16:46:56 -0600 Subject: [PATCH 11/12] Fixed confusion with wrong test being marked --- .../services/apigateway/test_apigateway_basic.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index 896922b17803f..97d8235c12d86 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -157,8 +157,7 @@ def test_delete_rest_api_with_invalid_id(self, aws_client): assert "foobar" in e.value.response["Error"]["Message"] @pytest.mark.parametrize("url_function", [path_based_url, host_based_url]) - @markers.aws.needs_fixing - # This is not a possible feature on aws. Is there a reason for us to add that support? + @markers.aws.only_localstack def test_create_rest_api_with_custom_id(self, create_rest_apigw, url_function, aws_client): apigw_name = f"gw-{short_uid()}" test_id = "testId123" @@ -539,13 +538,17 @@ def _test_api_gateway_lambda_proxy_integration( assert "/yCqIBE=" == result_content["body"] assert ["isBase64Encoded"] - @markers.aws.unknown + # This test fails as it tries to create a lambda locally? + # It then leaves some resources behind, apigateway and policies + @markers.aws.needs_fixing def test_api_gateway_lambda_proxy_integration_any_method(self, integration_lambda): self._test_api_gateway_lambda_proxy_integration_any_method( integration_lambda, API_PATH_LAMBDA_PROXY_BACKEND_ANY_METHOD ) - @markers.aws.unknown + # This test fails as it tries to create a lambda locally? + # It then leaves some resources behind, apigateway and policies + @markers.aws.needs_fixing def test_api_gateway_lambda_proxy_integration_any_method_with_path_param( self, integration_lambda ): @@ -637,9 +640,7 @@ def test_api_gateway_authorizer_crud(self, aws_client): restApiId=get_api_gateway_id, authorizerId=authorizer_id ) - # This test fails as it tries to create a lambda locally? - # It then leaves some resources behind, apigateway and policies - @markers.aws.needs_fixing + @markers.aws.unknown def test_malformed_response_apigw_invocation( self, create_lambda_function, aws_client, region_name ): From 93873182e7cc5f0275f3e4e68ab8e2f6a332fa77 Mon Sep 17 00:00:00 2001 From: Mathieu Cloutier Date: Mon, 15 Apr 2024 08:34:48 -0600 Subject: [PATCH 12/12] added comment --- tests/aws/services/apigateway/test_apigateway_basic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/aws/services/apigateway/test_apigateway_basic.py b/tests/aws/services/apigateway/test_apigateway_basic.py index 97d8235c12d86..8c3734ad1068f 100644 --- a/tests/aws/services/apigateway/test_apigateway_basic.py +++ b/tests/aws/services/apigateway/test_apigateway_basic.py @@ -158,6 +158,7 @@ def test_delete_rest_api_with_invalid_id(self, aws_client): @pytest.mark.parametrize("url_function", [path_based_url, host_based_url]) @markers.aws.only_localstack + # This is not a possible feature on aws. def test_create_rest_api_with_custom_id(self, create_rest_apigw, url_function, aws_client): apigw_name = f"gw-{short_uid()}" test_id = "testId123"