def testPerRequestSetting(self): os.environ['REQUEST_LOG_ID'] = '1' retry_params = api_utils.RetryParams(max_retries=1000) api_utils.set_default_retry_params(retry_params) self.assertEqual(retry_params, api_utils._get_default_retry_params()) os.environ['REQUEST_LOG_ID'] = '2' self.assertEqual(api_utils.RetryParams(), api_utils._get_default_retry_params())
def testValidation(self): self.assertRaises(TypeError, api_utils.RetryParams, 2) self.assertRaises(TypeError, api_utils.RetryParams, urlfetch_timeout='foo') self.assertRaises(TypeError, api_utils.RetryParams, max_retries=1.1) self.assertRaises(ValueError, api_utils.RetryParams, initial_delay=0) self.assertRaises(TypeError, api_utils.RetryParams, save_access_token='') api_utils.RetryParams(backoff_factor=1) api_utils.RetryParams(save_access_token=True)
def testInitialization(self): retry_params = api_utils._get_default_retry_params() self.assertEqual('AppEngine-Python-GCS', retry_params._user_agent) user_agent = 'Test User Agent String' retry_params = api_utils.RetryParams(_user_agent=user_agent) self.assertEqual(user_agent, retry_params._user_agent)
def testPickling(self): retry_params = api_utils.RetryParams(max_retries=1000) api = rest_api._RestApi('scope', service_account_id=1, retry_params=retry_params) self.assertNotEqual(None, api.get_token()) pickled_api = pickle.loads(pickle.dumps(api)) self.assertEqual( 0, len(set(api.__dict__.keys()) ^ set(pickled_api.__dict__.keys()))) for k, v in api.__dict__.iteritems(): if not hasattr(v, '__call__'): self.assertEqual(v, pickled_api.__dict__[k]) pickled_api.token = None fut_urlfetch = ndb.Future() fut_urlfetch.set_result( test_utils.MockUrlFetchResult(200, {'foo': 'bar'}, 'yoohoo')) pickled_api.urlfetch_async = mock.create_autospec( pickled_api.urlfetch_async, return_value=fut_urlfetch) res = pickled_api.do_request('http://example.com') self.assertEqual(res, (200, {'foo': 'bar'}, 'yoohoo'))
def testTooLittleRetry(self): fut = api_utils._RetryWrapper(api_utils.RetryParams(min_retries=0, max_retries=1), retriable_exceptions=(ValueError, )).run( self.tasklet_for_test, results=[ValueError, ValueError]) self.assertRaises(ValueError, fut.get_result)
def __init__(self, gs_path, gs_temp, service_account_key=None): self._gs_path = gs_path.rstrip('/') self._gs_temp = gs_temp.rstrip('/') self._service_account_key = service_account_key self._retry_params = api_utils.RetryParams() cloudstorage.validate_file_path(self._gs_path) cloudstorage.validate_file_path(self._gs_temp)
def testBasicCallWithUserAgent(self): user_agent = 'Test User Agent String' retry_params = api_utils.RetryParams(_user_agent=user_agent) api = rest_api._RestApi('scope', retry_params=retry_params) self.assertEqual(api.scopes, ['scope']) fut_get_token = ndb.Future() fut_get_token.set_result('blah') api.get_token_async = mock.create_autospec(api.get_token_async, return_value=fut_get_token) fut_urlfetch = ndb.Future() fut_urlfetch.set_result( test_utils.MockUrlFetchResult(200, {'foo': 'bar'}, 'yoohoo')) ctx_urlfetch = mock.Mock(return_value=fut_urlfetch) ndb.get_context().urlfetch = ctx_urlfetch res = api.do_request('http://example.com') self.assertEqual(res, (200, {'foo': 'bar'}, 'yoohoo')) ctx_urlfetch.assert_called_once_with( 'http://example.com', headers={'authorization': 'OAuth blah', 'User-Agent': user_agent}, follow_redirects=False, payload=None, method='GET', deadline=None, callback=None)
def testMinRetries(self): start_time = time.time() retry_params = api_utils.RetryParams(min_retries=3, max_retry_period=10, initial_delay=1) with mock.patch('time.time') as t: t.return_value = start_time + 11 self.assertEqual(1, retry_params.delay(1, start_time))
def testRetryReturnedABadResult(self): fut = api_utils._RetryWrapper(api_utils.RetryParams(min_retries=1, max_retries=3), should_retry=lambda r: r < 0).run( self.tasklet_for_test, results=[-1, -1, -1, -1]) r = fut.get_result() self.assertEqual(-1, r)
def testRetryDueToError(self): fut = api_utils._RetryWrapper( api_utils.RetryParams(min_retries=1, max_retries=3), retriable_exceptions=(ValueError, )).run( self.tasklet_for_test, results=[ValueError, ValueError, ValueError, 1]) r = fut.get_result() self.assertEqual(1, r)
def testNoRetryAfterDoRequestUrlFetchTimeout(self): retry_params = api_utils.RetryParams(max_retries=0) api = rest_api._RestApi('scope', retry_params=retry_params) fut = ndb.Future() fut.set_exception(urlfetch.DownloadError()) ndb.Context.urlfetch = mock.create_autospec(ndb.Context.urlfetch, return_value=fut) self.assertRaises(urlfetch.DownloadError, api.do_request, 'foo')
def testNoRetryAfterDoRequestResponseTimeout(self): retry_params = api_utils.RetryParams(max_retries=0) api = rest_api._RestApi('scope', retry_params=retry_params) fut = ndb.Future() fut.set_result( test_utils.MockUrlFetchResult(httplib.REQUEST_TIMEOUT, None, None)) ndb.Context.urlfetch = mock.create_autospec(ndb.Context.urlfetch, return_value=fut) self.assertEqual(httplib.REQUEST_TIMEOUT, api.do_request('foo')[0])
def testPerThreadSetting(self): set_count = [0] cv = threading.Condition() retry_params1 = api_utils.RetryParams(max_retries=1000) retry_params2 = api_utils.RetryParams(max_retries=2000) retry_params3 = api_utils.RetryParams(max_retries=3000) def Target(retry_params): api_utils.set_default_retry_params(retry_params) with cv: set_count[0] += 1 if set_count[0] != 3: cv.wait() cv.notify() self.assertEqual(retry_params, api_utils._get_default_retry_params()) threading.Thread(target=Target, args=(retry_params1, )).start() threading.Thread(target=Target, args=(retry_params2, )).start() threading.Thread(target=Target, args=(retry_params3, )).start()
def testRetryDueToTransientError(self): results = [ urlfetch.DownloadError, apiproxy_errors.Error, app_identity.InternalError, app_identity.BackendDeadlineExceeded, urlfetch_errors.InternalTransientError, 1 ] fut = api_utils._RetryWrapper( api_utils.RetryParams(min_retries=1, max_retries=len(results)), retriable_exceptions=api_utils._RETRIABLE_EXCEPTIONS).run( self.tasklet_for_test, results=results) r = fut.get_result() self.assertEqual(1, r)
def testTokenSaved(self): retry_params = api_utils.RetryParams(save_access_token=True) api = rest_api._RestApi('scope', retry_params=retry_params) t1 = api.get_token() self.assertNotEqual(None, t1) api = rest_api._RestApi('scope', retry_params=retry_params) t2 = api.get_token() self.assertEqual(t2, t1) memcache.flush_all() ndb.get_context().clear_cache() api = rest_api._RestApi('scope', retry_params=retry_params) t3 = api.get_token() self.assertEqual(t3, t1)
def testUrlFetchCalledWithUserProvidedDeadline(self): retry_params = api_utils.RetryParams(urlfetch_timeout=90) api = rest_api._RestApi('scope', retry_params=retry_params) resp_fut1 = ndb.Future() resp_fut1.set_exception(urlfetch.DownloadError()) resp_fut2 = ndb.Future() resp_fut2.set_result( test_utils.MockUrlFetchResult(httplib.ACCEPTED, None, None)) ndb.Context.urlfetch = mock.create_autospec( ndb.Context.urlfetch, side_effect=[resp_fut1, resp_fut2]) self.assertEqual(httplib.ACCEPTED, api.do_request('foo')[0]) self.assertEqual(90, ndb.Context.urlfetch.call_args_list[0][1]['deadline']) self.assertEqual(90, ndb.Context.urlfetch.call_args_list[1][1]['deadline'])
def testDelay(self): start_time = time.time() retry_params = api_utils.RetryParams(backoff_factor=3, initial_delay=1, max_delay=28, max_retries=10, max_retry_period=100) with mock.patch('time.time') as t: t.return_value = start_time + 1 self.assertEqual(1, retry_params.delay(1, start_time)) self.assertEqual(3, retry_params.delay(2, start_time)) self.assertEqual(9, retry_params.delay(3, start_time)) self.assertEqual(27, retry_params.delay(4, start_time)) self.assertEqual(28, retry_params.delay(5, start_time)) self.assertEqual(28, retry_params.delay(6, start_time)) t.return_value = start_time + 101 self.assertEqual(-1, retry_params.delay(7, start_time))
def testRuntimeError(self): fut = api_utils._RetryWrapper( api_utils.RetryParams()).run(test_tasklet4) self.assertRaises(runtime.DeadlineExceededError, fut.get_result)
def testNoRetryDueToErrorType(self): fut = api_utils._RetryWrapper(api_utils.RetryParams(), retriable_exceptions=[TypeError]).run( test_tasklet3, a=1) self.assertRaises(ValueError, fut.get_result)
def testNoRetryDueToRetryParams(self): retry_params = api_utils.RetryParams(min_retries=0, max_retries=0) fut = api_utils._RetryWrapper(retry_params, retriable_exceptions=[ValueError]).run( test_tasklet3, a=1) self.assertRaises(ValueError, fut.get_result)
def setUp(self): super(RetryFetchTest, self).setUp() self.results = [] self.max_retries = 10 self.retry_params = api_utils.RetryParams(backoff_factor=1, max_retries=self.max_retries)
def testNoRetry(self): retry_params = api_utils.RetryParams(max_retries=0) self.assertEqual(None, api_utils._retry_fetch('foo', retry_params))
def testNoDelay(self): start_time = time.time() retry_params = api_utils.RetryParams(max_retries=0, min_retries=5) self.assertEqual(-1, retry_params.delay(1, start_time)) retry_params = api_utils.RetryParams(max_retry_period=1, max_retries=1) self.assertEqual(-1, retry_params.delay(2, start_time - 2))
def testTaskletWasSuccessful(self): fut = api_utils._RetryWrapper(api_utils.RetryParams()).run( test_tasklet1, a=1, b=2) a, b = fut.get_result() self.assertEqual(1, a) self.assertEqual(2, b)