ManagedChannelImpl extends ManagedChannel implements WithLogId { @Override public <ReqT, RespT> ClientCall<ReqT, RespT> newCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions) { return interceptorChannel.newCall(method, callOptions); } ManagedChannelImpl(String target, BackoffPolicy.Provider backoffPolicyProvider,
      NameResolver.Factory nameResolverFactory, Attributes nameResolverParams,
      LoadBalancer.Factory loadBalancerFactory, ClientTransportFactory transportFactory,
      DecompressorRegistry decompressorRegistry, CompressorRegistry compressorRegistry,
      @Nullable Executor executor, @Nullable String userAgent,
      List<ClientInterceptor> interceptors); @Override ManagedChannelImpl shutdown(); @Override ManagedChannelImpl shutdownNow(); @Override boolean isShutdown(); @Override boolean awaitTermination(long timeout, TimeUnit unit); @Override boolean isTerminated(); @Override ClientCall<ReqT, RespT> newCall(MethodDescriptor<ReqT, RespT> method,
      CallOptions callOptions); @Override String authority(); @Override String getLogId();  }
@Test public void immediateDeadlineExceeded() { ManagedChannel channel = createChannel( new FakeNameResolverFactory(true), NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT.withDeadlineAfter(0, TimeUnit.NANOSECONDS)); call.start(mockCallListener, new Metadata()); verify(mockCallListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class)); Status status = statusCaptor.getValue(); assertSame(Status.DEADLINE_EXCEEDED.getCode(), status.getCode()); }
@Test public void interceptor() throws Exception { final AtomicLong atomic = new AtomicLong(); ClientInterceptor interceptor = new ClientInterceptor() { @Override public <RequestT, ResponseT> ClientCall<RequestT, ResponseT> interceptCall( MethodDescriptor<RequestT, ResponseT> method, CallOptions callOptions, Channel next) { atomic.set(1); return next.newCall(method, callOptions); } }; ManagedChannel channel = createChannel( new FakeNameResolverFactory(true), Arrays.asList(interceptor)); assertNotNull(channel.newCall(method, CallOptions.DEFAULT)); assertEquals(1, atomic.get()); }
@Test public void callOptionsExecutor() { Metadata headers = new Metadata(); ClientStream mockStream = mock(ClientStream.class); when(mockTransport.newStream(same(method), same(headers))).thenReturn(mockStream); FakeClock fakeExecutor = new FakeClock(); ManagedChannel channel = createChannel( new FakeNameResolverFactory(true), NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT.withExecutor( fakeExecutor.scheduledExecutorService)); call.start(mockCallListener, headers); verify(mockTransport, timeout(1000)).start(transportListenerCaptor.capture()); transportListenerCaptor.getValue().transportReady(); verify(mockTransport, timeout(1000)).newStream(same(method), same(headers)); verify(mockStream, timeout(1000)).start(streamListenerCaptor.capture()); ClientStreamListener streamListener = streamListenerCaptor.getValue(); Metadata trailers = new Metadata(); assertEquals(0, fakeExecutor.numPendingTasks()); streamListener.closed(Status.CANCELLED, trailers); verify(mockCallListener, never()).onClose(same(Status.CANCELLED), same(trailers)); assertEquals(1, fakeExecutor.runDueTasks()); verify(mockCallListener).onClose(same(Status.CANCELLED), same(trailers)); }
@Test public void nameResolutionFailed() { Status error = Status.UNAVAILABLE.withCause(new Throwable("fake name resolution error")); ManagedChannel channel = createChannel(new FailingNameResolverFactory(error), NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT); call.start(mockCallListener, new Metadata()); verify(mockCallListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class)); Status status = statusCaptor.getValue(); assertSame(error.getCode(), status.getCode()); assertSame(error.getCause(), status.getCause()); assertEquals(1, loadBalancerFactory.balancers.size()); verify(loadBalancerFactory.balancers.get(0)).handleNameResolutionError(same(error)); }
@Test public void nameResolverReturnsEmptyList() { String errorDescription = "NameResolver returned an empty list"; ManagedChannel channel = createChannel( new FakeNameResolverFactory(new ArrayList<ResolvedServerInfo>()), NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT); call.start(mockCallListener, new Metadata()); verify(mockCallListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class)); Status status = statusCaptor.getValue(); assertSame(Status.Code.UNAVAILABLE, status.getCode()); assertTrue(status.getDescription(), status.getDescription().contains(errorDescription)); assertEquals(1, loadBalancerFactory.balancers.size()); verify(loadBalancerFactory.balancers.get(0)).handleNameResolutionError(statusCaptor.capture()); status = statusCaptor.getValue(); assertSame(Status.Code.UNAVAILABLE, status.getCode()); assertEquals(errorDescription, status.getDescription()); }
@Test public void loadBalancerThrowsInHandleResolvedAddresses() { RuntimeException ex = new RuntimeException("simulated"); FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(false); ManagedChannel channel = createChannel(nameResolverFactory, NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT); call.start(mockCallListener, new Metadata()); assertEquals(1, loadBalancerFactory.balancers.size()); LoadBalancer<?> loadBalancer = loadBalancerFactory.balancers.get(0); doThrow(ex).when(loadBalancer).handleResolvedAddresses( Matchers.<List<ResolvedServerInfo>>anyObject(), any(Attributes.class)); nameResolverFactory.allResolved(); verify(mockCallListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class)); Status status = statusCaptor.getValue(); assertSame(Status.Code.INTERNAL, status.getCode()); assertSame(ex, status.getCause()); verify(loadBalancer).handleNameResolutionError(statusCaptor.capture()); status = statusCaptor.getValue(); assertSame(Status.Code.INTERNAL, status.getCode()); assertSame(ex, status.getCause()); }
@Test public void firstResolvedServerFailedToConnect() throws Exception { final SocketAddress goodAddress = new SocketAddress() { @Override public String toString() { return "goodAddress"; } }; final SocketAddress badAddress = new SocketAddress() { @Override public String toString() { return "badAddress"; } }; final ResolvedServerInfo goodServer = new ResolvedServerInfo(goodAddress, Attributes.EMPTY); final ResolvedServerInfo badServer = new ResolvedServerInfo(badAddress, Attributes.EMPTY); final ManagedClientTransport goodTransport = mock(ManagedClientTransport.class); final ManagedClientTransport badTransport = mock(ManagedClientTransport.class); when(goodTransport.newStream(any(MethodDescriptor.class), any(Metadata.class))) .thenReturn(mock(ClientStream.class)); when(mockTransportFactory.newClientTransport(same(goodAddress), any(String.class))) .thenReturn(goodTransport); when(mockTransportFactory.newClientTransport(same(badAddress), any(String.class))) .thenReturn(badTransport); FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(Arrays.asList(badServer, goodServer)); ManagedChannel channel = createChannel(nameResolverFactory, NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT); Metadata headers = new Metadata(); call.start(mockCallListener, headers); ArgumentCaptor<ManagedClientTransport.Listener> badTransportListenerCaptor = ArgumentCaptor.forClass(ManagedClientTransport.Listener.class); verify(badTransport, timeout(1000)).start(badTransportListenerCaptor.capture()); verify(mockTransportFactory).newClientTransport(same(badAddress), any(String.class)); verify(mockTransportFactory, times(0)) .newClientTransport(same(goodAddress), any(String.class)); badTransportListenerCaptor.getValue().transportShutdown(Status.UNAVAILABLE); ArgumentCaptor<ManagedClientTransport.Listener> goodTransportListenerCaptor = ArgumentCaptor.forClass(ManagedClientTransport.Listener.class); verify(mockTransportFactory, timeout(1000)) .newClientTransport(same(goodAddress), any(String.class)); verify(goodTransport, timeout(1000)).start(goodTransportListenerCaptor.capture()); goodTransportListenerCaptor.getValue().transportReady(); verify(goodTransport, timeout(1000)).newStream(same(method), same(headers)); verify(badTransport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class)); }
@Test public void allServersFailedToConnect() throws Exception { final SocketAddress addr1 = new SocketAddress() { @Override public String toString() { return "addr1"; } }; final SocketAddress addr2 = new SocketAddress() { @Override public String toString() { return "addr2"; } }; final ResolvedServerInfo server1 = new ResolvedServerInfo(addr1, Attributes.EMPTY); final ResolvedServerInfo server2 = new ResolvedServerInfo(addr2, Attributes.EMPTY); final ManagedClientTransport transport1 = mock(ManagedClientTransport.class); final ManagedClientTransport transport2 = mock(ManagedClientTransport.class); when(mockTransportFactory.newClientTransport(same(addr1), any(String.class))) .thenReturn(transport1); when(mockTransportFactory.newClientTransport(same(addr2), any(String.class))) .thenReturn(transport2); FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(Arrays.asList(server1, server2)); ManagedChannel channel = createChannel(nameResolverFactory, NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT); Metadata headers = new Metadata(); call.start(mockCallListener, headers); verify(transport1, timeout(1000)).start(transportListenerCaptor.capture()); verify(mockTransportFactory).newClientTransport(same(addr1), any(String.class)); verify(mockTransportFactory, times(0)) .newClientTransport(same(addr2), any(String.class)); transportListenerCaptor.getValue().transportShutdown(Status.UNAVAILABLE); verify(transport2, timeout(1000)).start(transportListenerCaptor.capture()); verify(mockTransportFactory).newClientTransport(same(addr2), any(String.class)); verify(transport2, timeout(1000)).start(transportListenerCaptor.capture()); transportListenerCaptor.getValue().transportShutdown(Status.UNAVAILABLE); verify(mockCallListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class)); assertEquals(Status.Code.UNAVAILABLE, statusCaptor.getValue().getCode()); verify(transport1, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class)); verify(transport2, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class)); }
@Test public void firstResolvedServerConnectedThenDisconnected() throws Exception { final SocketAddress addr1 = new SocketAddress() { @Override public String toString() { return "addr1"; } }; final SocketAddress addr2 = new SocketAddress() { @Override public String toString() { return "addr2"; } }; final ResolvedServerInfo server1 = new ResolvedServerInfo(addr1, Attributes.EMPTY); final ResolvedServerInfo server2 = new ResolvedServerInfo(addr2, Attributes.EMPTY); final ManagedClientTransport transport1 = mock(ManagedClientTransport.class); final ManagedClientTransport transport2 = mock(ManagedClientTransport.class); when(transport1.newStream(any(MethodDescriptor.class), any(Metadata.class))) .thenReturn(mock(ClientStream.class)); when(transport2.newStream(any(MethodDescriptor.class), any(Metadata.class))) .thenReturn(mock(ClientStream.class)); when(mockTransportFactory.newClientTransport(same(addr1), any(String.class))) .thenReturn(transport1, transport2); FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(Arrays.asList(server1, server2)); ManagedChannel channel = createChannel(nameResolverFactory, NO_INTERCEPTOR); ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT); Metadata headers = new Metadata(); call.start(mockCallListener, headers); verify(mockTransportFactory, timeout(1000)).newClientTransport(same(addr1), any(String.class)); verify(transport1, timeout(1000)).start(transportListenerCaptor.capture()); transportListenerCaptor.getValue().transportReady(); verify(transport1, timeout(1000)).newStream(same(method), same(headers)); transportListenerCaptor.getValue().transportShutdown(Status.UNAVAILABLE); ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT); call2.start(mockCallListener, headers); verify(transport2, timeout(1000)).start(transportListenerCaptor.capture()); verify(mockTransportFactory, times(2)).newClientTransport(same(addr1), any(String.class)); transportListenerCaptor.getValue().transportReady(); verify(transport2, timeout(1000)).newStream(same(method), same(headers)); }