Search in sources :

Example 21 with ClientStreamTracer

use of io.grpc.ClientStreamTracer in project grpc-java by grpc.

the class ManagedChannelImplTest method allServersFailedToConnect.

/**
 * Verify that if all resolved addresses failed to connect, a fail-fast call will fail, while a
 * wait-for-ready call will still be buffered.
 */
@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";
        }
    };
    InOrder inOrder = inOrder(mockLoadBalancer, subchannelStateListener);
    List<SocketAddress> resolvedAddrs = Arrays.asList(addr1, addr2);
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(Collections.singletonList(new EquivalentAddressGroup(resolvedAddrs))).build();
    channelBuilder.nameResolverFactory(nameResolverFactory);
    createChannel();
    // Start a wait-for-ready call
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT.withWaitForReady());
    Metadata headers = new Metadata();
    call.start(mockCallListener, headers);
    // ... and a fail-fast call
    ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT.withoutWaitForReady());
    call2.start(mockCallListener2, headers);
    executor.runDueTasks();
    // Simulate name resolution results
    EquivalentAddressGroup addressGroup = new EquivalentAddressGroup(resolvedAddrs);
    inOrder.verify(mockLoadBalancer).handleResolvedAddresses(resolvedAddressCaptor.capture());
    assertThat(resolvedAddressCaptor.getValue().getAddresses()).containsExactly(addressGroup);
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    requestConnectionSafely(helper, subchannel);
    inOrder.verify(subchannelStateListener).onSubchannelState(stateInfoCaptor.capture());
    assertEquals(CONNECTING, stateInfoCaptor.getValue().getState());
    // Connecting to server1, which will fail
    verify(mockTransportFactory).newClientTransport(same(addr1), any(ClientTransportOptions.class), any(ChannelLogger.class));
    verify(mockTransportFactory, times(0)).newClientTransport(same(addr2), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo transportInfo1 = transports.poll();
    transportInfo1.listener.transportShutdown(Status.UNAVAILABLE);
    // Connecting to server2, which will fail too
    verify(mockTransportFactory).newClientTransport(same(addr2), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo transportInfo2 = transports.poll();
    Status server2Error = Status.UNAVAILABLE.withDescription("Server2 failed to connect");
    transportInfo2.listener.transportShutdown(server2Error);
    // ... which makes the subchannel enter TRANSIENT_FAILURE. The last error Status is propagated
    // to LoadBalancer.
    inOrder.verify(subchannelStateListener).onSubchannelState(stateInfoCaptor.capture());
    assertEquals(TRANSIENT_FAILURE, stateInfoCaptor.getValue().getState());
    assertSame(server2Error, stateInfoCaptor.getValue().getStatus());
    // A typical LoadBalancer would create a picker with error
    SubchannelPicker picker2 = mock(SubchannelPicker.class);
    when(picker2.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withError(server2Error));
    updateBalancingStateSafely(helper, TRANSIENT_FAILURE, picker2);
    executor.runDueTasks();
    // ... which fails the fail-fast call
    verify(mockCallListener2).onClose(same(server2Error), any(Metadata.class));
    // ... while the wait-for-ready call stays
    verifyNoMoreInteractions(mockCallListener);
    // No real stream was ever created
    verify(transportInfo1.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
    verify(transportInfo2.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
}
Also used : Status(io.grpc.Status) ClientStreamTracer(io.grpc.ClientStreamTracer) InOrder(org.mockito.InOrder) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) ClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions) MethodDescriptor(io.grpc.MethodDescriptor) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) ChannelLogger(io.grpc.ChannelLogger) ProxiedSocketAddress(io.grpc.ProxiedSocketAddress) SocketAddress(java.net.SocketAddress) Test(org.junit.Test)

Example 22 with ClientStreamTracer

use of io.grpc.ClientStreamTracer in project grpc-java by grpc.

the class ManagedChannelImplTest method channelsAndSubchannels_oob_instrumented0.

