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); + } + } }