use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.
the class ManagedChannelImplTest method resetConnectBackoff_noOpWithoutPendingResolverBackoff.
@Test
public void resetConnectBackoff_noOpWithoutPendingResolverBackoff() {
FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress))).build();
channelBuilder.nameResolverFactory(nameResolverFactory);
createChannel();
FakeNameResolverFactory.FakeNameResolver nameResolver = nameResolverFactory.resolvers.get(0);
assertEquals(0, nameResolver.refreshCalled);
channel.resetConnectBackoff();
assertEquals(0, nameResolver.refreshCalled);
}
use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.
the class ManagedChannelImplTest method loadBalancerThrowsInHandleResolvedAddresses.
@Test
public void loadBalancerThrowsInHandleResolvedAddresses() {
RuntimeException ex = new RuntimeException("simulated");
// Delay the success of name resolution until allResolved() is called
FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setResolvedAtStart(false).setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress))).build();
channelBuilder.nameResolverFactory(nameResolverFactory);
createChannel();
verify(mockLoadBalancerProvider).newLoadBalancer(any(Helper.class));
doThrow(ex).when(mockLoadBalancer).handleResolvedAddresses(any(ResolvedAddresses.class));
// NameResolver returns addresses.
nameResolverFactory.allResolved();
// Exception thrown from balancer is caught by ChannelExecutor, making channel enter panic mode.
verifyPanicMode(ex);
}
use of io.grpc.EquivalentAddressGroup 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.EquivalentAddressGroup in project grpc-java by grpc.
the class ManagedChannelImplTest method badServiceConfigIsRecoverable.
@Test
public void badServiceConfigIsRecoverable() throws Exception {
final List<EquivalentAddressGroup> addresses = ImmutableList.of(new EquivalentAddressGroup(new SocketAddress() {
}));
final class FakeNameResolver extends NameResolver {
Listener2 listener;
@Override
public String getServiceAuthority() {
return "also fake";
}
@Override
public void start(Listener2 listener) {
this.listener = listener;
listener.onResult(ResolutionResult.newBuilder().setAddresses(addresses).setServiceConfig(ConfigOrError.fromError(Status.INTERNAL.withDescription("kaboom is invalid"))).build());
}
@Override
public void shutdown() {
}
}
final class FakeNameResolverFactory2 extends NameResolver.Factory {
FakeNameResolver resolver;
@Nullable
@Override
public NameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
return (resolver = new FakeNameResolver());
}
@Override
public String getDefaultScheme() {
return "fake";
}
}
FakeNameResolverFactory2 factory = new FakeNameResolverFactory2();
ManagedChannelImplBuilder customBuilder = new ManagedChannelImplBuilder(TARGET, new ClientTransportFactoryBuilder() {
@Override
public ClientTransportFactory buildClientTransportFactory() {
return mockTransportFactory;
}
}, null);
customBuilder.executorPool = executorPool;
customBuilder.channelz = channelz;
ManagedChannel mychannel = customBuilder.nameResolverFactory(factory).build();
ClientCall<Void, Void> call1 = mychannel.newCall(TestMethodDescriptors.voidMethod(), CallOptions.DEFAULT);
ListenableFuture<Void> future1 = ClientCalls.futureUnaryCall(call1, null);
executor.runDueTasks();
try {
future1.get(1, TimeUnit.SECONDS);
Assert.fail();
} catch (ExecutionException e) {
assertThat(Throwables.getStackTraceAsString(e.getCause())).contains("kaboom");
}
// ok the service config is bad, let's fix it.
Map<String, Object> rawServiceConfig = parseConfig("{\"loadBalancingConfig\": [{\"round_robin\": {}}]}");
Object fakeLbConfig = new Object();
PolicySelection lbConfigs = new PolicySelection(mockLoadBalancerProvider, fakeLbConfig);
mockLoadBalancerProvider.parseLoadBalancingPolicyConfig(rawServiceConfig);
ManagedChannelServiceConfig managedChannelServiceConfig = createManagedChannelServiceConfig(rawServiceConfig, lbConfigs);
factory.resolver.listener.onResult(ResolutionResult.newBuilder().setAddresses(addresses).setServiceConfig(ConfigOrError.fromConfig(managedChannelServiceConfig)).build());
ClientCall<Void, Void> call2 = mychannel.newCall(TestMethodDescriptors.voidMethod(), CallOptions.DEFAULT.withDeadlineAfter(5, TimeUnit.SECONDS));
ListenableFuture<Void> future2 = ClientCalls.futureUnaryCall(call2, null);
timer.forwardTime(1234, TimeUnit.SECONDS);
executor.runDueTasks();
try {
future2.get();
Assert.fail();
} catch (ExecutionException e) {
assertThat(Throwables.getStackTraceAsString(e.getCause())).contains("deadline");
}
mychannel.shutdownNow();
}
use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.
the class ManagedChannelImplIdlenessTest method updateSubchannelAddresses_existingAddressDoesNotConnect.
@Test
public void updateSubchannelAddresses_existingAddressDoesNotConnect() {
ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
// Create LB
call.start(mockCallListener, new Metadata());
ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
deliverResolutionResult();
Helper helper = helperCaptor.getValue();
Subchannel subchannel = createSubchannelSafely(helper, servers.get(0), Attributes.EMPTY);
requestConnectionSafely(helper, subchannel);
MockClientTransportInfo t0 = newTransports.poll();
t0.listener.transportReady();
List<SocketAddress> changedList = new ArrayList<>(servers.get(0).getAddresses());
changedList.add(new FakeSocketAddress("aDifferentServer"));
updateSubchannelAddressesSafely(helper, subchannel, new EquivalentAddressGroup(changedList));
requestConnectionSafely(helper, subchannel);
assertNull(newTransports.poll());
}
Aggregations