Skip to content

Commit

Permalink
Merge branch 'release-v1.53.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
aws-sam-cli-bot committed Oct 11, 2022
2 parents d39650f + ee3f28f commit b534773
Show file tree
Hide file tree
Showing 38 changed files with 697 additions and 50 deletions.
2 changes: 1 addition & 1 deletion integration/combination/test_api_with_authorizer_apikey.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def test_authorizer_apikey(self):
# ApiKeySourceType is AUTHORIZER. Passing api key via x-api-key will not get authorized
self.verify_authorized_request(base_url + "lambda-token-api-key", 401, "x-api-key", key["value"])

@retry(StatusCodeError, 10)
@retry(StatusCodeError, 10, 0.25)
def verify_authorized_request(
self,
url,
Expand Down
2 changes: 1 addition & 1 deletion integration/combination/test_api_with_authorizers.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ def test_authorizers_with_invoke_function_set_none(self):
auth_type_for_api_event_without_auth = api_event_with_out_auth["authorizationType"]
self.assertEqual(auth_type_for_api_event_without_auth, "NONE")

@retry(StatusCodeError, 10)
@retry(StatusCodeError, 10, 0.25)
def verify_authorized_request(
self,
url,
Expand Down
12 changes: 12 additions & 0 deletions integration/combination/test_connectors.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
from time import sleep
from unittest import SkipTest
from parameterized import parameterized
from tenacity import retry, stop_after_attempt, retry_if_exception
from integration.conftest import clean_bucket
from integration.helpers.base_test import S3_BUCKET_PREFIX, BaseTest
from integration.helpers.resource import generate_suffix

retry_once = retry(
stop=stop_after_attempt(2),
# unittest raises SkipTest for skipping tests
retry=retry_if_exception(lambda e: not isinstance(e, SkipTest)),
)


class TestConnectors(BaseTest):
def tearDown(self):
Expand Down Expand Up @@ -41,6 +49,7 @@ def tearDown(self):
("combination/connector_table_to_function_read",),
]
)
@retry_once
def test_connector_by_invoking_a_function(self, template_file_path):
self.skip_using_service_detector(template_file_path)
self.create_and_verify_stack(template_file_path)
Expand Down Expand Up @@ -72,6 +81,7 @@ def test_connector_by_invoking_a_function(self, template_file_path):
("combination/connector_sfn_to_eb_custom_write",),
]
)
@retry_once
def test_connector_by_sync_execute_an_state_machine(self, template_file_path):
self.skip_using_service_detector(template_file_path)
self.create_and_verify_stack(template_file_path)
Expand All @@ -91,6 +101,7 @@ def test_connector_by_sync_execute_an_state_machine(self, template_file_path):
("combination/connector_sfn_to_sfn_sync",),
]
)
@retry_once
def test_connector_by_async_execute_an_state_machine(self, template_file_path):
self.skip_using_service_detector(template_file_path)
self.create_and_verify_stack(template_file_path)
Expand Down Expand Up @@ -123,6 +134,7 @@ def test_connector_by_async_execute_an_state_machine(self, template_file_path):
("combination/connector_bucket_to_function_write",),
]
)
@retry_once
def test_connector_by_execute_a_s3_bucket(self, template_file_path):
self.skip_using_service_detector(template_file_path)
bucket_name = S3_BUCKET_PREFIX + "connector" + generate_suffix()
Expand Down
5 changes: 4 additions & 1 deletion integration/combination/test_custom_http_api_domains_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ def test_custom_http_api_domains_regional(self):
api_gateway_client = self.client_provider.api_v2_client
result = api_gateway_client.get_domain_name(DomainName=domain_name_id)

self.assertEqual("httpapi.sam-gamma-regional.com", result["DomainName"])
if "FeatureToggle" in self.pipeline_prefix:
self.assertEqual("httpapi.ftl.sam-gamma-regional.com", result["DomainName"])
else:
self.assertEqual("httpapi.sam-gamma-regional.com", result["DomainName"])

mtls_auth_config = result["MutualTlsAuthentication"]
self.assertEqual(self.file_to_s3_uri_map["MTLSCert.pem"]["uri"], mtls_auth_config["TruststoreUri"])
Expand Down
12 changes: 10 additions & 2 deletions integration/combination/test_custom_rest_api_domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@
class TestCustomRestApiDomains(BaseInternalTest):
def test_custom_rest_api_domains_edge(self):
self.create_and_verify_stack("combination/api_with_custom_domains_edge")

