Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Unified Diff: recipe_engine/unittests/fetch_test.py

Issue 2362993002: More strategic retries in fetch. (Closed)
Patch Set: More strategic retries in fetch. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « recipe_engine/fetch.py ('k') | recipe_engine/util.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: recipe_engine/unittests/fetch_test.py
diff --git a/recipe_engine/unittests/fetch_test.py b/recipe_engine/unittests/fetch_test.py
index 9b8c38fe73ada09143e32094d438fd6166721b32..b3c7260d9ea92a8bef0b77f73e76d89388f592ef 100755
--- a/recipe_engine/unittests/fetch_test.py
+++ b/recipe_engine/unittests/fetch_test.py
@@ -9,6 +9,7 @@ import json
import os
import sys
import unittest
+import time
import test_env
@@ -158,9 +159,9 @@ project_id: "foo"
recipes_path: "path/to/recipes"
""".lstrip()
requests_get.side_effect = [
- mock.Mock(text=u')]}\'\n{ "commit": "abc123" }'),
- mock.Mock(text=base64.b64encode(proto_text)),
- mock.Mock(content=''),
+ mock.Mock(text=u')]}\'\n{ "commit": "abc123" }', status_code=200),
+ mock.Mock(text=base64.b64encode(proto_text), status_code=200),
+ mock.Mock(content='', status_code=200),
]
fetch.GitilesBackend().checkout(
@@ -217,9 +218,9 @@ recipes_path: "path/to/recipes"
],
}
requests_get.side_effect = [
- mock.Mock(text=u')]}\'\n{ "commit": "sha_a" }'),
- mock.Mock(text=u')]}\'\n{ "commit": "sha_b" }'),
- mock.Mock(text=u')]}\'\n%s' % json.dumps(log_json)),
+ mock.Mock(text=u')]}\'\n{ "commit": "sha_a" }', status_code=200),
+ mock.Mock(text=u')]}\'\n{ "commit": "sha_b" }', status_code=200),
+ mock.Mock(text=u')]}\'\n%s' % json.dumps(log_json), status_code=200),
]
self.assertEqual(
@@ -241,7 +242,8 @@ recipes_path: "path/to/recipes"
'message': 'message',
}
requests_get.side_effect = [
- mock.Mock(text=u')]}\'\n%s' % json.dumps(revision_json)),
+ mock.Mock(text=u')]}\'\n%s' % json.dumps(revision_json),
+ status_code=200),
]
result = fetch.GitilesBackend().commit_metadata(
'repo', 'revision', 'dir', allow_fetch=True)
@@ -253,6 +255,56 @@ recipes_path: "path/to/recipes"
mock.call('repo/+/revision?format=JSON'),
])
+ @mock.patch('requests.get')
+ def test_non_transient_error(self, requests_get):
+ requests_get.side_effect = [
+ mock.Mock(text='Not permitted.', status_code=403),
+ ]
+ with self.assertRaises(fetch.GitilesFetchError):
+ fetch.GitilesBackend().commit_metadata(
+ 'repo', 'revision', 'dir', allow_fetch=True)
+ requests_get.assert_has_calls([
+ mock.call('repo/+/revision?format=JSON'),
+ ])
+
+ @mock.patch('requests.get')
+ @mock.patch('time.sleep')
+ @mock.patch('logging.exception')
+ def test_transient_retry(self, logging_exception, time_sleep, requests_get):
+ counts = {
+ 'sleeps': 0,
+ 'fails': 0,
+ }
+
+ def count_sleep(delay):
+ counts['sleeps'] += 1
+ time_sleep.side_effect = count_sleep
+
+ revision_json = {
+ 'author': {'email': 'author'},
+ 'message': 'message',
+ }
+
+ # Fail transiently 4 times, but succeed on the 5th.
+ def transient_side_effect(*args, **kwargs):
+ if counts['fails'] < 4:
+ counts['fails'] += 1
+ return mock.Mock(text=u'Not permitted (%(fails)d).' % counts,
+ status_code=500)
+ return mock.Mock(text=u')]}\'\n%s' % json.dumps(revision_json),
+ status_code=200)
+ requests_get.side_effect = transient_side_effect
+
+ result = fetch.GitilesBackend().commit_metadata(
+ 'repo', 'revision', 'dir', allow_fetch=True)
+ self.assertEqual(result, {
+ 'author': 'author',
+ 'message': 'message',
+ })
+ self.assertEqual(counts['sleeps'], 4)
+ requests_get.assert_has_calls([
+ mock.call('repo/+/revision?format=JSON'),
+ ] * 5)
if __name__ == '__main__':
unittest.main()
« no previous file with comments | « recipe_engine/fetch.py ('k') | recipe_engine/util.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698