Revert "Do not filter out refs removals when filtering pull-replication fetches" This reverts commit 05960652371637b0e33ddae4005b1149bed5667a. Reason for revert: Created the regression Issue 515801262. Bug: Issue 515801262 Change-Id: I15b8587d2cb93bd378b5b0d62fd516acb3210d52
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java index 8423d2e..6f90b6c 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java +++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Sets; import com.google.common.flogger.FluentLogger; import com.google.gerrit.entities.Project; +import com.google.gerrit.entities.Project.NameKey; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -69,6 +70,7 @@ gitRepositoryManager.openRepository(Project.nameKey(projectName))) { RefDatabase refDb = repository.getRefDatabase(); return refs.stream() + .filter(ref -> !hasBeenRemovedFromGlobalRefDb(projectName, ref)) .filter( ref -> { if (shouldNotBeTrackedAnymoreOnGlobalRefDb(ref)) { @@ -133,6 +135,31 @@ return refLocks; } + /* If the ref to fetch has been set to all zeros on the global-refdb, it means + * that whatever is the situation locally, we do not need to fetch it: + * - If the remote still has it, fetching it will be useless because the global + * state is that the ref should be removed. + * - If the remote doesn't have it anymore, trying to fetch the ref won't do + * anything because you can't just remove local refs by fetching. + */ + private boolean hasBeenRemovedFromGlobalRefDb(String projectName, String ref) { + if (foundAsZeroInSharedRefDb(Project.nameKey(projectName), ref)) { + repLog.info( + "{}:{} is found as zeros (removed) in shared-refdb thus will NOT BE fetched", + projectName, + ref); + return true; + } + return false; + } + + private boolean foundAsZeroInSharedRefDb(NameKey projectName, String ref) { + return sharedRefDb + .get(projectName, ref, String.class) + .map(r -> ZERO_ID_NAME.equals(r)) + .orElse(false); + } + private Optional<ObjectId> getLocalSha1IfEqualsToExistingGlobalRefDb( Repository repository, String projectName,
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java index b9ec588..e09f6f6 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java
@@ -17,7 +17,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -148,7 +147,7 @@ Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch); assertThat(filteredRefsToFetch).hasSize(1); - verify(sharedRefDatabaseMock, atLeastOnce()) + verify(sharedRefDatabaseMock, times(3)) .get(eq(projectName), eq(temporaryOutdated), eq(String.class)); } @@ -173,6 +172,12 @@ @Test public void shouldNotFilterOutWhenRefsMultisiteVersionIsPresentInSharedRefDb() throws Exception { String refsMultisiteVersionRef = ProjectVersionRefUpdate.MULTI_SITE_VERSIONING_REF; + RevCommit multiSiteVersionRef = newRef(refsMultisiteVersionRef); + + doReturn(Optional.of(multiSiteVersionRef.getId().getName())) + .when(sharedRefDatabaseMock) + .get(eq(projectName), eq(refsMultisiteVersionRef), eq(String.class)); + Set<String> refsToFetch = Set.of(refsMultisiteVersionRef); MultisiteReplicationFetchFilter fetchFilter = @@ -183,7 +188,7 @@ } @Test - public void shouldNotFilterOutWhenRefIsDeletedInTheSharedRefDb() throws Exception { + public void shouldFilterOutWhenRefIsDeletedInTheSharedRefDb() throws Exception { String temporaryOutdated = "refs/heads/temporaryOutdated"; newRef(temporaryOutdated); @@ -196,8 +201,25 @@ new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config); Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch); + assertThat(filteredRefsToFetch).hasSize(0); + verify(sharedRefDatabaseMock).get(eq(projectName), any(), any()); + } + + @Test + public void shouldNotFilterOutWhenRefIsMissingOnlyInTheLocalRepository() throws Exception { + String refObjectId = "0000000000000000000000000000000000000001"; + String nonExistingLocalRef = "refs/heads/temporaryOutdated"; + + Set<String> refsToFetch = Set.of(nonExistingLocalRef); + doReturn(Optional.of(refObjectId)) + .when(sharedRefDatabaseMock) + .get(eq(projectName), any(), any()); + + MultisiteReplicationFetchFilter fetchFilter = + new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config); + Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch); + assertThat(filteredRefsToFetch).hasSize(1); - verify(sharedRefDatabaseMock, atLeastOnce()).get(eq(projectName), any(), any()); } @Test @@ -213,6 +235,23 @@ assertThat(filteredRefsToFetch).hasSize(1); } + @Test + public void shouldFilterOutRefMissingInTheLocalRepositoryAndDeletedInSharedRefDb() + throws Exception { + String nonExistingLocalRef = "refs/heads/temporaryOutdated"; + + Set<String> refsToFetch = Set.of(nonExistingLocalRef); + doReturn(Optional.of(ObjectId.zeroId().getName())) + .when(sharedRefDatabaseMock) + .get(eq(projectName), any(), any()); + + MultisiteReplicationFetchFilter fetchFilter = + new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config); + Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch); + + assertThat(filteredRefsToFetch).hasSize(0); + } + private RevCommit newRef(String refName) throws Exception { return repo.branch(refName).commit().create(); }