def test_settings_merge_options1(self):
     options = CallOptions(timeout=46)
     settings = CallSettings(timeout=9, page_descriptor=None, retry=None)
     final = settings.merge(options)
     self.assertEqual(final.timeout, 46)
     self.assertIsNone(final.retry)
     self.assertIsNone(final.page_descriptor)
 def test_settings_merge_options1(self):
     options = CallOptions(timeout=46)
     settings = CallSettings(timeout=9, page_descriptor=None, retry=None)
     final = settings.merge(options)
     self.assertEqual(final.timeout, 46)
     self.assertIsNone(final.retry)
     self.assertIsNone(final.page_descriptor)
Beispiel #3
0
 def test_settings_merge_options_page_streaming(self):
     retry = RetryOptions(None, None)
     options = CallOptions(timeout=46, is_page_streaming=False)
     settings = CallSettings(timeout=9, retry=retry)
     final = settings.merge(options)
     self.assertEqual(final.timeout, 46)
     self.assertIsNone(final.page_descriptor)
     self.assertEqual(final.retry, retry)
 def test_settings_merge_options2(self):
     retry = RetryOptions(None, None)
     options = CallOptions(retry=retry)
     settings = CallSettings(
         timeout=9, page_descriptor=None, retry=RetryOptions(None, None))
     final = settings.merge(options)
     self.assertEqual(final.timeout, 9)
     self.assertIsNone(final.page_descriptor)
     self.assertEqual(final.retry, retry)
Beispiel #5
0
 def test_settings_merge_none(self):
     settings = CallSettings(
         timeout=23, page_descriptor=object(), bundler=object(),
         retry=object())
     final = settings.merge(None)
     self.assertEqual(final.timeout, settings.timeout)
     self.assertEqual(final.retry, settings.retry)
     self.assertEqual(final.page_descriptor, settings.page_descriptor)
     self.assertEqual(final.bundler, settings.bundler)
     self.assertEqual(final.bundle_descriptor, settings.bundle_descriptor)
 def test_settings_merge_options2(self):
     retry = RetryOptions(None, None)
     options = CallOptions(retry=retry)
     settings = CallSettings(timeout=9,
                             page_descriptor=None,
                             retry=RetryOptions(None, None))
     final = settings.merge(options)
     self.assertEqual(final.timeout, 9)
     self.assertIsNone(final.page_descriptor)
     self.assertEqual(final.retry, retry)
 def test_settings_merge_none(self):
     settings = CallSettings(
         timeout=23, page_descriptor=object(), bundler=object(),
         retry=object())
     final = settings.merge(None)
     self.assertEqual(final.timeout, settings.timeout)
     self.assertEqual(final.retry, settings.retry)
     self.assertEqual(final.page_descriptor, settings.page_descriptor)
     self.assertEqual(final.bundler, settings.bundler)
     self.assertEqual(final.bundle_descriptor, settings.bundle_descriptor)
 def test_settings_merge_options_page_streaming(self):
     retry = RetryOptions(None, None)
     page_descriptor = object()
     options = CallOptions(timeout=46, page_token=INITIAL_PAGE)
     settings = CallSettings(timeout=9, retry=retry,
                             page_descriptor=page_descriptor)
     final = settings.merge(options)
     self.assertEqual(final.timeout, 46)
     self.assertEqual(final.page_descriptor, page_descriptor)
     self.assertEqual(final.page_token, INITIAL_PAGE)
     self.assertFalse(final.flatten_pages)
     self.assertEqual(final.retry, retry)
 def test_settings_merge_options_page_streaming(self):
     retry = RetryOptions(None, None)
     page_descriptor = object()
     options = CallOptions(timeout=46, page_token=INITIAL_PAGE)
     settings = CallSettings(timeout=9,
                             retry=retry,
                             page_descriptor=page_descriptor)
     final = settings.merge(options)
     self.assertEqual(final.timeout, 46)
     self.assertEqual(final.page_descriptor, page_descriptor)
     self.assertEqual(final.page_token, INITIAL_PAGE)
     self.assertFalse(final.flatten_pages)
     self.assertEqual(final.retry, retry)
