@@ -13,10 +13,12 @@ import (
13
13
"fmt"
14
14
"reflect"
15
15
"sync"
16
+ "sync/atomic"
16
17
"testing"
17
18
"time"
18
19
19
20
"go.mongodb.org/mongo-driver/v2/bson"
21
+ "go.mongodb.org/mongo-driver/v2/event"
20
22
"go.mongodb.org/mongo-driver/v2/internal/assert"
21
23
"go.mongodb.org/mongo-driver/v2/internal/integration/mtest"
22
24
"go.mongodb.org/mongo-driver/v2/internal/mongoutil"
@@ -508,6 +510,78 @@ func TestSessionsProse(t *testing.T) {
508
510
assert .True (mt , limitedSessionUse , limitedSessMsg , len (ops ))
509
511
510
512
})
513
+
514
+ mt .ResetClient (options .Client ())
515
+ client := mt .Client
516
+ heartbeatStarted := make (chan struct {}, 1 )
517
+ heartbeatSucceeded := make (chan struct {}, 1 )
518
+ var clusterTimeAdvanced uint32
519
+ serverMonitor := & event.ServerMonitor {
520
+ ServerHeartbeatStarted : func (* event.ServerHeartbeatStartedEvent ) {
521
+ if atomic .LoadUint32 (& clusterTimeAdvanced ) == 1 {
522
+ select {
523
+ case heartbeatStarted <- struct {}{}:
524
+ // NOOP
525
+ default :
526
+ // NOOP
527
+ }
528
+ }
529
+ },
530
+ ServerHeartbeatSucceeded : func (* event.ServerHeartbeatSucceededEvent ) {
531
+ if atomic .LoadUint32 (& clusterTimeAdvanced ) == 1 {
532
+ select {
533
+ case heartbeatSucceeded <- struct {}{}:
534
+ // NOOP
535
+ default :
536
+ // NOOP
537
+ }
538
+ }
539
+ },
540
+ }
541
+ pingOpts := mtest .NewOptions ().
542
+ CreateCollection (false ).
543
+ ClientOptions (options .Client ().
544
+ SetServerMonitor (serverMonitor ).
545
+ SetHeartbeatInterval (500 * time .Millisecond ). // Minimum interval
546
+ SetDirect (true )).
547
+ ClientType (mtest .Pinned )
548
+ mt .RunOpts ("20 Drivers do not gossip $clusterTime on SDAM commands" , pingOpts , func (mt * mtest.T ) {
549
+ wait := func (mt * mtest.T , ch <- chan struct {}, label string ) {
550
+ mt .Helper ()
551
+
552
+ select {
553
+ case <- ch :
554
+ case <- time .After (5 * time .Second ):
555
+ mt .Fatalf ("timed out waiting for %s" , label )
556
+ }
557
+ }
558
+
559
+ err := mt .Client .Ping (context .Background (), readpref .Primary ())
560
+ assert .NoError (mt , err , "expected no error, got: %v" , err )
561
+
562
+ _ , err = client .Database ("test" ).Collection ("test" ).InsertOne (context .Background (), bson.D {{"advance" , "$clusterTime" }})
563
+ require .NoError (mt , err , "expected no error inserting document, got: %v" , err )
564
+
565
+ atomic .StoreUint32 (& clusterTimeAdvanced , 1 )
566
+ wait (mt , heartbeatStarted , "ServerHeartbeatStartedEvent" )
567
+ wait (mt , heartbeatSucceeded , "ServerHeartbeatSucceededEvent" )
568
+
569
+ err = mt .Client .Ping (context .Background (), readpref .Primary ())
570
+ require .NoError (mt , err , "expected no error, got: %v" , err )
571
+
572
+ succeededEvents := mt .GetAllSucceededEvents ()
573
+ require .Len (mt , succeededEvents , 2 , "expected 2 succeeded events, got: %v" , len (succeededEvents ))
574
+ require .Equal (mt , "ping" , succeededEvents [0 ].CommandName , "expected first command to be ping, got: %v" , succeededEvents [0 ].CommandName )
575
+ initialClusterTime , err := succeededEvents [0 ].Reply .LookupErr ("$clusterTime" )
576
+ require .NoError (mt , err , "$clusterTime not found in response" )
577
+
578
+ startedEvents := mt .GetAllStartedEvents ()
579
+ require .Len (mt , startedEvents , 2 , "expected 2 started events, got: %v" , len (startedEvents ))
580
+ require .Equal (mt , "ping" , startedEvents [1 ].CommandName , "expected second command to be ping, got: %v" , startedEvents [1 ].CommandName )
581
+ currentClusterTime , err := startedEvents [1 ].Command .LookupErr ("$clusterTime" )
582
+ require .NoError (mt , err , "$clusterTime not found in command" )
583
+ assert .Equal (mt , initialClusterTime , currentClusterTime , "expected same cluster time, got %v and %v" , initialClusterTime , currentClusterTime )
584
+ })
511
585
}
512
586
513
587
type sessionFunction struct {
0 commit comments