Пример #1
0
 def test_waiter_handles_retry_state(self):
     acceptor_with_retry_state = [
         {
             'state': 'success',
             'matcher': 'status',
             'expected': 200
         },
         {
             'state': 'retry',
             'matcher': 'error',
             'expected': 'RetryMe'
         },
     ]
     config = self.create_waiter_config(acceptors=acceptor_with_retry_state)
     operation_method = mock.Mock()
     self.client_responses_are(
         {'Nothing': 'foo'},
         {'Error': {
             'Code': 'RetryMe',
             'Message': 'foo'
         }}, {
             'Success': True,
             'ResponseMetadata': {
                 'HTTPStatusCode': 200
             }
         }, {'NeverCalled': True},
         for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     waiter.wait()
     self.assertEqual(operation_method.call_count, 3)
Пример #2
0
 def test_waiter_transitions_to_retry_but_max_attempts_exceeded(self):
     acceptors = [
         {
             'state': 'success',
             'matcher': 'status',
             'expected': 200
         },
         {
             'state': 'retry',
             'matcher': 'error',
             'expected': 'RetryMe'
         },
     ]
     config = self.create_waiter_config(acceptors=acceptors)
     operation_method = mock.Mock()
     self.client_responses_are({
         'Success': False
     }, {'Error': {
         'Code': 'RetryMe',
         'Message': 'foo'
     }}, {'Success': False}, {'Success': False},
                               for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
Пример #3
0
 def test_waiter_transitions_to_retry_but_max_attempts_exceeded(self):
     acceptors = [
         {
             'state': 'success',
             'matcher': 'status',
             'expected': 200
         },
         {
             'state': 'retry',
             'matcher': 'error',
             'expected': 'RetryMe'
         },
     ]
     config = self.create_waiter_config(acceptors=acceptors)
     operation_method = mock.Mock()
     self.client_responses_are(
         {'Success': False},
         {'Error': {
             'Code': 'RetryMe',
             'Message': 'foo'
         }}, {'Success': False}, {'Success': False},
         for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
Пример #4
0
 def test_waiter_transitions_to_failure_state(self):
     acceptors = [
         # A success state that will never be hit.
         {
             'state': 'success',
             'matcher': 'status',
             'expected': 1000
         },
         {
             'state': 'failure',
             'matcher': 'error',
             'expected': 'FailError'
         },
     ]
     config = self.create_waiter_config(acceptors=acceptors)
     operation_method = mock.Mock()
     self.client_responses_are(
         {'Nothing': 'foo'},
         # And on the second attempt, a FailError is seen, which
         # causes the waiter to fail fast.
         {'Error': {
             'Code': 'FailError',
             'Message': 'foo'
         }},
         {'WillNeverGetCalled': True},
         for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
     # Not only should we raise an exception, but we should have
     # only called the operation_method twice because the second
     # response triggered a fast fail.
     self.assertEqual(operation_method.call_count, 2)
Пример #5
0
 def test_waiter_transitions_to_failure_state(self):
     acceptors = [
         # A success state that will never be hit.
         {
             'state': 'success',
             'matcher': 'status',
             'expected': 1000
         },
         {
             'state': 'failure',
             'matcher': 'error',
             'expected': 'FailError'
         },
     ]
     config = self.create_waiter_config(acceptors=acceptors)
     operation_method = mock.Mock()
     self.client_responses_are(
         {
             'Nothing': 'foo'
         },
         # And on the second attempt, a FailError is seen, which
         # causes the waiter to fail fast.
         {'Error': {
             'Code': 'FailError',
             'Message': 'foo'
         }},
         {'WillNeverGetCalled': True},
         for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
     # Not only should we raise an exception, but we should have
     # only called the operation_method twice because the second
     # response triggered a fast fail.
     self.assertEqual(operation_method.call_count, 2)
Пример #6
0
 def test_waiter_handles_retry_state(self):
     acceptor_with_retry_state = [
         {
             'state': 'success',
             'matcher': 'status',
             'expected': 200
         },
         {
             'state': 'retry',
             'matcher': 'error',
             'expected': 'RetryMe'
         },
     ]
     config = self.create_waiter_config(acceptors=acceptor_with_retry_state)
     operation_method = mock.Mock()
     self.client_responses_are({
         'Nothing': 'foo'
     }, {'Error': {
         'Code': 'RetryMe',
         'Message': 'foo'
     }}, {
         'Success': True,
         'ResponseMetadata': {
             'HTTPStatusCode': 200
         }
     }, {'NeverCalled': True},
                               for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     waiter.wait()
     self.assertEqual(operation_method.call_count, 3)
Пример #7
0
 def _assert_failure_state_error_raised(self, acceptors, responses,
                                        expected_msg):
     config = self.create_waiter_config(acceptors=acceptors)
     operation_method = mock.Mock()
     waiter = Waiter('MyWaiter', config, operation_method)
     self.client_responses_are(*responses, for_operation=operation_method)
     with self.assertRaisesRegex(WaiterError, expected_msg):
         waiter.wait()
Пример #8
0
 def test_last_response_available_on_waiter_error(self):
     last_response = {'Error': {'Code': 'UnknownError', 'Message': 'bad error'}}
     config = self.create_waiter_config()
     operation_method = mock.Mock()
     self.client_responses_are(last_response,
                               for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError) as e:
         waiter.wait()
     self.assertEqual(e.exception.last_response, last_response)
Пример #9
0
    def test_waiter_invocation_config_honors_max_attempts(self):
        config = self.create_waiter_config()
        operation_method = mock.Mock()
        self.client_responses_are({'Success': False}, {'Success': False},
                                  for_operation=operation_method)
        waiter = Waiter('MyWaiter', config, operation_method)
        custom_max = 2
        with self.assertRaises(WaiterError):
            waiter.wait(WaiterConfig={'MaxAttempts': custom_max})

        self.assertEqual(operation_method.call_count, 2)
Пример #10
0
 def test_waiter_never_matches(self):
     # Verify that a matcher will fail after max_attempts
     # is exceeded.
     config = self.create_waiter_config(max_attempts=3)
     operation_method = mock.Mock()
     self.client_responses_are({'Foo': 'FAILURE'}, {'Foo': 'FAILURE'},
                               {'Foo': 'FAILURE'},
                               for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
Пример #11
0
 def test_waiter_never_matches(self):
     # Verify that a matcher will fail after max_attempts
     # is exceeded.
     config = self.create_waiter_config(max_attempts=3)
     operation_method = mock.Mock()
     self.client_responses_are({
         'Foo': 'FAILURE'
     }, {'Foo': 'FAILURE'}, {'Foo': 'FAILURE'},
                               for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
Пример #12
0
    def test_kwargs_are_passed_through(self):
        acceptors = [
            {'state': 'success', 'matcher': 'error', 'expected': 'MyError'},
        ]
        config = self.create_waiter_config(acceptors=acceptors)
        operation_method = mock.Mock()
        self.client_responses_are(
            {'Error': {'Code': 'MyError'}},
            for_operation=operation_method)
        waiter = Waiter('MyWaiter', config, operation_method)
        waiter.wait(Foo='foo', Bar='bar', Baz='baz')

        operation_method.assert_called_with(Foo='foo', Bar='bar',
                                            Baz='baz')
Пример #13
0
    def test_kwargs_are_passed_through(self):
        acceptors = [
            {'state': 'success', 'matcher': 'error', 'expected': 'MyError'},
        ]
        config = self.create_waiter_config(acceptors=acceptors)
        operation_method = mock.Mock()
        self.client_responses_are(
            {'Error': {'Code': 'MyError'}},
            for_operation=operation_method)
        waiter = Waiter('MyWaiter', config, operation_method)
        waiter.wait(Foo='foo', Bar='bar', Baz='baz')

        operation_method.assert_called_with(Foo='foo', Bar='bar',
                                            Baz='baz')
Пример #14
0
    def test_waiter_invocation_config_honors_max_attempts(self):
        config = self.create_waiter_config()
        operation_method = mock.Mock()
        self.client_responses_are(
            {'Success': False},
            {'Success': False},
            for_operation=operation_method
        )
        waiter = Waiter('MyWaiter', config, operation_method)
        custom_max = 2
        with self.assertRaises(WaiterError):
            waiter.wait(WaiterConfig={'MaxAttempts': custom_max})

        self.assertEqual(operation_method.call_count, 2)
Пример #15
0
    def test_waiter_invocation_config_honors_delay(self, sleep_mock):
        config = self.create_waiter_config()
        operation_method = mock.Mock()
        self.client_responses_are({'Success': False}, {'Success': False},
                                  {'Success': False},
                                  for_operation=operation_method)
        waiter = Waiter('MyWaiter', config, operation_method)
        custom_delay = 3
        with self.assertRaises(WaiterError):
            waiter.wait(WaiterConfig={'Delay': custom_delay})

        # We attempt three times, which means we need to sleep
        # twice, once before each subsequent request.
        self.assertEqual(sleep_mock.call_count, 2)
        sleep_mock.assert_called_with(custom_delay)
Пример #16
0
 def test_last_response_available_on_waiter_error(self):
     last_response = {
         'Error': {
             'Code': 'UnknownError',
             'Message': 'bad error'
         }
     }
     config = self.create_waiter_config()
     operation_method = mock.Mock()
     self.client_responses_are(last_response,
                               for_operation=operation_method)
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError) as e:
         waiter.wait()
     self.assertEqual(e.exception.last_response, last_response)
Пример #17
0
 def test_unspecified_errors_stops_waiter(self):
     # If a waiter receives an error response, then the
     # waiter immediately stops.
     config = self.create_waiter_config()
     operation_method = mock.Mock()
     self.client_responses_are(
         # This is an unknown error that's not called out
         # in any of the waiter config, so when the
         # waiter encounters this response it will transition
         # to the failure state.
         {'Error': {'Code': 'UnknownError', 'Message': 'bad error'}},
         for_operation=operation_method
     )
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
Пример #18
0
 def test_unspecified_errors_stops_waiter(self):
     # If a waiter receives an error response, then the
     # waiter immediately stops.
     config = self.create_waiter_config()
     operation_method = mock.Mock()
     self.client_responses_are(
         # This is an unknown error that's not called out
         # in any of the waiter config, so when the
         # waiter encounters this response it will transition
         # to the failure state.
         {'Error': {'Code': 'UnknownError', 'Message': 'bad error'}},
         for_operation=operation_method
     )
     waiter = Waiter('MyWaiter', config, operation_method)
     with self.assertRaises(WaiterError):
         waiter.wait()
Пример #19
0
 def test_waiter_waits_until_acceptor_matches(self):
     config = self.create_waiter_config(max_attempts=3,
                                        acceptors=[{
                                            'state': 'success',
                                            'matcher': 'path',
                                            'argument': 'Foo',
                                            'expected': 'SUCCESS'
                                        }])
     # Simulate the client having two calls that don't
     # match followed by a third call that matches the
     # acceptor.
     operation_method = mock.Mock()
     waiter = Waiter('MyWaiter', config, operation_method)
     self.client_responses_are({'Foo': 'FAILURE'}, {'Foo': 'FAILURE'},
                               {'Foo': 'SUCCESS'},
                               for_operation=operation_method)
     waiter.wait()
     self.assertEqual(operation_method.call_count, 3)
Пример #20
0
    def test_waiter_invocation_config_honors_delay(self, sleep_mock):
        config = self.create_waiter_config()
        operation_method = mock.Mock()
        self.client_responses_are(
            {'Success': False},
            {'Success': False},
            {'Success': False},
            for_operation=operation_method
        )
        waiter = Waiter('MyWaiter', config, operation_method)
        custom_delay = 3
        with self.assertRaises(WaiterError):
            waiter.wait(WaiterConfig={'Delay': custom_delay})

        # We attempt three times, which means we need to sleep
        # twice, once before each subsequent request.
        self.assertEqual(sleep_mock.call_count, 2)
        sleep_mock.assert_called_with(custom_delay)
Пример #21
0
 def test_waiter_waits_until_acceptor_matches(self):
     config = self.create_waiter_config(
         max_attempts=3,
         acceptors=[{'state': 'success', 'matcher': 'path',
                     'argument': 'Foo', 'expected': 'SUCCESS'}])
     # Simulate the client having two calls that don't
     # match followed by a third call that matches the
     # acceptor.
     operation_method = mock.Mock()
     waiter = Waiter('MyWaiter', config, operation_method)
     self.client_responses_are(
         {'Foo': 'FAILURE'},
         {'Foo': 'FAILURE'},
         {'Foo': 'SUCCESS'},
         for_operation=operation_method
     )
     waiter.wait()
     self.assertEqual(operation_method.call_count, 3)
Пример #22
0
    def test_unspecified_errors_propagate_error_code(self):
        # If a waiter receives an error response, then the
        # waiter should pass along the error code
        config = self.create_waiter_config()
        operation_method = mock.Mock()
        error_code = 'error_message'
        error_message = 'error_message'
        self.client_responses_are(
            # This is an unknown error that's not called out
            # in any of the waiter config, so when the
            # waiter encounters this response it will transition
            # to the failure state.
            {'Error': {'Code': error_code, 'Message': error_message}},
            for_operation=operation_method
        )
        waiter = Waiter('MyWaiter', config, operation_method)

        with self.assertRaisesRegexp(WaiterError, error_message):
            waiter.wait()
Пример #23
0
    def test_unspecified_errors_propagate_error_code(self):
        # If a waiter receives an error response, then the
        # waiter should pass along the error code
        config = self.create_waiter_config()
        operation_method = mock.Mock()
        error_code = 'error_message'
        error_message = 'error_message'
        self.client_responses_are(
            # This is an unknown error that's not called out
            # in any of the waiter config, so when the
            # waiter encounters this response it will transition
            # to the failure state.
            {'Error': {'Code': error_code, 'Message': error_message}},
            for_operation=operation_method
        )
        waiter = Waiter('MyWaiter', config, operation_method)

        with self.assertRaisesRegexp(WaiterError, error_message):
            waiter.wait()
Пример #24
0
 def test_waiter_matches_with_invalid_error_response(self):
     # Verify that the call will not raise WaiterError
     # because of 'Error' key in success response.
     config = self.create_waiter_config(max_attempts=3,
                                        acceptors=[{
                                            'state': 'success',
                                            'matcher': 'path',
                                            'argument': 'Foo',
                                            'expected': 'SUCCESS'
                                        }])
     operation_method = mock.Mock()
     waiter = Waiter('MyWaiter', config, operation_method)
     self.client_responses_are({
         'Foo': 'SUCCESS',
         'Error': 'foo'
     },
                               for_operation=operation_method)
     waiter.wait()
     self.assertEqual(operation_method.call_count, 1)
Пример #25
0
def make_waiter(op, path, expected, matcher="path", delay=1, max_attempts=30):
    from botocore.waiter import Waiter, SingleWaiterConfig
    acceptor = dict(matcher=matcher,
                    argument=path,
                    expected=expected,
                    state="success")
    waiter_cfg = dict(operation=op.__name__,
                      delay=delay,
                      maxAttempts=max_attempts,
                      acceptors=[acceptor])
    return Waiter(op.__name__, SingleWaiterConfig(waiter_cfg), op)
Пример #26
0
    def test_waiter_honors_delay_time_between_retries(self, sleep_mock):
        delay_time = 5
        config = self.create_waiter_config(delay=delay_time)
        operation_method = mock.Mock()
        self.client_responses_are(
            # This is an unknown error that's not called out
            # in any of the waiter config, so when the
            # waiter encounters this response it will transition
            # to the failure state.
            {'Success': False},
            {'Success': False},
            {'Success': False},
            for_operation=operation_method)
        waiter = Waiter('MyWaiter', config, operation_method)
        with self.assertRaises(WaiterError):
            waiter.wait()

        # We attempt three times, which means we need to sleep
        # twice, once before each subsequent request.
        self.assertEqual(sleep_mock.call_count, 2)
        sleep_mock.assert_called_with(delay_time)
Пример #27
0
    def test_waiter_honors_delay_time_between_retries(self, sleep_mock):
        delay_time = 5
        config = self.create_waiter_config(delay=delay_time)
        operation_method = mock.Mock()
        self.client_responses_are(
            # This is an unknown error that's not called out
            # in any of the waiter config, so when the
            # waiter encounters this response it will transition
            # to the failure state.
            {'Success': False},
            {'Success': False},
            {'Success': False},
            for_operation=operation_method)
        waiter = Waiter('MyWaiter', config, operation_method)
        with self.assertRaises(WaiterError):
            waiter.wait()

        # We attempt three times, which means we need to sleep
        # twice, once before each subsequent request.
        self.assertEqual(sleep_mock.call_count, 2)
        sleep_mock.assert_called_with(delay_time)
Пример #28
0
    TemplateBody=cfn,
    Capabilities=["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"],
    PermissionModel='SERVICE_MANAGED',
    #AdministrationRoleARN='AWSControlTowerStackSetRole',
    #ExecutionRoleName='AWSControlTowerExecution',
    AutoDeployment={
        'Enabled': True,
        'RetainStacksOnAccountRemoval': False
    })
stack_set_id = response['StackSetId']
print("Stack Set Id is {}".format((stack_set_id)))

organizations_client = boto3.client('organizations')
root_id = organizations_client.list_roots()['Roots'][0]['Id']

waiter = Waiter('StackSetOperationComplete', waiter_config,
                cloudformation_client.describe_stack_set_operation)

ec2_client = boto3.client('ec2')
all_regions = [
    region['RegionName'] for region in ec2_client.describe_regions()['Regions']
]

response = cloudformation_client.create_stack_instances(
    StackSetName=StackSetName,
    DeploymentTargets={'OrganizationalUnitIds': [root_id]},
    Regions=all_regions,
    OperationPreferences={
        'FailureToleranceCount': 1,
        'MaxConcurrentCount': 10
    })