|
28 | 28 | import static org.mockito.Mockito.atLeastOnce;
|
29 | 29 | import static org.mockito.Mockito.clearInvocations;
|
30 | 30 | import static org.mockito.Mockito.doReturn;
|
| 31 | +import static org.mockito.Mockito.inOrder; |
31 | 32 | import static org.mockito.Mockito.mock;
|
32 | 33 | import static org.mockito.Mockito.never;
|
33 | 34 | import static org.mockito.Mockito.times;
|
|
70 | 71 | import org.junit.runners.JUnit4;
|
71 | 72 | import org.mockito.ArgumentCaptor;
|
72 | 73 | import org.mockito.Captor;
|
| 74 | +import org.mockito.InOrder; |
73 | 75 | import org.mockito.Mock;
|
74 | 76 | import org.mockito.junit.MockitoJUnit;
|
75 | 77 | import org.mockito.junit.MockitoRule;
|
@@ -554,6 +556,55 @@ public void connectingResetFailOverIfSeenReadyOrIdleSinceTransientFailure() {
|
554 | 556 | assertThat(fooHelpers).hasSize(2);
|
555 | 557 | }
|
556 | 558 |
|
| 559 | + @Test |
| 560 | + public void failoverTimerNotRestartedOnDupConnecting() { |
| 561 | + InOrder inOrder = inOrder(helper); |
| 562 | + PriorityChildConfig priorityChildConfig0 = |
| 563 | + new PriorityChildConfig(newChildConfig(fooLbProvider, new Object()), true); |
| 564 | + PriorityChildConfig priorityChildConfig1 = |
| 565 | + new PriorityChildConfig(newChildConfig(fooLbProvider, new Object()), true); |
| 566 | + PriorityLbConfig priorityLbConfig = |
| 567 | + new PriorityLbConfig( |
| 568 | + ImmutableMap.of("p0", priorityChildConfig0, "p1", priorityChildConfig1), |
| 569 | + ImmutableList.of("p0", "p1")); |
| 570 | + priorityLb.acceptResolvedAddresses( |
| 571 | + ResolvedAddresses.newBuilder() |
| 572 | + .setAddresses(ImmutableList.<EquivalentAddressGroup>of()) |
| 573 | + .setLoadBalancingPolicyConfig(priorityLbConfig) |
| 574 | + .build()); |
| 575 | + // Nothing important about this verify, other than to provide a baseline |
| 576 | + inOrder.verify(helper) |
| 577 | + .updateBalancingState(eq(CONNECTING), pickerReturns(PickResult.withNoResult())); |
| 578 | + assertThat(fooBalancers).hasSize(1); |
| 579 | + assertThat(fooHelpers).hasSize(1); |
| 580 | + Helper helper0 = Iterables.getOnlyElement(fooHelpers); |
| 581 | + |
| 582 | + // Cause seenReadyOrIdleSinceTransientFailure = true |
| 583 | + helper0.updateBalancingState(IDLE, EMPTY_PICKER); |
| 584 | + inOrder.verify(helper) |
| 585 | + .updateBalancingState(eq(IDLE), pickerReturns(PickResult.withNoResult())); |
| 586 | + helper0.updateBalancingState(CONNECTING, EMPTY_PICKER); |
| 587 | + |
| 588 | + // p0 keeps repeating CONNECTING, failover happens |
| 589 | + fakeClock.forwardTime(5, TimeUnit.SECONDS); |
| 590 | + helper0.updateBalancingState(CONNECTING, EMPTY_PICKER); |
| 591 | + fakeClock.forwardTime(5, TimeUnit.SECONDS); |
| 592 | + assertThat(fooBalancers).hasSize(2); |
| 593 | + assertThat(fooHelpers).hasSize(2); |
| 594 | + inOrder.verify(helper, times(2)) |
| 595 | + .updateBalancingState(eq(CONNECTING), pickerReturns(PickResult.withNoResult())); |
| 596 | + Helper helper1 = Iterables.getLast(fooHelpers); |
| 597 | + |
| 598 | + // p0 keeps repeating CONNECTING, no reset of failover timer |
| 599 | + helper1.updateBalancingState(IDLE, EMPTY_PICKER); // Stop timer for p1 |
| 600 | + inOrder.verify(helper) |
| 601 | + .updateBalancingState(eq(IDLE), pickerReturns(PickResult.withNoResult())); |
| 602 | + helper0.updateBalancingState(CONNECTING, EMPTY_PICKER); |
| 603 | + fakeClock.forwardTime(10, TimeUnit.SECONDS); |
| 604 | + inOrder.verify(helper, never()) |
| 605 | + .updateBalancingState(eq(CONNECTING), any()); |
| 606 | + } |
| 607 | + |
557 | 608 | @Test
|
558 | 609 | public void readyToConnectDoesNotFailOverButUpdatesPicker() {
|
559 | 610 | PriorityChildConfig priorityChildConfig0 =
|
|
0 commit comments