Search in sources :

Example 6 with Subchannel

use of io.grpc.LoadBalancer.Subchannel 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";
        }
    };
    final ResolvedServerInfo goodServer = new ResolvedServerInfo(goodAddress, Attributes.EMPTY);
    final ResolvedServerInfo badServer = new ResolvedServerInfo(badAddress, Attributes.EMPTY);
    InOrder inOrder = inOrder(mockLoadBalancer);
    ResolvedServerInfoGroup serverInfoGroup = ResolvedServerInfoGroup.builder().add(badServer).add(goodServer).build();
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(serverInfoGroup.getResolvedServerInfoList());
    createChannel(nameResolverFactory, NO_INTERCEPTOR);
    // 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
    inOrder.verify(mockLoadBalancer).handleResolvedAddresses(eq(Arrays.asList(serverInfoGroup)), eq(Attributes.EMPTY));
    Subchannel subchannel = helper.createSubchannel(serverInfoGroup.toEquivalentAddressGroup(), Attributes.EMPTY);
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    subchannel.requestConnection();
    inOrder.verify(mockLoadBalancer).handleSubchannelState(same(subchannel), stateInfoCaptor.capture());
    assertEquals(CONNECTING, stateInfoCaptor.getValue().getState());
    // The channel will starts with the first address (badAddress)
    verify(mockTransportFactory).newClientTransport(same(badAddress), any(String.class), any(String.class));
    verify(mockTransportFactory, times(0)).newClientTransport(same(goodAddress), any(String.class), any(String.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(String.class), any(String.class));
    MockClientTransportInfo goodTransportInfo = transports.poll();
    when(goodTransportInfo.transport.newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), any(StatsTraceContext.class))).thenReturn(mock(ClientStream.class));
    goodTransportInfo.listener.transportReady();
    inOrder.verify(mockLoadBalancer).handleSubchannelState(same(subchannel), stateInfoCaptor.capture());
    assertEquals(READY, stateInfoCaptor.getValue().getState());
    // A typical LoadBalancer will call this once the subchannel becomes READY
    helper.updatePicker(mockPicker);
    // Delayed transport uses the app executor to create real streams.
    executor.runDueTasks();
    verify(goodTransportInfo.transport).newStream(same(method), same(headers), same(CallOptions.DEFAULT), any(StatsTraceContext.class));
    // The bad transport was never used.
    verify(badTransportInfo.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), any(StatsTraceContext.class));
}
Also used : InOrder(org.mockito.InOrder) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) ResolvedServerInfo(io.grpc.ResolvedServerInfo) ResolvedServerInfoGroup(io.grpc.ResolvedServerInfoGroup) Matchers.anyString(org.mockito.Matchers.anyString) CallOptions(io.grpc.CallOptions) MethodDescriptor(io.grpc.MethodDescriptor) Subchannel(io.grpc.LoadBalancer.Subchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) SocketAddress(java.net.SocketAddress) Test(org.junit.Test)

Example 7 with Subchannel

use of io.grpc.LoadBalancer.Subchannel 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";
        }
    };
    final ResolvedServerInfo server1 = new ResolvedServerInfo(addr1, Attributes.EMPTY);
    final ResolvedServerInfo server2 = new ResolvedServerInfo(addr2, Attributes.EMPTY);
    InOrder inOrder = inOrder(mockLoadBalancer);
    ResolvedServerInfoGroup serverInfoGroup = ResolvedServerInfoGroup.builder().add(server1).add(server2).build();
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory(serverInfoGroup.getResolvedServerInfoList());
    createChannel(nameResolverFactory, NO_INTERCEPTOR);
    // 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
    inOrder.verify(mockLoadBalancer).handleResolvedAddresses(eq(Arrays.asList(serverInfoGroup)), eq(Attributes.EMPTY));
    Subchannel subchannel = helper.createSubchannel(serverInfoGroup.toEquivalentAddressGroup(), Attributes.EMPTY);
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    subchannel.requestConnection();
    inOrder.verify(mockLoadBalancer).handleSubchannelState(same(subchannel), stateInfoCaptor.capture());
    assertEquals(CONNECTING, stateInfoCaptor.getValue().getState());
    // Connecting to server1, which will fail
    verify(mockTransportFactory).newClientTransport(same(addr1), any(String.class), any(String.class));
    verify(mockTransportFactory, times(0)).newClientTransport(same(addr2), any(String.class), any(String.class));
    MockClientTransportInfo transportInfo1 = transports.poll();
    transportInfo1.listener.transportShutdown(Status.UNAVAILABLE);
    // Connecting to server2, which will fail too
    verify(mockTransportFactory).newClientTransport(same(addr2), any(String.class), any(String.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(mockLoadBalancer).handleSubchannelState(same(subchannel), 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));
    helper.updatePicker(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));
    verify(transportInfo2.transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class));
}
Also used : Status(io.grpc.Status) InOrder(org.mockito.InOrder) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) ResolvedServerInfo(io.grpc.ResolvedServerInfo) ResolvedServerInfoGroup(io.grpc.ResolvedServerInfoGroup) Matchers.anyString(org.mockito.Matchers.anyString) MethodDescriptor(io.grpc.MethodDescriptor) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) Subchannel(io.grpc.LoadBalancer.Subchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) SocketAddress(java.net.SocketAddress) Test(org.junit.Test)

Example 8 with Subchannel

use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.

the class RoundRobinLoadBalancerTest method subchannelStateIsolation.

