Search in sources :

Example 1 with SingleMessageProducer

use of io.grpc.internal.testing.SingleMessageProducer in project grpc-java by grpc.

the class DelayedStreamTest method listener_allQueued.

@Test
public void listener_allQueued() {
    final Metadata headers = new Metadata();
    final InputStream message1 = mock(InputStream.class);
    final InputStream message2 = mock(InputStream.class);
    final SingleMessageProducer producer1 = new SingleMessageProducer(message1);
    final SingleMessageProducer producer2 = new SingleMessageProducer(message2);
    final Metadata trailers = new Metadata();
    final Status status = Status.UNKNOWN.withDescription("unique status");
    final InOrder inOrder = inOrder(listener);
    stream.start(listener);
    callMeMaybe(stream.setStream(new NoopClientStream() {

        @Override
        public void start(ClientStreamListener passedListener) {
            passedListener.onReady();
            passedListener.headersRead(headers);
            passedListener.messagesAvailable(producer1);
            passedListener.onReady();
            passedListener.messagesAvailable(producer2);
            passedListener.closed(status, RpcProgress.PROCESSED, trailers);
            verifyNoMoreInteractions(listener);
        }
    }));
    inOrder.verify(listener).onReady();
    inOrder.verify(listener).headersRead(headers);
    inOrder.verify(listener).messagesAvailable(producer1);
    inOrder.verify(listener).onReady();
    inOrder.verify(listener).messagesAvailable(producer2);
    inOrder.verify(listener).closed(status, RpcProgress.PROCESSED, trailers);
}
Also used : Status(io.grpc.Status) InOrder(org.mockito.InOrder) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Metadata(io.grpc.Metadata) SingleMessageProducer(io.grpc.internal.testing.SingleMessageProducer) Test(org.junit.Test)

Example 2 with SingleMessageProducer

use of io.grpc.internal.testing.SingleMessageProducer in project grpc-java by grpc.

the class ClientCallImplTest method callerContextPropagatedToListener.

@Test
public void callerContextPropagatedToListener() throws Exception {
    // Attach the context which is recorded when the call is created
    final Context.Key<String> testKey = Context.key("testing");
    Context context = Context.current().withValue(testKey, "testValue");
    Context previous = context.attach();
    ClientCallImpl<Void, Void> call = new ClientCallImpl<>(method.toBuilder().setType(MethodType.UNKNOWN).build(), new SerializingExecutor(Executors.newSingleThreadExecutor()), baseCallOptions, clientStreamProvider, deadlineCancellationExecutor, channelCallTracer, configSelector).setDecompressorRegistry(decompressorRegistry);
    context.detach(previous);
    // Override the value after creating the call, this should not be seen by callbacks
    context = Context.current().withValue(testKey, "badValue");
    previous = context.attach();
    final AtomicBoolean onHeadersCalled = new AtomicBoolean();
    final AtomicBoolean onMessageCalled = new AtomicBoolean();
    final AtomicBoolean onReadyCalled = new AtomicBoolean();
    final AtomicBoolean observedIncorrectContext = new AtomicBoolean();
    final CountDownLatch latch = new CountDownLatch(1);
    call.start(new ClientCall.Listener<Void>() {

        @Override
        public void onHeaders(Metadata headers) {
            onHeadersCalled.set(true);
            checkContext();
        }

        @Override
        public void onMessage(Void message) {
            onMessageCalled.set(true);
            checkContext();
        }

        @Override
        public void onClose(Status status, Metadata trailers) {
            checkContext();
            latch.countDown();
        }

        @Override
        public void onReady() {
            onReadyCalled.set(true);
            checkContext();
        }

        private void checkContext() {
            if (!"testValue".equals(testKey.get())) {
                observedIncorrectContext.set(true);
            }
        }
    }, new Metadata());
    context.detach(previous);
    verify(stream).start(listenerArgumentCaptor.capture());
    ClientStreamListener listener = listenerArgumentCaptor.getValue();
    listener.onReady();
    listener.headersRead(new Metadata());
    listener.messagesAvailable(new SingleMessageProducer(new ByteArrayInputStream(new byte[0])));
    listener.messagesAvailable(new SingleMessageProducer(new ByteArrayInputStream(new byte[0])));
    listener.closed(Status.OK, PROCESSED, new Metadata());
    assertTrue(latch.await(5, TimeUnit.SECONDS));
    assertTrue(onHeadersCalled.get());
    assertTrue(onMessageCalled.get());
    assertTrue(onReadyCalled.get());
    assertFalse(observedIncorrectContext.get());
}
Also used : Context(io.grpc.Context) Status(io.grpc.Status) Metadata(io.grpc.Metadata) SingleMessageProducer(io.grpc.internal.testing.SingleMessageProducer) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ByteArrayInputStream(java.io.ByteArrayInputStream) ClientCall(io.grpc.ClientCall) Test(org.junit.Test)

