Merge branch 'stable-3.0' into stable-3.1 * stable-3.0: Fix replication of project deletion Improve project creation replication integration test Change-Id: Id1a8412e6bfc09e6e22ddb236c37472bd7e5df96
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java index 27e3756..fcf5dfa 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java
@@ -87,7 +87,7 @@ SetMultimap<Destination, URIish> uris = HashMultimap.create(); for (Destination config : getAll(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 545ae4b..3eb6baf 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java +++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java
@@ -27,8 +27,11 @@ import com.google.gerrit.acceptance.testsuite.project.ProjectOperations; import com.google.gerrit.entities.Project; 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.server.config.SitePaths; import com.google.inject.Inject; import com.google.inject.Key; @@ -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(Project.nameKey(sourceProject + "replica.git"))); + waitUntil(() -> nonEmptyProjectExists(Project.nameKey(sourceProject + "replica.git"))); 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"); @@ -362,7 +396,7 @@ assertThat(tasksStorage.listRunning()).hasSize(0); Project.NameKey sourceProject = createTestProject("task_cleanup_project"); - waitUntil(() -> projectExists(Project.nameKey(sourceProject + "replica.git"))); + waitUntil(() -> nonEmptyProjectExists(Project.nameKey(sourceProject + "replica.git"))); waitUntil(() -> tasksStorage.listRunning().size() == 0); } @@ -394,11 +428,18 @@ .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.setBoolean("gerrit", null, "autoReload", true); 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); } @@ -458,9 +499,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; }