private void channelsAndSubchannels_oob_instrumented0(boolean success) throws Exception {
    // set up
    ClientStream mockStream = mock(ClientStream.class);
    createChannel();
    OobChannel oobChannel = (OobChannel) helper.createOobChannel(Collections.singletonList(addressGroup), "oobauthority");
    AbstractSubchannel oobSubchannel = (AbstractSubchannel) oobChannel.getSubchannel();
    FakeClock callExecutor = new FakeClock();
    CallOptions options = CallOptions.DEFAULT.withExecutor(callExecutor.getScheduledExecutorService());
    ClientCall<String, Integer> call = oobChannel.newCall(method, options);
    Metadata headers = new Metadata();
    // Channel stat bumped when ClientCall.start() called
    assertEquals(0, getStats(oobChannel).callsStarted);
    call.start(mockCallListener, headers);
    assertEquals(1, getStats(oobChannel).callsStarted);
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ManagedClientTransport.Listener transportListener = transportInfo.listener;
    when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
    // subchannel stat bumped when call gets assigned to it
    assertEquals(0, getStats(oobSubchannel).callsStarted);
    transportListener.transportReady();
    callExecutor.runDueTasks();
    verify(mockStream).start(streamListenerCaptor.capture());
    assertEquals(1, getStats(oobSubchannel).callsStarted);
    ClientStreamListener streamListener = streamListenerCaptor.getValue();
    call.halfClose();
    // closing stream listener affects subchannel stats immediately
    assertEquals(0, getStats(oobSubchannel).callsSucceeded);
    assertEquals(0, getStats(oobSubchannel).callsFailed);
    streamListener.closed(success ? Status.OK : Status.UNKNOWN, PROCESSED, new Metadata());
    if (success) {
        assertEquals(1, getStats(oobSubchannel).callsSucceeded);
        assertEquals(0, getStats(oobSubchannel).callsFailed);
    } else {
        assertEquals(0, getStats(oobSubchannel).callsSucceeded);
        assertEquals(1, getStats(oobSubchannel).callsFailed);
    }
    // channel stats bumped when the ClientCall.Listener is notified
    assertEquals(0, getStats(oobChannel).callsSucceeded);
    assertEquals(0, getStats(oobChannel).callsFailed);
    callExecutor.runDueTasks();
    if (success) {
        assertEquals(1, getStats(oobChannel).callsSucceeded);
        assertEquals(0, getStats(oobChannel).callsFailed);
    } else {
        assertEquals(0, getStats(oobChannel).callsSucceeded);
        assertEquals(1, getStats(oobChannel).callsFailed);
    }
    // oob channel is separate from the original channel
    assertEquals(0, getStats(channel).callsSucceeded);
    assertEquals(0, getStats(channel).callsFailed);
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions)

Example 23 with ClientStreamTracer

use of io.grpc.ClientStreamTracer in project grpc-java by grpc.

the class ManagedChannelImplTest method firstResolvedServerFailedToConnect.

/**
 * Verify that if the first resolved address points to a server that cannot be connected, the call
 * will end up with the second address which works.
 */
@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";
        }
    };
    InOrder inOrder = inOrder(mockLoadBalancer, subchannelStateListener);
    List<SocketAddress> resolvedAddrs = Arrays.asList(badAddress, goodAddress);
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(Collections.singletonList(new EquivalentAddressGroup(resolvedAddrs))).build();
    channelBuilder.nameResolverFactory(nameResolverFactory);
    createChannel();
    // Start the call
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    Metadata headers = new Metadata();
    call.start(mockCallListener, headers);
    executor.runDueTasks();
    // Simulate name resolution results
    EquivalentAddressGroup addressGroup = new EquivalentAddressGroup(resolvedAddrs);
    inOrder.verify(mockLoadBalancer).handleResolvedAddresses(resolvedAddressCaptor.capture());
    assertThat(resolvedAddressCaptor.getValue().getAddresses()).containsExactly(addressGroup);
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    requestConnectionSafely(helper, subchannel);
    inOrder.verify(subchannelStateListener).onSubchannelState(stateInfoCaptor.capture());
    assertEquals(CONNECTING, stateInfoCaptor.getValue().getState());
    // The channel will starts with the first address (badAddress)
    verify(mockTransportFactory).newClientTransport(same(badAddress), any(ClientTransportOptions.class), any(ChannelLogger.class));
    verify(mockTransportFactory, times(0)).newClientTransport(same(goodAddress), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo badTransportInfo = transports.poll();
    // Which failed to connect
    badTransportInfo.listener.transportShutdown(Status.UNAVAILABLE);
    inOrder.verifyNoMoreInteractions();
    // The channel then try the second address (goodAddress)
    verify(mockTransportFactory).newClientTransport(same(goodAddress), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo goodTransportInfo = transports.poll();
    when(goodTransportInfo.transport.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mock(ClientStream.class));
    goodTransportInfo.listener.transportReady();
    inOrder.verify(subchannelStateListener).onSubchannelState(stateInfoCaptor.capture());
    assertEquals(READY, stateInfoCaptor.getValue().getState());
    // A typical LoadBalancer will call this once the subchannel becomes READY
    updateBalancingStateSafely(helper, READY, mockPicker);
    // Delayed transport uses the app executor to create real streams.
    executor.runDueTasks();
    verify(goodTransportInfo.transport).newStream(same(method), same(headers), same(CallOptions.DEFAULT), ArgumentMatchers.<ClientStreamTracer[]>any());
    // The bad transport was never used.
    verify(badTransportInfo.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) InOrder(org.mockito.InOrder) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) ClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions) MethodDescriptor(io.grpc.MethodDescriptor) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) ChannelLogger(io.grpc.ChannelLogger) ProxiedSocketAddress(io.grpc.ProxiedSocketAddress) SocketAddress(java.net.SocketAddress) Test(org.junit.Test)

Example 24 with ClientStreamTracer

use of io.grpc.ClientStreamTracer in project grpc-java by grpc.

the class ManagedChannelImplTest method startCallBeforeNameResolution.

