Conversation
After action=reset, the sgReplicateManager goroutine calls alignState(ctx, resetting) on the local ActiveReplicator, which clears the checkpoint (c.Checkpointer = nil) and removes the persisted status document. At this point the in-memory replicator reports status=stopped and LastSeqPull="". The test's EventuallyWithT saw both conditions satisfied and proceeded to call action=start. However, the manager hadn't yet called UpdateReplicationState(id, stopped) to persist TargetState=stopped back to the cluster config. That call happens synchronously after alignState returns, but there is a window between the two where TargetState is still "resetting" in the cluster config. UpdateReplicationState (called by action=start) reads the cluster config and passes TargetState to isValidStateChange, which rejects the "resetting -> running" transition with a 400. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses a test flake in Sync Gateway’s sg-replicate status-action flow by ensuring the test waits not only for the in-memory replication status to be reset/stopped, but also for the persisted replication config’s TargetState to be updated back to stopped before issuing a subsequent start action.
Changes:
- Improve failure attribution in test helpers by marking key assertion/wait helper functions as
t.Helper(). - Harden
TestReplicationStatusActionsby additionally waiting until the replication config in/_replication/reflectsTargetState=stoppedafter a reset. - Add a lightweight guard/assertion that the replication config entry exists before checking
TargetState.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| rest/utilities_testing.go | Marks RequireStatus/AssertStatus as helpers to improve test failure line reporting. |
| rest/utilities_testing_resttester.go | Marks several RestTester helper methods as helpers for clearer stack traces in failing tests. |
| rest/replicatortest/replicator_test.go | Extends the reset verification in TestReplicationStatusActions to also wait for persisted TargetState to become stopped, closing the flake window. |
bbrks
approved these changes
Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CBG-5557: fix TestReplicationStatusActions flake
After action=reset, the sgReplicateManager goroutine calls alignState(ctx, resetting) on the local ActiveReplicator, which clears the checkpoint (c.Checkpointer = nil) and removes the persisted status document. At this point the in-memory replicator reports status=stopped and LastSeqPull="". The test's EventuallyWithT saw both conditions satisfied and proceeded to call action=start.
However, the manager hadn't yet called UpdateReplicationState(id, stopped) to persist TargetState=stopped back to the cluster config. That call happens synchronously after alignState returns, but there is a window between the two where TargetState is still "resetting" in the cluster config. UpdateReplicationState (called by action=start) reads the cluster config and passes TargetState to isValidStateChange, which rejects the "resetting -> running" transition with a 400.