diff --git a/integration/conftest.py b/integration/conftest.py index 98afb1803..f8a679680 100644 --- a/integration/conftest.py +++ b/integration/conftest.py @@ -10,7 +10,11 @@ from integration.helpers.deployer.utils.retry import retry_with_exponential_backoff_and_jitter from integration.helpers.stack import Stack from integration.helpers.yaml_utils import load_yaml -from integration.helpers.resource import read_test_config_file, write_test_config_file_to_json +from integration.helpers.resource import ( + read_test_config_file, + write_test_config_file_to_json, + current_region_does_not_support, +) try: from pathlib import Path @@ -21,6 +25,9 @@ COMPANION_STACK_NAME = "sam-integ-stack-companion" COMPANION_STACK_TEMPLATE = "companion-stack.yaml" +SAR_APP_TEMPLATE = "example-sar-app.yaml" +SAR_APP_NAME = "sam-integration-test-sar-app" +SAR_APP_VERSION = "1.0.3" def _get_all_buckets(): @@ -68,6 +75,38 @@ def setup_companion_stack_once(tmpdir_factory, get_prefix): companion_stack.create_or_update(_stack_exists(stack_name)) +@pytest.fixture() +def get_serverless_application_repository_app(): + """Create or re-use a simple SAR app""" + if current_region_does_not_support(["ServerlessRepo"]): + LOG.info("Creating SAR application is skipped since SAR tests are not supported in this region.") + return + + sar_client = ClientProvider().sar_client + sar_apps = sar_client.list_applications().get("Applications", []) + for sar_app in sar_apps: + if sar_app.get("Name") == SAR_APP_NAME: + LOG.info("SAR Application was already created, skipping SAR application publish") + return sar_app.get("ApplicationId") + + LOG.info("SAR application not found, publishing new one...") + + tests_integ_dir = Path(__file__).resolve().parents[1] + template_foler = Path(tests_integ_dir, "integration", "setup") + sar_app_template_path = Path(template_foler, SAR_APP_TEMPLATE) + with open(sar_app_template_path) as f: + sar_template_contents = f.read() + create_app_result = sar_client.create_application( + Author="SAM Team", + Description="SAR Application for Integration Tests", + Name=SAR_APP_NAME, + SemanticVersion=SAR_APP_VERSION, + TemplateBody=sar_template_contents, + ) + LOG.info("SAR application creation result: %s", create_app_result) + return create_app_result.get("ApplicationId") + + @pytest.fixture() def upload_resources(get_s3): """ diff --git a/integration/helpers/client_provider.py b/integration/helpers/client_provider.py index 25855765a..d5958435d 100644 --- a/integration/helpers/client_provider.py +++ b/integration/helpers/client_provider.py @@ -24,6 +24,7 @@ def __init__(self): self._iot_client = None self._kafka_client = None self._code_deploy_client = None + self._sar_client = None @property def cfn_client(self): @@ -205,3 +206,13 @@ def code_deploy_client(self): if not self._code_deploy_client: self._code_deploy_client = boto3.client("codedeploy") return self._code_deploy_client + + @property + def sar_client(self): + """ + Serverless Application Repo. Client + """ + with self._lock: + if not self._sar_client: + self._sar_client = boto3.client("serverlessrepo") + return self._sar_client diff --git a/integration/resources/templates/single/basic_application_sar_location.yaml b/integration/resources/templates/single/basic_application_sar_location.yaml index 254eca341..e0c922296 100644 --- a/integration/resources/templates/single/basic_application_sar_location.yaml +++ b/integration/resources/templates/single/basic_application_sar_location.yaml @@ -1,9 +1,13 @@ +Parameters: + SarApplicationId: + Type: String + Resources: MyNestedApp: Type: AWS::Serverless::Application Properties: Location: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 - SemanticVersion: 1.0.2 + ApplicationId: !Ref SarApplicationId + SemanticVersion: 1.0.3 Parameters: IdentityNameParameter: test diff --git a/integration/resources/templates/single/basic_application_sar_location_with_intrinsics.yaml b/integration/resources/templates/single/basic_application_sar_location_with_intrinsics.yaml index 3de30267d..2c1dd3ba3 100644 --- a/integration/resources/templates/single/basic_application_sar_location_with_intrinsics.yaml +++ b/integration/resources/templates/single/basic_application_sar_location_with_intrinsics.yaml @@ -1,40 +1,39 @@ Parameters: - SemanticVersion: + SarApplicationId: Type: String - Default: 1.0.2 Mappings: SARApplication: us-east-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 us-east-2: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 us-west-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 us-west-2: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 eu-central-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 eu-west-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 eu-west-2: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 eu-west-3: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 ap-south-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 ap-northeast-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 ap-northeast-2: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 ap-southeast-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 ap-southeast-2: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 ca-central-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 sa-east-1: - ApplicationId: arn:aws:serverlessrepo:us-east-1:077246666028:applications/hello-world-python3 + SemanticVersion: 1.0.3 Resources: MyNestedApp: @@ -42,12 +41,12 @@ Resources: Properties: Location: ApplicationId: + Ref: SarApplicationId + SemanticVersion: Fn::FindInMap: - SARApplication - - {Ref: 'AWS::Region'} - - ApplicationId - SemanticVersion: - Ref: SemanticVersion + - { Ref: 'AWS::Region' } + - SemanticVersion Parameters: IdentityNameParameter: test NotificationARNs: diff --git a/integration/setup/example-sar-app.yaml b/integration/setup/example-sar-app.yaml new file mode 100644 index 000000000..483eec305 --- /dev/null +++ b/integration/setup/example-sar-app.yaml @@ -0,0 +1,21 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: Hello world app with inline code + +Parameters: + IdentityNameParameter: + Type: String + +Resources: + HelloWorldPython3: + Type: AWS::Serverless::Function + Properties: + InlineCode: | + def handler(*args): + return 'Hello world!' + Handler: index.handler + Runtime: python3.9 + Timeout: 5 + Environment: + Variables: + IdentityNameParameter: !Ref IdentityNameParameter \ No newline at end of file diff --git a/integration/setup/test_setup_teardown.py b/integration/setup/test_setup_teardown.py index 35d2d1be7..e81800eab 100644 --- a/integration/setup/test_setup_teardown.py +++ b/integration/setup/test_setup_teardown.py @@ -3,7 +3,7 @@ @pytest.mark.setup -def test_setup(setup_companion_stack_once, upload_resources, get_s3): +def test_setup(setup_companion_stack_once, upload_resources, get_s3, get_serverless_application_repository_app): assert s3_upload_successful() diff --git a/integration/single/test_basic_application.py b/integration/single/test_basic_application.py index afc7a97c5..eff7116d4 100644 --- a/integration/single/test_basic_application.py +++ b/integration/single/test_basic_application.py @@ -1,5 +1,7 @@ from unittest.case import skipIf +import pytest + from integration.helpers.base_test import BaseTest from integration.helpers.resource import current_region_does_not_support @@ -9,6 +11,10 @@ class TestBasicApplication(BaseTest): Basic AWS::Serverless::Application tests """ + @pytest.fixture(autouse=True) + def companion_stack_outputs(self, get_serverless_application_repository_app): + self.sar_app_id = get_serverless_application_repository_app + @skipIf( current_region_does_not_support(["ServerlessRepo"]), "ServerlessRepo is not supported in this testing region" ) @@ -32,13 +38,14 @@ def test_basic_application_sar_location(self): """ Creates an application with a lamda function """ - self.create_and_verify_stack("single/basic_application_sar_location") + parameters = [self.generate_parameter("SarApplicationId", self.sar_app_id)] + self.create_and_verify_stack("single/basic_application_sar_location", parameters) nested_stack_resource = self.get_stack_nested_stack_resources() functions = self.get_stack_resources("AWS::Lambda::Function", nested_stack_resource) self.assertEqual(len(functions), 1) - self.assertEqual(functions[0]["LogicalResourceId"], "helloworldpython3") + self.assertEqual(functions[0]["LogicalResourceId"], "HelloWorldPython3") @skipIf( current_region_does_not_support(["ServerlessRepo"]), "ServerlessRepo is not supported in this testing region" @@ -47,8 +54,9 @@ def test_basic_application_sar_location_with_intrinsics(self): """ Creates an application with a lambda function with intrinsics """ - expected_function_name = "helloworldpython3" - self.create_and_verify_stack("single/basic_application_sar_location_with_intrinsics") + expected_function_name = "HelloWorldPython3" + parameters = [self.generate_parameter("SarApplicationId", self.sar_app_id)] + self.create_and_verify_stack("single/basic_application_sar_location_with_intrinsics", parameters) nested_stack_resource = self.get_stack_nested_stack_resources() functions = self.get_stack_resources("AWS::Lambda::Function", nested_stack_resource)