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);
}
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());
}
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));
}
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);
}
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));
}
Aggregations