Example 3 with SingleMessageProducer

use of io.grpc.internal.testing.SingleMessageProducer in project grpc-java by grpc.

the class ClientCallImplTest method exceptionInOnMessageTakesPrecedenceOverServer.

@Test
public void exceptionInOnMessageTakesPrecedenceOverServer() {
    DelayedExecutor executor = new DelayedExecutor();
    ClientCallImpl<Void, Void> call = new ClientCallImpl<>(method, executor, baseCallOptions, clientStreamProvider, deadlineCancellationExecutor, channelCallTracer, configSelector);
    call.start(callListener, new Metadata());
    verify(stream).start(listenerArgumentCaptor.capture());
    final ClientStreamListener streamListener = listenerArgumentCaptor.getValue();
    streamListener.headersRead(new Metadata());
    RuntimeException failure = new RuntimeException("bad");
    doThrow(failure).when(callListener).onMessage(ArgumentMatchers.<Void>any());
    /*
     * In unary calls, the server closes the call right after responding, so the onClose call is
     * queued to run.  When messageRead is called, an exception will occur and attempt to cancel the
     * stream.  However, since the server closed it "first" the second exception is lost leading to
     * the call being counted as successful.
     */
    streamListener.messagesAvailable(new SingleMessageProducer(new ByteArrayInputStream(new byte[] {})));
    streamListener.closed(Status.OK, PROCESSED, new Metadata());
    executor.release();
    verify(callListener).onClose(statusArgumentCaptor.capture(), ArgumentMatchers.isA(Metadata.class));
    Status callListenerStatus = statusArgumentCaptor.getValue();
    assertThat(callListenerStatus.getCode()).isEqualTo(Status.Code.CANCELLED);
    assertThat(callListenerStatus.getCause()).isSameInstanceAs(failure);
    verify(stream).cancel(same(callListenerStatus));
}
Also used : Status(io.grpc.Status) ByteArrayInputStream(java.io.ByteArrayInputStream) Metadata(io.grpc.Metadata) SingleMessageProducer(io.grpc.internal.testing.SingleMessageProducer) Test(org.junit.Test)

Example 4 with SingleMessageProducer

use of io.grpc.internal.testing.SingleMessageProducer in project grpc-java by grpc.

the class ServerCallImplTest method streamListener_messageRead_onlyOnce.

@Test
public void streamListener_messageRead_onlyOnce() {
    ServerStreamListenerImpl<Long> streamListener = new ServerCallImpl.ServerStreamListenerImpl<>(call, callListener, context);
    streamListener.messagesAvailable(new SingleMessageProducer(UNARY_METHOD.streamRequest(1234L)));
    // canceling the call should short circuit future halfClosed() calls.
    streamListener.closed(Status.CANCELLED);
    streamListener.messagesAvailable(new SingleMessageProducer(UNARY_METHOD.streamRequest(1234L)));
    verify(callListener).onMessage(1234L);
}
Also used : SingleMessageProducer(io.grpc.internal.testing.SingleMessageProducer) ServerStreamListenerImpl(io.grpc.internal.ServerCallImpl.ServerStreamListenerImpl) Test(org.junit.Test)

Example 5 with SingleMessageProducer

use of io.grpc.internal.testing.SingleMessageProducer in project grpc-java by grpc.

the class ServerImplTest method basicExchangeHelper.

