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..a52898f90b 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,42 @@ 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: + """ + 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() + 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()