|
37 | 37 | import com.google.common.collect.Maps; |
38 | 38 | import com.google.protobuf.Duration; |
39 | 39 | import io.grpc.Attributes; |
| 40 | +import io.grpc.CallOptions; |
40 | 41 | import io.grpc.Channel; |
41 | 42 | import io.grpc.ClientCall; |
42 | 43 | import io.grpc.ConnectivityState; |
|
52 | 53 | import io.grpc.LoadBalancer.SubchannelPicker; |
53 | 54 | import io.grpc.LoadBalancer.SubchannelStateListener; |
54 | 55 | import io.grpc.LongCounterMetricInstrument; |
| 56 | +import io.grpc.Metadata; |
55 | 57 | import io.grpc.MetricRecorder; |
| 58 | +import io.grpc.MetricSink; |
| 59 | +import io.grpc.NoopMetricSink; |
| 60 | +import io.grpc.ServerCall; |
| 61 | +import io.grpc.ServerServiceDefinition; |
56 | 62 | import io.grpc.Status; |
57 | 63 | import io.grpc.SynchronizationContext; |
| 64 | +import io.grpc.inprocess.InProcessChannelBuilder; |
| 65 | +import io.grpc.inprocess.InProcessServerBuilder; |
58 | 66 | import io.grpc.internal.FakeClock; |
59 | 67 | import io.grpc.internal.GrpcUtil; |
60 | 68 | import io.grpc.internal.TestUtils; |
| 69 | +import io.grpc.internal.testing.StreamRecorder; |
61 | 70 | import io.grpc.services.InternalCallMetricRecorder; |
62 | 71 | import io.grpc.services.MetricReport; |
| 72 | +import io.grpc.stub.ClientCalls; |
| 73 | +import io.grpc.stub.StreamObserver; |
| 74 | +import io.grpc.testing.GrpcCleanupRule; |
| 75 | +import io.grpc.testing.TestMethodDescriptors; |
63 | 76 | import io.grpc.util.AbstractTestHelper; |
64 | 77 | import io.grpc.util.MultiChildLoadBalancer.ChildLbState; |
65 | 78 | import io.grpc.xds.WeightedRoundRobinLoadBalancer.StaticStrideScheduler; |
|
100 | 113 | public class WeightedRoundRobinLoadBalancerTest { |
101 | 114 | @Rule |
102 | 115 | public final MockitoRule mockito = MockitoJUnit.rule(); |
| 116 | + @Rule |
| 117 | + public final GrpcCleanupRule grpcCleanupRule = new GrpcCleanupRule(); |
103 | 118 |
|
104 | 119 | private final TestHelper testHelperInstance; |
105 | 120 | private final Helper helper; |
@@ -1234,6 +1249,50 @@ public void metrics() { |
1234 | 1249 | verifyNoMoreInteractions(mockMetricRecorder); |
1235 | 1250 | } |
1236 | 1251 |
|
| 1252 | + @Test |
| 1253 | + public void metricWithRealChannel() throws Exception { |
| 1254 | + String serverName = "wrr-metrics"; |
| 1255 | + grpcCleanupRule.register( |
| 1256 | + InProcessServerBuilder.forName(serverName) |
| 1257 | + .addService(ServerServiceDefinition.builder( |
| 1258 | + TestMethodDescriptors.voidMethod().getServiceName()) |
| 1259 | + .addMethod(TestMethodDescriptors.voidMethod(), (call, headers) -> { |
| 1260 | + call.sendHeaders(new Metadata()); |
| 1261 | + call.sendMessage(null); |
| 1262 | + call.close(Status.OK, new Metadata()); |
| 1263 | + return new ServerCall.Listener<Void>() {}; |
| 1264 | + }) |
| 1265 | + .build()) |
| 1266 | + .directExecutor() |
| 1267 | + .build() |
| 1268 | + .start()); |
| 1269 | + MetricSink metrics = mock(MetricSink.class, delegatesTo(new NoopMetricSink())); |
| 1270 | + Channel channel = grpcCleanupRule.register( |
| 1271 | + InProcessChannelBuilder.forName(serverName) |
| 1272 | + .defaultServiceConfig(Collections.singletonMap( |
| 1273 | + "loadBalancingConfig", Arrays.asList(Collections.singletonMap( |
| 1274 | + "weighted_round_robin", Collections.emptyMap())))) |
| 1275 | + .addMetricSink(metrics) |
| 1276 | + .directExecutor() |
| 1277 | + .build()); |
| 1278 | + |
| 1279 | + // Ping-pong to wait for channel to fully start |
| 1280 | + StreamRecorder<Void> recorder = StreamRecorder.create(); |
| 1281 | + StreamObserver<Void> requestObserver = ClientCalls.asyncClientStreamingCall( |
| 1282 | + channel.newCall(TestMethodDescriptors.voidMethod(), CallOptions.DEFAULT), recorder); |
| 1283 | + requestObserver.onCompleted(); |
| 1284 | + assertThat(recorder.awaitCompletion(10, TimeUnit.SECONDS)).isTrue(); |
| 1285 | + assertThat(recorder.getError()).isNull(); |
| 1286 | + |
| 1287 | + // Make sure at least one metric works. The other tests will make sure other metrics and the |
| 1288 | + // edge cases are working. |
| 1289 | + verify(metrics).addLongCounter( |
| 1290 | + argThat((instr) -> instr.getName().equals("grpc.lb.wrr.rr_fallback")), |
| 1291 | + eq(1L), |
| 1292 | + eq(Arrays.asList("directaddress:///wrr-metrics")), |
| 1293 | + eq(Arrays.asList(""))); |
| 1294 | + } |
| 1295 | + |
1237 | 1296 | // Verifies that the MetricRecorder has been called to record a long counter value of 1 for the |
1238 | 1297 | // given metric name, the given number of times |
1239 | 1298 | private void verifyLongCounterRecord(String name, int times, long value) { |
|
0 commit comments