Page MenuHomeSoftware Heritage

D7878.id28430.diff
No OneTemporary

D7878.id28430.diff

diff --git a/swh/loader/svn/svn.py b/swh/loader/svn/svn.py
--- a/swh/loader/svn/svn.py
+++ b/swh/loader/svn/svn.py
@@ -212,6 +212,19 @@
):
yield self.__to_entry(log_entry)
+ @svn_retry()
+ def commit_info(self, revision: int) -> Dict:
+ """Return commit information.
+
+ Args:
+ revision: svn revision to return commit info
+
+ Returns:
+ A dictionary filled with commit info, see :meth:`swh.loader.svn.svn.logs`
+ for details about its content.
+ """
+ return list(self.logs(revision, revision))[0]
+
@svn_retry()
def remote_access(self, auth: Auth) -> RemoteAccess:
"""Simple wrapper around subvertpy.ra.RemoteAccess creation
@@ -519,7 +532,7 @@
)
# Retrieve the commit information for revision
- commit = list(self.logs(revision, revision))[0]
+ commit = self.commit_info(revision)
# Clean export directory
self.clean_fs(local_dirname)
diff --git a/swh/loader/svn/tests/conftest.py b/swh/loader/svn/tests/conftest.py
--- a/swh/loader/svn/tests/conftest.py
+++ b/swh/loader/svn/tests/conftest.py
@@ -56,3 +56,4 @@
mocker.patch.object(SvnRepo.propget.retry, "sleep")
mocker.patch.object(SvnRepo.remote_access.retry, "sleep")
mocker.patch.object(SvnRepo.info.retry, "sleep")
+ mocker.patch.object(SvnRepo.commit_info.retry, "sleep")
diff --git a/swh/loader/svn/tests/test_svn_retry.py b/swh/loader/svn/tests/test_svn_retry.py
--- a/swh/loader/svn/tests/test_svn_retry.py
+++ b/swh/loader/svn/tests/test_svn_retry.py
@@ -62,6 +62,30 @@
return self._wrapped_svn_cmd(self.client.info, *args, **kwargs)
+class SVNRemoteAccessWrapper:
+ """Methods of subvertpy.ra.RemoteAccess cannot be patched by mocker fixture
+ as they are read only attributes due to subvertpy._ra module being
+ a C extension module. So we use that wrapper class instead to simulate
+ mocking behavior.
+ """
+
+ def __init__(self, svn_ra, exception, nb_failed_calls):
+ self.svn_ra = svn_ra
+ self.exception = exception
+ self.nb_failed_calls = nb_failed_calls
+ self.nb_calls = 0
+
+ def _wrapped_svn_ra_cmd(self, svn_ra_cmd, *args, **kwargs):
+ self.nb_calls = self.nb_calls + 1
+ if self.nb_calls <= self.nb_failed_calls:
+ raise self.exception
+ else:
+ return svn_ra_cmd(*args, **kwargs)
+
+ def iter_log(self, *args, **kwargs):
+ return self._wrapped_svn_ra_cmd(self.svn_ra.iter_log, *args, **kwargs)
+
+
def assert_sleep_calls(mock_sleep, mocker, nb_failures):
mock_sleep.assert_has_calls(
[
@@ -334,3 +358,45 @@
svnrepo.info(sample_repo_url)
assert_sleep_calls(mock_sleep, mocker, nb_failed_calls - 1)
+
+
+@pytest.mark.parametrize("exception_to_retry", RETRYABLE_EXCEPTIONS)
+def test_svn_commit_info_retry_success(
+ mocker, tmp_path, sample_repo_url, exception_to_retry
+):
+ svnrepo = SvnRepo(
+ sample_repo_url, sample_repo_url, tmp_path, max_content_length=100000
+ )
+
+ mock_sleep = mocker.patch.object(svnrepo.commit_info.retry, "sleep")
+
+ nb_failed_calls = 2
+ svnrepo.conn_log = SVNRemoteAccessWrapper(
+ svnrepo.conn_log, exception_to_retry, nb_failed_calls
+ )
+
+ commit = svnrepo.commit_info(revision=1)
+ assert commit
+
+ assert_sleep_calls(mock_sleep, mocker, nb_failed_calls)
+
+
+@pytest.mark.parametrize("exception_to_retry", RETRYABLE_EXCEPTIONS)
+def test_svn_commit_info_retry_failure(
+ mocker, tmp_path, sample_repo_url, exception_to_retry
+):
+ svnrepo = SvnRepo(
+ sample_repo_url, sample_repo_url, tmp_path, max_content_length=100000
+ )
+
+ mock_sleep = mocker.patch.object(svnrepo.commit_info.retry, "sleep")
+
+ nb_failed_calls = SVN_RETRY_MAX_ATTEMPTS
+ svnrepo.conn_log = SVNRemoteAccessWrapper(
+ svnrepo.conn_log, exception_to_retry, nb_failed_calls
+ )
+
+ with pytest.raises(type(exception_to_retry)):
+ svnrepo.commit_info(sample_repo_url)
+
+ assert_sleep_calls(mock_sleep, mocker, nb_failed_calls - 1)

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 2, 12:00 PM (4 d, 8 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3227723

Event Timeline