diff --git a/swh/loader/svn/loader.py b/swh/loader/svn/loader.py --- a/swh/loader/svn/loader.py +++ b/swh/loader/svn/loader.py @@ -46,9 +46,9 @@ ) DEFAULT_BRANCH = b"HEAD" - - TEMPORARY_DIR_PREFIX_PATTERN = "swh.loader.svn." +SUBVERSION_ERROR = re.compile(r".*(E[0-9]{6}):.*") +SUBVERSION_NOT_FOUND = "E170013" class SvnLoader(BaseLoader): @@ -659,6 +659,9 @@ If the svnrdump command failed somehow, the produced dump file is analyzed to determine if a partial loading is still feasible. + + Raises: + NotFound when the repository is no longer found at url """ # Build the svnrdump command line svnrdump_cmd = ["svnrdump", "dump", svn_url] @@ -676,11 +679,17 @@ os.close(stderr_w) stderr_stream = OutputStream(stderr_r) readable = True + error_codes: List[str] = [] + error_messages: List[str] = [] while readable: lines, readable = stderr_stream.read_lines() stderr_lines += lines for line in lines: self.log.debug(line) + match = SUBVERSION_ERROR.search(line) + if match: + error_codes.append(match.group(1)) + error_messages.append(lines) svnrdump.wait() os.close(stderr_r) @@ -741,9 +750,14 @@ % (last_dumped_rev, last_loaded_svn_rev) ) + if SUBVERSION_NOT_FOUND in error_codes: + raise NotFound( + f"{SUBVERSION_NOT_FOUND}: Repository never existed or disappeared" + ) + raise Exception( "An error occurred when running svnrdump and " - "no exploitable dump file has been generated." + "no exploitable dump file has been generated.\n" + "\n".join(error_messages) ) def prepare(self): diff --git a/swh/loader/svn/tests/test_loader.py b/swh/loader/svn/tests/test_loader.py --- a/swh/loader/svn/tests/test_loader.py +++ b/swh/loader/svn/tests/test_loader.py @@ -41,13 +41,13 @@ def test_loader_svn_not_found_no_mock(swh_storage, tmp_path): """Given an unknown repository, the loader visit ends up in status not_found""" - unknown_repo_url = "unknown-repository" - loader = SvnLoader(swh_storage, unknown_repo_url, destination_path=tmp_path) + repo_url = "unknown-repository" + loader = SvnLoader(swh_storage, repo_url, destination_path=tmp_path) assert loader.load() == {"status": "uneventful"} assert_last_visit_matches( - swh_storage, unknown_repo_url, status="not_found", type="svn", + swh_storage, repo_url, status="not_found", type="svn", ) @@ -92,6 +92,21 @@ ) +def test_loader_svnrdump_not_found(swh_storage, tmp_path, mocker): + """Loading from remote dump which does not exist should end up as not_found visit""" + unknown_repo_url = "file:///tmp/svn.code.sf.net/p/white-rats-studios/svn" + + loader = SvnLoaderFromRemoteDump( + swh_storage, unknown_repo_url, destination_path=tmp_path + ) + + assert loader.load() == {"status": "uneventful"} + + assert_last_visit_matches( + swh_storage, unknown_repo_url, status="not_found", type="svn", + ) + + def test_loader_svn_new_visit(swh_storage, datadir, tmp_path): """Eventful visit should yield 1 snapshot""" archive_name = "pkg-gourmet"