Add ITs for replication events
Ahead of some refactoring, ensure there's at least some minimal test
coverage.
Change-Id: If7c6cd66b19d3b98ab0be2a5cbd6298b3d41a865
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationEventsIT.java b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationEventsIT.java
new file mode 100644
index 0000000..841bfd7
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationEventsIT.java
@@ -0,0 +1,119 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.replication;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.gerrit.acceptance.PushOneCommit.Result;
+import com.google.gerrit.acceptance.Sandboxed;
+import com.google.gerrit.acceptance.TestPlugin;
+import com.google.gerrit.acceptance.UseLocalDisk;
+import com.google.gerrit.acceptance.WaitUtil;
+import com.google.gerrit.entities.BranchNameKey;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.extensions.api.projects.BranchInput;
+import com.google.gerrit.extensions.registration.DynamicItem;
+import com.google.gerrit.server.events.EventDispatcher;
+import com.google.gerrit.server.events.RefEvent;
+import com.google.inject.Inject;
+import java.time.Duration;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Supplier;
+import org.junit.Before;
+import org.junit.Test;
+
+@UseLocalDisk
+@Sandboxed
+@TestPlugin(
+ name = "replication",
+ sysModule = "com.googlesource.gerrit.plugins.replication.ReplicationModule")
+public class ReplicationEventsIT extends ReplicationDaemon {
+ private static final Duration TEST_POST_EVENT_TIMEOUT = Duration.ofSeconds(1);
+
+ @Inject private DynamicItem<EventDispatcher> eventDispatcher;
+ private TestDispatcher testDispatcher;
+
+ @Before
+ public void setup() throws Exception {
+ initConfig();
+ setReplicationDestination(
+ "remote1",
+ "suffix1",
+ Optional.of("not-used-project")); // Simulates a full replication.config initialization
+ setUpTestPlugin();
+ testDispatcher = new TestDispatcher();
+ eventDispatcher.set(testDispatcher, eventDispatcher.getPluginName());
+ }
+
+ @Test
+ public void replicateNewChangeSendsEvents() throws Exception {
+ Project.NameKey targetProject = createTestProject(project + "replica");
+
+ setReplicationDestination("foo", "replica", ALL_PROJECTS);
+ reloadConfig();
+
+ Result pushResult = createChange();
+ String sourceRef = pushResult.getPatchSet().refName();
+ String metaRef = pushResult.getChange().notes().getRefName();
+ BranchNameKey changeBranch = BranchNameKey.create(project, sourceRef);
+ BranchNameKey metaBranch = BranchNameKey.create(project, metaRef);
+
+ assertThat(testDispatcher.getEvents(changeBranch, ReplicationScheduledEvent.class)).hasSize(1);
+ assertThat(testDispatcher.getEvents(metaBranch, ReplicationScheduledEvent.class)).hasSize(1);
+
+ isPushCompleted(targetProject, sourceRef, TEST_PUSH_TIMEOUT);
+ isPushCompleted(targetProject, metaRef, TEST_PUSH_TIMEOUT);
+
+ waitForRefEvent(() -> testDispatcher.getEvents(RefReplicatedEvent.class), metaRef);
+ waitForRefEvent(() -> testDispatcher.getEvents(RefReplicatedEvent.class), sourceRef);
+ assertThat(testDispatcher.getEvents(RefReplicatedEvent.class).size()).isEqualTo(2);
+
+ waitForRefEvent(() -> testDispatcher.getEvents(RefReplicationDoneEvent.class), metaRef);
+ waitForRefEvent(() -> testDispatcher.getEvents(RefReplicationDoneEvent.class), sourceRef);
+ assertThat(testDispatcher.getEvents(RefReplicationDoneEvent.class).size()).isEqualTo(2);
+ }
+
+ @Test
+ public void replicateNewBranchSendsEvents() throws Exception {
+ setReplicationDestination("foo", "replica", ALL_PROJECTS);
+ reloadConfig();
+
+ Project.NameKey targetProject = createTestProject(project + "replica");
+ String newBranch = "refs/heads/mybranch";
+ BranchNameKey branchName = BranchNameKey.create(project, newBranch);
+ String master = "refs/heads/master";
+ BranchInput input = new BranchInput();
+ input.revision = master;
+ gApi.projects().name(project.get()).branch(newBranch).create(input);
+
+ assertThat(testDispatcher.getEvents(branchName, ReplicationScheduledEvent.class)).hasSize(1);
+
+ isPushCompleted(targetProject, newBranch, TEST_PUSH_TIMEOUT);
+
+ waitForRefEvent(() -> testDispatcher.getEvents(RefReplicatedEvent.class), newBranch);
+ assertThat(testDispatcher.getEvents(RefReplicatedEvent.class).size()).isEqualTo(1);
+
+ waitForRefEvent(() -> testDispatcher.getEvents(RefReplicationDoneEvent.class), newBranch);
+ assertThat(testDispatcher.getEvents(RefReplicationDoneEvent.class).size()).isEqualTo(1);
+ }
+
+ private <T extends RefEvent> void waitForRefEvent(Supplier<List<T>> events, String refName)
+ throws InterruptedException {
+ WaitUtil.waitUntil(
+ () -> events.get().stream().filter(e -> refName.equals(e.getRefName())).count() == 1,
+ TEST_POST_EVENT_TIMEOUT);
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/TestDispatcher.java b/src/test/java/com/googlesource/gerrit/plugins/replication/TestDispatcher.java
new file mode 100644
index 0000000..bc5c35c
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/TestDispatcher.java
@@ -0,0 +1,63 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.replication;
+
+import com.google.gerrit.entities.BranchNameKey;
+import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.server.events.ChangeEvent;
+import com.google.gerrit.server.events.Event;
+import com.google.gerrit.server.events.EventDispatcher;
+import com.google.gerrit.server.events.ProjectEvent;
+import com.google.gerrit.server.events.RefEvent;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class TestDispatcher implements EventDispatcher {
+ private final List<RefEvent> refEvents = new LinkedList<>();
+ private final List<Event> events = new LinkedList<>();
+
+ @Override
+ public void postEvent(Change change, ChangeEvent event) {} // Not used in replication
+
+ @Override
+ public void postEvent(BranchNameKey branchName, RefEvent event) {
+ refEvents.add(event);
+ }
+
+ @Override
+ public void postEvent(
+ Project.NameKey projectName, ProjectEvent event) {} // Not used in replication
+
+ @Override
+ public void postEvent(Event event) {
+ events.add(event);
+ }
+
+ public List<RefEvent> getEvents(BranchNameKey branch, Class<? extends RefEvent> clazz) {
+ return getEvents(branch).stream().filter(clazz::isInstance).collect(Collectors.toList());
+ }
+
+ public <T extends RefEvent> List<T> getEvents(Class<T> clazz) {
+ return events.stream().filter(clazz::isInstance).map(clazz::cast).collect(Collectors.toList());
+ }
+
+ private List<RefEvent> getEvents(BranchNameKey branch) {
+ return refEvents.stream()
+ .filter(e -> e.getBranchNameKey().equals(branch))
+ .collect(Collectors.toList());
+ }
+}