util: Status desc for outlier detection ejection (#11036) · grpc/grpc-java@10cb4a3
@@ -19,8 +19,8 @@
1919import static com.google.common.truth.Truth.assertThat;
2020import static com.google.common.truth.Truth.assertWithMessage;
2121import static io.grpc.ConnectivityState.READY;
22+import static io.grpc.ConnectivityState.TRANSIENT_FAILURE;
2223import static org.mockito.ArgumentMatchers.any;
23-import static org.mockito.ArgumentMatchers.eq;
2424import static org.mockito.Mockito.doAnswer;
2525import static org.mockito.Mockito.mock;
2626import static org.mockito.Mockito.times;
5050import io.grpc.LoadBalancerProvider;
5151import io.grpc.Metadata;
5252import io.grpc.Status;
53+import io.grpc.Status.Code;
5354import io.grpc.SynchronizationContext;
5455import io.grpc.internal.FakeClock;
5556import io.grpc.internal.FakeClock.ScheduledTask;
@@ -1203,9 +1204,21 @@ public void successRateAndFailurePercentage_successRateOutlier_() { // with heal
12031204// The one subchannel that was returning errors should be ejected.
12041205assertEjectedSubchannels(ImmutableSet.of(ImmutableSet.copyOf(servers.get(0).getAddresses())));
12051206if (hasHealthConsumer) {
1206-verify(healthListeners.get(servers.get(0))).onSubchannelState(eq(
1207-ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE)
1208- ));
1207+ArgumentCaptor<ConnectivityStateInfo> csiCaptor = ArgumentCaptor.forClass(
1208+ConnectivityStateInfo.class);
1209+verify(healthListeners.get(servers.get(0)), times(2)).onSubchannelState(csiCaptor.capture());
1210+List<ConnectivityStateInfo> connectivityStateInfos = csiCaptor.getAllValues();
1211+1212+// The subchannel went through two state transitions...
1213+assertThat(connectivityStateInfos).hasSize(2);
1214+// ...it first went to the READY state...
1215+assertThat(connectivityStateInfos.get(0).getState()).isEqualTo(READY);
1216+1217+// ...and then to TRANSIENT_FAILURE as outlier detection ejected it.
1218+assertThat(connectivityStateInfos.get(1).getState()).isEqualTo(TRANSIENT_FAILURE);
1219+assertThat(connectivityStateInfos.get(1).getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
1220+assertThat(connectivityStateInfos.get(1).getStatus().getDescription()).isEqualTo(
1221+"The subchannel has been ejected by outlier detection");
12091222 }
12101223 }
12111224@@ -1264,9 +1277,21 @@ public void successRateAndFailurePercentage_errorPercentageOutlier_() { // with
12641277// The one subchannel that was returning errors should be ejected.
12651278assertEjectedSubchannels(ImmutableSet.of(ImmutableSet.copyOf(servers.get(0).getAddresses())));
12661279if (hasHealthConsumer) {
1267-verify(healthListeners.get(servers.get(0))).onSubchannelState(eq(
1268-ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE)
1269- ));
1280+ArgumentCaptor<ConnectivityStateInfo> csiCaptor = ArgumentCaptor.forClass(
1281+ConnectivityStateInfo.class);
1282+verify(healthListeners.get(servers.get(0)), times(2)).onSubchannelState(csiCaptor.capture());
1283+List<ConnectivityStateInfo> connectivityStateInfos = csiCaptor.getAllValues();
1284+1285+// The subchannel went through two state transitions...
1286+assertThat(connectivityStateInfos).hasSize(2);
1287+// ...it first went to the READY state...
1288+assertThat(connectivityStateInfos.get(0).getState()).isEqualTo(READY);
1289+1290+// ...and then to TRANSIENT_FAILURE as outlier detection ejected it.
1291+assertThat(connectivityStateInfos.get(1).getState()).isEqualTo(TRANSIENT_FAILURE);
1292+assertThat(connectivityStateInfos.get(1).getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
1293+assertThat(connectivityStateInfos.get(1).getStatus().getDescription()).isEqualTo(
1294+"The subchannel has been ejected by outlier detection");
12701295 }
12711296 }
12721297