ReplicationIT: remove dependency of ReviewDb/NoteDb

Tests need to be independent on the underlying changes storage
and thus make assertions of the expected replication tasks and
the associated refs regex.

Change-Id: I1e645339888deef609670ca3e58517a159e93b2b
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 1381c99..1bb0bbf 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java
@@ -28,16 +28,24 @@
 import com.google.gerrit.extensions.common.ProjectInfo;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.SitePaths;
+import com.google.gson.Gson;
 import com.google.inject.Inject;
 import com.google.inject.Key;
+import com.googlesource.gerrit.plugins.replication.ReplicationTasksStorage.ReplicateRefUpdate;
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.time.Duration;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Supplier;
+import java.util.regex.Pattern;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
@@ -61,6 +69,7 @@
   private Path gitPath;
   private Path storagePath;
   private FileBasedConfig config;
+  private Gson GSON = new Gson();
 
   @Override
   public void setUpTestPlugin() throws Exception {
@@ -84,11 +93,11 @@
   public void shouldReplicateNewProject() throws Exception {
     setReplicationDestination("foo", "replica", ALL_PROJECTS);
     reloadConfig();
+    waitForEmptyTasks();
 
     Project.NameKey sourceProject = createProject("foo");
 
-    String[] replicationTasks = storagePath.toFile().list();
-    assertThat(replicationTasks).hasLength(2); // refs/heads/master and /refs/meta/config
+    assertThat(listReplicationTasks("refs/meta/config")).hasSize(1);
 
     waitUntil(() -> gitPath.resolve(sourceProject + "replica.git").toFile().isDirectory());
 
@@ -102,13 +111,13 @@
 
     setReplicationDestination("foo", "replica", ALL_PROJECTS);
     reloadConfig();
+    waitForEmptyTasks();
 
     Result pushResult = createChange();
     RevCommit sourceCommit = pushResult.getCommit();
     String sourceRef = pushResult.getPatchSet().getRefName();
 
-    String[] replicationTasks = storagePath.toFile().list();
-    assertThat(replicationTasks).hasLength(1);
+    assertThat(listReplicationTasks("refs/changes/\\d*/\\d*/\\d*")).hasSize(1);
 
     try (Repository repo = repoManager.openRepository(targetProject)) {
       waitUntil(() -> checkedGetRef(repo, sourceRef) != null);
@@ -123,6 +132,7 @@
   public void shouldReplicateNewBranch() throws Exception {
     setReplicationDestination("foo", "replica", ALL_PROJECTS);
     reloadConfig();
+    waitForEmptyTasks();
 
     Project.NameKey targetProject = createProject("projectreplica");
     String newBranch = "refs/heads/mybranch";
@@ -131,6 +141,8 @@
     input.revision = master;
     gApi.projects().name(project.get()).branch(newBranch).create(input);
 
+    assertThat(listReplicationTasks("refs/heads/(mybranch|master)")).hasSize(2);
+
     try (Repository repo = repoManager.openRepository(targetProject)) {
       waitUntil(() -> checkedGetRef(repo, newBranch) != null);
 
@@ -149,13 +161,13 @@
     setReplicationDestination("foo1", "replica1", ALL_PROJECTS);
     setReplicationDestination("foo2", "replica2", ALL_PROJECTS);
     reloadConfig();
+    waitForEmptyTasks();
 
     Result pushResult = createChange();
     RevCommit sourceCommit = pushResult.getCommit();
     String sourceRef = pushResult.getPatchSet().getRefName();
 
-    String[] replicationTasks = storagePath.toFile().list();
-    assertThat(replicationTasks).hasLength(2);
+    assertThat(listReplicationTasks("refs/changes/\\d*/\\d*/\\d*")).hasSize(2);
 
     try (Repository repo1 = repoManager.openRepository(targetProject1);
         Repository repo2 = repoManager.openRepository(targetProject2)) {
@@ -182,10 +194,11 @@
     setReplicationDestination("foo1", replicaSuffixes, ALL_PROJECTS);
     setReplicationDestination("foo2", replicaSuffixes, ALL_PROJECTS);
     reloadConfig();
+    waitForEmptyTasks();
 
     createChange();
 
-    assertThat(storagePath.toFile().list()).hasLength(4);
+    assertThat(listReplicationTasks("refs/changes/\\d*/\\d*/\\d*")).hasSize(4);
   }
 
   @Test
@@ -252,4 +265,40 @@
   private void reloadConfig() {
     plugin.getSysInjector().getInstance(AutoReloadConfigDecorator.class).forceReload();
   }
+
+  private void waitForEmptyTasks() throws InterruptedException {
+    waitUntil(
+        () -> {
+          try {
+            return listReplicationTasks(".*").size() == 0;
+          } catch (Exception e) {
+            logger.atSevere().withCause(e).log("Failed to list replication tasks");
+            throw new IllegalStateException(e);
+          }
+        });
+  }
+
+  private List<ReplicateRefUpdate> listReplicationTasks(String refRegex) throws IOException {
+    Pattern refmaskPattern = Pattern.compile(refRegex);
+    List<ReplicateRefUpdate> tasks = new ArrayList<>();
+    try (DirectoryStream<Path> files = Files.newDirectoryStream(storagePath)) {
+      for (Path path : files) {
+        ReplicateRefUpdate task = readTask(path);
+        if (refmaskPattern.matcher(task.ref).matches()) {
+          tasks.add(readTask(path));
+        }
+      }
+    }
+
+    return tasks;
+  }
+
+  private ReplicateRefUpdate readTask(Path file) {
+    try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
+      return GSON.fromJson(reader, ReplicateRefUpdate.class);
+    } catch (Exception e) {
+      logger.atSevere().withCause(e).log("failed to read replication task %s", file);
+      throw new IllegalStateException(e);
+    }
+  }
 }