@@ -30,6 +30,22 @@ func closeProducer(t *testing.T, p AsyncProducer) {
30
30
wg .Wait ()
31
31
}
32
32
33
+ func expectSuccesses (t * testing.T , p AsyncProducer , successes int ) {
34
+ for i := 0 ; i < successes ; i ++ {
35
+ select {
36
+ case msg := <- p .Errors ():
37
+ t .Error (msg .Err )
38
+ if msg .Msg .flags != 0 {
39
+ t .Error ("Message had flags set" )
40
+ }
41
+ case msg := <- p .Successes ():
42
+ if msg .flags != 0 {
43
+ t .Error ("Message had flags set" )
44
+ }
45
+ }
46
+ }
47
+ }
48
+
33
49
func TestAsyncProducer (t * testing.T ) {
34
50
seedBroker := newMockBroker (t , 1 )
35
51
leader := newMockBroker (t , 2 )
@@ -103,19 +119,7 @@ func TestAsyncProducerMultipleFlushes(t *testing.T) {
103
119
for i := 0 ; i < 5 ; i ++ {
104
120
producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage )}
105
121
}
106
- for i := 0 ; i < 5 ; i ++ {
107
- select {
108
- case msg := <- producer .Errors ():
109
- t .Error (msg .Err )
110
- if msg .Msg .flags != 0 {
111
- t .Error ("Message had flags set" )
112
- }
113
- case msg := <- producer .Successes ():
114
- if msg .flags != 0 {
115
- t .Error ("Message had flags set" )
116
- }
117
- }
118
- }
122
+ expectSuccesses (t , producer , 5 )
119
123
}
120
124
121
125
closeProducer (t , producer )
@@ -155,19 +159,7 @@ func TestAsyncProducerMultipleBrokers(t *testing.T) {
155
159
for i := 0 ; i < 10 ; i ++ {
156
160
producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage )}
157
161
}
158
- for i := 0 ; i < 10 ; i ++ {
159
- select {
160
- case msg := <- producer .Errors ():
161
- t .Error (msg .Err )
162
- if msg .Msg .flags != 0 {
163
- t .Error ("Message had flags set" )
164
- }
165
- case msg := <- producer .Successes ():
166
- if msg .flags != 0 {
167
- t .Error ("Message had flags set" )
168
- }
169
- }
170
- }
162
+ expectSuccesses (t , producer , 10 )
171
163
172
164
closeProducer (t , producer )
173
165
leader1 .Close ()
@@ -210,38 +202,14 @@ func TestAsyncProducerFailureRetry(t *testing.T) {
210
202
prodSuccess := new (ProduceResponse )
211
203
prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
212
204
leader2 .Returns (prodSuccess )
213
- for i := 0 ; i < 10 ; i ++ {
214
- select {
215
- case msg := <- producer .Errors ():
216
- t .Error (msg .Err )
217
- if msg .Msg .flags != 0 {
218
- t .Error ("Message had flags set" )
219
- }
220
- case msg := <- producer .Successes ():
221
- if msg .flags != 0 {
222
- t .Error ("Message had flags set" )
223
- }
224
- }
225
- }
205
+ expectSuccesses (t , producer , 10 )
226
206
leader1 .Close ()
227
207
228
208
for i := 0 ; i < 10 ; i ++ {
229
209
producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage )}
230
210
}
231
211
leader2 .Returns (prodSuccess )
232
- for i := 0 ; i < 10 ; i ++ {
233
- select {
234
- case msg := <- producer .Errors ():
235
- t .Error (msg .Err )
236
- if msg .Msg .flags != 0 {
237
- t .Error ("Message had flags set" )
238
- }
239
- case msg := <- producer .Successes ():
240
- if msg .flags != 0 {
241
- t .Error ("Message had flags set" )
242
- }
243
- }
244
- }
212
+ expectSuccesses (t , producer , 10 )
245
213
246
214
leader2 .Close ()
247
215
closeProducer (t , producer )
@@ -276,19 +244,7 @@ func TestAsyncProducerBrokerBounce(t *testing.T) {
276
244
prodSuccess := new (ProduceResponse )
277
245
prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
278
246
leader .Returns (prodSuccess )
279
- for i := 0 ; i < 10 ; i ++ {
280
- select {
281
- case msg := <- producer .Errors ():
282
- t .Error (msg .Err )
283
- if msg .Msg .flags != 0 {
284
- t .Error ("Message had flags set" )
285
- }
286
- case msg := <- producer .Successes ():
287
- if msg .flags != 0 {
288
- t .Error ("Message had flags set" )
289
- }
290
- }
291
- }
247
+ expectSuccesses (t , producer , 10 )
292
248
seedBroker .Close ()
293
249
leader .Close ()
294
250
@@ -331,19 +287,7 @@ func TestAsyncProducerBrokerBounceWithStaleMetadata(t *testing.T) {
331
287
prodSuccess := new (ProduceResponse )
332
288
prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
333
289
leader2 .Returns (prodSuccess )
334
- for i := 0 ; i < 10 ; i ++ {
335
- select {
336
- case msg := <- producer .Errors ():
337
- t .Error (msg .Err )
338
- if msg .Msg .flags != 0 {
339
- t .Error ("Message had flags set" )
340
- }
341
- case msg := <- producer .Successes ():
342
- if msg .flags != 0 {
343
- t .Error ("Message had flags set" )
344
- }
345
- }
346
- }
290
+ expectSuccesses (t , producer , 10 )
347
291
seedBroker .Close ()
348
292
leader2 .Close ()
349
293
@@ -391,37 +335,13 @@ func TestAsyncProducerMultipleRetries(t *testing.T) {
391
335
prodSuccess := new (ProduceResponse )
392
336
prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
393
337
leader2 .Returns (prodSuccess )
394
- for i := 0 ; i < 10 ; i ++ {
395
- select {
396
- case msg := <- producer .Errors ():
397
- t .Error (msg .Err )
398
- if msg .Msg .flags != 0 {
399
- t .Error ("Message had flags set" )
400
- }
401
- case msg := <- producer .Successes ():
402
- if msg .flags != 0 {
403
- t .Error ("Message had flags set" )
404
- }
405
- }
406
- }
338
+ expectSuccesses (t , producer , 10 )
407
339
408
340
for i := 0 ; i < 10 ; i ++ {
409
341
producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage )}
410
342
}
411
343
leader2 .Returns (prodSuccess )
412
- for i := 0 ; i < 10 ; i ++ {
413
- select {
414
- case msg := <- producer .Errors ():
415
- t .Error (msg .Err )
416
- if msg .Msg .flags != 0 {
417
- t .Error ("Message had flags set" )
418
- }
419
- case msg := <- producer .Successes ():
420
- if msg .flags != 0 {
421
- t .Error ("Message had flags set" )
422
- }
423
- }
424
- }
344
+ expectSuccesses (t , producer , 10 )
425
345
426
346
seedBroker .Close ()
427
347
leader1 .Close ()
@@ -479,13 +399,7 @@ func TestAsyncProducerOutOfRetries(t *testing.T) {
479
399
prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
480
400
leader .Returns (prodSuccess )
481
401
482
- for i := 0 ; i < 10 ; i ++ {
483
- select {
484
- case msg := <- producer .Errors ():
485
- t .Error (msg .Err )
486
- case <- producer .Successes ():
487
- }
488
- }
402
+ expectSuccesses (t , producer , 10 )
489
403
490
404
leader .Close ()
491
405
seedBroker .Close ()
@@ -518,22 +432,14 @@ func TestAsyncProducerRetryWithReferenceOpen(t *testing.T) {
518
432
prodSuccess := new (ProduceResponse )
519
433
prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
520
434
leader .Returns (prodSuccess )
521
- select {
522
- case msg := <- producer .Errors ():
523
- t .Error (msg .Err )
524
- case <- producer .Successes ():
525
- }
435
+ expectSuccesses (t , producer , 1 )
526
436
527
437
// prime partition 1
528
438
producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage )}
529
439
prodSuccess = new (ProduceResponse )
530
440
prodSuccess .AddTopicPartition ("my_topic" , 1 , ErrNoError )
531
441
leader .Returns (prodSuccess )
532
- select {
533
- case msg := <- producer .Errors ():
534
- t .Error (msg .Err )
535
- case <- producer .Successes ():
536
- }
442
+ expectSuccesses (t , producer , 1 )
537
443
538
444
// reboot the broker (the producer will get EOF on its existing connection)
539
445
leader .Close ()
@@ -549,11 +455,69 @@ func TestAsyncProducerRetryWithReferenceOpen(t *testing.T) {
549
455
prodSuccess = new (ProduceResponse )
550
456
prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
551
457
leader .Returns (prodSuccess )
552
- select {
553
- case msg := <- producer .Errors ():
554
- t .Error (msg .Err )
555
- case <- producer .Successes ():
458
+ expectSuccesses (t , producer , 1 )
459
+
460
+ // shutdown
461
+ closeProducer (t , producer )
462
+ seedBroker .Close ()
463
+ leader .Close ()
464
+ }
465
+
466
+ func TestAsyncProducerFlusherRetryCondition (t * testing.T ) {
467
+ seedBroker := newMockBroker (t , 1 )
468
+ leader := newMockBroker (t , 2 )
469
+
470
+ metadataResponse := new (MetadataResponse )
471
+ metadataResponse .AddBroker (leader .Addr (), leader .BrokerID ())
472
+ metadataResponse .AddTopicPartition ("my_topic" , 0 , leader .BrokerID (), nil , nil , ErrNoError )
473
+ metadataResponse .AddTopicPartition ("my_topic" , 1 , leader .BrokerID (), nil , nil , ErrNoError )
474
+ seedBroker .Returns (metadataResponse )
475
+
476
+ config := NewConfig ()
477
+ config .Producer .Flush .Messages = 5
478
+ config .Producer .Return .Successes = true
479
+ config .Producer .Retry .Backoff = 0
480
+ config .Producer .Retry .Max = 1
481
+ config .Producer .Partitioner = NewManualPartitioner
482
+ producer , err := NewAsyncProducer ([]string {seedBroker .Addr ()}, config )
483
+ if err != nil {
484
+ t .Fatal (err )
485
+ }
486
+
487
+ // prime partitions
488
+ for p := int32 (0 ); p < 2 ; p ++ {
489
+ for i := 0 ; i < 5 ; i ++ {
490
+ producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage ), Partition : p }
491
+ }
492
+ prodSuccess := new (ProduceResponse )
493
+ prodSuccess .AddTopicPartition ("my_topic" , p , ErrNoError )
494
+ leader .Returns (prodSuccess )
495
+ expectSuccesses (t , producer , 5 )
496
+ }
497
+
498
+ // send more messages on partition 0
499
+ for i := 0 ; i < 5 ; i ++ {
500
+ producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage ), Partition : 0 }
501
+ }
502
+ prodNotLeader := new (ProduceResponse )
503
+ prodNotLeader .AddTopicPartition ("my_topic" , 0 , ErrNotLeaderForPartition )
504
+ leader .Returns (prodNotLeader )
505
+
506
+ // tell partition 0 to go to that broker again
507
+ seedBroker .Returns (metadataResponse )
508
+
509
+ // succeed this time
510
+ prodSuccess := new (ProduceResponse )
511
+ prodSuccess .AddTopicPartition ("my_topic" , 0 , ErrNoError )
512
+ leader .Returns (prodSuccess )
513
+ expectSuccesses (t , producer , 5 )
514
+
515
+ // put five more through
516
+ for i := 0 ; i < 5 ; i ++ {
517
+ producer .Input () <- & ProducerMessage {Topic : "my_topic" , Key : nil , Value : StringEncoder (TestMessage ), Partition : 0 }
556
518
}
519
+ leader .Returns (prodSuccess )
520
+ expectSuccesses (t , producer , 5 )
557
521
558
522
// shutdown
559
523
closeProducer (t , producer )
0 commit comments