ReplicationIT: don't wait a full retry window to prove non-replication ReplicationIT takes ~343s (5m40s) while the rest of the build finishes in seconds. Five of its 26 cases each burn ~62s; the rest run in <=2s. All five bottom out on the replication retry quantum: a failed push is rescheduled in TimeUnit.MINUTES (Destination#reschedule), so the smallest non-zero retry is one minute and the tests set replicationRetry=1. The three negative tests -- shouldNotDrainTheQueueWhenReloading, shouldNotReplicateToNonMatchingRemote and shouldNotReplicateProjectListedInProjectsAndExcludeProjects -- assert a ref is never replicated by waiting for it and expecting the wait to expire. They reuse TEST_TIMEOUT, which is sized to span a retry cycle ((delay + retry*60)+1 = 62s), so each burns the full minute only to prove a negative. Give those waits their own TEST_NOT_REPLICATED_TIMEOUT (replication delay + push time + a few seconds cushion, ~7s), applied via a private waitUntil(Supplier, Duration) overload in ReplicationIT. This does not weaken the tests: waitUntil still throws on timeout, so assertThrows still verifies non-replication -- only the wait shortens. Replication is structurally suppressed in these cases (destination down, project excluded, remote non-matching), so the ref can never appear; were a regression to leak a push it would replicate within the ~1s delay, well inside the window, and the assertion would then fail. The shared TEST_REPLICATION_RETRY_MINUTES is left untouched so tests that rely on the real one-minute retry (e.g. ReplicationStorageIT) keep their timing. The two remaining ~60s cases (new-project replication) genuinely wait a retry: the first push fails as REPOSITORY_MISSING while the replica repo is still being created, and that reason is retried on the minutes-based delay. That is a separate, arguably production-side latency issue and is handled in a follow-up. Net, the three negatives drop from ~62s to ~7s each while the two new-project cases are untouched here, so ReplicationIT drops from ~343s to ~173s (~2x60s new-project waits + ~24 fast tests), all 26 green. Change-Id: I2d561950e51761a1d1b0fe09dc50763b3e5421af
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 d54cb7c..4a3bb9b 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java +++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationIT.java
@@ -59,10 +59,18 @@ name = "replication", sysModule = "com.googlesource.gerrit.plugins.replication.TestReplicationModule") public class ReplicationIT extends ReplicationDaemon { - private static final int TEST_REPLICATION_DELAY = 1; - private static final int TEST_REPLICATION_RETRY = 1; private static final Duration TEST_TIMEOUT = - Duration.ofSeconds((TEST_REPLICATION_DELAY + TEST_REPLICATION_RETRY * 60) + 1); + Duration.ofSeconds(TEST_REPLICATION_DELAY_SECONDS + TEST_REPLICATION_RETRY_MINUTES * 60 + 1); + + // Timeout for asserting that a ref is *not* replicated. Unlike TEST_TIMEOUT it + // deliberately excludes the retry cycle: a push that is going to happen at all + // completes within the replication delay plus the push time, so if the ref has + // not appeared within that window (plus a small cushion) it never will + // (destination shut down / project excluded / non-matching remote). Sized in + // seconds rather than the ~60s retry quantum so these negative tests do not each + // burn a full retry window while proving a negative. + private static final Duration TEST_NOT_REPLICATED_TIMEOUT = + Duration.ofSeconds(TEST_REPLICATION_DELAY_SECONDS + TEST_PUSH_TIME_SECONDS + 5); @Inject private DynamicSet<ProjectDeletedListener> deletedListeners; @@ -457,7 +465,7 @@ InterruptedException.class, () -> { try (Repository repo = repoManager.openRepository(targetProject)) { - waitUntil(() -> checkedGetRef(repo, sourceRef) != null); + waitUntil(() -> checkedGetRef(repo, sourceRef) != null, TEST_NOT_REPLICATED_TIMEOUT); } }); } @@ -741,7 +749,8 @@ try (Repository repo = repoManager.openRepository(targetProject)) { assertThrows( InterruptedException.class, - () -> waitUntil(() -> checkedGetRef(repo, sourceRef) != null)); + () -> + waitUntil(() -> checkedGetRef(repo, sourceRef) != null, TEST_NOT_REPLICATED_TIMEOUT)); } } @@ -763,12 +772,18 @@ try (Repository repo = repoManager.openRepository(targetProject)) { assertThrows( - InterruptedException.class, () -> waitUntil(() -> checkedGetRef(repo, newRef) != null)); + InterruptedException.class, + () -> waitUntil(() -> checkedGetRef(repo, newRef) != null, TEST_NOT_REPLICATED_TIMEOUT)); } } private void waitUntil(Supplier<Boolean> waitCondition) throws InterruptedException { - WaitUtil.waitUntil(waitCondition, TEST_TIMEOUT); + waitUntil(waitCondition, TEST_TIMEOUT); + } + + private void waitUntil(Supplier<Boolean> waitCondition, Duration timeout) + throws InterruptedException { + WaitUtil.waitUntil(waitCondition, timeout); } private void shutdownDestinations() {