domain_name_list = self.get_stack_resources("AWS::ApiGateway::DomainName")
self.assertEqual(1, len(domain_name_list))

domain_name_id = self.get_physical_id_by_type("AWS::ApiGateway::DomainName")
api_gateway_client = self.client_provider.api_client
result = api_gateway_client.get_domain_name(domainName=domain_name_id)

self.assertEqual("sam-gamma-edge.com", result["domainName"])
if "FeatureToggle" in self.pipeline_prefix:
self.assertEqual("ftl.sam-gamma-edge.com", result["domainName"])
else:
self.assertEqual("sam-gamma-edge.com", result["domainName"])

end_point_config = result["endpointConfiguration"]
end_point_types = end_point_config["types"]
Expand All @@ -37,7 +41,11 @@ def test_custom_rest_api_domains_regional(self):
api_gateway_client = self.client_provider.api_client
result = api_gateway_client.get_domain_name(domainName=domain_name_id)

self.assertEqual("sam-gamma-regional.com", result["domainName"])
if "FeatureToggle" in self.pipeline_prefix:
self.assertEqual("ftl.sam-gamma-regional.com", result["domainName"])
else:
self.assertEqual("sam-gamma-regional.com", result["domainName"])

self.assertEqual("TLS_1_2", result["securityPolicy"])

end_point_config = result["endpointConfiguration"]
Expand Down
30 changes: 30 additions & 0 deletions integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
import boto3
import botocore
import pytest
Expand Down Expand Up @@ -63,6 +64,26 @@ def clean_all_integ_buckets():
clean_bucket(bucket.name, s3_client)


def _delete_unused_network_interface_by_subnet(ec2_client, subnet_id):
"""Deletes unused network interface under the provided subnet"""
paginator = ec2_client.get_paginator("describe_network_interfaces")
response_iterator = paginator.paginate(
Filters=[
{"Name": "subnet-id", "Values": [subnet_id]},
{"Name": "status", "Values": ["available"]},
]
)
network_interface_ids = []
for page in response_iterator:
network_interface_ids += [ni["NetworkInterfaceId"] for ni in page["NetworkInterfaces"]]

for ni_id in network_interface_ids:
ec2_client.delete_network_interface(NetworkInterfaceId=ni_id)
time.sleep(0.5)

LOG.info("Deleted %s unused network interfaces under subnet %s", len(network_interface_ids), subnet_id)


@pytest.fixture()
def setup_companion_stack_once(tmpdir_factory, get_prefix):
tests_integ_dir = Path(__file__).resolve().parents[1]
Expand All @@ -74,6 +95,15 @@ def setup_companion_stack_once(tmpdir_factory, get_prefix):
companion_stack = Stack(stack_name, companion_stack_tempalte_path, cfn_client, output_dir)
companion_stack.create_or_update(_stack_exists(stack_name))

ec2_client = ClientProvider().ec2_client
precreated_subnet_ids = [
resource["PhysicalResourceId"]
for resource in companion_stack.stack_resources["StackResourceSummaries"]
if resource["LogicalResourceId"].startswith("PreCreatedSubnet")
]
for subnet_id in precreated_subnet_ids:
_delete_unused_network_interface_by_subnet(ec2_client, subnet_id)


@pytest.fixture()
def get_serverless_application_repository_app():
Expand Down
18 changes: 16 additions & 2 deletions integration/helpers/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@

STACK_NAME_PREFIX = "sam-integ-stack-"
S3_BUCKET_PREFIX = "sam-integ-bucket-"
FEATURE_TOGGLE_JSON_FILES = [
"http_api_with_custom_domains_regional",
"http_api_with_custom_domains_regional_ownership_verification",
"api_with_custom_domains_edge",
"api_with_custom_domains_regional",
"api_with_custom_domains_regional_ownership_verification",
]


class BaseTest(TestCase):
Expand Down Expand Up @@ -154,13 +161,20 @@ def create_and_verify_stack(self, file_path, parameters=None, s3_uploader=None):
s3_uploader: S3Uploader object
Object for uploading files to s3
"""
folder, file_name = file_path.split("/")

# If template is too large, calling the method with self.s3_uploader to send the template to s3 then deploy
self.create_stack(file_path, parameters, s3_uploader)
self.expected_resource_path = str(Path(self.expected_dir, folder, file_name + ".json"))
self.get_expected_json_file_name(file_path)
self.verify_stack()

def get_expected_json_file_name(self, file_path):
folder, file_name = file_path.split("/")

if "FeatureToggle" in self.pipeline_prefix and file_name in FEATURE_TOGGLE_JSON_FILES:
self.expected_resource_path = str(Path(self.expected_dir, folder, file_name + "_feature_toggle.json"))
else:
self.expected_resource_path = str(Path(self.expected_dir, folder, file_name + ".json"))

def skip_using_service_detector(self, file_path):
"""
Skips the test if it cannot pass the test of
Expand Down
11 changes: 11 additions & 0 deletions integration/helpers/client_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def __init__(self):
self._kafka_client = None
self._code_deploy_client = None
self._sar_client = None
self._ec2_client = None

