Skip to content

Commit 4807763

Browse files
committed
chore(test): parallelise version matrix
Run the producer and consumer loops in parallel to speedup the FVT
1 parent b12642e commit 4807763

File tree

4 files changed

+82
-40
lines changed

4 files changed

+82
-40
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ test: $(GOBIN)/tparse
3333
|| NO_COLOR=1 $(GOBIN)/tparse -format markdown -file output.json -all >"$${GITHUB_STEP_SUMMARY:-/dev/null}"
3434
.PHONY: test_functional
3535
test_functional: $(GOBIN)/tparse
36-
$(GOTEST) -timeout 12m -tags=functional -json ./... \
36+
$(GOTEST) -timeout 15m -tags=functional -json ./... \
3737
| tee output.json | $(GOBIN)/tparse -follow -all
3838
[ -z "$${GITHUB_STEP_SUMMARY:-}" ] \
3939
|| NO_COLOR=1 $(GOBIN)/tparse -format markdown -file output.json -all >"$${GITHUB_STEP_SUMMARY:-/dev/null}"

functional_consumer_test.go

+79-39
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
"testing"
1717
"time"
1818

19+
"golang.org/x/sync/errgroup"
20+
1921
"github.com/stretchr/testify/require"
2022
)
2123

@@ -439,33 +441,44 @@ func versionRange(lower KafkaVersion) []KafkaVersion {
439441

440442
func produceMsgs(t *testing.T, clientVersions []KafkaVersion, codecs []CompressionCodec, flush int, countPerVerCodec int, idempotent bool) []*ProducerMessage {
441443
var (
442-
wg sync.WaitGroup
443444
producers []SyncProducer
444445
producedMessagesMu sync.Mutex
445446
producedMessages []*ProducerMessage
446447
)
448+
g := errgroup.Group{}
447449
for _, prodVer := range clientVersions {
448450
for _, codec := range codecs {
449-
t.Run("producer-"+prodVer.String()+"-"+codec.String(), func(t *testing.T) {
450-
t.Logf("*** Producing with client version %s codec %s\n", prodVer, codec)
451-
prodCfg := NewTestConfig()
452-
prodCfg.Version = prodVer
453-
prodCfg.Producer.Return.Successes = true
454-
prodCfg.Producer.Return.Errors = true
455-
prodCfg.Producer.Flush.MaxMessages = flush
456-
prodCfg.Producer.Compression = codec
457-
prodCfg.Producer.Idempotent = idempotent
458-
if idempotent {
459-
prodCfg.Producer.RequiredAcks = WaitForAll
460-
prodCfg.Net.MaxOpenRequests = 1
461-
}
451+
prodCfg := NewTestConfig()
452+
prodCfg.ClientID = t.Name() + "-Producer-" + prodVer.String()
453+
if idempotent {
454+
prodCfg.ClientID += "-idempotent"
455+
}
456+
if codec > 0 {
457+
prodCfg.ClientID += "-" + codec.String()
458+
}
459+
prodCfg.Metadata.Full = false
460+
prodCfg.Version = prodVer
461+
prodCfg.Producer.Return.Successes = true
462+
prodCfg.Producer.Return.Errors = true
463+
prodCfg.Producer.Flush.MaxMessages = flush
464+
prodCfg.Producer.Compression = codec
465+
prodCfg.Producer.Idempotent = idempotent
466+
if idempotent {
467+
prodCfg.Producer.RequiredAcks = WaitForAll
468+
prodCfg.Net.MaxOpenRequests = 1
469+
}
462470

463-
p, err := NewSyncProducer(FunctionalTestEnv.KafkaBrokerAddrs, prodCfg)
464-
if err != nil {
465-
t.Errorf("Failed to create producer: version=%s, compression=%s, err=%v", prodVer, codec, err)
466-
return
467-
}
468-
producers = append(producers, p)
471+
p, err := NewSyncProducer(FunctionalTestEnv.KafkaBrokerAddrs, prodCfg)
472+
if err != nil {
473+
t.Fatalf("Failed to create producer: version=%s, compression=%s, err=%v", prodVer, codec, err)
474+
}
475+
producers = append(producers, p)
476+
477+
prodVer := prodVer
478+
codec := codec
479+
g.Go(func() error {
480+
t.Logf("*** Producing with client version %s codec %s\n", prodVer, codec)
481+
var wg sync.WaitGroup
469482
for i := 0; i < countPerVerCodec; i++ {
470483
msg := &ProducerMessage{
471484
Topic: "test.1",
@@ -483,10 +496,14 @@ func produceMsgs(t *testing.T, clientVersions []KafkaVersion, codecs []Compressi
483496
producedMessagesMu.Unlock()
484497
}()
485498
}
499+
wg.Wait()
500+
return nil
486501
})
487502
}
488503
}
489-
wg.Wait()
504+
if err := g.Wait(); err != nil {
505+
t.Fatal(err)
506+
}
490507

491508
for _, p := range producers {
492509
safeClose(t, p)
@@ -496,6 +513,7 @@ func produceMsgs(t *testing.T, clientVersions []KafkaVersion, codecs []Compressi
496513
sort.Slice(producedMessages, func(i, j int) bool {
497514
return producedMessages[i].Offset < producedMessages[j].Offset
498515
})
516+
require.NotEmpty(t, producedMessages, "should have produced >0 messages")
499517
t.Logf("*** Total produced %d, firstOffset=%d, lastOffset=%d\n",
500518
len(producedMessages), producedMessages[0].Offset, producedMessages[len(producedMessages)-1].Offset)
501519
return producedMessages
@@ -504,26 +522,33 @@ func produceMsgs(t *testing.T, clientVersions []KafkaVersion, codecs []Compressi
504522
func consumeMsgs(t *testing.T, clientVersions []KafkaVersion, producedMessages []*ProducerMessage) {
505523
// Consume all produced messages with all client versions supported by the
506524
// cluster.
525+
g := errgroup.Group{}
507526
for _, consVer := range clientVersions {
508-
t.Run("consumer-"+consVer.String(), func(t *testing.T) {
509-
t.Logf("*** Consuming with client version %s\n", consVer)
510-
// Create a partition consumer that should start from the first produced
511-
// message.
512-
consCfg := NewTestConfig()
513-
consCfg.Version = consVer
514-
c, err := NewConsumer(FunctionalTestEnv.KafkaBrokerAddrs, consCfg)
515-
if err != nil {
516-
t.Fatal(err)
517-
}
518-
defer safeClose(t, c)
519-
pc, err := c.ConsumePartition("test.1", 0, producedMessages[0].Offset)
520-
if err != nil {
521-
t.Fatal(err)
522-
}
523-
defer safeClose(t, pc)
527+
// Create a partition consumer that should start from the first produced
528+
// message.
529+
consCfg := NewTestConfig()
530+
consCfg.ClientID = t.Name() + "-Consumer-" + consVer.String()
531+
consCfg.Consumer.MaxProcessingTime = time.Second
532+
consCfg.Metadata.Full = false
533+
consCfg.Version = consVer
534+
c, err := NewConsumer(FunctionalTestEnv.KafkaBrokerAddrs, consCfg)
535+
if err != nil {
536+
t.Fatal(err)
537+
}
538+
defer safeClose(t, c)
539+
pc, err := c.ConsumePartition("test.1", 0, producedMessages[0].Offset)
540+
if err != nil {
541+
t.Fatal(err)
542+
}
543+
defer safeClose(t, pc)
524544

545+
var wg sync.WaitGroup
546+
wg.Add(1)
547+
consVer := consVer
548+
g.Go(func() error {
525549
// Consume as many messages as there have been produced and make sure that
526550
// order is preserved.
551+
t.Logf("*** Consuming with client version %s\n", consVer)
527552
for i, prodMsg := range producedMessages {
528553
select {
529554
case consMsg := <-pc.Messages():
@@ -535,10 +560,25 @@ func consumeMsgs(t *testing.T, clientVersions []KafkaVersion, producedMessages [
535560
t.Fatalf("Consumed unexpected msg: version=%s, index=%d, want=%s, got=%s",
536561
consVer, i, prodMsg2Str(prodMsg), consMsg2Str(consMsg))
537562
}
538-
case <-time.After(3 * time.Second):
539-
t.Fatalf("Timeout waiting for: index=%d, offset=%d, msg=%s", i, prodMsg.Offset, prodMsg.Value)
563+
if i == 0 {
564+
t.Logf("Consumed first msg: version=%s, index=%d, got=%s",
565+
consVer, i, consMsg2Str(consMsg))
566+
wg.Done()
567+
}
568+
if i%1000 == 0 {
569+
t.Logf("Consumed messages: version=%s, index=%d, got=%s",
570+
consVer, i, consMsg2Str(consMsg))
571+
}
572+
case <-time.After(15 * time.Second):
573+
t.Fatalf("Timeout %s waiting for: index=%d, offset=%d, msg=%s",
574+
consCfg.ClientID, i, prodMsg.Offset, prodMsg.Value)
540575
}
541576
}
577+
return nil
542578
})
579+
wg.Wait() // wait for first message to be consumed before starting next consumer
580+
}
581+
if err := g.Wait(); err != nil {
582+
t.Fatal(err)
543583
}
544584
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ require (
2121
github.com/xdg-go/scram v1.1.1
2222
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
2323
golang.org/x/net v0.0.0-20220708220712-1185a9018129
24+
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
2425
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
2526
)
2627

go.sum

+1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
333333
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
334334
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
335335
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
336+
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
336337
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
337338
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
338339
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

0 commit comments

Comments
 (0)