def test_apply_change_set(client, config, capsys, monkeypatch): # Prevent differences in format depending upon where this runs monkeypatch.setenv('STACKMANAGER_TIMEZONE', 'UTC') runner = Runner(client, config) runner.apply_change_set() client.describe_stack_events.assert_called_once_with(StackName='TestStack') client.get_waiter.assert_called_once_with('stack_update_complete') client.get_waiter().wait.assert_called_once_with(StackName='TestStack', WaiterConfig={ 'Delay': 10, 'MaxAttempts': 360 }) client.get_paginator.assert_called_once_with('describe_stack_events') client.get_paginator().paginate.assert_called_once_with( StackName='TestStack') client.update_termination_protection.assert_not_called() captured = capsys.readouterr() assert 'Executing ChangeSet TestChangeSet for TestStack' in captured.out assert 'ChangeSet TestChangeSet for TestStack successfully completed:' in captured.out assert 'Timestamp LogicalResourceId ResourceType ResourceStatus Reason' in captured.out assert '2020-01-01 13:23:11 TestStack AWS::CloudFormation::Stack UPDATE_IN_PROGRESS User Initiated' in captured.out assert '2020-01-01 13:24:53 Queue AWS::SQS::Queue CREATE_COMPLETE -' in captured.out assert '2020-01-01 13:25:01 TestStack AWS::CloudFormation::Stack UPDATE_COMPLETE -' in captured.out # We shouldn't have the previous events in the output assert 'AWS::CloudFormation::Stack CREATE_COMPLETE' not in captured.out
def test_apply_change_set_client_error(client, config): client.configure_mock(**{ 'execute_change_set.side_effect': ClientError({}, 'execute_change_set') }) runner = Runner(client, config) with pytest.raises( StackError, match= 'An error occurred \\(Unknown\\) when calling the execute_change_set .*' ): runner.apply_change_set()
def test_apply_change_set_waiter_error(client, config, capsys, monkeypatch): # Prevent differences in format depending upon where this runs monkeypatch.setenv('STACKMANAGER_TIMEZONE', 'UTC') # Configure waiter to throw WaiterError waiter_error = WaiterError('stack_update_complete', 'Update Failed', { 'Status': 'FAILED', 'StatusReason': 'Some reason' }) waiter_mock = MagicMock(**{'wait.side_effect': waiter_error}) # Override Stack events stack_events = { 'StackEvents': [{ 'Timestamp': datetime(2020, 1, 1, 13, 33, 41, 0, tzinfo=timezone.utc), 'LogicalResourceId': 'Queue', 'ResourceType': 'AWS::SQS::Queue', 'ResourceStatus': 'CREATE_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_update_complete failed: Update Failed'): runner.apply_change_set() captured = capsys.readouterr() assert 'ChangeSet TestChangeSet for TestStack failed:' in captured.err assert '2020-01-01 13:33:41 Queue AWS::SQS::Queue CREATE_FAILED Something went wrong' \ in captured.out