@@ -484,6 +484,67 @@ func (s) TestBalancerGroupBuildOptions(t *testing.T) {
484
484
}
485
485
}
486
486
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
+
487
548
func (s ) TestBalancerExitIdleOne (t * testing.T ) {
488
549
const balancerName = "stub-balancer-test-balancergroup-exit-idle-one"
489
550
exitIdleCh := make (chan struct {}, 1 )
@@ -505,7 +566,7 @@ func (s) TestBalancerExitIdleOne(t *testing.T) {
505
566
builder := balancer .Get (balancerName )
506
567
bg .Add (testBalancerIDs [0 ], builder )
507
568
508
- // Call ExitIdle on the child policy.
569
+ // Call ExitIdleOne on the child policy.
509
570
bg .ExitIdleOne (testBalancerIDs [0 ])
510
571
select {
511
572
case <- time .After (time .Second ):
@@ -514,6 +575,62 @@ func (s) TestBalancerExitIdleOne(t *testing.T) {
514
575
}
515
576
}
516
577
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
+
517
634
// TestBalancerGracefulSwitch tests the graceful switch functionality for a
518
635
// child of the balancer group. At first, the child is configured as a round
519
636
// robin load balancer, and thus should behave accordingly. The test then
@@ -639,3 +756,92 @@ func (s) TestBalancerGracefulSwitch(t *testing.T) {
639
756
}
640
757
}
641
758
}
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