From 0cdf996e6e2deef451e5d041710e8fe25800e8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Sedl=C3=A1=C5=99?= Date: Fri, 2 Jun 2017 09:46:05 +0200 Subject: [PATCH] util: Retry resolving git branches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When there's a temporary network issue, Pungi will fail to turn a branch into a commit hash. This would abort the whole compose. Instead we should just retry a few times. Signed-off-by: Lubomír Sedlář --- pungi/util.py | 7 ++++++- tests/test_util.py | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pungi/util.py b/pungi/util.py index 25540bdb..7be2cb84 100644 --- a/pungi/util.py +++ b/pungi/util.py @@ -253,7 +253,7 @@ def resolve_git_url(url): scheme = r.scheme.replace('git+', '') baseurl = urlparse.urlunsplit((scheme, r.netloc, r.path, '', '')) - _, output = run(['git', 'ls-remote', baseurl, ref]) + _, output = git_ls_remote(baseurl, ref) lines = [line for line in output.split('\n') if line] if len(lines) == 0: @@ -776,3 +776,8 @@ def retry(timeout=120, interval=30, wait_on=Exception): time.sleep(interval) return inner return wrapper + + +@retry(wait_on=RuntimeError) +def git_ls_remote(baseurl, ref): + return run(['git', 'ls-remote', baseurl, ref]) diff --git a/tests/test_util.py b/tests/test_util.py index 731e525f..cb40ece3 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -92,6 +92,18 @@ class TestGitRefResolver(unittest.TestCase): ['git', 'ls-remote', 'https://git.example.com/repo.git', 'refs/heads/my-branch']) self.assertIn('ref does not exist in remote repo', str(ctx.exception)) + @mock.patch('time.sleep') + @mock.patch('pungi.util.run') + def test_retry(self, run, sleep): + run.side_effect = [RuntimeError('Boom'), (0, 'CAFEBABE\tHEAD\n')] + + url = util.resolve_git_url('https://git.example.com/repo.git?somedir#HEAD') + + self.assertEqual(url, 'https://git.example.com/repo.git?somedir#CAFEBABE') + self.assertEqual(sleep.call_args_list, [mock.call(30)]) + self.assertEqual(run.call_args_list, + [mock.call(['git', 'ls-remote', 'https://git.example.com/repo.git', 'HEAD'])] * 2) + class TestGetVariantData(unittest.TestCase): def test_get_simple(self):