use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.
the class ManagedChannelImplTest method retryBackoffThenChannelShutdown_retryShouldStillHappen_newCallShouldFail.
@Test
public void retryBackoffThenChannelShutdown_retryShouldStillHappen_newCallShouldFail() {
Map<String, Object> retryPolicy = new HashMap<>();
retryPolicy.put("maxAttempts", 3D);
retryPolicy.put("initialBackoff", "10s");
retryPolicy.put("maxBackoff", "30s");
retryPolicy.put("backoffMultiplier", 2D);
retryPolicy.put("retryableStatusCodes", Arrays.<Object>asList("UNAVAILABLE"));
Map<String, Object> methodConfig = new HashMap<>();
Map<String, Object> name = new HashMap<>();
name.put("service", "service");
methodConfig.put("name", Arrays.<Object>asList(name));
methodConfig.put("retryPolicy", retryPolicy);
Map<String, Object> rawServiceConfig = new HashMap<>();
rawServiceConfig.put("methodConfig", Arrays.<Object>asList(methodConfig));
FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress))).build();
ManagedChannelServiceConfig managedChannelServiceConfig = createManagedChannelServiceConfig(rawServiceConfig, null);
nameResolverFactory.nextConfigOrError.set(ConfigOrError.fromConfig(managedChannelServiceConfig));
channelBuilder.nameResolverFactory(nameResolverFactory);
channelBuilder.executor(MoreExecutors.directExecutor());
channelBuilder.enableRetry();
RetriableStream.setRandom(// not random
new Random() {
@Override
public double nextDouble() {
// fake random
return 1D;
}
});
requestConnection = false;
createChannel();
ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
call.start(mockCallListener, new Metadata());
ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(Helper.class);
verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
helper = helperCaptor.getValue();
verify(mockLoadBalancer).handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(nameResolverFactory.servers).build());
// simulating request connection and then transport ready after resolved address
Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
requestConnectionSafely(helper, subchannel);
MockClientTransportInfo transportInfo = transports.poll();
ConnectionClientTransport mockTransport = transportInfo.transport;
ClientStream mockStream = mock(ClientStream.class);
ClientStream mockStream2 = mock(ClientStream.class);
when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream).thenReturn(mockStream2);
transportInfo.listener.transportReady();
updateBalancingStateSafely(helper, READY, mockPicker);
ArgumentCaptor<ClientStreamListener> streamListenerCaptor = ArgumentCaptor.forClass(ClientStreamListener.class);
verify(mockStream).start(streamListenerCaptor.capture());
assertThat(timer.getPendingTasks()).isEmpty();
// trigger retry
streamListenerCaptor.getValue().closed(Status.UNAVAILABLE, PROCESSED, new Metadata());
// in backoff
timer.forwardTime(5, TimeUnit.SECONDS);
assertThat(timer.getPendingTasks()).hasSize(1);
verify(mockStream2, never()).start(any(ClientStreamListener.class));
// shutdown during backoff period
channel.shutdown();
assertThat(timer.getPendingTasks()).hasSize(1);
verify(mockCallListener, never()).onClose(any(Status.class), any(Metadata.class));
ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT);
call2.start(mockCallListener2, new Metadata());
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
verify(mockCallListener2).onClose(statusCaptor.capture(), any(Metadata.class));
assertSame(Status.Code.UNAVAILABLE, statusCaptor.getValue().getCode());
assertEquals("Channel shutdown invoked", statusCaptor.getValue().getDescription());
// backoff ends
timer.forwardTime(5, TimeUnit.SECONDS);
assertThat(timer.getPendingTasks()).isEmpty();
verify(mockStream2).start(streamListenerCaptor.capture());
verify(mockLoadBalancer, never()).shutdown();
assertFalse("channel.isTerminated() is expected to be false but was true", channel.isTerminated());
streamListenerCaptor.getValue().closed(Status.INTERNAL, PROCESSED, new Metadata());
verify(mockLoadBalancer).shutdown();
// simulating the shutdown of load balancer triggers the shutdown of subchannel
shutdownSafely(helper, subchannel);
transportInfo.listener.transportShutdown(Status.INTERNAL);
// simulating transport terminated
transportInfo.listener.transportTerminated();
assertTrue("channel.isTerminated() is expected to be true but was false", channel.isTerminated());
}
use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.
the class ManagedChannelImplTest method channelsAndSubchannels_instrumented_name.
@Test
public void channelsAndSubchannels_instrumented_name() throws Exception {
createChannel();
assertEquals(TARGET, getStats(channel).target);
Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
assertEquals(Collections.singletonList(addressGroup).toString(), getStats((AbstractSubchannel) subchannel).target);
}
use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.
the class ManagedChannelImplTest method subchannelLoggerCreatedBeforeSubchannelStarted.
@Test
public void subchannelLoggerCreatedBeforeSubchannelStarted() {
createChannel();
Subchannel subchannel = createUnstartedSubchannel(helper, addressGroup, Attributes.EMPTY);
assertThat(subchannel.getChannelLogger()).isNotNull();
}
use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.
the class ManagedChannelImplTest method subchannelChannel_failWhenNotReady.
@Test
public void subchannelChannel_failWhenNotReady() {
createChannel();
Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
Channel sChannel = subchannel.asChannel();
Metadata headers = new Metadata();
requestConnectionSafely(helper, subchannel);
verify(mockTransportFactory).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
MockClientTransportInfo transportInfo = transports.poll();
ConnectionClientTransport mockTransport = transportInfo.transport;
assertEquals(0, balancerRpcExecutor.numPendingTasks());
// Subchannel is still CONNECTING, but not READY yet
ClientCall<String, Integer> call = sChannel.newCall(method, CallOptions.DEFAULT);
call.start(mockCallListener, headers);
verify(mockTransport, never()).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
verifyNoInteractions(mockCallListener);
assertEquals(1, balancerRpcExecutor.runDueTasks());
verify(mockCallListener).onClose(same(SubchannelChannel.NOT_READY_ERROR), any(Metadata.class));
}
use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.
the class ManagedChannelImplTest method pickerReturnsStreamTracer_delayed.
@Test
public void pickerReturnsStreamTracer_delayed() {
ClientStream mockStream = mock(ClientStream.class);
final ClientStreamTracer tracer1 = new ClientStreamTracer() {
};
final ClientStreamTracer tracer2 = new ClientStreamTracer() {
};
ClientStreamTracer.Factory factory1 = new ClientStreamTracer.Factory() {
@Override
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
return tracer1;
}
};
ClientStreamTracer.Factory factory2 = new ClientStreamTracer.Factory() {
@Override
public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) {
return tracer2;
}
};
createChannel();
CallOptions callOptions = CallOptions.DEFAULT.withStreamTracerFactory(factory1);
ClientCall<String, Integer> call = channel.newCall(method, callOptions);
call.start(mockCallListener, new Metadata());
Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
requestConnectionSafely(helper, subchannel);
MockClientTransportInfo transportInfo = transports.poll();
transportInfo.listener.transportReady();
ClientTransport mockTransport = transportInfo.transport;
when(mockTransport.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel, factory2));
updateBalancingStateSafely(helper, READY, mockPicker);
assertEquals(1, executor.runDueTasks());
verify(mockPicker).pickSubchannel(any(PickSubchannelArgs.class));
verify(mockTransport).newStream(same(method), any(Metadata.class), callOptionsCaptor.capture(), tracersCaptor.capture());
assertThat(tracersCaptor.getValue()).isEqualTo(new ClientStreamTracer[] { tracer1, tracer2 });
}
Aggregations