@Test
public void subchannelStateIsolation() throws Exception {
    Iterator<Subchannel> subchannelIterator = subchannels.values().iterator();
    Subchannel sc1 = subchannelIterator.next();
    Subchannel sc2 = subchannelIterator.next();
    Subchannel sc3 = subchannelIterator.next();
    loadBalancer.handleResolvedAddresses(Lists.newArrayList(servers.keySet()), Attributes.EMPTY);
    verify(sc1, times(1)).requestConnection();
    verify(sc2, times(1)).requestConnection();
    verify(sc3, times(1)).requestConnection();
    loadBalancer.handleSubchannelState(sc1, ConnectivityStateInfo.forNonError(READY));
    loadBalancer.handleSubchannelState(sc2, ConnectivityStateInfo.forNonError(READY));
    loadBalancer.handleSubchannelState(sc3, ConnectivityStateInfo.forNonError(READY));
    loadBalancer.handleSubchannelState(sc2, ConnectivityStateInfo.forNonError(IDLE));
    loadBalancer.handleSubchannelState(sc3, ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE));
    verify(mockHelper, times(6)).updatePicker(pickerCaptor.capture());
    Iterator<Picker> pickers = pickerCaptor.getAllValues().iterator();
    // The picker is incrementally updated as subchannels become READY
    assertThat(pickers.next().getList()).isEmpty();
    assertThat(pickers.next().getList()).containsExactly(sc1);
    assertThat(pickers.next().getList()).containsExactly(sc1, sc2);
    assertThat(pickers.next().getList()).containsExactly(sc1, sc2, sc3);
    // The IDLE subchannel is dropped from the picker, but a reconnection is requested
    assertThat(pickers.next().getList()).containsExactly(sc1, sc3);
    verify(sc2, times(2)).requestConnection();
    // The failing subchannel is dropped from the picker, with no requested reconnect
    assertThat(pickers.next().getList()).containsExactly(sc1);
    verify(sc3, times(1)).requestConnection();
    assertThat(pickers.hasNext()).isFalse();
}
Also used : Subchannel(io.grpc.LoadBalancer.Subchannel) Picker(io.grpc.util.RoundRobinLoadBalancerFactory.Picker) Test(org.junit.Test)

Example 9 with Subchannel

use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.

the class RoundRobinLoadBalancerTest method setUp.

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    for (int i = 0; i < 3; i++) {
        SocketAddress addr = new FakeSocketAddress("server" + i);
        EquivalentAddressGroup eag = new EquivalentAddressGroup(addr);
        servers.put(ResolvedServerInfoGroup.builder().add(new ResolvedServerInfo(addr)).build(), eag);
        subchannels.put(eag, mock(Subchannel.class));
    }
    when(mockHelper.createSubchannel(any(EquivalentAddressGroup.class), any(Attributes.class))).then(new Answer<Subchannel>() {

        @Override
        public Subchannel answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            Subchannel subchannel = subchannels.get(args[0]);
            when(subchannel.getAttributes()).thenReturn((Attributes) args[1]);
            return subchannel;
        }
    });
    loadBalancer = (RoundRobinLoadBalancer) RoundRobinLoadBalancerFactory.getInstance().newLoadBalancer(mockHelper);
}
Also used : EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Attributes(io.grpc.Attributes) ResolvedServerInfo(io.grpc.ResolvedServerInfo) SocketAddress(java.net.SocketAddress) Before(org.junit.Before)

Example 10 with Subchannel

use of io.grpc.LoadBalancer.Subchannel in project grpc-java by grpc.

the class RoundRobinLoadBalancerTest method pickAfterResolved.

@Test
public void pickAfterResolved() throws Exception {
    final Subchannel readySubchannel = subchannels.values().iterator().next();
    loadBalancer.handleResolvedAddresses(Lists.newArrayList(servers.keySet()), affinity);
    loadBalancer.handleSubchannelState(readySubchannel, ConnectivityStateInfo.forNonError(READY));
    verify(mockHelper, times(3)).createSubchannel(eagCaptor.capture(), any(Attributes.class));
    assertThat(eagCaptor.getAllValues()).containsAllIn(subchannels.keySet());
    for (Subchannel subchannel : subchannels.values()) {
        verify(subchannel).requestConnection();
        verify(subchannel, never()).shutdown();
    }
    verify(mockHelper, times(2)).updatePicker(pickerCaptor.capture());
    assertThat(pickerCaptor.getValue().getList()).containsExactly(readySubchannel);
    verifyNoMoreInteractions(mockHelper);
}
Also used : Subchannel(io.grpc.LoadBalancer.Subchannel) Attributes(io.grpc.Attributes) Test(org.junit.Test)

Aggregations

Subchannel (io.grpc.LoadBalancer.Subchannel)22 Test (org.junit.Test)18 Attributes (io.grpc.Attributes)8 MockClientTransportInfo (io.grpc.internal.TestUtils.MockClientTransportInfo)8 SocketAddress (java.net.SocketAddress)8 Metadata (io.grpc.Metadata)7 InOrder (org.mockito.InOrder)7 Matchers.anyString (org.mockito.Matchers.anyString)7 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)6 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)6 ResolvedServerInfoGroup (io.grpc.ResolvedServerInfoGroup)5 Status (io.grpc.Status)5 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)4 ResolvedServerInfo (io.grpc.ResolvedServerInfo)4 Picker (io.grpc.util.RoundRobinLoadBalancerFactory.Picker)4 CallOptions (io.grpc.CallOptions)3 MethodDescriptor (io.grpc.MethodDescriptor)3 InvocationOnMock (org.mockito.invocation.InvocationOnMock)3 ConnectivityStateInfo (io.grpc.ConnectivityStateInfo)2 Helper (io.grpc.LoadBalancer.Helper)2