private void basicExchangeHelper(MethodDescriptor<String, Integer> method, String request, int firstResponse, Integer extraResponse) throws Exception {
    final Metadata.Key<String> metadataKey = Metadata.Key.of("inception", Metadata.ASCII_STRING_MARSHALLER);
    final AtomicReference<ServerCall<String, Integer>> callReference = new AtomicReference<>();
    final AtomicReference<Context> callContextReference = new AtomicReference<>();
    mutableFallbackRegistry.addService(ServerServiceDefinition.builder(new ServiceDescriptor("Waiter", method)).addMethod(method, new ServerCallHandler<String, Integer>() {

        @Override
        public ServerCall.Listener<String> startCall(ServerCall<String, Integer> call, Metadata headers) {
            assertEquals("Waiter/serve", call.getMethodDescriptor().getFullMethodName());
            assertNotNull(call);
            assertNotNull(headers);
            assertEquals("value", headers.get(metadataKey));
            callReference.set(call);
            callContextReference.set(Context.current());
            return callListener;
        }
    }).build());
    ServerTransportListener transportListener = transportServer.registerNewServerTransport(new SimpleServerTransport());
    transportListener.transportReady(Attributes.EMPTY);
    Metadata requestHeaders = new Metadata();
    requestHeaders.put(metadataKey, "value");
    StatsTraceContext statsTraceCtx = StatsTraceContext.newServerContext(streamTracerFactories, "Waiter/serve", requestHeaders);
    when(stream.statsTraceContext()).thenReturn(statsTraceCtx);
    transportListener.streamCreated(stream, "Waiter/serve", requestHeaders);
    verify(stream).setListener(streamListenerCaptor.capture());
    ServerStreamListener streamListener = streamListenerCaptor.getValue();
    assertNotNull(streamListener);
    verify(stream, atLeast(1)).statsTraceContext();
    verify(fallbackRegistry, never()).lookupMethod(any(String.class), any(String.class));
    assertEquals(1, executor.runDueTasks());
    ServerCall<String, Integer> call = callReference.get();
    assertNotNull(call);
    assertEquals(new ServerCallInfoImpl<>(call.getMethodDescriptor(), call.getAttributes(), call.getAuthority()), streamTracer.getServerCallInfo());
    verify(fallbackRegistry).lookupMethod("Waiter/serve", AUTHORITY);
    Context callContext = callContextReference.get();
    assertNotNull(callContext);
    assertEquals("context added by tracer", SERVER_TRACER_ADDED_KEY.get(callContext));
    assertEquals(server, io.grpc.InternalServer.SERVER_CONTEXT_KEY.get(callContext));
    streamListener.messagesAvailable(new SingleMessageProducer(STRING_MARSHALLER.stream(request)));
    assertEquals(1, executor.runDueTasks());
    verify(callListener).onMessage(request);
    Metadata responseHeaders = new Metadata();
    responseHeaders.put(metadataKey, "response value");
    call.sendHeaders(responseHeaders);
    verify(stream).writeHeaders(responseHeaders);
    verify(stream).setCompressor(isA(Compressor.class));
    call.sendMessage(firstResponse);
    ArgumentCaptor<InputStream> inputCaptor = ArgumentCaptor.forClass(InputStream.class);
    verify(stream).writeMessage(inputCaptor.capture());
    verify(stream).flush();
    assertEquals(firstResponse, INTEGER_MARSHALLER.parse(inputCaptor.getValue()).intValue());
    // All full; no dessert.
    streamListener.halfClosed();
    assertEquals(1, executor.runDueTasks());
    verify(callListener).onHalfClose();
    if (extraResponse != null) {
        call.sendMessage(extraResponse);
        verify(stream, times(2)).writeMessage(inputCaptor.capture());
        verify(stream, times(2)).flush();
        assertEquals((int) extraResponse, INTEGER_MARSHALLER.parse(inputCaptor.getValue()).intValue());
    }
    Metadata trailers = new Metadata();
    trailers.put(metadataKey, "another value");
    Status status = Status.OK.withDescription("A okay");
    call.close(status, trailers);
    verify(stream).close(status, trailers);
    streamListener.closed(Status.OK);
    assertEquals(1, executor.runDueTasks());
    verify(callListener).onComplete();
    verify(stream, atLeast(1)).statsTraceContext();
    verifyNoMoreInteractions(callListener);
    verify(streamTracerFactory).newServerStreamTracer(eq("Waiter/serve"), same(requestHeaders));
}
Also used : Context(io.grpc.Context) Status(io.grpc.Status) JumpToApplicationThreadServerStreamListener(io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener) Listener(io.grpc.ServerCall.Listener) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Metadata(io.grpc.Metadata) SingleMessageProducer(io.grpc.internal.testing.SingleMessageProducer) Compressor(io.grpc.Compressor) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ServerCall(io.grpc.ServerCall) ServiceDescriptor(io.grpc.ServiceDescriptor) JumpToApplicationThreadServerStreamListener(io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener)

Aggregations

SingleMessageProducer (io.grpc.internal.testing.SingleMessageProducer)10 Test (org.junit.Test)9 ByteArrayInputStream (java.io.ByteArrayInputStream)8 Metadata (io.grpc.Metadata)7 Status (io.grpc.Status)7 InputStream (java.io.InputStream)4 Context (io.grpc.Context)3 ServerStreamListenerImpl (io.grpc.internal.ServerCallImpl.ServerStreamListenerImpl)3 ClientCall (io.grpc.ClientCall)2 ServerCall (io.grpc.ServerCall)2 Listener (io.grpc.ServerCall.Listener)2 ServiceDescriptor (io.grpc.ServiceDescriptor)2 JumpToApplicationThreadServerStreamListener (io.grpc.internal.ServerImpl.JumpToApplicationThreadServerStreamListener)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)2 Compressor (io.grpc.Compressor)1 IOException (java.io.IOException)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1