use of io.grpc.LoadBalancer.Helper in project grpc-java by grpc.
the class ManagedChannelImplIdlenessTest method oobTransportDoesNotAffectIdleness.
@Test
public void oobTransportDoesNotAffectIdleness() {
// Start a call, which goes to delayed transport
ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
call.start(mockCallListener, new Metadata());
// Verify that we have exited the idle mode
ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
Helper helper = helperCaptor.getValue();
deliverResolutionResult();
// Fail the RPC
SubchannelPicker failingPicker = mock(SubchannelPicker.class);
when(failingPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withError(Status.UNAVAILABLE));
updateBalancingStateSafely(helper, TRANSIENT_FAILURE, failingPicker);
executor.runDueTasks();
verify(mockCallListener).onClose(same(Status.UNAVAILABLE), any(Metadata.class));
// ... so that the channel resets its in-use state
assertFalse(channel.inUseStateAggregator.isInUse());
// Now make an RPC on an OOB channel
ManagedChannel oob = helper.createOobChannel(servers, "oobauthority");
verify(mockTransportFactory, never()).newClientTransport(any(SocketAddress.class), eq(new ClientTransportFactory.ClientTransportOptions().setAuthority("oobauthority").setUserAgent(USER_AGENT)), any(ChannelLogger.class));
ClientCall<String, Integer> oobCall = oob.newCall(method, CallOptions.DEFAULT);
oobCall.start(mockCallListener2, new Metadata());
verify(mockTransportFactory).newClientTransport(any(SocketAddress.class), eq(new ClientTransportFactory.ClientTransportOptions().setAuthority("oobauthority").setUserAgent(USER_AGENT)), any(ChannelLogger.class));
MockClientTransportInfo oobTransportInfo = newTransports.poll();
assertEquals(0, newTransports.size());
// The OOB transport reports in-use state
oobTransportInfo.listener.transportInUse(true);
// But it won't stop the channel from going idle
verify(mockLoadBalancer, never()).shutdown();
timer.forwardTime(IDLE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
verify(mockLoadBalancer).shutdown();
}
use of io.grpc.LoadBalancer.Helper in project grpc-java by grpc.
the class ManagedChannelImplTest method hedgingScheduledThenChannelShutdown_hedgeShouldStillHappen_newCallShouldFail.
@Test
public void hedgingScheduledThenChannelShutdown_hedgeShouldStillHappen_newCallShouldFail() {
Map<String, Object> hedgingPolicy = new HashMap<>();
hedgingPolicy.put("maxAttempts", 3D);
hedgingPolicy.put("hedgingDelay", "10s");
hedgingPolicy.put("nonFatalStatusCodes", 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("hedgingPolicy", hedgingPolicy);
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();
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());
// in hedging delay backoff
timer.forwardTime(5, TimeUnit.SECONDS);
assertThat(timer.numPendingTasks()).isEqualTo(1);
// first hedge fails
streamListenerCaptor.getValue().closed(Status.UNAVAILABLE, PROCESSED, new Metadata());
verify(mockStream2, never()).start(any(ClientStreamListener.class));
// shutdown during backoff period
channel.shutdown();
assertThat(timer.numPendingTasks()).isEqualTo(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.numPendingTasks()).isEqualTo(1);
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());
assertThat(timer.numPendingTasks()).isEqualTo(0);
verify(mockLoadBalancer).shutdown();
// simulating the shutdown of load balancer triggers the shutdown of subchannel
shutdownSafely(helper, subchannel);
// simulating transport shutdown & terminated
transportInfo.listener.transportShutdown(Status.INTERNAL);
transportInfo.listener.transportTerminated();
assertTrue("channel.isTerminated() is expected to be true but was false", channel.isTerminated());
}
use of io.grpc.LoadBalancer.Helper in project grpc-java by grpc.
the class ManagedChannelImplTest method channelsAndSubchannels_instrumented_state.
@Test
public void channelsAndSubchannels_instrumented_state() throws Exception {
createChannel();
ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
helper = helperCaptor.getValue();
assertEquals(IDLE, getStats(channel).state);
updateBalancingStateSafely(helper, CONNECTING, mockPicker);
assertEquals(CONNECTING, getStats(channel).state);
AbstractSubchannel subchannel = (AbstractSubchannel) createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
assertEquals(IDLE, getStats(subchannel).state);
requestConnectionSafely(helper, subchannel);
assertEquals(CONNECTING, getStats(subchannel).state);
MockClientTransportInfo transportInfo = transports.poll();
assertEquals(CONNECTING, getStats(subchannel).state);
transportInfo.listener.transportReady();
assertEquals(READY, getStats(subchannel).state);
assertEquals(CONNECTING, getStats(channel).state);
updateBalancingStateSafely(helper, READY, mockPicker);
assertEquals(READY, getStats(channel).state);
channel.shutdownNow();
assertEquals(SHUTDOWN, getStats(channel).state);
assertEquals(SHUTDOWN, getStats(subchannel).state);
}
use of io.grpc.LoadBalancer.Helper in project grpc-java by grpc.
the class ManagedChannelImplTest method oobChannelWithOobChannelCredsHasChannelCallCredentials.
@Test
public void oobChannelWithOobChannelCredsHasChannelCallCredentials() {
Metadata.Key<String> metadataKey = Metadata.Key.of("token", Metadata.ASCII_STRING_MARSHALLER);
String channelCredValue = "channel-provided call cred";
when(mockTransportFactory.swapChannelCredentials(any(CompositeChannelCredentials.class))).thenAnswer(new Answer<SwapChannelCredentialsResult>() {
@Override
public SwapChannelCredentialsResult answer(InvocationOnMock invocation) {
CompositeChannelCredentials c = invocation.getArgument(0, CompositeChannelCredentials.class);
return new SwapChannelCredentialsResult(mockTransportFactory, c.getCallCredentials());
}
});
channelBuilder = new ManagedChannelImplBuilder(TARGET, InsecureChannelCredentials.create(), new FakeCallCredentials(metadataKey, channelCredValue), new UnsupportedClientTransportFactoryBuilder(), new FixedPortProvider(DEFAULT_PORT));
channelBuilder.disableRetry();
configureBuilder(channelBuilder);
createChannel();
// Verify that the normal channel has call creds, to validate configuration
Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
requestConnectionSafely(helper, subchannel);
MockClientTransportInfo transportInfo = transports.poll();
transportInfo.listener.transportReady();
when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
updateBalancingStateSafely(helper, READY, mockPicker);
String callCredValue = "per-RPC call cred";
CallOptions callOptions = CallOptions.DEFAULT.withCallCredentials(new FakeCallCredentials(metadataKey, callCredValue));
Metadata headers = new Metadata();
ClientCall<String, Integer> call = channel.newCall(method, callOptions);
call.start(mockCallListener, headers);
verify(transportInfo.transport).newStream(same(method), same(headers), same(callOptions), ArgumentMatchers.<ClientStreamTracer[]>any());
assertThat(headers.getAll(metadataKey)).containsExactly(channelCredValue, callCredValue).inOrder();
// Verify that resolving oob channel with oob channel creds provides call creds
String oobChannelCredValue = "oob-channel-provided call cred";
ChannelCredentials oobChannelCreds = CompositeChannelCredentials.create(InsecureChannelCredentials.create(), new FakeCallCredentials(metadataKey, oobChannelCredValue));
ManagedChannel oob = helper.createResolvingOobChannelBuilder("fake://oobauthority/", oobChannelCreds).nameResolverFactory(new FakeNameResolverFactory.Builder(URI.create("fake://oobauthority/")).build()).defaultLoadBalancingPolicy(MOCK_POLICY_NAME).idleTimeout(ManagedChannelImplBuilder.IDLE_MODE_MAX_TIMEOUT_DAYS, TimeUnit.DAYS).disableRetry().build();
oob.getState(true);
ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(Helper.class);
verify(mockLoadBalancerProvider, times(2)).newLoadBalancer(helperCaptor.capture());
Helper oobHelper = helperCaptor.getValue();
subchannel = createSubchannelSafely(oobHelper, addressGroup, Attributes.EMPTY, subchannelStateListener);
requestConnectionSafely(oobHelper, subchannel);
transportInfo = transports.poll();
transportInfo.listener.transportReady();
SubchannelPicker mockPicker2 = mock(SubchannelPicker.class);
when(mockPicker2.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
updateBalancingStateSafely(oobHelper, READY, mockPicker2);
headers = new Metadata();
call = oob.newCall(method, callOptions);
call.start(mockCallListener2, headers);
// CallOptions may contain StreamTracerFactory for census that is added by default.
verify(transportInfo.transport).newStream(same(method), same(headers), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
assertThat(headers.getAll(metadataKey)).containsExactly(oobChannelCredValue, callCredValue).inOrder();
oob.shutdownNow();
}
use of io.grpc.LoadBalancer.Helper in project grpc-java by grpc.
the class ManagedChannelImplTest method subchannelConnectionBroken_ignoreRefreshNameResolutionCheck_noRefresh.
@Test
public void subchannelConnectionBroken_ignoreRefreshNameResolutionCheck_noRefresh() {
FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress))).build();
channelBuilder.nameResolverFactory(nameResolverFactory);
createChannel();
FakeNameResolverFactory.FakeNameResolver resolver = Iterables.getOnlyElement(nameResolverFactory.resolvers);
assertThat(resolver.refreshCalled).isEqualTo(0);
ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(Helper.class);
verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
helper = helperCaptor.getValue();
helper.ignoreRefreshNameResolutionCheck();
Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
InternalSubchannel internalSubchannel = (InternalSubchannel) subchannel.getInternalSubchannel();
internalSubchannel.obtainActiveTransport();
MockClientTransportInfo transportInfo = transports.poll();
// Break subchannel connection
transportInfo.listener.transportShutdown(Status.UNAVAILABLE.withDescription("unreachable"));
assertThat(logs).isEmpty();
assertThat(resolver.refreshCalled).isEqualTo(0);
}
Aggregations