Beispiel #10
0
    def test_catch_error(self):
        def abortion_error_func(*dummy_args, **dummy_kwargs):
            raise CustomException(None, None)

        def other_error_func(*dummy_args, **dummy_kwargs):
            raise AnotherException

        gax_error_callable = api_callable.create_api_call(
            abortion_error_func, CallSettings())
        self.assertRaises(GaxError, gax_error_callable, None)

        other_error_callable = api_callable.create_api_call(
            other_error_func, CallSettings())
        self.assertRaises(AnotherException, other_error_callable, None)
 def test_call_kwargs(self):
     settings = CallSettings(kwargs={'key': 'value'})
     my_callable = api_callable.create_api_call(
         lambda _req, _timeout, **kwargs: kwargs['key'], settings)
     self.assertEqual(my_callable(None), 'value')
     self.assertEqual(my_callable(None, CallOptions(key='updated')),
                      'updated')
    def test_retry_times_out_no_response(self, mock_time):
        mock_time.return_value = 1
        retry = RetryOptions([_FAKE_STATUS_CODE_1],
                             BackoffSettings(0, 0, 0, 0, 0, 0, 0))
        settings = CallSettings(timeout=0, retry=retry)
        my_callable = api_callable.create_api_call(lambda: None, settings)

        self.assertRaises(RetryError, my_callable, None)
Beispiel #13
0
    def test_no_retry_if_no_codes(self, mock_time):
        retry = RetryOptions([], BackoffSettings(1, 2, 3, 4, 5, 6, 7))

        mock_call = mock.Mock()
        mock_call.side_effect = CustomException('', _FAKE_STATUS_CODE_1)
        mock_time.return_value = 0

        settings = CallSettings(timeout=0, retry=retry)
        my_callable = api_callable.create_api_call(mock_call, settings)
        self.assertRaises(CustomException, my_callable, None)
        self.assertEqual(mock_call.call_count, 1)
 def test_retry_aborts_on_unexpected_exception(self, mock_exc_to_code,
                                               mock_time):
     mock_exc_to_code.side_effect = lambda e: e.code
     retry = RetryOptions([_FAKE_STATUS_CODE_1],
                          BackoffSettings(0, 0, 0, 0, 0, 0, 1))
     mock_call = mock.Mock()
     mock_call.side_effect = CustomException('', _FAKE_STATUS_CODE_2)
     mock_time.return_value = 0
     settings = CallSettings(timeout=0, retry=retry)
     my_callable = api_callable.create_api_call(mock_call, settings)
     self.assertRaises(Exception, my_callable, None)
     self.assertEqual(mock_call.call_count, 1)
    def test_retry_aborts_simple(self, mock_exc_to_code, mock_time):
        def fake_call(dummy_request, dummy_timeout):
            raise CustomException('', _FAKE_STATUS_CODE_1)

        retry = RetryOptions([_FAKE_STATUS_CODE_1],
                             BackoffSettings(0, 0, 0, 0, 0, 0, 1))
        mock_time.side_effect = [0, 2]
        mock_exc_to_code.side_effect = lambda e: e.code
        settings = CallSettings(timeout=0, retry=retry)
        my_callable = api_callable.create_api_call(fake_call, settings)

        try:
            my_callable(None)
        except RetryError as exc:
            self.assertIsInstance(exc.cause, CustomException)
    def test_retry(self, mock_exc_to_code, mock_time):
        mock_exc_to_code.side_effect = lambda e: e.code
        to_attempt = 3
        retry = RetryOptions([_FAKE_STATUS_CODE_1],
                             BackoffSettings(0, 0, 0, 0, 0, 0, 1))

        # Succeeds on the to_attempt'th call, and never again afterward
        mock_call = mock.Mock()
        mock_call.side_effect = ([CustomException('', _FAKE_STATUS_CODE_1)] *
                                 (to_attempt - 1) + [mock.DEFAULT])
        mock_call.return_value = 1729
        mock_time.return_value = 0
        settings = CallSettings(timeout=0, retry=retry)
        my_callable = api_callable.create_api_call(mock_call, settings)
        self.assertEqual(my_callable(None), 1729)
        self.assertEqual(mock_call.call_count, to_attempt)
    def test_retry_times_out_simple(self, mock_exc_to_code, mock_time):
        mock_exc_to_code.side_effect = lambda e: e.code
        to_attempt = 3
        retry = RetryOptions([_FAKE_STATUS_CODE_1],
                             BackoffSettings(0, 0, 0, 0, 0, 0, 1))
        mock_call = mock.Mock()
        mock_call.side_effect = CustomException('', _FAKE_STATUS_CODE_1)
        mock_time.side_effect = ([0] * to_attempt + [2])
        settings = CallSettings(timeout=0, retry=retry)
        my_callable = api_callable.create_api_call(mock_call, settings)

        try:
            my_callable(None)
        except RetryError as exc:
            self.assertIsInstance(exc.cause, CustomException)

        self.assertEqual(mock_call.call_count, to_attempt)