@Test
public void startCallBeforeNameResolution() throws Exception {
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(ImmutableList.of(addressGroup)).build();
    channelBuilder.nameResolverFactory(nameResolverFactory);
    channel = new ManagedChannelImpl(channelBuilder, mockTransportFactory, new FakeBackoffPolicyProvider(), balancerRpcExecutorPool, timer.getStopwatchSupplier(), Collections.<ClientInterceptor>emptyList(), timer.getTimeProvider());
    Map<String, Object> rawServiceConfig = parseConfig("{\"methodConfig\":[{" + "\"name\":[{\"service\":\"service\"}]," + "\"waitForReady\":true}]}");
    ManagedChannelServiceConfig managedChannelServiceConfig = createManagedChannelServiceConfig(rawServiceConfig, null);
    nameResolverFactory.nextConfigOrError.set(ConfigOrError.fromConfig(managedChannelServiceConfig));
    Metadata headers = new Metadata();
    ClientStream mockStream = mock(ClientStream.class);
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, headers);
    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
    verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
    helper = helperCaptor.getValue();
    // Make the transport available
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    verify(mockTransportFactory, never()).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
    requestConnectionSafely(helper, subchannel);
    verify(mockTransportFactory).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ManagedClientTransport.Listener transportListener = transportInfo.listener;
    when(mockTransport.newStream(same(method), same(headers), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
    transportListener.transportReady();
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    updateBalancingStateSafely(helper, READY, mockPicker);
    executor.runDueTasks();
    ArgumentCaptor<CallOptions> callOptionsCaptor = ArgumentCaptor.forClass(null);
    verify(mockTransport).newStream(same(method), same(headers), callOptionsCaptor.capture(), ArgumentMatchers.<ClientStreamTracer[]>any());
    assertThat(callOptionsCaptor.getValue().isWaitForReady()).isTrue();
    verify(mockStream).start(streamListenerCaptor.capture());
    // Clean up as much as possible to allow the channel to terminate.
    shutdownSafely(helper, subchannel);
    timer.forwardNanos(TimeUnit.SECONDS.toNanos(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS));
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) ClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) Helper(io.grpc.LoadBalancer.Helper) ClientInterceptor(io.grpc.ClientInterceptor) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) ChannelLogger(io.grpc.ChannelLogger) ProxiedSocketAddress(io.grpc.ProxiedSocketAddress) SocketAddress(java.net.SocketAddress) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) Test(org.junit.Test)

Example 25 with ClientStreamTracer

use of io.grpc.ClientStreamTracer in project grpc-java by grpc.

the class ManagedChannelImplTest method enterIdle_exitsIdleIfDelayedStreamPending.

@Test
public void enterIdle_exitsIdleIfDelayedStreamPending() {
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress))).build();
    channelBuilder.nameResolverFactory(nameResolverFactory);
    createChannel();
    // Start a call that will be buffered in delayedTransport
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, new Metadata());
    // enterIdle() will shut down the name resolver and lb policy used to get a pick for the delayed
    // call
    channel.enterIdle();
    assertEquals(IDLE, channel.getState(false));
    // enterIdle() will restart the delayed call by exiting idle. This creates a new helper.
    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(Helper.class);
    verify(mockLoadBalancerProvider, times(2)).newLoadBalancer(helperCaptor.capture());
    Helper helper2 = helperCaptor.getValue();
    // Establish a connection
    Subchannel subchannel = createSubchannelSafely(helper2, addressGroup, Attributes.EMPTY, subchannelStateListener);
    requestConnectionSafely(helper, subchannel);
    ClientStream mockStream = mock(ClientStream.class);
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ManagedClientTransport.Listener transportListener = transportInfo.listener;
    when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream);
    transportListener.transportReady();
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    updateBalancingStateSafely(helper2, READY, mockPicker);
    assertEquals(READY, channel.getState(false));
    // Verify the original call was drained
    executor.runDueTasks();
    verify(mockTransport).newStream(same(method), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any());
    verify(mockStream).start(any(ClientStreamListener.class));
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) ClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions) Helper(io.grpc.LoadBalancer.Helper) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Aggregations

ClientStreamTracer (io.grpc.ClientStreamTracer)57 Metadata (io.grpc.Metadata)54 Test (org.junit.Test)44 CallOptions (io.grpc.CallOptions)28 Subchannel (io.grpc.LoadBalancer.Subchannel)22 MockClientTransportInfo (io.grpc.internal.TestUtils.MockClientTransportInfo)21 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)19 ForwardingSubchannel (io.grpc.util.ForwardingSubchannel)18 MethodDescriptor (io.grpc.MethodDescriptor)16 Status (io.grpc.Status)14 ChannelLogger (io.grpc.ChannelLogger)11 ClientTransportOptions (io.grpc.internal.ClientTransportFactory.ClientTransportOptions)10 ProxiedSocketAddress (io.grpc.ProxiedSocketAddress)9 StreamInfo (io.grpc.ClientStreamTracer.StreamInfo)8 CallAttemptsTracerFactory (io.grpc.census.CensusTracingModule.CallAttemptsTracerFactory)8 SocketAddress (java.net.SocketAddress)8 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)7 Helper (io.grpc.LoadBalancer.Helper)7 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)7 ManagedChannel (io.grpc.ManagedChannel)7