def test_delete_no_stack(config): attrs = {'describe_stacks.side_effect': STACK_DOES_NOT_EXIST} mock = MagicMock(**attrs) runner = Runner(mock, config) with pytest.raises(ValidationError, match='Stack TestStack not found'): runner.delete()
def test_delete_client_error(client, config): client.configure_mock( **{'delete_stack.side_effect': ClientError({}, 'delete_stack')}) runner = Runner(client, config) with pytest.raises( StackError, match= 'An error occurred \\(Unknown\\) when calling the delete_stack operation.*' ): runner.delete()
def test_delete(client, config, capsys): runner = Runner(client, config) runner.delete() assert runner.stack is None client.describe_stack_events.assert_called_once_with(StackName='TestStack') client.delete_stack.assert_called_once_with(StackName='TestStack', RetainResources=[]) client.get_waiter.assert_called_once_with('stack_delete_complete') client.get_waiter().wait.assert_called_once_with(StackName='TestStack', WaiterConfig={ 'Delay': 10, 'MaxAttempts': 360 })
def test_delete_invalid_status(client, config): describe_stacks = { 'Stacks': [{ 'StackName': 'TestStack', 'StackStatus': StackStatus.UPDATE_IN_PROGRESS.name, 'CreationTime': '2019-12-31T18:30:11.12345+0000' }] } client.configure_mock(**{'describe_stacks.return_value': describe_stacks}) runner = Runner(client, config) with pytest.raises( ValidationError, match= 'Stack TestStack is not in a deletable status: UPDATE_IN_PROGRESS' ): runner.delete()
def test_delete_waiter_error(client, config, capsys, monkeypatch): # Prevent differences in format depending upon where this runs monkeypatch.setenv('STACKMANAGER_TIMEZONE', 'UTC') # Configure waiter waiter_error = WaiterError('stack_delete_complete', 'Delete Failed', { 'Status': 'FAILED', 'StatusReason': 'Delete failed' }) waiter_mock = MagicMock(**{'wait.side_effect': waiter_error}) # Override Stack events stack_events = { 'StackEvents': [{ 'Timestamp': datetime(2020, 1, 1, 13, 35, 11, 0, tzinfo=timezone.utc), 'LogicalResourceId': 'Topic', 'ResourceType': 'AWS::SNS::Topic', 'ResourceStatus': 'DELETE_FAILED', 'ResourceStatusReason': 'Something went wrong' }, { 'Timestamp': datetime(2020, 1, 1, 12, 0, 0, 0, tzinfo=timezone.utc), 'LogicalResourceId': 'TestStack', 'ResourceType': 'AWS::CloudFormation::Stack', 'ResourceStatus': 'CREATE_COMPLETE' }, { 'Timestamp': datetime(2020, 1, 1, 11, 58, 20, 12436, tzinfo=timezone.utc), 'LogicalResourceId': 'Topic', 'ResourceType': 'AWS::SNS::Topic', 'ResourceStatus': 'CREATE_COMPLETE' }] } paginator_mock = MagicMock(**{'paginate.return_value': [stack_events]}) client.configure_mock( **{ 'get_waiter.return_value': waiter_mock, 'get_paginator.return_value': paginator_mock }) runner = Runner(client, config) with pytest.raises( StackError, match='Waiter stack_delete_complete failed: Delete Failed'): runner.delete() captured = capsys.readouterr() assert 'Deletion of Stack TestStack failed:' in captured.err assert '2020-01-01 13:35:11 Topic AWS::SNS::Topic DELETE_FAILED Something went wrong' \ in captured.out