Beispiel #18
0
    def test_page_streaming(self):
        # A mock grpc function that page streams a list of consecutive
        # integers, returning `page_size` integers with each call and using
        # the next integer to return as the page token, until `pages_to_stream`
        # pages have been returned.
        page_size = 3
        pages_to_stream = 5

        # pylint: disable=abstract-method, too-few-public-methods
        class PageStreamingRequest(object):
            def __init__(self, page_token=0):
                self.page_token = page_token

        class PageStreamingResponse(object):
            def __init__(self, nums=(), next_page_token=0):
                self.nums = nums
                self.next_page_token = next_page_token

        fake_grpc_func_descriptor = PageDescriptor(
            'page_token', 'next_page_token', 'nums')

        def grpc_return_value(request, *dummy_args, **dummy_kwargs):
            if (request.page_token > 0 and
                    request.page_token < page_size * pages_to_stream):
                return PageStreamingResponse(
                    nums=iter(range(request.page_token,
                                    request.page_token + page_size)),
                    next_page_token=request.page_token + page_size)
            elif request.page_token >= page_size * pages_to_stream:
                return PageStreamingResponse()
            else:
                return PageStreamingResponse(nums=iter(range(page_size)),
                                             next_page_token=page_size)

        with mock.patch('grpc.framework.crust.implementations.'
                        '_UnaryUnaryMultiCallable') as mock_grpc:
            mock_grpc.side_effect = grpc_return_value
            settings = CallSettings(
                page_descriptor=fake_grpc_func_descriptor, timeout=0)
            my_callable = api_callable.create_api_call(mock_grpc, settings=settings)
            self.assertEqual(list(my_callable(PageStreamingRequest())),
                             list(range(page_size * pages_to_stream)))
Beispiel #19
0
    def test_bundling(self):
        # pylint: disable=abstract-method, too-few-public-methods
        class BundlingRequest(object):
            def __init__(self, elements=None):
                self.elements = elements

        fake_grpc_func_descriptor = BundleDescriptor('elements', [])
        bundler = bundling.Executor(BundleOptions(element_count_threshold=8))

        def my_func(request, dummy_timeout):
            return len(request.elements)

        settings = CallSettings(
            bundler=bundler, bundle_descriptor=fake_grpc_func_descriptor,
            timeout=0)
        my_callable = api_callable.create_api_call(my_func, settings)
        first = my_callable(BundlingRequest([0] * 3))
        self.assertIsInstance(first, bundling.Event)
        self.assertIsNone(first.result)  # pylint: disable=no-member
        second = my_callable(BundlingRequest([0] * 5))
        self.assertEquals(second.result, 8)  # pylint: disable=no-member
