diff --git a/logs/log1756012262.md b/logs/log1756012262.md
new file mode 100644
index 0000000000..ac390723d9
--- /dev/null
+++ b/logs/log1756012262.md
@@ -0,0 +1 @@
+- Updated GossipTransportTests to await topology consensus using ExpectUpdatedTopologyConsensus, removing manual polling via AwaitConditionAsync. This ensures tests wait for deterministic membership updates before sending gossip.
diff --git a/logs/log1756013526.md b/logs/log1756013526.md
new file mode 100644
index 0000000000..91e7c2c5c0
--- /dev/null
+++ b/logs/log1756013526.md
@@ -0,0 +1,2 @@
+- Added ExpectMemberToExist helper in Proto.TestKit for clearer cluster membership checks.
+- Updated GossipTransportTests to use ExpectMemberToExist instead of manual AwaitConditionAsync calls.
diff --git a/src/Proto.TestKit/ClusterTestKitExtensions.cs b/src/Proto.TestKit/ClusterTestKitExtensions.cs
index 2e8ad8a53f..423f2824b6 100644
--- a/src/Proto.TestKit/ClusterTestKitExtensions.cs
+++ b/src/Proto.TestKit/ClusterTestKitExtensions.cs
@@ -34,5 +34,21 @@ await TestKit.AwaitConditionAsync(async () =>
return updatedTopologyHash;
}
+
+ ///
+ /// Waits until the cluster's member list contains the specified .
+ ///
+ /// Cluster to inspect.
+ /// Member expected to exist in the cluster.
+ /// Maximum time to wait. Defaults to 10 seconds.
+ /// A task that completes when the member is present.
+ public static Task ExpectMemberToExist(this Proto.Cluster.Cluster cluster, Member member, TimeSpan? timeout = null)
+ {
+ var waitTimeout = timeout ?? TimeSpan.FromSeconds(10);
+ return TestKit.AwaitConditionAsync(
+ () => cluster.MemberList.ContainsMemberId(member.Id),
+ waitTimeout,
+ $"Member {member.Id} was not found within {waitTimeout}");
+ }
}
diff --git a/tests/Proto.Cluster.Tests/GossipTransportTests.cs b/tests/Proto.Cluster.Tests/GossipTransportTests.cs
index 6f4c3ed91c..95beba7340 100644
--- a/tests/Proto.Cluster.Tests/GossipTransportTests.cs
+++ b/tests/Proto.Cluster.Tests/GossipTransportTests.cs
@@ -10,8 +10,8 @@
using Proto;
using Proto.Cluster;
using Proto.Cluster.Gossip;
+using Proto.TestKit;
using Xunit;
-using static Proto.TestKit.TestKit;
namespace Proto.Cluster.Tests;
@@ -41,7 +41,8 @@ public async Task Success_should_commit_offsets()
await fixture.InitializeAsync();
var cluster = fixture.Members[0];
var targetMember = fixture.Members[1].MemberList.Self;
- await AwaitConditionAsync(() => cluster.MemberList.ContainsMemberId(targetMember.Id), TimeSpan.FromSeconds(10));
+ // Wait for the cluster to register the other member before proceeding
+ await cluster.ExpectMemberToExist(targetMember);
var committed = false;
var delta = new MemberStateDelta(targetMember.Id, true, new GossipState(), () => committed = true);
var request = new GossipRequest { MemberId = cluster.System.Id, State = delta.State };
@@ -73,7 +74,8 @@ public async Task Rejection_should_not_commit_offsets()
await fixture.InitializeAsync();
var cluster = fixture.Members[0];
var targetMember = fixture.Members[1].MemberList.Self;
- await AwaitConditionAsync(() => cluster.MemberList.ContainsMemberId(targetMember.Id), TimeSpan.FromSeconds(10));
+ // Wait for the cluster to register the other member before proceeding
+ await cluster.ExpectMemberToExist(targetMember);
var committed = false;
var delta = new MemberStateDelta(targetMember.Id, true, new GossipState(), () => committed = true);
var request = new GossipRequest { MemberId = cluster.System.Id, State = delta.State };
@@ -106,7 +108,8 @@ public async Task Timeout_should_not_commit_offsets()
await fixture.InitializeAsync();
var cluster = fixture.Members[0];
var targetMember = fixture.Members[1].MemberList.Self;
- await AwaitConditionAsync(() => cluster.MemberList.ContainsMemberId(targetMember.Id), TimeSpan.FromSeconds(10));
+ // Wait for the cluster to register the other member before proceeding
+ await cluster.ExpectMemberToExist(targetMember);
var committed = false;
var delta = new MemberStateDelta(targetMember.Id, true, new GossipState(), () => committed = true);
var request = new GossipRequest { MemberId = cluster.System.Id, State = delta.State };
@@ -138,7 +141,8 @@ public async Task DeadLetter_should_not_commit_offsets()
await fixture.InitializeAsync();
var cluster = fixture.Members[0];
var targetMember = fixture.Members[1].MemberList.Self;
- await AwaitConditionAsync(() => cluster.MemberList.ContainsMemberId(targetMember.Id), TimeSpan.FromSeconds(10));
+ // Wait for the cluster to register the other member before proceeding
+ await cluster.ExpectMemberToExist(targetMember);
var committed = false;
var delta = new MemberStateDelta(targetMember.Id, true, new GossipState(), () => committed = true);
var request = new GossipRequest { MemberId = cluster.System.Id, State = delta.State };