grpc: Fix flaky picker_wrapper tests (#7560)

* Wait for go routines to finish before cancelling the context

* improve error messages
This commit is contained in:
Arjan Singh Bal 2024-08-27 00:18:44 +05:30 committed by GitHub
parent 9feed00eee
commit c535946889
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 25 additions and 4 deletions

View File

@ -21,6 +21,7 @@ package grpc
import (
"context"
"fmt"
"sync"
"sync/atomic"
"testing"
"time"
@ -80,12 +81,15 @@ func (s) TestBlockingPick(t *testing.T) {
var finishedCount uint64
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()
wg := sync.WaitGroup{}
wg.Add(goroutineCount)
for i := goroutineCount; i > 0; i-- {
go func() {
if tr, _, err := bp.pick(ctx, true, balancer.PickInfo{}); err != nil || tr != testT {
t.Errorf("bp.pick returned non-nil error: %v", err)
t.Errorf("bp.pick returned transport: %v, error: %v, want transport: %v, error: nil", tr, err, testT)
}
atomic.AddUint64(&finishedCount, 1)
wg.Done()
}()
}
time.Sleep(50 * time.Millisecond)
@ -93,6 +97,8 @@ func (s) TestBlockingPick(t *testing.T) {
t.Errorf("finished goroutines count: %v, want 0", c)
}
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
// Wait for all pickers to finish before the context is cancelled.
wg.Wait()
}
func (s) TestBlockingPickNoSubAvailable(t *testing.T) {
@ -102,12 +108,15 @@ func (s) TestBlockingPickNoSubAvailable(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()
// All goroutines should block because picker returns no subConn available.
wg := sync.WaitGroup{}
wg.Add(goroutineCount)
for i := goroutineCount; i > 0; i-- {
go func() {
if tr, _, err := bp.pick(ctx, true, balancer.PickInfo{}); err != nil || tr != testT {
t.Errorf("bp.pick returned non-nil error: %v", err)
t.Errorf("bp.pick returned transport: %v, error: %v, want transport: %v, error: nil", tr, err, testT)
}
atomic.AddUint64(&finishedCount, 1)
wg.Done()
}()
}
time.Sleep(50 * time.Millisecond)
@ -115,6 +124,8 @@ func (s) TestBlockingPickNoSubAvailable(t *testing.T) {
t.Errorf("finished goroutines count: %v, want 0", c)
}
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
// Wait for all pickers to finish before the context is cancelled.
wg.Wait()
}
func (s) TestBlockingPickTransientWaitforready(t *testing.T) {
@ -125,12 +136,15 @@ func (s) TestBlockingPickTransientWaitforready(t *testing.T) {
defer cancel()
// All goroutines should block because picker returns transientFailure and
// picks are not failfast.
wg := sync.WaitGroup{}
wg.Add(goroutineCount)
for i := goroutineCount; i > 0; i-- {
go func() {
if tr, _, err := bp.pick(ctx, false, balancer.PickInfo{}); err != nil || tr != testT {
t.Errorf("bp.pick returned non-nil error: %v", err)
t.Errorf("bp.pick returned transport: %v, error: %v, want transport: %v, error: nil", tr, err, testT)
}
atomic.AddUint64(&finishedCount, 1)
wg.Done()
}()
}
time.Sleep(time.Millisecond)
@ -138,6 +152,8 @@ func (s) TestBlockingPickTransientWaitforready(t *testing.T) {
t.Errorf("finished goroutines count: %v, want 0", c)
}
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
// Wait for all pickers to finish before the context is cancelled.
wg.Wait()
}
func (s) TestBlockingPickSCNotReady(t *testing.T) {
@ -147,12 +163,15 @@ func (s) TestBlockingPickSCNotReady(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()
// All goroutines should block because subConn is not ready.
wg := sync.WaitGroup{}
wg.Add(goroutineCount)
for i := goroutineCount; i > 0; i-- {
go func() {
if tr, _, err := bp.pick(ctx, true, balancer.PickInfo{}); err != nil || tr != testT {
t.Errorf("bp.pick returned non-nil error: %v", err)
t.Errorf("bp.pick returned transport: %v, error: %v, want transport: %v, error: nil", tr, err, testT)
}
atomic.AddUint64(&finishedCount, 1)
wg.Done()
}()
}
time.Sleep(time.Millisecond)
@ -160,4 +179,6 @@ func (s) TestBlockingPickSCNotReady(t *testing.T) {
t.Errorf("finished goroutines count: %v, want 0", c)
}
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
// Wait for all pickers to finish before the context is cancelled.
wg.Wait()
}