@Test
  public void contextCancellationCancelsStream() throws Exception {
    // Attach the context which is recorded when the call is created
    Context.CancellableContext cancellableContext = Context.current().withCancellation();
    Context previous = cancellableContext.attach();

    ClientCallImpl<Void, Void> call =
        new ClientCallImpl<Void, Void>(
                DESCRIPTOR,
                new SerializingExecutor(Executors.newSingleThreadExecutor()),
                CallOptions.DEFAULT,
                provider,
                deadlineCancellationExecutor)
            .setDecompressorRegistry(decompressorRegistry);

    previous.attach();

    call.start(callListener, new Metadata());

    Throwable t = new Throwable();
    cancellableContext.cancel(t);

    verify(stream, times(1)).cancel(statusArgumentCaptor.capture());

    verify(stream, times(1)).cancel(statusCaptor.capture());
    assertEquals(Status.Code.CANCELLED, statusCaptor.getValue().getCode());
  }
Example #2
0
 @Test
 public void statusFromCancelled_returnCancelledIfCauseIsNull() {
   Context.CancellableContext cancellableContext = Context.current().withCancellation();
   cancellableContext.cancel(null);
   assertTrue(cancellableContext.isCancelled());
   Status status = statusFromCancelled(cancellableContext);
   assertNotNull(status);
   assertEquals(Status.Code.CANCELLED, status.getCode());
 }
Example #3
0
 @Test
 public void statusFromCancelled_returnStatusAsSetOnCtx() {
   Context.CancellableContext cancellableContext = Context.current().withCancellation();
   cancellableContext.cancel(Status.DEADLINE_EXCEEDED.withDescription("foo bar").asException());
   Status status = statusFromCancelled(cancellableContext);
   assertNotNull(status);
   assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getCode());
   assertEquals("foo bar", status.getDescription());
 }
Example #4
0
 @Test
 public void statusFromCancelled_shouldReturnStatusWithCauseAttached() {
   Context.CancellableContext cancellableContext = Context.current().withCancellation();
   Throwable t = new Throwable();
   cancellableContext.cancel(t);
   Status status = statusFromCancelled(cancellableContext);
   assertNotNull(status);
   assertEquals(Status.Code.CANCELLED, status.getCode());
   assertSame(t, status.getCause());
 }
Example #5
0
  /** This is a whitebox test, to verify a special case of the implementation. */
  @Test
  public void statusFromCancelled_StatusUnknownShouldWork() {
    Context.CancellableContext cancellableContext = Context.current().withCancellation();
    Exception e = Status.UNKNOWN.asException();
    cancellableContext.cancel(e);
    assertTrue(cancellableContext.isCancelled());

    Status status = statusFromCancelled(cancellableContext);
    assertNotNull(status);
    assertEquals(Status.Code.UNKNOWN, status.getCode());
    assertSame(e, status.getCause());
  }
  @Test
  public void contextAlreadyCancelledNotifiesImmediately() throws Exception {
    // Attach the context which is recorded when the call is created
    Context.CancellableContext cancellableContext = Context.current().withCancellation();
    Throwable cause = new Throwable();
    cancellableContext.cancel(cause);
    Context previous = cancellableContext.attach();

    ClientCallImpl<Void, Void> call =
        new ClientCallImpl<Void, Void>(
                DESCRIPTOR,
                new SerializingExecutor(Executors.newSingleThreadExecutor()),
                CallOptions.DEFAULT,
                provider,
                deadlineCancellationExecutor)
            .setDecompressorRegistry(decompressorRegistry);

    previous.attach();

    final SettableFuture<Status> statusFuture = SettableFuture.create();
    call.start(
        new ClientCall.Listener<Void>() {
          @Override
          public void onClose(Status status, Metadata trailers) {
            statusFuture.set(status);
          }
        },
        new Metadata());

    // Caller should receive onClose callback.
    Status status = statusFuture.get(5, TimeUnit.SECONDS);
    assertEquals(Status.Code.CANCELLED, status.getCode());
    assertSame(cause, status.getCause());

    // Following operations should be no-op.
    call.request(1);
    call.sendMessage(null);
    call.halfClose();

    // Stream should never be created.
    verifyZeroInteractions(transport);

    try {
      call.sendMessage(null);
      fail("Call has been cancelled");
    } catch (IllegalStateException ise) {
      // expected
    }
  }
Example #7
0
  @Test
  public void statusFromCancelled_TimeoutExceptionShouldMapToDeadlineExceeded() {
    FakeClock fakeClock = new FakeClock();
    Context.CancellableContext cancellableContext =
        Context.current()
            .withDeadlineAfter(100, TimeUnit.MILLISECONDS, fakeClock.scheduledExecutorService);
    fakeClock.forwardTime(System.nanoTime(), TimeUnit.NANOSECONDS);
    fakeClock.forwardMillis(100);

    assertTrue(cancellableContext.isCancelled());
    assertThat(cancellableContext.cancellationCause(), instanceOf(TimeoutException.class));

    Status status = statusFromCancelled(cancellableContext);
    assertNotNull(status);
    assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getCode());
    assertEquals("context timed out", status.getDescription());
  }