From f69f95343ddd7d18be22e18fee6cc1197227d5bd Mon Sep 17 00:00:00 2001 From: Mohamed ElAsmar Date: Fri, 2 Jun 2023 12:09:31 -0700 Subject: [PATCH 1/3] fix: fix build SAR integration test cases --- .../remote_invoke/remote_invoke_context.py | 1 - tests/integration/buildcmd/test_build_cmd.py | 15 ++++ .../integration/deploy/test_deploy_command.py | 70 ++++++++++--------- ...s-application-with-application-id-map.yaml | 6 +- tests/testing_utils.py | 35 ++++++++++ 5 files changed, 90 insertions(+), 37 deletions(-) diff --git a/samcli/commands/remote_invoke/remote_invoke_context.py b/samcli/commands/remote_invoke/remote_invoke_context.py index 7795476b89..1e176f01a3 100644 --- a/samcli/commands/remote_invoke/remote_invoke_context.py +++ b/samcli/commands/remote_invoke/remote_invoke_context.py @@ -30,7 +30,6 @@ class RemoteInvokeContext: - _boto_client_provider: BotoProviderType _boto_resource_provider: BotoProviderType _stack_name: Optional[str] diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index e9e0f34d3d..f23b4f4f10 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -26,6 +26,7 @@ SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE, run_command_with_input, + UpdatableSARTemplate, ) from .build_integ_base import ( BuildIntegBase, @@ -2959,6 +2960,20 @@ def test_functions_layers_with_s3_codeuri(self): class TestBuildSAR(BuildIntegBase): template = "aws-serverless-application-with-application-id-map.yaml" + @classmethod + def setUpClass(cls): + super(TestBuildSAR, cls).setUpClass() + cls.update_sar_template = None + if cls.template_path: + cls.update_sar_template = UpdatableSARTemplate(cls.template_path) + cls.update_sar_template.setup() + cls.template_path = cls.update_sar_template.updated_template_path + + @classmethod + def tearDownClass(cls): + if cls.update_sar_template: + cls.update_sar_template.clean() + @parameterized.expand( [ ("use_container", "us-east-2"), diff --git a/tests/integration/deploy/test_deploy_command.py b/tests/integration/deploy/test_deploy_command.py index 87dbe5374f..131d3969ab 100644 --- a/tests/integration/deploy/test_deploy_command.py +++ b/tests/integration/deploy/test_deploy_command.py @@ -12,7 +12,7 @@ from samcli.lib.bootstrap.bootstrap import SAM_CLI_STACK_NAME from samcli.lib.config.samconfig import DEFAULT_CONFIG_FILE_NAME from tests.integration.deploy.deploy_integ_base import DeployIntegBase -from tests.testing_utils import RUNNING_ON_CI, RUNNING_TEST_FOR_MASTER_ON_CI, RUN_BY_CANARY +from tests.testing_utils import RUNNING_ON_CI, RUNNING_TEST_FOR_MASTER_ON_CI, RUN_BY_CANARY, UpdatableSARTemplate # Deploy tests require credentials and CI/CD will only add credentials to the env if the PR is from the same repo. # This is to restrict package tests to run outside of CI/CD, when the branch is not master or tests are not run by Canary @@ -888,25 +888,28 @@ def test_deploy_with_code_signing_params(self, should_sign, should_enforce, will ] ) def test_deploy_sar_with_location_from_map(self, template_file, region, will_succeed): - template_path = Path(__file__).resolve().parents[1].joinpath("testdata", "buildcmd", template_file) - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name, "region": region}) + with UpdatableSARTemplate( + Path(__file__).resolve().parents[1].joinpath("testdata", "buildcmd", template_file) + ) as sar_app: + template_path = sar_app.updated_template_path + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name, "region": region}) - # The default region (us-east-1) has no entry in the map - deploy_command_list = self.get_deploy_command_list( - template_file=template_path, - s3_prefix=self.s3_prefix, - stack_name=stack_name, - capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], - region=region, # the !FindInMap has an entry for use-east-2 region only - ) - deploy_process_execute = self.run_command(deploy_command_list) + # The default region (us-east-1) has no entry in the map + deploy_command_list = self.get_deploy_command_list( + template_file=template_path, + s3_prefix=self.s3_prefix, + stack_name=stack_name, + capabilities_list=["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"], + region=region, # the !FindInMap has an entry for use-east-2 region only + ) + deploy_process_execute = self.run_command(deploy_command_list) - if will_succeed: - self.assertEqual(deploy_process_execute.process.returncode, 0) - else: - self.assertEqual(deploy_process_execute.process.returncode, 1) - self.assertIn("Property \\'ApplicationId\\' cannot be resolved.", str(deploy_process_execute.stderr)) + if will_succeed: + self.assertEqual(deploy_process_execute.process.returncode, 0) + else: + self.assertEqual(deploy_process_execute.process.returncode, 1) + self.assertIn("Property \\'ApplicationId\\' cannot be resolved.", str(deploy_process_execute.stderr)) @parameterized.expand( [ @@ -915,23 +918,26 @@ def test_deploy_sar_with_location_from_map(self, template_file, region, will_suc ] ) def test_deploy_guided_sar_with_location_from_map(self, template_file, region, will_succeed): - template_path = Path(__file__).resolve().parents[1].joinpath("testdata", "buildcmd", template_file) - stack_name = self._method_to_stack_name(self.id()) - self.stacks.append({"name": stack_name, "region": region}) + with UpdatableSARTemplate( + Path(__file__).resolve().parents[1].joinpath("testdata", "buildcmd", template_file) + ) as sar_app: + template_path = sar_app.updated_template_path + stack_name = self._method_to_stack_name(self.id()) + self.stacks.append({"name": stack_name, "region": region}) - # Package and Deploy in one go without confirming change set. - deploy_command_list = self.get_deploy_command_list(template_file=template_path, guided=True) + # Package and Deploy in one go without confirming change set. + deploy_command_list = self.get_deploy_command_list(template_file=template_path, guided=True) - deploy_process_execute = self.run_command_with_input( - deploy_command_list, - f"{stack_name}\n{region}\n\nN\nCAPABILITY_IAM CAPABILITY_AUTO_EXPAND\nn\nN\n".encode(), - ) + deploy_process_execute = self.run_command_with_input( + deploy_command_list, + f"{stack_name}\n{region}\n\nN\nCAPABILITY_IAM CAPABILITY_AUTO_EXPAND\nn\nN\n".encode(), + ) - if will_succeed: - self.assertEqual(deploy_process_execute.process.returncode, 0) - else: - self.assertEqual(deploy_process_execute.process.returncode, 1) - self.assertIn("Property \\'ApplicationId\\' cannot be resolved.", str(deploy_process_execute.stderr)) + if will_succeed: + self.assertEqual(deploy_process_execute.process.returncode, 0) + else: + self.assertEqual(deploy_process_execute.process.returncode, 1) + self.assertIn("Property \\'ApplicationId\\' cannot be resolved.", str(deploy_process_execute.stderr)) @parameterized.expand( [os.path.join("deep-nested", "template.yaml"), os.path.join("deep-nested-image", "template.yaml")] diff --git a/tests/integration/testdata/buildcmd/aws-serverless-application-with-application-id-map.yaml b/tests/integration/testdata/buildcmd/aws-serverless-application-with-application-id-map.yaml index d1f83aaf40..683b40b9b6 100644 --- a/tests/integration/testdata/buildcmd/aws-serverless-application-with-application-id-map.yaml +++ b/tests/integration/testdata/buildcmd/aws-serverless-application-with-application-id-map.yaml @@ -4,7 +4,7 @@ Transform: AWS::Serverless-2016-10-31 Mappings: MappingExample: us-east-2: - ApplicationId: !Sub arn:aws:serverlessrepo:us-east-1:${AWS::AccountId}:applications/sam-cli-integration-test-sar-app + ApplicationId: arn:aws:serverlessrepo:us-east-1:${AWS::AccountId}:applications/shared-sam-cli-integration-test-sar-app Resources: MyApplication: @@ -12,6 +12,4 @@ Resources: Properties: Location: ApplicationId: !FindInMap [ MappingExample, !Ref AWS::Region, ApplicationId ] - SemanticVersion: 1.0.4 - Parameters: - IdentityNameParameter: AnyValue \ No newline at end of file + SemanticVersion: 1.0.4 \ No newline at end of file diff --git a/tests/testing_utils.py b/tests/testing_utils.py index cd98d7d8e4..c3e075bb20 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -3,6 +3,7 @@ import platform import subprocess import tempfile +from pathlib import Path from threading import Thread from typing import Callable, List, Optional @@ -13,6 +14,7 @@ import shutil from uuid import uuid4 +import boto3 import psutil RUNNING_ON_APPVEYOR = os.environ.get("APPVEYOR", False) @@ -232,3 +234,36 @@ def full_path(self, filename): f.full_path('foo/bar.txt') -> /tmp/asdfasd/foo/bar.txt """ return os.path.join(self.rootdir, filename) + + +def _get_current_account_id(): + sts = boto3.client("sts") + account_id = sts.get_caller_identity()["Account"] + return account_id + + +class UpdatableSARTemplate: + def __init__(self, source_template_path): + self.source_template_path = source_template_path + self.temp_directory = tempfile.TemporaryDirectory() + self.temp_directory_path = Path(tempfile.TemporaryDirectory().name) + self.updated_template_path = None + + def setup(self): + with open(self.source_template_path, "r") as sar_template: + updated_template_content = sar_template.read() + updated_template_content = updated_template_content.replace("${AWS::AccountId}", _get_current_account_id()) + self.temp_directory_path.mkdir() + self.updated_template_path = os.path.join(self.temp_directory_path, "template.yml") + with open(self.updated_template_path, "w") as updated_template: + updated_template.write(updated_template_content) + + def clean(self): + self.temp_directory.cleanup() + + def __enter__(self): + self.setup() + return self + + def __exit__(self, *args): + self.clean() From 25ac5f0983e4257cade6d814e6b7a9da6e5270b1 Mon Sep 17 00:00:00 2001 From: Mohamed ElAsmar Date: Fri, 2 Jun 2023 12:15:41 -0700 Subject: [PATCH 2/3] add comments to the UpdatableSARTemplate class usage. --- tests/testing_utils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/testing_utils.py b/tests/testing_utils.py index c3e075bb20..e0dc053586 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -243,6 +243,11 @@ def _get_current_account_id(): class UpdatableSARTemplate: + """ + This class is used to replace the `${AWS::AccountId}` in the testing templates with the account id for the testing + is used during the integration testing. This class helps to resolve the problem that SAM CLI does not support Sub + intrinsic function, and to avoid exposing any of our testing accounts ids. + """ def __init__(self, source_template_path): self.source_template_path = source_template_path self.temp_directory = tempfile.TemporaryDirectory() From 73ef3478f8b76cdf823881313b9eff869c3e6225 Mon Sep 17 00:00:00 2001 From: Mohamed ElAsmar Date: Fri, 2 Jun 2023 12:42:25 -0700 Subject: [PATCH 3/3] fix black check --- tests/testing_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testing_utils.py b/tests/testing_utils.py index e0dc053586..a52898f90b 100644 --- a/tests/testing_utils.py +++ b/tests/testing_utils.py @@ -248,6 +248,7 @@ class UpdatableSARTemplate: is used during the integration testing. This class helps to resolve the problem that SAM CLI does not support Sub intrinsic function, and to avoid exposing any of our testing accounts ids. """ + def __init__(self, source_template_path): self.source_template_path = source_template_path self.temp_directory = tempfile.TemporaryDirectory()