@@ -662,7 +662,7 @@ public void nameResolutionError_emptyAddressList() {
662662 }
663663
664664 @ Test
665- public void nameResolutionAfterSufficientTFs () {
665+ public void nameResolutionAfterSufficientTFs_multipleEags () {
666666 InOrder inOrder = inOrder (mockHelper );
667667 acceptXSubchannels (3 );
668668 Status error = Status .UNAVAILABLE .withDescription ("boom!" );
@@ -707,6 +707,57 @@ public void nameResolutionAfterSufficientTFs() {
707707 inOrder .verify (mockHelper ).refreshNameResolution ();
708708 }
709709
710+ @ Test
711+ public void nameResolutionAfterSufficientTFs_singleEag () {
712+ InOrder inOrder = inOrder (mockHelper );
713+ EquivalentAddressGroup eag = new EquivalentAddressGroup (Arrays .asList (
714+ new FakeSocketAddress ("server1" ),
715+ new FakeSocketAddress ("server2" ),
716+ new FakeSocketAddress ("server3" )));
717+ loadBalancer .acceptResolvedAddresses (
718+ ResolvedAddresses .newBuilder ().setAddresses (Arrays .asList (eag )).build ());
719+ Status error = Status .UNAVAILABLE .withDescription ("boom!" );
720+
721+ // Initial subchannel gets TF, LB is still in CONNECTING
722+ verify (mockSubchannel1 ).start (stateListenerCaptor .capture ());
723+ SubchannelStateListener stateListener1 = stateListenerCaptor .getValue ();
724+ stateListener1 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
725+ inOrder .verify (mockHelper ).updateBalancingState (eq (CONNECTING ), pickerCaptor .capture ());
726+ assertEquals (Status .OK , pickerCaptor .getValue ().pickSubchannel (mockArgs ).getStatus ());
727+
728+ // Second subchannel gets TF, no UpdateBalancingState called
729+ verify (mockSubchannel2 ).start (stateListenerCaptor .capture ());
730+ SubchannelStateListener stateListener2 = stateListenerCaptor .getValue ();
731+ stateListener2 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
732+ inOrder .verify (mockHelper , never ()).refreshNameResolution ();
733+ inOrder .verify (mockHelper , never ()).updateBalancingState (any (), any ());
734+
735+ // Third subchannel gets TF, LB goes into TRANSIENT_FAILURE and does a refreshNameResolution
736+ verify (mockSubchannel3 ).start (stateListenerCaptor .capture ());
737+ SubchannelStateListener stateListener3 = stateListenerCaptor .getValue ();
738+ stateListener3 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
739+ inOrder .verify (mockHelper ).updateBalancingState (eq (TRANSIENT_FAILURE ), pickerCaptor .capture ());
740+ inOrder .verify (mockHelper ).refreshNameResolution ();
741+ assertEquals (error , pickerCaptor .getValue ().pickSubchannel (mockArgs ).getStatus ());
742+
743+ // Only after we have TFs reported for # of subchannels do we call refreshNameResolution
744+ stateListener2 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
745+ inOrder .verify (mockHelper , never ()).refreshNameResolution ();
746+ stateListener2 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
747+ inOrder .verify (mockHelper , never ()).refreshNameResolution ();
748+ stateListener2 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
749+ inOrder .verify (mockHelper ).refreshNameResolution ();
750+
751+ // Now that we have refreshed, the count should have been reset
752+ // Only after we have TFs reported for # of subchannels do we call refreshNameResolution
753+ stateListener1 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
754+ inOrder .verify (mockHelper , never ()).refreshNameResolution ();
755+ stateListener2 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
756+ inOrder .verify (mockHelper , never ()).refreshNameResolution ();
757+ stateListener3 .onSubchannelState (ConnectivityStateInfo .forTransientFailure (error ));
758+ inOrder .verify (mockHelper ).refreshNameResolution ();
759+ }
760+
710761 @ Test
711762 public void nameResolutionSuccessAfterError () {
712763 loadBalancer .handleNameResolutionError (Status .NOT_FOUND .withDescription ("nameResolutionError" ));
0 commit comments