コード例 #1
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()
コード例 #2
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)
コード例 #3
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)
コード例 #4
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)
コード例 #5
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()
コード例 #6
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()
コード例 #7
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)
コード例 #8
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')
コード例 #9
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)
コード例 #10
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()
コード例 #11
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)
コード例 #12
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)
コード例 #13
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.assertRaisesRegex(WaiterError, error_message):
            waiter.wait()
コード例 #14
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)