Search in sources :

Example 16 with ClientStream

use of io.grpc.internal.ClientStream in project grpc-java by grpc.

the class AbstractTransportTest method earlyServerClose_serverFailure.

@Test
public void earlyServerClose_serverFailure() throws Exception {
    server.start(serverListener);
    client = newClientTransport(server);
    runIfNotNull(client.start(mockClientTransportListener));
    MockServerTransportListener serverTransportListener = serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    serverTransport = serverTransportListener.transport;
    ClientStream clientStream = client.newStream(methodDescriptor, new Metadata());
    clientStream.start(mockClientStreamListener);
    StreamCreation serverStreamCreation = serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    ServerStream serverStream = serverStreamCreation.stream;
    ServerStreamListener mockServerStreamListener = serverStreamCreation.listener;
    Status status = Status.INTERNAL.withDescription("I'm not listening").withCause(new Exception());
    serverStream.close(status, new Metadata());
    verify(mockServerStreamListener, timeout(TIMEOUT_MS)).closed(statusCaptor.capture());
    assertCodeEquals(Status.OK, statusCaptor.getValue());
    verify(mockClientStreamListener, timeout(TIMEOUT_MS)).closed(statusCaptor.capture(), any(Metadata.class));
    assertEquals(status.getCode(), statusCaptor.getValue().getCode());
    assertEquals(status.getDescription(), statusCaptor.getValue().getDescription());
    assertNull(statusCaptor.getValue().getCause());
}
Also used : Status(io.grpc.Status) ServerStreamListener(io.grpc.internal.ServerStreamListener) Metadata(io.grpc.Metadata) ServerStream(io.grpc.internal.ServerStream) ClientStream(io.grpc.internal.ClientStream) TimeoutException(java.util.concurrent.TimeoutException) ExpectedException(org.junit.rules.ExpectedException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 17 with ClientStream

use of io.grpc.internal.ClientStream in project grpc-java by grpc.

the class AbstractTransportTest method frameAfterRstStreamShouldNotBreakClientChannel.

// TODO(ejona):
//   multiple streams on same transport
//   multiple client transports to same server
//   halfClose to trigger flush (client and server)
//   flow control pushes back (client and server)
//   flow control provides precisely number of messages requested (client and server)
//   onReady called when buffer drained (on server and client)
//   test no start reentrancy (esp. during failure) (transport and call)
//   multiple requests/responses (verifying contents received)
//   server transport shutdown triggers client shutdown (via GOAWAY)
//   queued message InputStreams are closed on stream cancel
//     (and maybe exceptions handled)
/**
   * Test for issue https://github.com/grpc/grpc-java/issues/1682
   */
@Test
public void frameAfterRstStreamShouldNotBreakClientChannel() throws Exception {
    server.start(serverListener);
    client = newClientTransport(server);
    runIfNotNull(client.start(mockClientTransportListener));
    MockServerTransportListener serverTransportListener = serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    serverTransport = serverTransportListener.transport;
    // Try to create a sequence of frames so that the client receives a HEADERS or DATA frame
    // after having sent a RST_STREAM to the server. Previously, this would have broken the
    // Netty channel.
    ClientStream stream = client.newStream(methodDescriptor, new Metadata());
    stream.start(mockClientStreamListener);
    StreamCreation serverStreamCreation = serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    stream.flush();
    stream.writeMessage(methodDescriptor.streamRequest("foo"));
    stream.flush();
    stream.cancel(Status.CANCELLED);
    stream.flush();
    serverStreamCreation.stream.writeHeaders(new Metadata());
    serverStreamCreation.stream.flush();
    serverStreamCreation.stream.writeMessage(methodDescriptor.streamResponse("bar"));
    serverStreamCreation.stream.flush();
    verify(mockClientStreamListener, timeout(250)).closed(eq(Status.CANCELLED), any(Metadata.class));
    ClientStreamListener mockClientStreamListener2 = mock(ClientStreamListener.class);
    // Test that the channel is still usable i.e. we can receive headers from the server on a
    // new stream.
    stream = client.newStream(methodDescriptor, new Metadata());
    stream.start(mockClientStreamListener2);
    serverStreamCreation = serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    serverStreamCreation.stream.writeHeaders(new Metadata());
    serverStreamCreation.stream.flush();
    verify(mockClientStreamListener2, timeout(250)).headersRead(any(Metadata.class));
}
Also used : ClientStreamListener(io.grpc.internal.ClientStreamListener) Metadata(io.grpc.Metadata) ClientStream(io.grpc.internal.ClientStream) Test(org.junit.Test)

Example 18 with ClientStream

use of io.grpc.internal.ClientStream in project grpc-java by grpc.

the class AbstractTransportTest method newStream_afterTermination.

@Test
public void newStream_afterTermination() throws Exception {
    // We expect the same general behavior as duringShutdown, but for some transports (e.g., Netty)
    // dealing with afterTermination is harder than duringShutdown.
    server.start(serverListener);
    client = newClientTransport(server);
    runIfNotNull(client.start(mockClientTransportListener));
    verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportReady();
    client.shutdown();
    verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportTerminated();
    Thread.sleep(100);
    ClientStream stream = client.newStream(methodDescriptor, new Metadata());
    stream.start(mockClientStreamListener);
    verify(mockClientStreamListener, timeout(TIMEOUT_MS)).closed(statusCaptor.capture(), any(Metadata.class));
    verify(mockClientTransportListener, never()).transportInUse(anyBoolean());
    assertCodeEquals(Status.UNAVAILABLE, statusCaptor.getValue());
}
Also used : Metadata(io.grpc.Metadata) ClientStream(io.grpc.internal.ClientStream) Test(org.junit.Test)

Example 19 with ClientStream

use of io.grpc.internal.ClientStream in project grpc-java by grpc.

the class AbstractTransportTest method clientCancel.

@Test
public void clientCancel() throws Exception {
    server.start(serverListener);
    client = newClientTransport(server);
    runIfNotNull(client.start(mockClientTransportListener));
    MockServerTransportListener serverTransportListener = serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    serverTransport = serverTransportListener.transport;
    ClientStream clientStream = client.newStream(methodDescriptor, new Metadata());
    clientStream.start(mockClientStreamListener);
    StreamCreation serverStreamCreation = serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    ServerStreamListener mockServerStreamListener = serverStreamCreation.listener;
    Status status = Status.CANCELLED.withDescription("Nevermind").withCause(new Exception());
    clientStream.cancel(status);
    verify(mockClientStreamListener, timeout(TIMEOUT_MS)).closed(Matchers.same(status), any(Metadata.class));
    verify(mockServerStreamListener, timeout(TIMEOUT_MS)).closed(statusCaptor.capture());
    assertNotEquals(Status.Code.OK, statusCaptor.getValue().getCode());
    // Cause should not be transmitted between client and server
    assertNull(statusCaptor.getValue().getCause());
    reset(mockServerStreamListener);
    reset(mockClientStreamListener);
    clientStream.cancel(status);
    verify(mockServerStreamListener, never()).closed(any(Status.class));
    verify(mockClientStreamListener, never()).closed(any(Status.class), any(Metadata.class));
}
Also used : Status(io.grpc.Status) ServerStreamListener(io.grpc.internal.ServerStreamListener) Metadata(io.grpc.Metadata) ClientStream(io.grpc.internal.ClientStream) TimeoutException(java.util.concurrent.TimeoutException) ExpectedException(org.junit.rules.ExpectedException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 20 with ClientStream

use of io.grpc.internal.ClientStream in project grpc-java by grpc.

the class AbstractTransportTest method flowControlPushBack.

@Test
public void flowControlPushBack() throws Exception {
    server.start(serverListener);
    client = newClientTransport(server);
    runIfNotNull(client.start(mockClientTransportListener));
    MockServerTransportListener serverTransportListener = serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    serverTransport = serverTransportListener.transport;
    ClientStream clientStream = client.newStream(methodDescriptor, new Metadata());
    clientStream.start(mockClientStreamListener);
    StreamCreation serverStreamCreation = serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
    assertEquals(methodDescriptor.getFullMethodName(), serverStreamCreation.method);
    ServerStream serverStream = serverStreamCreation.stream;
    ServerStreamListener mockServerStreamListener = serverStreamCreation.listener;
    serverStream.writeHeaders(new Metadata());
    Answer<Void> closeStream = new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Exception {
            Object[] args = invocation.getArguments();
            ((InputStream) args[0]).close();
            return null;
        }
    };
    String largeMessage;
    {
        int size = 1 * 1024;
        StringBuffer sb = new StringBuffer(size);
        for (int i = 0; i < size; i++) {
            sb.append('a');
        }
        largeMessage = sb.toString();
    }
    doAnswer(closeStream).when(mockServerStreamListener).messageRead(any(InputStream.class));
    serverStream.request(1);
    verify(mockClientStreamListener, timeout(TIMEOUT_MS)).onReady();
    assertTrue(clientStream.isReady());
    final int maxToSend = 10 * 1024;
    int clientSent;
    // Verify that flow control will push back on client.
    for (clientSent = 0; clientStream.isReady(); clientSent++) {
        if (clientSent > maxToSend) {
            // It seems like flow control isn't working. _Surely_ flow control would have pushed-back
            // already. If this is normal, please configure the transport to buffer less.
            fail("Too many messages sent before isReady() returned false");
        }
        clientStream.writeMessage(methodDescriptor.streamRequest(largeMessage));
        clientStream.flush();
    }
    assertTrue(clientSent > 0);
    // Make sure there are at least a few messages buffered.
    for (; clientSent < 5; clientSent++) {
        clientStream.writeMessage(methodDescriptor.streamResponse(largeMessage));
        clientStream.flush();
    }
    doPingPong(serverListener);
    verify(mockServerStreamListener, timeout(TIMEOUT_MS)).messageRead(any(InputStream.class));
    doAnswer(closeStream).when(mockClientStreamListener).messageRead(any(InputStream.class));
    clientStream.request(1);
    verify(mockServerStreamListener, timeout(TIMEOUT_MS)).onReady();
    assertTrue(serverStream.isReady());
    int serverSent;
    // Verify that flow control will push back on server.
    for (serverSent = 0; serverStream.isReady(); serverSent++) {
        if (serverSent > maxToSend) {
            // It seems like flow control isn't working. _Surely_ flow control would have pushed-back
            // already. If this is normal, please configure the transport to buffer less.
            fail("Too many messages sent before isReady() returned false");
        }
        serverStream.writeMessage(methodDescriptor.streamResponse(largeMessage));
        serverStream.flush();
    }
    assertTrue(serverSent > 0);
    // Make sure there are at least a few messages buffered.
    for (; serverSent < 5; serverSent++) {
        serverStream.writeMessage(methodDescriptor.streamResponse(largeMessage));
        serverStream.flush();
    }
    doPingPong(serverListener);
    verify(mockClientStreamListener, timeout(TIMEOUT_MS)).messageRead(any(InputStream.class));
    serverStream.request(3);
    clientStream.request(3);
    doPingPong(serverListener);
    // times() is total number throughout the entire test
    verify(mockClientStreamListener, timeout(TIMEOUT_MS).times(4)).messageRead(any(InputStream.class));
    verify(mockServerStreamListener, timeout(TIMEOUT_MS).times(4)).messageRead(any(InputStream.class));
    // Request the rest
    serverStream.request(clientSent);
    clientStream.request(serverSent);
    verify(mockClientStreamListener, timeout(TIMEOUT_MS).times(clientSent)).messageRead(any(InputStream.class));
    verify(mockServerStreamListener, timeout(TIMEOUT_MS).times(serverSent)).messageRead(any(InputStream.class));
    verify(mockClientStreamListener, timeout(TIMEOUT_MS).times(2)).onReady();
    assertTrue(clientStream.isReady());
    verify(mockServerStreamListener, timeout(TIMEOUT_MS).times(2)).onReady();
    assertTrue(serverStream.isReady());
    // Request four more
    for (int i = 0; i < 5; i++) {
        clientStream.writeMessage(methodDescriptor.streamRequest(largeMessage));
        clientStream.flush();
        serverStream.writeMessage(methodDescriptor.streamResponse(largeMessage));
        serverStream.flush();
    }
    doPingPong(serverListener);
    verify(mockClientStreamListener, timeout(TIMEOUT_MS).times(clientSent + 4)).messageRead(any(InputStream.class));
    verify(mockServerStreamListener, timeout(TIMEOUT_MS).times(serverSent + 4)).messageRead(any(InputStream.class));
    // Drain exactly how many messages are left
    serverStream.request(1);
    clientStream.request(1);
    verify(mockServerStreamListener, timeout(TIMEOUT_MS).times(serverSent + 5)).messageRead(any(InputStream.class));
    verify(mockClientStreamListener, timeout(TIMEOUT_MS).times(clientSent + 5)).messageRead(any(InputStream.class));
    // And now check that the streams can still complete gracefully
    clientStream.writeMessage(methodDescriptor.streamRequest(largeMessage));
    clientStream.flush();
    clientStream.halfClose();
    doPingPong(serverListener);
    verify(mockServerStreamListener, never()).halfClosed();
    serverStream.request(1);
    verify(mockServerStreamListener, timeout(TIMEOUT_MS).times(serverSent + 6)).messageRead(any(InputStream.class));
    verify(mockServerStreamListener, timeout(TIMEOUT_MS)).halfClosed();
    serverStream.writeMessage(methodDescriptor.streamResponse(largeMessage));
    serverStream.flush();
    Status status = Status.OK.withDescription("... quite a lengthy discussion");
    serverStream.close(status, new Metadata());
    doPingPong(serverListener);
    verify(mockClientStreamListener, never()).closed(any(Status.class), any(Metadata.class));
    clientStream.request(1);
    verify(mockClientStreamListener, timeout(TIMEOUT_MS).times(clientSent + 6)).messageRead(any(InputStream.class));
    verify(mockServerStreamListener, timeout(TIMEOUT_MS)).closed(statusCaptor.capture());
    assertCodeEquals(Status.OK, statusCaptor.getValue());
    verify(mockClientStreamListener, timeout(TIMEOUT_MS)).closed(statusCaptor.capture(), any(Metadata.class));
    assertEquals(status.getCode(), statusCaptor.getValue().getCode());
    assertEquals(status.getDescription(), statusCaptor.getValue().getDescription());
}
Also used : Status(io.grpc.Status) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Metadata(io.grpc.Metadata) ServerStream(io.grpc.internal.ServerStream) ClientStream(io.grpc.internal.ClientStream) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Answer(org.mockito.stubbing.Answer) ServerStreamListener(io.grpc.internal.ServerStreamListener) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.Test)

Aggregations

Metadata (io.grpc.Metadata)20 ClientStream (io.grpc.internal.ClientStream)20 Test (org.junit.Test)19 Status (io.grpc.Status)15 ServerStreamListener (io.grpc.internal.ServerStreamListener)13 ServerStream (io.grpc.internal.ServerStream)11 IOException (java.io.IOException)5 ExecutionException (java.util.concurrent.ExecutionException)5 TimeoutException (java.util.concurrent.TimeoutException)5 ExpectedException (org.junit.rules.ExpectedException)5 ClientStreamListener (io.grpc.internal.ClientStreamListener)4 ManagedClientTransport (io.grpc.internal.ManagedClientTransport)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 InputStream (java.io.InputStream)2 ClientTransport (io.grpc.internal.ClientTransport)1 Matchers.anyBoolean (org.mockito.Matchers.anyBoolean)1 Mockito.doAnswer (org.mockito.Mockito.doAnswer)1 InvocationOnMock (org.mockito.invocation.InvocationOnMock)1 Answer (org.mockito.stubbing.Answer)1