Merge branch 'stable-3.0' into stable-3.1
* stable-3.0:
ReplicationTasksStorage: Add unit tests
Change-Id: Ic4d28918223e8b4f3b0d8a83b1c987be22d8db45
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java
index 98bc40f..e75e55b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java
@@ -94,7 +94,12 @@
@Inject
ReplicationTasksStorage(ReplicationConfig config) {
- refUpdates = config.getEventsDirectory().resolve("ref-updates");
+ this(config.getEventsDirectory().resolve("ref-updates"));
+ }
+
+ @VisibleForTesting
+ public ReplicationTasksStorage(Path refUpdates) {
+ this.refUpdates = refUpdates;
buildingUpdates = refUpdates.resolve("building");
runningUpdates = refUpdates.resolve("running");
waitingUpdates = refUpdates.resolve("waiting");
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorageTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorageTest.java
new file mode 100644
index 0000000..38d5421
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorageTest.java
@@ -0,0 +1,227 @@
+// Copyright (C) 2020 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+import com.googlesource.gerrit.plugins.replication.ReplicationTasksStorage.ReplicateRefUpdate;
+import java.net.URISyntaxException;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.util.Objects;
+import org.eclipse.jgit.transport.URIish;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ReplicationTasksStorageTest {
+ protected static final String PROJECT = "myProject";
+ protected static final String REF = "myRef";
+ protected static final String REMOTE = "myDest";
+ protected static final URIish URISH = getUrish("http://example.com/" + PROJECT + ".git");
+ protected static final ReplicateRefUpdate REF_UPDATE =
+ new ReplicateRefUpdate(PROJECT, REF, URISH, REMOTE);
+
+ protected ReplicationTasksStorage storage;
+ protected FileSystem fileSystem;
+ protected Path storageSite;
+
+ @Before
+ public void setUp() throws Exception {
+ fileSystem = Jimfs.newFileSystem(Configuration.unix());
+ storageSite = fileSystem.getPath("replication_site");
+ storage = new ReplicationTasksStorage(storageSite);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ fileSystem.close();
+ }
+
+ @Test
+ public void canListEmptyStorage() throws Exception {
+ assertThat(storage.list()).isEmpty();
+ }
+
+ @Test
+ public void canListPersistedUpdate() throws Exception {
+ storage.create(REF_UPDATE);
+ assertContainsExactly(storage, REF_UPDATE);
+ }
+
+ @Test
+ public void canDeletePersistedUpdate() throws Exception {
+ storage.create(REF_UPDATE);
+ storage.delete(REF_UPDATE);
+ assertThat(storage.list()).isEmpty();
+ }
+
+ @Test
+ public void instancesOfTheSameStorageHaveTheSameElements() throws Exception {
+ ReplicationTasksStorage persistedView = new ReplicationTasksStorage(storageSite);
+
+ assertThat(storage.list()).isEmpty();
+ assertThat(persistedView.list()).isEmpty();
+
+ storage.create(REF_UPDATE);
+ assertContainsExactly(storage, REF_UPDATE);
+ assertContainsExactly(persistedView, REF_UPDATE);
+
+ storage.delete(REF_UPDATE);
+ assertThat(storage.list()).isEmpty();
+ assertThat(persistedView.list()).isEmpty();
+ }
+
+ @Test
+ public void sameRefUpdatePersistedTwiceIsStoredOnce() throws Exception {
+ String key = storage.create(REF_UPDATE);
+ String secondKey = storage.create(REF_UPDATE);
+ assertEquals(key, secondKey);
+ assertContainsExactly(storage, REF_UPDATE);
+ }
+
+ @Test
+ public void canPersistDifferentUris() throws Exception {
+ ReplicateRefUpdate updateB =
+ new ReplicateRefUpdate(
+ PROJECT,
+ REF,
+ getUrish("ssh://example.com/" + PROJECT + ".git"), // uses ssh not http
+ REMOTE);
+
+ String keyA = storage.create(REF_UPDATE);
+ String keyB = storage.create(updateB);
+ assertThat(storage.list()).hasSize(2);
+ assertNotEquals(keyA, keyB);
+ }
+
+ @Test
+ public void canDeleteDifferentUris() throws Exception {
+ ReplicateRefUpdate updateB =
+ new ReplicateRefUpdate(
+ PROJECT,
+ REF,
+ getUrish("ssh://example.com/" + PROJECT + ".git"), // uses ssh not http
+ REMOTE);
+ storage.create(REF_UPDATE);
+ storage.create(updateB);
+
+ storage.delete(REF_UPDATE);
+ assertContainsExactly(storage, updateB);
+
+ storage.delete(updateB);
+ assertThat(storage.list()).isEmpty();
+ }
+
+ @Test
+ public void differentUrisPersistedTwiceIsStoredOnce() throws Exception {
+ ReplicateRefUpdate updateB =
+ new ReplicateRefUpdate(
+ PROJECT,
+ REF,
+ getUrish("ssh://example.com/" + PROJECT + ".git"), // uses ssh not http
+ REMOTE);
+
+ storage.create(REF_UPDATE);
+ storage.create(updateB);
+ storage.create(REF_UPDATE);
+ storage.create(updateB);
+ assertThat(storage.list()).hasSize(2);
+ }
+
+ @Test
+ public void canPersistMulipleRefsForSameUri() throws Exception {
+ ReplicateRefUpdate refA = new ReplicateRefUpdate(PROJECT, "refA", URISH, REMOTE);
+ ReplicateRefUpdate refB = new ReplicateRefUpdate(PROJECT, "refB", URISH, REMOTE);
+
+ String keyA = storage.create(refA);
+ String keyB = storage.create(refB);
+ assertThat(storage.list()).hasSize(2);
+ assertNotEquals(keyA, keyB);
+ }
+
+ @Test
+ public void canDeleteMulipleRefsForSameUri() throws Exception {
+ ReplicateRefUpdate refA = new ReplicateRefUpdate(PROJECT, "refA", URISH, REMOTE);
+ ReplicateRefUpdate refB = new ReplicateRefUpdate(PROJECT, "refB", URISH, REMOTE);
+ storage.create(refA);
+ storage.create(refB);
+
+ storage.delete(refA);
+ assertContainsExactly(storage, refB);
+
+ storage.delete(refB);
+ assertThat(storage.list()).isEmpty();
+ }
+
+ @Test(expected = Test.None.class /* no exception expected */)
+ public void illegalDeleteNonPersistedIsGraceful() throws Exception {
+ storage.delete(REF_UPDATE);
+ }
+
+ @Test(expected = Test.None.class /* no exception expected */)
+ public void illegalDoubleDeleteIsGraceful() throws Exception {
+ storage.create(REF_UPDATE);
+ storage.delete(REF_UPDATE);
+
+ storage.delete(REF_UPDATE);
+ }
+
+ @Test(expected = Test.None.class /* no exception expected */)
+ public void illegalDoubleDeleteDifferentUriIsGraceful() throws Exception {
+ ReplicateRefUpdate updateB =
+ new ReplicateRefUpdate(
+ PROJECT,
+ REF,
+ getUrish("ssh://example.com/" + PROJECT + ".git"), // uses ssh not http
+ REMOTE);
+ storage.create(REF_UPDATE);
+ storage.create(updateB);
+ storage.delete(REF_UPDATE);
+ storage.delete(updateB);
+
+ storage.delete(REF_UPDATE);
+ storage.delete(updateB);
+ assertThat(storage.list()).isEmpty();
+ }
+
+ private void assertContainsExactly(
+ ReplicationTasksStorage tasksStorage, ReplicateRefUpdate update) {
+ assertTrue(equals(tasksStorage.list().get(0), update));
+ }
+
+ private boolean equals(ReplicateRefUpdate one, ReplicateRefUpdate two) {
+ return (one == null && two == null)
+ || (one != null
+ && two != null
+ && Objects.equals(one.project, two.project)
+ && Objects.equals(one.ref, two.ref)
+ && Objects.equals(one.remote, two.remote)
+ && Objects.equals(one.uri, two.uri));
+ }
+
+ public static URIish getUrish(String uri) {
+ try {
+ return new URIish(uri);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Cannot instantiate URIish object", e);
+ }
+ }
+}