2525import static io .grpc .ConnectivityState .TRANSIENT_FAILURE ;
2626import static io .grpc .LoadBalancer .HAS_HEALTH_PRODUCER_LISTENER_KEY ;
2727import static io .grpc .LoadBalancer .HEALTH_CONSUMER_LISTENER_ARG_KEY ;
28+ import static io .grpc .LoadBalancer .IS_PETIOLE_POLICY ;
2829import static io .grpc .internal .PickFirstLeafLoadBalancer .CONNECTION_DELAY_INTERVAL_MS ;
2930import static org .junit .Assert .assertEquals ;
3031import static org .junit .Assert .assertFalse ;
@@ -389,15 +390,44 @@ public void pickAfterResolvedAndChanged() {
389390 verify (mockSubchannel2 ).requestConnection ();
390391 }
391392
393+ @ Test
394+ public void healthCheck_nonPetiolePolicy () {
395+ when (mockSubchannel1 .getAttributes ()).thenReturn (
396+ Attributes .newBuilder ().set (HAS_HEALTH_PRODUCER_LISTENER_KEY , true ).build ());
397+
398+ // Initialize with one server loadbalancer and both health and state listeners
399+ List <EquivalentAddressGroup > oneServer = Lists .newArrayList (servers .get (0 ));
400+ loadBalancer .acceptResolvedAddresses (ResolvedAddresses .newBuilder ().setAddresses (oneServer )
401+ .setAttributes (Attributes .EMPTY ).build ());
402+ InOrder inOrder = inOrder (mockHelper , mockSubchannel1 );
403+ inOrder .verify (mockHelper ).updateBalancingState (eq (CONNECTING ), any (SubchannelPicker .class ));
404+ inOrder .verify (mockHelper ).createSubchannel (createArgsCaptor .capture ());
405+ SubchannelStateListener healthListener = createArgsCaptor .getValue ()
406+ .getOption (HEALTH_CONSUMER_LISTENER_ARG_KEY );
407+ inOrder .verify (mockSubchannel1 ).start (stateListenerCaptor .capture ());
408+ SubchannelStateListener stateListener = stateListenerCaptor .getValue ();
409+
410+ stateListener .onSubchannelState (ConnectivityStateInfo .forNonError (CONNECTING ));
411+ healthListener .onSubchannelState (ConnectivityStateInfo .forNonError (CONNECTING ));
412+ inOrder .verify (mockHelper , never ()).updateBalancingState (any (), any ());
413+
414+ stateListener .onSubchannelState (ConnectivityStateInfo .forNonError (READY ));
415+ inOrder .verify (mockHelper ).updateBalancingState (eq (READY ), any ()); // health listener ignored
416+
417+ healthListener .onSubchannelState (ConnectivityStateInfo .forTransientFailure (Status .INTERNAL ));
418+ inOrder .verify (mockHelper , never ()).updateBalancingState (any (), any (SubchannelPicker .class ));
419+ }
420+
392421 @ Test
393422 public void healthCheckFlow () {
394423 when (mockSubchannel1 .getAttributes ()).thenReturn (
395424 Attributes .newBuilder ().set (HAS_HEALTH_PRODUCER_LISTENER_KEY , true ).build ());
396425 when (mockSubchannel2 .getAttributes ()).thenReturn (
397426 Attributes .newBuilder ().set (HAS_HEALTH_PRODUCER_LISTENER_KEY , true ).build ());
427+
398428 List <EquivalentAddressGroup > oneServer = Lists .newArrayList (servers .get (0 ), servers .get (1 ));
399429 loadBalancer .acceptResolvedAddresses (ResolvedAddresses .newBuilder ().setAddresses (oneServer )
400- .setAttributes (Attributes .EMPTY ).build ());
430+ .setAttributes (Attributes .newBuilder (). set ( IS_PETIOLE_POLICY , true ). build () ).build ());
401431
402432 InOrder inOrder = inOrder (mockHelper , mockSubchannel1 , mockSubchannel2 );
403433 inOrder .verify (mockHelper ).updateBalancingState (eq (CONNECTING ), any (SubchannelPicker .class ));
@@ -413,13 +443,13 @@ public void healthCheckFlow() {
413443 // subchannel2 | IDLE | IDLE
414444 stateListener .onSubchannelState (ConnectivityStateInfo .forNonError (CONNECTING ));
415445 healthListener .onSubchannelState (ConnectivityStateInfo .forNonError (CONNECTING ));
416- inOrder .verify (mockHelper , times ( 0 )).updateBalancingState (any (), any ());
446+ inOrder .verify (mockHelper , never ( )).updateBalancingState (any (), any ());
417447
418448 // subchannel | state | health
419449 // subchannel1 | READY | CONNECTING
420450 // subchannel2 | IDLE | IDLE
421451 stateListener .onSubchannelState (ConnectivityStateInfo .forNonError (READY ));
422- inOrder .verify (mockHelper , times ( 0 )).updateBalancingState (any (), any ());
452+ inOrder .verify (mockHelper , never ( )).updateBalancingState (any (), any ());
423453
424454 // subchannel | state | health
425455 // subchannel1 | READY | READY
0 commit comments