|
72 | 72 | import io.grpc.Status.Code; |
73 | 73 | import io.grpc.SynchronizationContext; |
74 | 74 | import io.grpc.grpclb.GrpclbState.BackendEntry; |
| 75 | +import io.grpc.grpclb.GrpclbState.ChildLbPickerEntry; |
75 | 76 | import io.grpc.grpclb.GrpclbState.DropEntry; |
76 | 77 | import io.grpc.grpclb.GrpclbState.ErrorEntry; |
77 | 78 | import io.grpc.grpclb.GrpclbState.IdleSubchannelEntry; |
@@ -1933,13 +1934,31 @@ public void grpclbWorking_pickFirstMode() throws Exception { |
1933 | 1934 | // One subchannel is created by the child LB |
1934 | 1935 | assertThat(mockSubchannels).hasSize(1); |
1935 | 1936 | Subchannel subchannel = mockSubchannels.poll(); |
| 1937 | + verify(subchannel).requestConnection(); |
1936 | 1938 | assertThat(picker0.dropList).containsExactly(null, null); |
| 1939 | + assertThat(picker0.pickList).hasSize(1); |
| 1940 | + assertThat(picker0.pickList.get(0)).isInstanceOf(ChildLbPickerEntry.class); |
1937 | 1941 |
|
1938 | 1942 | // READY |
1939 | 1943 | deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY)); |
1940 | 1944 | verify(helper, atLeast(1)).updateBalancingState(eq(READY), pickerCaptor.capture()); |
1941 | 1945 | RoundRobinPicker picker1 = (RoundRobinPicker) pickerCaptor.getValue(); |
1942 | 1946 | assertThat(picker1.dropList).containsExactly(null, null); |
| 1947 | + assertThat(picker1.pickList).hasSize(1); |
| 1948 | + ChildLbPickerEntry readyEntry = (ChildLbPickerEntry) picker1.pickList.get(0); |
| 1949 | + PickResult readyResult = |
| 1950 | + readyEntry.getChildPicker().pickSubchannel(mock(PickSubchannelArgs.class)); |
| 1951 | + assertThat(readyResult.getSubchannel()).isEqualTo(subchannel); |
| 1952 | + |
| 1953 | + Status error = Status.UNAVAILABLE.withDescription("Simulated connection error"); |
| 1954 | + deliverSubchannelState(subchannel, ConnectivityStateInfo.forTransientFailure(error)); |
| 1955 | + verify(helper, atLeast(1)).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture()); |
| 1956 | + RoundRobinPicker failurePicker = (RoundRobinPicker) pickerCaptor.getValue(); |
| 1957 | + assertThat(failurePicker.pickList).hasSize(1); |
| 1958 | + ChildLbPickerEntry failureEntry = (ChildLbPickerEntry) failurePicker.pickList.get(0); |
| 1959 | + PickResult failureResult = |
| 1960 | + failureEntry.getChildPicker().pickSubchannel(mock(PickSubchannelArgs.class)); |
| 1961 | + assertThat(failureResult.getStatus()).isEqualTo(error); |
1943 | 1962 |
|
1944 | 1963 | // New server list with drops |
1945 | 1964 | List<ServerEntry> backends2 = Arrays.asList( |
@@ -2108,6 +2127,14 @@ private void pickFirstModeFallback(long timeout) throws Exception { |
2108 | 2127 | // READY |
2109 | 2128 | deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY)); |
2110 | 2129 | verify(helper, atLeast(1)).updateBalancingState(eq(READY), pickerCaptor.capture()); |
| 2130 | + deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(IDLE)); |
| 2131 | + verify(helper, atLeast(1)).updateBalancingState(eq(IDLE), pickerCaptor.capture()); |
| 2132 | + RoundRobinPicker pickerIdle = (RoundRobinPicker) pickerCaptor.getValue(); |
| 2133 | + verify(subchannel, times(1)).requestConnection(); |
| 2134 | + |
| 2135 | + // Picking while IDLE should trigger a new connection request |
| 2136 | + pickerIdle.pickSubchannel(mock(PickSubchannelArgs.class)); |
| 2137 | + verify(subchannel, times(2)).requestConnection(); |
2111 | 2138 |
|
2112 | 2139 | // Finally, an LB response, which brings us out of fallback |
2113 | 2140 | List<ServerEntry> backends1 = Arrays.asList( |
|
0 commit comments