Beispiel #20
0
    def test_retry_exponential_backoff(self, mock_exc_to_code, mock_time,
                                       mock_sleep):
        # pylint: disable=too-many-locals
        mock_exc_to_code.side_effect = lambda e: e.code
        MILLIS_PER_SEC = 1000
        mock_time.return_value = 0

        def incr_time(secs):
            mock_time.return_value += secs

        def api_call(dummy_request, timeout, **dummy_kwargs):
            incr_time(timeout)
            raise CustomException(str(timeout), _FAKE_STATUS_CODE_1)

        mock_call = mock.Mock()
        mock_sleep.side_effect = incr_time
        mock_call.side_effect = api_call

        params = BackoffSettings(3, 2, 24, 5, 2, 80, 2500)
        retry = RetryOptions([_FAKE_STATUS_CODE_1], params)
        settings = CallSettings(timeout=0, retry=retry)
        my_callable = api_callable.create_api_call(mock_call, settings)

        try:
            my_callable(None)
        except RetryError as exc:
            self.assertIsInstance(exc.cause, CustomException)

        self.assertGreaterEqual(mock_time(),
                                params.total_timeout_millis / MILLIS_PER_SEC)

        # Very rough bounds
        calls_lower_bound = params.total_timeout_millis / (
            params.max_retry_delay_millis + params.max_rpc_timeout_millis)
        self.assertGreater(mock_call.call_count, calls_lower_bound)

        calls_upper_bound = (params.total_timeout_millis /
                             params.initial_retry_delay_millis)
        self.assertLess(mock_call.call_count, calls_upper_bound)
 def test_call_override(self):
     settings = CallSettings(timeout=10)
     my_callable = api_callable.create_api_call(
         lambda _req, timeout: timeout, settings)
     self.assertEqual(my_callable(None, CallOptions(timeout=20)), 20)
Beispiel #22
0
 def test_call_api_call(self):
     settings = CallSettings()
     my_callable = api_callable.create_api_call(
         lambda _req, _timeout: 42, settings)
     self.assertEqual(my_callable(None), 42)
    def test_page_streaming(self):
        # A mock grpc function that page streams a list of consecutive
        # integers, returning `page_size` integers with each call and using
        # the next integer to return as the page token, until `pages_to_stream`
        # pages have been returned.
        # pylint:disable=too-many-locals
        page_size = 3
        pages_to_stream = 5

        # pylint: disable=abstract-method, too-few-public-methods
        class PageStreamingRequest(object):
            def __init__(self, page_token=0):
                self.page_token = page_token

        class PageStreamingResponse(object):
            def __init__(self, nums=(), next_page_token=0):
                self.nums = nums
                self.next_page_token = next_page_token

        fake_grpc_func_descriptor = PageDescriptor('page_token',
                                                   'next_page_token', 'nums')

        def grpc_return_value(request, *dummy_args, **dummy_kwargs):
            start = int(request.page_token)
            if start > 0 and start < page_size * pages_to_stream:
                return PageStreamingResponse(nums=list(
                    range(start, start + page_size)),
                                             next_page_token=start + page_size)
            elif start >= page_size * pages_to_stream:
                return PageStreamingResponse()
            else:
                return PageStreamingResponse(nums=list(range(page_size)),
                                             next_page_token=page_size)

        with mock.patch('grpc.UnaryUnaryMultiCallable') as mock_grpc:
            mock_grpc.side_effect = grpc_return_value
            settings = CallSettings(page_descriptor=fake_grpc_func_descriptor,
                                    timeout=0)
            my_callable = api_callable.create_api_call(mock_grpc,
                                                       settings=settings)
            self.assertEqual(list(my_callable(PageStreamingRequest())),
                             list(range(page_size * pages_to_stream)))

            unflattened_option = CallOptions(page_token=INITIAL_PAGE)
            # Expect a list of pages_to_stream pages, each of size page_size,
            # plus one empty page
            expected = [
                list(range(page_size * n, page_size * (n + 1)))
                for n in range(pages_to_stream)
            ] + [()]
            self.assertEqual(
                list(my_callable(PageStreamingRequest(), unflattened_option)),
                expected)

            pages_already_read = 2
            explicit_page_token_option = CallOptions(
                page_token=str(page_size * pages_already_read))
            # Expect a list of pages_to_stream pages, each of size page_size,
            # plus one empty page, minus the pages_already_read
            expected = [
                list(range(page_size * n, page_size * (n + 1)))
                for n in range(pages_already_read, pages_to_stream)
            ]
            expected += [()]
            self.assertEqual(
                list(
                    my_callable(PageStreamingRequest(),
                                explicit_page_token_option)), expected)
Beispiel #24
0
 def test_bundling_page_streaming_error(self):
     settings = CallSettings(
         page_descriptor=object(), bundle_descriptor=object(),
         bundler=object())
     with self.assertRaises(ValueError):
         api_callable.create_api_call(lambda _req, _timeout: 42, settings)