@property
def cfn_client(self):
Expand Down Expand Up @@ -216,3 +217,13 @@ def sar_client(self):
if not self._sar_client:
self._sar_client = boto3.client("serverlessrepo")
return self._sar_client

@property
def ec2_client(self):
"""
EC2 Client
"""
with self._lock:
if not self._ec2_client:
self._ec2_client = boto3.client("ec2")
return self._ec2_client
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{ "LogicalResourceId":"RecordSetGroupc911be5759", "ResourceType":"AWS::Route53::RecordSetGroup" },
{ "LogicalResourceId":"MyApiDeployment", "ResourceType":"AWS::ApiGateway::Deployment" },
{ "LogicalResourceId":"ApiGatewayDomainName299fac327d", "ResourceType":"AWS::ApiGateway::DomainName" },
{ "LogicalResourceId":"MyApi", "ResourceType":"AWS::ApiGateway::RestApi" },
{ "LogicalResourceId":"MyApiProdStage", "ResourceType":"AWS::ApiGateway::Stage" },
{ "LogicalResourceId":"MyFunction", "ResourceType":"AWS::Lambda::Function" },
{ "LogicalResourceId":"MyFunctionRole", "ResourceType":"AWS::IAM::Role" },
{ "LogicalResourceId":"MyApigetBasePathMapping", "ResourceType":"AWS::ApiGateway::BasePathMapping" },
{ "LogicalResourceId":"MyFunctionFetchPermissionProd", "ResourceType":"AWS::Lambda::Permission" }
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{ "LogicalResourceId":"MyFunctionImplicitGetPermissionProd", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"ServerlessRestApiDeployment", "ResourceType":"AWS::ApiGateway::Deployment" },
{ "LogicalResourceId":"ServerlessRestApipostBasePathMapping", "ResourceType":"AWS::ApiGateway::BasePathMapping" },
{ "LogicalResourceId":"ServerlessRestApi", "ResourceType":"AWS::ApiGateway::RestApi" },
{ "LogicalResourceId":"RecordSetGroupd17dced08c", "ResourceType":"AWS::Route53::RecordSetGroup" },
{ "LogicalResourceId":"ServerlessRestApiProdStage", "ResourceType":"AWS::ApiGateway::Stage" },
{ "LogicalResourceId":"ServerlessRestApigetBasePathMapping", "ResourceType":"AWS::ApiGateway::BasePathMapping" },
{ "LogicalResourceId":"ApiGatewayDomainName98c928338d", "ResourceType":"AWS::ApiGateway::DomainName" },
{ "LogicalResourceId":"MyFunction", "ResourceType":"AWS::Lambda::Function" },
{ "LogicalResourceId":"MyFunctionImplicitPostPermissionProd", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"MyFunctionRole", "ResourceType":"AWS::IAM::Role" }
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{ "LogicalResourceId":"MyFunctionImplicitGetPermissionProd", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"ServerlessRestApiDeployment", "ResourceType":"AWS::ApiGateway::Deployment" },
{ "LogicalResourceId":"ServerlessRestApipostBasePathMapping", "ResourceType":"AWS::ApiGateway::BasePathMapping" },
{ "LogicalResourceId":"ServerlessRestApi", "ResourceType":"AWS::ApiGateway::RestApi" },
{ "LogicalResourceId":"RecordSetGroupd17dced08c", "ResourceType":"AWS::Route53::RecordSetGroup" },
{ "LogicalResourceId":"ServerlessRestApiProdStage", "ResourceType":"AWS::ApiGateway::Stage" },
{ "LogicalResourceId":"ServerlessRestApigetBasePathMapping", "ResourceType":"AWS::ApiGateway::BasePathMapping" },
{ "LogicalResourceId":"ApiGatewayDomainNamef593820b0b", "ResourceType":"AWS::ApiGateway::DomainName" },
{ "LogicalResourceId":"MyFunction", "ResourceType":"AWS::Lambda::Function" },
{ "LogicalResourceId":"MyFunctionImplicitPostPermissionProd", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"MyFunctionRole", "ResourceType":"AWS::IAM::Role" }
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{ "LogicalResourceId":"MyFunctionImplicitGetPermission", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"MyFunctionImplicitPostPermission", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"MyApipostApiMapping", "ResourceType":"AWS::ApiGatewayV2::ApiMapping" },
{ "LogicalResourceId":"MyApigetApiMapping", "ResourceType":"AWS::ApiGatewayV2::ApiMapping" },
{ "LogicalResourceId":"MyApi", "ResourceType":"AWS::ApiGatewayV2::Api" },
{ "LogicalResourceId":"RecordSetGroupd17dced08c", "ResourceType":"AWS::Route53::RecordSetGroup" },
{ "LogicalResourceId":"MyApiProdStage", "ResourceType":"AWS::ApiGatewayV2::Stage" },
{ "LogicalResourceId":"ApiGatewayDomainNameV26198c55d75", "ResourceType":"AWS::ApiGatewayV2::DomainName" },
{ "LogicalResourceId":"MyFunction", "ResourceType":"AWS::Lambda::Function" },
{ "LogicalResourceId":"MyFunctionRole", "ResourceType":"AWS::IAM::Role" }
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{ "LogicalResourceId":"MyFunctionImplicitGetPermission", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"MyFunctionImplicitPostPermission", "ResourceType":"AWS::Lambda::Permission" },
{ "LogicalResourceId":"MyApipostApiMapping", "ResourceType":"AWS::ApiGatewayV2::ApiMapping" },
{ "LogicalResourceId":"MyApigetApiMapping", "ResourceType":"AWS::ApiGatewayV2::ApiMapping" },
{ "LogicalResourceId":"MyApi", "ResourceType":"AWS::ApiGatewayV2::Api" },
{ "LogicalResourceId":"RecordSetGroupd17dced08c", "ResourceType":"AWS::Route53::RecordSetGroup" },
{ "LogicalResourceId":"MyApiProdStage", "ResourceType":"AWS::ApiGatewayV2::Stage" },
{ "LogicalResourceId":"ApiGatewayDomainNameV2483cac8ea6", "ResourceType":"AWS::ApiGatewayV2::DomainName" },
{ "LogicalResourceId":"MyFunction", "ResourceType":"AWS::Lambda::Function" },
{ "LogicalResourceId":"MyFunctionRole", "ResourceType":"AWS::IAM::Role" }
]
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Parameters:
Type: String
MyEdgeDomainCert:
Type: String
HostedZoneId:
Type: String

