def post_data(self, data): headers = {'Content-Length': len(data)} headers.update(self.request_headers) http_client = AsyncHTTPClient() retry_client = RetryClient( http_client=http_client, retry_attempts=3, retry_start_timeout=0.5, retry_max_timeout=10, retry_factor=2, ) try: response = yield retry_client.fetch(self.endpoint_url, method='POST', headers=headers, body=data, raise_error=False) finally: http_client.close() if 500 <= response.code < 600: raise ValueError(response.code + ': ' + response.body) if response.code < 200 or response.code >= 300: raise ValueError( 'Error sending report to Engine servers (HTTP status {}): {}'. format(response.code, response.body)) if self.options.debug_print_reports: LOGGER.info('Engine report: status ' + response.code)
class TestRetryClient(AsyncHTTPTestCase): def setUp(self): super(TestRetryClient, self).setUp() self.retry_client = RetryClient(self.http_client, max_retries=5, retry_start_timeout=0) def get_app(self): return app.make_app() def test_with_default_http_client(self): self.assertEqual(RetryClient().http_client, AsyncHTTPClient()) @gen_test def test_socket_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1)) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/timeout')) self.assertEqual(cm.exception.args[0], 599) self.assertEqual(cm.exception.args[1], 'Timeout') self.assertEqual(fetch_mock.call_count, 5) @gen_test def test_http_success(self): response = yield self.retry_client.fetch(self.get_url('/')) self.assertEqual(response.code, 200) @gen_test def test_http_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1)) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error_no_retry')) self.assertEqual(cm.exception.code, 422) self.assertEqual(fetch_mock.call_count, 1) @gen_test def test_http_error_with_retry2(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1)) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error')) self.assertEqual(cm.exception.code, 500) self.assertEqual(fetch_mock.call_count, 5)
class TestRetryClient(AsyncHTTPTestCase): def setUp(self): super(TestRetryClient, self).setUp() self.logger = MagicMock() self.retry_client = RetryClient( self.http_client, max_retries=5, retry_start_timeout=0, logger=self.logger, retry_for_statuses=(408, ), ) def get_app(self): return app.make_app() def test_with_default_http_client(self): self.assertEqual(RetryClient().http_client, AsyncHTTPClient()) @gen_test def test_socket_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1)) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/timeout')) self.assertEqual(cm.exception.args[0], 599) self.assertEqual(cm.exception.args[1], 'Timeout during request') self.assertEqual(fetch_mock.call_count, 5) self.assertTrue(self.logger.warning.called) self.assertEqual(self.logger.warning.call_args[0][0], 'attempt: %d, %s request failed: %s, body: %s') @gen_test def test_http_success(self): response = yield self.retry_client.fetch(self.get_url('/')) self.assertEqual(response.code, 200) self.assertFalse(self.logger.warning.called) @gen_test def test_http_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1)) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error_no_retry')) self.assertEqual(cm.exception.code, 422) self.assertEqual(fetch_mock.call_count, 1) @gen_test def test_http_error_with_retry_with_custom_code(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1)) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/custom_retry')) self.assertEqual(cm.exception.code, 408) self.assertEqual(fetch_mock.call_count, 5) @gen_test def test_http_error_with_retry2(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1)) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error')) self.assertEqual(cm.exception.code, 500) self.assertEqual(fetch_mock.call_count, 5) self.assertTrue(self.logger.warning.called) @gen_test def test_custom_http_client_error(self): class TokenError(Exception): pass class MyHttpClient(object): def __init__(self): self.count = 0 def fetch(self, *args, **kwargs): future = tornado.gen.Future() future.set_exception(TokenError('my token error')) self.count += 1 return future http_client = MyHttpClient() self.retry_client.http_client = http_client self.retry_client.retry_exceptions = (TokenError, ) with self.assertRaises(TokenError): yield self.retry_client.fetch(self.get_url('/'), retry_wait=.1, retry_exceptions=(TokenError, )) self.assertEqual(http_client.count, 5) self.assertTrue(self.logger.warning.called)
class TestRetryClient(AsyncHTTPTestCase): def setUp(self): super(TestRetryClient, self).setUp() self.retry_client = RetryClient( self.http_client, max_retries=5, retry_start_timeout=0 ) def get_app(self): return app.make_app() def test_with_default_http_client(self): self.assertEqual( RetryClient().http_client, AsyncHTTPClient() ) @gen_test def test_socket_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1) ) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch ) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/timeout')) self.assertEqual(cm.exception.args[0], 599) self.assertEqual(cm.exception.args[1], 'Timeout') self.assertEqual(fetch_mock.call_count, 5) @gen_test def test_http_success(self): response = yield self.retry_client.fetch(self.get_url('/')) self.assertEqual(response.code, 200) @gen_test def test_http_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1) ) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch ) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error_no_retry')) self.assertEqual(cm.exception.code, 422) self.assertEqual(fetch_mock.call_count, 1) @gen_test def test_http_error_with_retry2(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1) ) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch ) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error')) self.assertEqual(cm.exception.code, 500) self.assertEqual(fetch_mock.call_count, 5)
class TestRetryClient(AsyncHTTPTestCase): def setUp(self): super(TestRetryClient, self).setUp() self.retry_client = RetryClient( self.http_client, max_retries=5, retry_start_timeout=0 ) def get_app(self): return app.make_app() def test_with_default_http_client(self): self.assertEqual( RetryClient().http_client, AsyncHTTPClient() ) @gen_test def test_socket_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1) ) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch ) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/timeout')) self.assertEqual(cm.exception.args[0], 599) self.assertEqual(cm.exception.args[1], 'Timeout') self.assertEqual(fetch_mock.call_count, 5) @gen_test def test_http_success(self): response = yield self.retry_client.fetch(self.get_url('/')) self.assertEqual(response.code, 200) @gen_test def test_http_error_with_retry(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1) ) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch ) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error_no_retry')) self.assertEqual(cm.exception.code, 422) self.assertEqual(fetch_mock.call_count, 1) @gen_test def test_http_error_with_retry2(self): self.retry_client.http_client = tornado.httpclient.AsyncHTTPClient( force_instance=True, defaults=dict(request_timeout=.1) ) with patch.object( self.retry_client.http_client, 'fetch', wraps=self.retry_client.http_client.fetch ) as fetch_mock: with self.assertRaises(tornado.httpclient.HTTPError) as cm: yield self.retry_client.fetch(self.get_url('/error')) self.assertEqual(cm.exception.code, 500) self.assertEqual(fetch_mock.call_count, 5) @gen_test def test_custom_http_client_error(self): class TokenError(Exception): pass class MyHttpClient(object): def __init__(self): self.count = 0 def fetch(self, *args, **kwargs): future = tornado.gen.Future() future.set_exception(TokenError('my token error')) self.count += 1 return future http_client = MyHttpClient() self.retry_client.http_client = http_client self.retry_client.retry_exceptions = (TokenError,) with self.assertRaises(TokenError): yield self.retry_client.fetch( self.get_url('/'), retry_wait=.1, retry_exceptions=(TokenError,) ) self.assertEqual(http_client.count, 5)