|
29 | 29 | */
|
30 | 30 | package com.google.api.gax.grpc;
|
31 | 31 |
|
| 32 | +import static com.google.api.gax.grpc.testing.FakeServiceGrpc.METHOD_SERVER_STREAMING_RECOGNIZE; |
32 | 33 | import static com.google.common.truth.Truth.assertThat;
|
33 | 34 |
|
34 | 35 | import com.google.api.gax.grpc.testing.FakeChannelFactory;
|
35 | 36 | import com.google.api.gax.grpc.testing.FakeMethodDescriptor;
|
36 | 37 | import com.google.api.gax.grpc.testing.FakeServiceGrpc;
|
| 38 | +import com.google.api.gax.rpc.ClientContext; |
| 39 | +import com.google.api.gax.rpc.ResponseObserver; |
| 40 | +import com.google.api.gax.rpc.ServerStreamingCallSettings; |
| 41 | +import com.google.api.gax.rpc.ServerStreamingCallable; |
| 42 | +import com.google.api.gax.rpc.StreamController; |
37 | 43 | import com.google.common.collect.ImmutableList;
|
38 | 44 | import com.google.common.collect.Lists;
|
39 | 45 | import com.google.type.Color;
|
|
49 | 55 | import java.util.ArrayList;
|
50 | 56 | import java.util.Arrays;
|
51 | 57 | import java.util.List;
|
| 58 | +import java.util.concurrent.CancellationException; |
52 | 59 | import java.util.concurrent.ExecutorService;
|
53 | 60 | import java.util.concurrent.Executors;
|
54 | 61 | import java.util.concurrent.ScheduledExecutorService;
|
55 | 62 | import java.util.concurrent.ScheduledFuture;
|
56 | 63 | import java.util.concurrent.TimeUnit;
|
57 | 64 | import java.util.concurrent.atomic.AtomicInteger;
|
| 65 | +import org.junit.Assert; |
58 | 66 | import org.junit.Test;
|
59 | 67 | import org.junit.runner.RunWith;
|
60 | 68 | import org.junit.runners.JUnit4;
|
@@ -595,4 +603,50 @@ public void removedActiveChannelsAreShutdown() throws Exception {
|
595 | 603 | // Now the channel should be closed
|
596 | 604 | Mockito.verify(channels.get(1), Mockito.times(1)).shutdown();
|
597 | 605 | }
|
| 606 | + |
| 607 | + @Test |
| 608 | + public void testReleasingClientCallCancelEarly() throws IOException { |
| 609 | + ClientCall mockClientCall = Mockito.mock(ClientCall.class); |
| 610 | + Mockito.doAnswer(invocation -> null).when(mockClientCall).cancel(Mockito.any(), Mockito.any()); |
| 611 | + ManagedChannel fakeChannel = Mockito.mock(ManagedChannel.class); |
| 612 | + Mockito.when(fakeChannel.newCall(Mockito.any(), Mockito.any())).thenReturn(mockClientCall); |
| 613 | + ChannelPoolSettings channelPoolSettings = ChannelPoolSettings.staticallySized(1); |
| 614 | + ChannelFactory factory = new FakeChannelFactory(ImmutableList.of(fakeChannel)); |
| 615 | + ChannelPool channelPool = ChannelPool.create(channelPoolSettings, factory); |
| 616 | + ClientContext context = |
| 617 | + ClientContext.newBuilder() |
| 618 | + .setTransportChannel(GrpcTransportChannel.create(channelPool)) |
| 619 | + .setDefaultCallContext(GrpcCallContext.of(channelPool, CallOptions.DEFAULT)) |
| 620 | + .build(); |
| 621 | + ServerStreamingCallSettings settings = |
| 622 | + ServerStreamingCallSettings.<Color, Money>newBuilder().build(); |
| 623 | + ServerStreamingCallable streamingCallable = |
| 624 | + GrpcCallableFactory.createServerStreamingCallable( |
| 625 | + GrpcCallSettings.create(METHOD_SERVER_STREAMING_RECOGNIZE), settings, context); |
| 626 | + Color request = Color.newBuilder().setRed(0.5f).build(); |
| 627 | + |
| 628 | + IllegalStateException e = |
| 629 | + Assert.assertThrows( |
| 630 | + IllegalStateException.class, |
| 631 | + () -> |
| 632 | + streamingCallable.call( |
| 633 | + request, |
| 634 | + new ResponseObserver() { |
| 635 | + @Override |
| 636 | + public void onStart(StreamController controller) { |
| 637 | + controller.cancel(); |
| 638 | + } |
| 639 | + |
| 640 | + @Override |
| 641 | + public void onResponse(Object response) {} |
| 642 | + |
| 643 | + @Override |
| 644 | + public void onError(Throwable t) {} |
| 645 | + |
| 646 | + @Override |
| 647 | + public void onComplete() {} |
| 648 | + })); |
| 649 | + assertThat(e.getCause()).isInstanceOf(CancellationException.class); |
| 650 | + assertThat(e.getMessage()).isEqualTo("Call is already cancelled"); |
| 651 | + } |
598 | 652 | }
|
0 commit comments