@@ -10330,6 +10330,71 @@ func TestJetStreamClusterDeleteMsgEOF(t *testing.T) {
10330
10330
}
10331
10331
}
10332
10332
10333
+ func TestJetStreamClusterCatchupSkipMsgDesync (t * testing.T ) {
10334
+ for _ , storage := range []nats.StorageType {nats .FileStorage , nats .MemoryStorage } {
10335
+ t .Run (storage .String (), func (t * testing.T ) {
10336
+ c := createJetStreamClusterExplicit (t , "R3S" , 3 )
10337
+ defer c .shutdown ()
10338
+
10339
+ nc , js := jsClientConnect (t , c .randomServer ())
10340
+ defer nc .Close ()
10341
+
10342
+ _ , err := js .AddStream (& nats.StreamConfig {
10343
+ Name : "TEST" ,
10344
+ Subjects : []string {"foo" },
10345
+ Storage : storage ,
10346
+ Replicas : 3 ,
10347
+ })
10348
+ require_NoError (t , err )
10349
+ checkFor (t , 2 * time .Second , 200 * time .Millisecond , func () error {
10350
+ return checkState (t , c , globalAccountName , "TEST" )
10351
+ })
10352
+
10353
+ rs := c .randomNonStreamLeader (globalAccountName , "TEST" )
10354
+ mset , err := rs .globalAccount ().lookupStream ("TEST" )
10355
+ require_NoError (t , err )
10356
+ sa := mset .streamAssignment ()
10357
+
10358
+ // Make sure this server can't become the leader.
10359
+ n := mset .raftNode ().(* raft )
10360
+ n .SetObserver (true )
10361
+
10362
+ sysNc , err := nats .Connect (rs .ClientURL (), nats .UserInfo ("admin" , "s3cr3t!" ))
10363
+ require_NoError (t , err )
10364
+ defer sysNc .Close ()
10365
+
10366
+ sjs := rs .getJetStream ()
10367
+ sjs .mu .RLock ()
10368
+ syncSubj := sa .Sync
10369
+ sjs .mu .RUnlock ()
10370
+
10371
+ // Respond to the catchup with an out-of-order SkipMsg.
10372
+ var eof bool
10373
+ sub , err := sysNc .Subscribe (syncSubj , func (msg * nats.Msg ) {
10374
+ if ! eof {
10375
+ msg .Respond (encodeStreamMsg (_EMPTY_ , _EMPTY_ , nil , nil , 10 , 0 , false ))
10376
+ eof = true
10377
+ }
10378
+ msg .Respond (nil )
10379
+ })
10380
+ require_NoError (t , err )
10381
+ defer sub .Drain ()
10382
+ require_NoError (t , sysNc .Flush ()) // Must flush, otherwise our subscription could be too late.
10383
+
10384
+ err = mset .processSnapshot (& StreamReplicatedState {FirstSeq : 1 , LastSeq : 1 }, 1 )
10385
+ require_Error (t , err , errCatchupTooManyRetries )
10386
+ c .waitOnStreamLeader (globalAccountName , "TEST" )
10387
+
10388
+ pubAck , err := js .Publish ("foo" , nil )
10389
+ require_NoError (t , err )
10390
+ require_Equal (t , pubAck .Sequence , 1 )
10391
+ checkFor (t , 2 * time .Second , 200 * time .Millisecond , func () error {
10392
+ return checkState (t , c , globalAccountName , "TEST" )
10393
+ })
10394
+ })
10395
+ }
10396
+ }
10397
+
10333
10398
//
10334
10399
// DO NOT ADD NEW TESTS IN THIS FILE (unless to balance test times)
10335
10400
// Add at the end of jetstream_cluster_<n>_test.go, with <n> being the highest value.
0 commit comments