From c877266f8648664045b7be9fa2519269c898b825 Mon Sep 17 00:00:00 2001 From: Brandon Bradley Date: Wed, 29 Jan 2020 16:27:56 -0600 Subject: [PATCH 1/4] fix 500 error on non-existing stack name --- moto/cloudformation/models.py | 2 ++ moto/cloudformation/responses.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py index 0ae5d1ae4..c05783fb4 100644 --- a/moto/cloudformation/models.py +++ b/moto/cloudformation/models.py @@ -677,6 +677,8 @@ class CloudFormationBackend(BaseBackend): def list_stack_resources(self, stack_name_or_id): stack = self.get_stack(stack_name_or_id) + if stack is None: + return [] return stack.stack_resources def delete_stack(self, name_or_stack_id): diff --git a/moto/cloudformation/responses.py b/moto/cloudformation/responses.py index bf68a6325..7effb03fa 100644 --- a/moto/cloudformation/responses.py +++ b/moto/cloudformation/responses.py @@ -229,6 +229,9 @@ class CloudFormationResponse(BaseResponse): stack_name_or_id = self._get_param("StackName") resources = self.cloudformation_backend.list_stack_resources(stack_name_or_id) + if not resources: + raise ValidationError(stack_name_or_id) + template = self.response_template(LIST_STACKS_RESOURCES_RESPONSE) return template.render(resources=resources) From b7795b7111158c3974040cf24ad1b56cfc1042c8 Mon Sep 17 00:00:00 2001 From: Brandon Bradley Date: Thu, 30 Jan 2020 16:35:19 -0600 Subject: [PATCH 2/4] test for ListStackResources --- .../test_cloudformation_stack_crud_boto3.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py index 40fb2d669..a3e5097d7 100644 --- a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py +++ b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py @@ -522,6 +522,16 @@ def test_boto3_list_stack_set_operations(): list_operation["Summaries"][-1]["Action"].should.equal("UPDATE") +@mock_cloudformation +def test_boto3_bad_list_stack_resources(): + cf_conn = boto3.client("cloudformation", region_name="us-east-1") + cf_conn.create_stack_set( + StackSetName="test_stack_set", TemplateBody=dummy_template_json + ) + with assert_raises(ClientError): + cf_conn.list_stack_resources(StackName="test_stack_set") + + @mock_cloudformation def test_boto3_delete_stack_set(): cf_conn = boto3.client("cloudformation", region_name="us-east-1") From 8b3c2b66544d82b91472fe3ad792ce5c18b773d3 Mon Sep 17 00:00:00 2001 From: Brandon Bradley Date: Thu, 30 Jan 2020 17:50:21 -0600 Subject: [PATCH 3/4] fix test --- .../test_cloudformation_stack_crud_boto3.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py index a3e5097d7..b7e86a1d5 100644 --- a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py +++ b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py @@ -525,9 +525,6 @@ def test_boto3_list_stack_set_operations(): @mock_cloudformation def test_boto3_bad_list_stack_resources(): cf_conn = boto3.client("cloudformation", region_name="us-east-1") - cf_conn.create_stack_set( - StackSetName="test_stack_set", TemplateBody=dummy_template_json - ) with assert_raises(ClientError): cf_conn.list_stack_resources(StackName="test_stack_set") From 800e5ab7d2e25970515b9612f6e998d9434e76d4 Mon Sep 17 00:00:00 2001 From: Brandon Bradley Date: Sat, 1 Feb 2020 14:52:48 -0600 Subject: [PATCH 4/4] requested changes from review --- moto/cloudformation/models.py | 2 +- moto/cloudformation/responses.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py index c05783fb4..b32d63b32 100644 --- a/moto/cloudformation/models.py +++ b/moto/cloudformation/models.py @@ -678,7 +678,7 @@ class CloudFormationBackend(BaseBackend): def list_stack_resources(self, stack_name_or_id): stack = self.get_stack(stack_name_or_id) if stack is None: - return [] + return None return stack.stack_resources def delete_stack(self, name_or_stack_id): diff --git a/moto/cloudformation/responses.py b/moto/cloudformation/responses.py index 7effb03fa..77a3051fd 100644 --- a/moto/cloudformation/responses.py +++ b/moto/cloudformation/responses.py @@ -229,7 +229,7 @@ class CloudFormationResponse(BaseResponse): stack_name_or_id = self._get_param("StackName") resources = self.cloudformation_backend.list_stack_resources(stack_name_or_id) - if not resources: + if resources is None: raise ValidationError(stack_name_or_id) template = self.response_template(LIST_STACKS_RESOURCES_RESPONSE)