@@ -23,10 +23,11 @@ import (
2323 "testing"
2424 "time"
2525
26+ "github.com/apache/pulsar-client-go/pulsar/internal"
27+ pb "github.com/apache/pulsar-client-go/pulsar/internal/pulsar_proto"
2628 "github.com/apache/pulsar-client-go/pulsaradmin"
2729 "github.com/apache/pulsar-client-go/pulsaradmin/pkg/admin/config"
2830 "github.com/apache/pulsar-client-go/pulsaradmin/pkg/utils"
29-
3031 "github.com/stretchr/testify/assert"
3132)
3233
@@ -317,3 +318,102 @@ func runMultiTopicAckIDList(t *testing.T, regex bool) {
317318 assert .Fail (t , "AckIDList should return AckError" )
318319 }
319320}
321+
322+ type dummyConnection struct {
323+ }
324+
325+ func (dummyConnection ) SendRequest (_ uint64 , _ * pb.BaseCommand , _ func (* pb.BaseCommand , error )) {
326+ }
327+
328+ func (dummyConnection ) SendRequestNoWait (_ * pb.BaseCommand ) error {
329+ return nil
330+ }
331+
332+ func (dummyConnection ) WriteData (_ internal.Buffer ) {
333+ }
334+
335+ func (dummyConnection ) RegisterListener (_ uint64 , _ internal.ConnectionListener ) error {
336+ return nil
337+ }
338+
339+ func (dummyConnection ) UnregisterListener (_ uint64 ) {
340+ }
341+
342+ func (dummyConnection ) AddConsumeHandler (_ uint64 , _ internal.ConsumerHandler ) error {
343+ return nil
344+ }
345+
346+ func (dummyConnection ) DeleteConsumeHandler (_ uint64 ) {
347+ }
348+
349+ func (dummyConnection ) ID () string {
350+ return "cnx"
351+ }
352+
353+ func (dummyConnection ) GetMaxMessageSize () int32 {
354+ return 0
355+ }
356+
357+ func (dummyConnection ) Close () {
358+ }
359+
360+ func (dummyConnection ) WaitForClose () <- chan struct {} {
361+ return nil
362+ }
363+
364+ func (dummyConnection ) IsProxied () bool {
365+ return false
366+ }
367+
368+ func TestMultiTopicAckIDListTimeout (t * testing.T ) {
369+ topic := fmt .Sprintf ("multiTopicAckIDListTimeout%v" , time .Now ().UnixNano ())
370+ createPartitionedTopic (topic , 5 )
371+
372+ cli , err := NewClient (ClientOptions {
373+ URL : "pulsar://localhost:6650" ,
374+ OperationTimeout : 3 * time .Second ,
375+ })
376+ assert .Nil (t , err )
377+ defer cli .Close ()
378+
379+ consumer , err := cli .Subscribe (ConsumerOptions {
380+ Topic : topic ,
381+ SubscriptionName : "sub" ,
382+ AckWithResponse : true ,
383+ })
384+ assert .Nil (t , err )
385+ defer consumer .Close ()
386+
387+ const numMessages = 5
388+ sendMessages (t , cli , topic , 0 , numMessages , false )
389+ msgs := receiveMessages (t , consumer , numMessages )
390+ msgIDs := make ([]MessageID , len (msgs ))
391+
392+ var conn internal.Connection
393+ for i := 0 ; i < len (msgs ); i ++ {
394+ msgIDs [i ] = msgs [i ].ID ()
395+ pc , ok := msgIDs [i ].(* trackingMessageID ).consumer .(* partitionConsumer )
396+ assert .True (t , ok )
397+ conn = pc ._getConn ()
398+ pc ._setConn (dummyConnection {})
399+ }
400+
401+ start := time .Now ()
402+ err = consumer .AckIDList (msgIDs )
403+ elapsed := time .Since (start )
404+ t .Logf ("AckIDList takes %v msv" , elapsed )
405+ assert .True (t , elapsed < 4 * time .Second && elapsed >= 3 * time .Second )
406+ if ackError , ok := err .(AckError ); ok {
407+ for _ , err := range ackError {
408+ assert .Equal (t , "request timed out" , err .Error ())
409+ }
410+ } else {
411+ assert .Fail (t , "AckIDList should return AckError" )
412+ }
413+
414+ for i := 0 ; i < len (msgs ); i ++ {
415+ pc , ok := msgIDs [i ].(* trackingMessageID ).consumer .(* partitionConsumer )
416+ assert .True (t , ok )
417+ pc ._setConn (conn )
418+ }
419+ }
0 commit comments