diff --git a/tests/MongoDB.Driver.Tests/Specifications/sessions/SessionsProseTests.cs b/tests/MongoDB.Driver.Tests/Specifications/sessions/SessionsProseTests.cs index c41f1e28636..be46e6acb10 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/sessions/SessionsProseTests.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/sessions/SessionsProseTests.cs @@ -21,6 +21,7 @@ using MongoDB.Bson; using MongoDB.Bson.TestHelpers; using MongoDB.Driver.Core; +using MongoDB.Driver.Core.Clusters; using MongoDB.Driver.Core.Events; using MongoDB.Driver.Core.Misc; using MongoDB.Driver.Core.TestHelpers.Logging; @@ -302,6 +303,59 @@ public async Task Ensure_server_session_are_allocated_only_on_connection_checkou await eventsTask.WithTimeout(1000); } + // https://specifications.readthedocs.io/en/latest/sessions/tests/#20-drivers-do-not-gossip-clustertime-on-sdam-commands + [Fact] + public void Ensure_cluster_times_are_not_gossiped_on_SDAM_commands() + { + RequireServer.Check().ClusterTypes(ClusterType.ReplicaSet, ClusterType.Sharded); + + var eventCapturer = new EventCapturer() + .Capture() + .Capture() + .Capture(); + + using var c1 = DriverTestConfiguration.CreateMongoClient( + settings => + { + settings.ClusterConfigurator = c => c.Subscribe(eventCapturer); + settings.DirectConnection = true; + settings.HeartbeatInterval = TimeSpan.FromMilliseconds(10); + if (settings.Servers.Count() > 1) + { + settings.Servers = settings.Servers.Take(1); + } + }); + + var pingCommand = new BsonDocument("ping", 1); + var pingResult = c1.GetDatabase("admin").RunCommand(pingCommand); + + var clusterTime = pingResult["$clusterTime"]; + + var c2 = DriverTestConfiguration.Client; + c2.GetDatabase("test").GetCollection("test").InsertOne(new BsonDocument("advance", "$clusterTime")); + + eventCapturer.Clear(); + + eventCapturer.WaitForOrThrowIfTimeout( + events => + { + var capturedEvents = events.ToArray(); + return capturedEvents.Count(e => e is ServerHeartbeatSucceededEvent) > 1 && + capturedEvents + .Where((e, i) => + e is ServerHeartbeatStartedEvent && + capturedEvents[i + 1] is ServerHeartbeatSucceededEvent) + .Any(); + }, TimeSpan.FromSeconds(1), "Didn't get any server heartbeat pairs"); + + c1.GetDatabase("admin").RunCommand(pingCommand); + + var commandStartedEvents = eventCapturer.Events.OfType().ToArray(); + commandStartedEvents.Length.Should().Be(1); + commandStartedEvents[0].CommandName.Should().Be("ping"); + commandStartedEvents[0].Command["$clusterTime"].Should().Be(clusterTime); + } + private sealed class MongocryptdContext : IDisposable { public IMongoClient MongoClient { get; }