Resources:
MyFunction:
Expand Down Expand Up @@ -41,5 +43,6 @@ Resources:
BasePath:
- /get
Route53:
HostedZoneId: Z1SKZDMQ2UR7IW
HostedZoneId:
Ref: HostedZoneId
IpV6: true
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Parameters:
Type: String
MyRestRegionalDomainCert:
Type: String
HostedZoneId:
Type: String

Globals:
Api:
Expand All @@ -20,7 +22,8 @@ Globals:
- /get
- /post
Route53:
HostedZoneId: Z1DTV8GVAVOHDR
HostedZoneId:
Ref: HostedZoneId

Resources:
MyFunction:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Parameters:
Type: String
MyDomainOwnershipVerificationCertificate:
Type: String
HostedZoneId:
Type: String

Globals:
Api:
Expand All @@ -22,7 +24,8 @@ Globals:
- /get
- /post
Route53:
HostedZoneId: Z1DTV8GVAVOHDR
HostedZoneId:
Ref: HostedZoneId
OwnershipVerificationCertificateArn:
Ref: MyDomainOwnershipVerificationCertificate

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Resources:
TriggerFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs16.x
Runtime: nodejs14.x
Handler: index.handler
Timeout: 10 # in case eb has delay
InlineCode: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Resources:
TriggerFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs16.x
Runtime: nodejs14.x
Handler: index.handler
Timeout: 10 # in case eb has delay
InlineCode: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Resources:
TriggerFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs16.x
Runtime: nodejs14.x
Handler: index.handler
Timeout: 10 # in case eb has delay
InlineCode: |
Expand Down Expand Up @@ -52,7 +52,7 @@ Resources:
Function:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs16.x
Runtime: nodejs14.x
Handler: index.handler
InlineCode: |
const AWS = require('aws-sdk');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Resources:
TriggerFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs16.x
Runtime: nodejs14.x
Handler: index.handler
Timeout: 10 # in case eb has delay
InlineCode: |
Expand Down
Loading

0 comments on commit b534773

Please sign in to comment.