Skip to content

Commit 0ebea3e

Browse files
authored
grpctest: add test coverages of ExitIdle (#8375)
Fixes: #8118
1 parent e847f29 commit 0ebea3e

File tree

1 file changed

+207
-1
lines changed

1 file changed

+207
-1
lines changed

internal/balancergroup/balancergroup_test.go

Lines changed: 207 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,67 @@ func (s) TestBalancerGroupBuildOptions(t *testing.T) {
484484
}
485485
}
486486

487+
func (s) TestBalancerGroup_UpdateClientConnState_AfterClose(t *testing.T) {
488+
balancerName := t.Name()
489+
clientConnStateCh := make(chan struct{}, 1)
490+
491+
stub.Register(balancerName, stub.BalancerFuncs{
492+
UpdateClientConnState: func(_ *stub.BalancerData, _ balancer.ClientConnState) error {
493+
clientConnStateCh <- struct{}{}
494+
return nil
495+
},
496+
})
497+
498+
bg := New(Options{
499+
CC: testutils.NewBalancerClientConn(t),
500+
BuildOpts: balancer.BuildOptions{},
501+
StateAggregator: nil,
502+
Logger: nil,
503+
})
504+
505+
bg.Add(testBalancerIDs[0], balancer.Get(balancerName))
506+
bg.Close()
507+
508+
if err := bg.UpdateClientConnState(testBalancerIDs[0], balancer.ClientConnState{}); err != nil {
509+
t.Fatalf("Expected nil error, got %v", err)
510+
}
511+
512+
select {
513+
case <-clientConnStateCh:
514+
t.Fatalf("UpdateClientConnState was called after BalancerGroup was closed")
515+
case <-time.After(defaultTestShortTimeout):
516+
}
517+
}
518+
519+
func (s) TestBalancerGroup_ResolverError_AfterClose(t *testing.T) {
520+
balancerName := t.Name()
521+
resolveErrorCh := make(chan struct{}, 1)
522+
523+
stub.Register(balancerName, stub.BalancerFuncs{
524+
ResolverError: func(_ *stub.BalancerData, _ error) {
525+
resolveErrorCh <- struct{}{}
526+
},
527+
})
528+
529+
bg := New(Options{
530+
CC: testutils.NewBalancerClientConn(t),
531+
BuildOpts: balancer.BuildOptions{},
532+
StateAggregator: nil,
533+
Logger: nil,
534+
})
535+
536+
bg.Add(testBalancerIDs[0], balancer.Get(balancerName))
537+
bg.Close()
538+
539+
bg.ResolverError(errors.New("test error"))
540+
541+
select {
542+
case <-resolveErrorCh:
543+
t.Fatalf("ResolverError was called on sub-balancer after BalancerGroup was closed")
544+
case <-time.After(defaultTestShortTimeout):
545+
}
546+
}
547+
487548
func (s) TestBalancerExitIdleOne(t *testing.T) {
488549
const balancerName = "stub-balancer-test-balancergroup-exit-idle-one"
489550
exitIdleCh := make(chan struct{}, 1)
@@ -505,7 +566,7 @@ func (s) TestBalancerExitIdleOne(t *testing.T) {
505566
builder := balancer.Get(balancerName)
506567
bg.Add(testBalancerIDs[0], builder)
507568

508-
// Call ExitIdle on the child policy.
569+
// Call ExitIdleOne on the child policy.
509570
bg.ExitIdleOne(testBalancerIDs[0])
510571
select {
511572
case <-time.After(time.Second):
@@ -514,6 +575,62 @@ func (s) TestBalancerExitIdleOne(t *testing.T) {
514575
}
515576
}
516577

578+
func (s) TestBalancerGroup_ExitIdleOne_AfterClose(t *testing.T) {
579+
balancerName := t.Name()
580+
exitIdleCh := make(chan struct{})
581+
582+
stub.Register(balancerName, stub.BalancerFuncs{
583+
ExitIdle: func(_ *stub.BalancerData) {
584+
close(exitIdleCh)
585+
},
586+
})
587+
588+
bg := New(Options{
589+
CC: testutils.NewBalancerClientConn(t),
590+
BuildOpts: balancer.BuildOptions{},
591+
StateAggregator: nil,
592+
Logger: nil,
593+
})
594+
595+
bg.Add(testBalancerIDs[0], balancer.Get(balancerName))
596+
bg.Close()
597+
bg.ExitIdleOne(testBalancerIDs[0])
598+
599+
select {
600+
case <-time.After(defaultTestShortTimeout):
601+
case <-exitIdleCh:
602+
t.Fatalf("ExitIdleOne called ExitIdle on sub-balancer after BalancerGroup was closed")
603+
}
604+
}
605+
606+
func (s) TestBalancerGroup_ExitIdleOne_NonExistentID(t *testing.T) {
607+
balancerName := t.Name()
608+
exitIdleCh := make(chan struct{}, 1)
609+
610+
stub.Register(balancerName, stub.BalancerFuncs{
611+
ExitIdle: func(_ *stub.BalancerData) {
612+
exitIdleCh <- struct{}{}
613+
},
614+
})
615+
616+
bg := New(Options{
617+
CC: testutils.NewBalancerClientConn(t),
618+
BuildOpts: balancer.BuildOptions{},
619+
StateAggregator: nil,
620+
Logger: nil,
621+
})
622+
defer bg.Close()
623+
624+
bg.Add(testBalancerIDs[0], balancer.Get(balancerName))
625+
bg.ExitIdleOne("non-existent-id")
626+
627+
select {
628+
case <-time.After(defaultTestShortTimeout):
629+
case <-exitIdleCh:
630+
t.Fatalf("ExitIdleOne called ExitIdle on wrong sub-balancer ID")
631+
}
632+
}
633+
517634
// TestBalancerGracefulSwitch tests the graceful switch functionality for a
518635
// child of the balancer group. At first, the child is configured as a round
519636
// robin load balancer, and thus should behave accordingly. The test then
@@ -639,3 +756,92 @@ func (s) TestBalancerGracefulSwitch(t *testing.T) {
639756
}
640757
}
641758
}
759+
760+
func (s) TestBalancerExitIdle_All(t *testing.T) {
761+
balancer1 := t.Name() + "-1"
762+
balancer2 := t.Name() + "-2"
763+
764+
testID1, testID2 := testBalancerIDs[0], testBalancerIDs[1]
765+
766+
exitIdleCh1, exitIdleCh2 := make(chan struct{}, 1), make(chan struct{}, 1)
767+
768+
stub.Register(balancer1, stub.BalancerFuncs{
769+
ExitIdle: func(_ *stub.BalancerData) {
770+
exitIdleCh1 <- struct{}{}
771+
},
772+
})
773+
774+
stub.Register(balancer2, stub.BalancerFuncs{
775+
ExitIdle: func(_ *stub.BalancerData) {
776+
exitIdleCh2 <- struct{}{}
777+
},
778+
})
779+
780+
cc := testutils.NewBalancerClientConn(t)
781+
bg := New(Options{
782+
CC: cc,
783+
BuildOpts: balancer.BuildOptions{},
784+
StateAggregator: nil,
785+
Logger: nil,
786+
})
787+
defer bg.Close()
788+
789+
bg.Add(testID1, balancer.Get(balancer1))
790+
bg.Add(testID2, balancer.Get(balancer2))
791+
792+
bg.ExitIdle()
793+
794+
errCh := make(chan error, 2)
795+
796+
go func() {
797+
select {
798+
case <-exitIdleCh1:
799+
errCh <- nil
800+
case <-time.After(defaultTestTimeout):
801+
errCh <- fmt.Errorf("timeout waiting for ExitIdle on balancer1")
802+
}
803+
}()
804+
805+
go func() {
806+
select {
807+
case <-exitIdleCh2:
808+
errCh <- nil
809+
case <-time.After(defaultTestTimeout):
810+
errCh <- fmt.Errorf("timeout waiting for ExitIdle on balancer2")
811+
}
812+
}()
813+
814+
for i := 0; i < 2; i++ {
815+
if err := <-errCh; err != nil {
816+
t.Fatal(err)
817+
}
818+
}
819+
}
820+
821+
func (s) TestBalancerGroup_ExitIdle_AfterClose(t *testing.T) {
822+
balancerName := t.Name()
823+
exitIdleCh := make(chan struct{}, 1)
824+
825+
stub.Register(balancerName, stub.BalancerFuncs{
826+
ExitIdle: func(_ *stub.BalancerData) {
827+
exitIdleCh <- struct{}{}
828+
},
829+
})
830+
831+
bg := New(Options{
832+
CC: testutils.NewBalancerClientConn(t),
833+
BuildOpts: balancer.BuildOptions{},
834+
StateAggregator: nil,
835+
Logger: nil,
836+
})
837+
838+
bg.Add(testBalancerIDs[0], balancer.Get(balancerName))
839+
bg.Close()
840+
bg.ExitIdle()
841+
842+
select {
843+
case <-exitIdleCh:
844+
t.Fatalf("ExitIdle was called on sub-balancer even after BalancerGroup was closed")
845+
case <-time.After(defaultTestShortTimeout):
846+
}
847+
}

0 commit comments

Comments
 (0)