Merge branch 'stable-2.16' into stable-3.0 * stable-2.16: Fix replication of project deletion Improve project creation replication integration test Change-Id: I1818511118ed1738cf76d48cb49b66a52f1d83c8
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java index 1f0c40e..45fa150 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
@@ -189,7 +189,7 @@ SetMultimap<Destination, URIish> uris = HashMultimap.create(); for (Destination config : getDestinations(filterType)) { - if (!config.wouldPushProject(projectName)) { + if (filterType != FilterType.PROJECT_DELETION && !config.wouldPushProject(projectName)) { continue; }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java index 62664b1..f982efb 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java +++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java
@@ -26,8 +26,11 @@ import com.google.gerrit.acceptance.UseLocalDisk; import com.google.gerrit.acceptance.testsuite.project.ProjectOperations; import com.google.gerrit.extensions.annotations.PluginData; +import com.google.gerrit.extensions.api.changes.NotifyHandling; import com.google.gerrit.extensions.api.projects.BranchInput; import com.google.gerrit.extensions.common.ProjectInfo; +import com.google.gerrit.extensions.events.ProjectDeletedListener; +import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.server.config.SitePaths; import com.google.inject.Inject; @@ -59,10 +62,13 @@ private static final Optional<String> ALL_PROJECTS = Optional.empty(); private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private static final int TEST_REPLICATION_DELAY = 1; - private static final Duration TEST_TIMEOUT = Duration.ofSeconds(TEST_REPLICATION_DELAY * 2); + private static final int TEST_REPLICATION_RETRY = 1; + private static final Duration TEST_TIMEOUT = + Duration.ofSeconds((TEST_REPLICATION_DELAY + TEST_REPLICATION_RETRY * 60) + 1); @Inject private SitePaths sitePaths; @Inject private ProjectOperations projectOperations; + @Inject private DynamicSet<ProjectDeletedListener> deletedListeners; private Path pluginDataDir; private Path gitPath; private Path storagePath; @@ -99,13 +105,41 @@ assertThat(listReplicationTasks("refs/meta/config")).hasSize(1); - waitUntil(() -> projectExists(new Project.NameKey(sourceProject + "replica.git"))); + waitUntil(() -> nonEmptyProjectExists(new Project.NameKey(sourceProject + "replica"))); ProjectInfo replicaProject = gApi.projects().name(sourceProject + "replica").get(); assertThat(replicaProject).isNotNull(); } @Test + public void shouldReplicateProjectDeletion() throws Exception { + String projectNameDeleted = "project-deleted"; + Project.NameKey replicaProject = createTestProject(projectNameDeleted + "replica"); + setReplicationDestination("foo", "replica", ALL_PROJECTS); + setProjectDeletionReplication("foo", true); + reloadConfig(); + + ProjectDeletedListener.Event event = + new ProjectDeletedListener.Event() { + @Override + public String getProjectName() { + return projectNameDeleted; + } + + @Override + public NotifyHandling getNotify() { + return NotifyHandling.NONE; + } + }; + + for (ProjectDeletedListener l : deletedListeners) { + l.onProjectDeleted(event); + } + + waitUntil(() -> !nonEmptyProjectExists(replicaProject)); + } + + @Test public void shouldReplicateNewChangeRef() throws Exception { Project.NameKey targetProject = createTestProject(project + "replica"); @@ -380,10 +414,17 @@ .collect(toList()); config.setStringList("remote", remoteName, "url", replicaUrls); config.setInt("remote", remoteName, "replicationDelay", TEST_REPLICATION_DELAY); + config.setInt("remote", remoteName, "replicationRetry", TEST_REPLICATION_RETRY); project.ifPresent(prj -> config.setString("remote", remoteName, "projects", prj)); config.save(); } + private void setProjectDeletionReplication(String remoteName, boolean replicateProjectDeletion) + throws IOException { + config.setBoolean("remote", remoteName, "replicateProjectDeletions", replicateProjectDeletion); + config.save(); + } + private void waitUntil(Supplier<Boolean> waitCondition) throws InterruptedException { WaitUtil.waitUntil(waitCondition, TEST_TIMEOUT); } @@ -435,9 +476,9 @@ } } - private boolean projectExists(Project.NameKey name) { + private boolean nonEmptyProjectExists(Project.NameKey name) { try (Repository r = repoManager.openRepository(name)) { - return true; + return !r.getAllRefsByPeeledObjectId().isEmpty(); } catch (Exception e) { return false; }