/** * Create a callable object with grpc-specific functionality. Designed for use by generated code. * * @param innerCallable the callable that performs the work * @param callSettings {@link UnaryCallSettings} to configure the method-level settings with. * @param clientContext {@link ClientContext} to use to connect to the service. * @return {@link UnaryCallable} callable object. */ public static <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createUnaryCallable( UnaryCallable<RequestT, ResponseT> innerCallable, UnaryCallSettings<RequestT, ResponseT> callSettings, ClientContext clientContext) { UnaryCallable<RequestT, ResponseT> callable = createBaseUnaryCallable(innerCallable, callSettings, clientContext); return callable.withDefaultCallContext(FakeCallContext.create(clientContext)); }
@Test public void bidiStreaming_BidiStreamObserver() throws InterruptedException { BidiStreamingStashCallable<Integer, Integer> callIntList = new BidiStreamingStashCallable<>(Arrays.asList(0, 1, 2)); BidiStreamingCallable<Integer, Integer> callable = FakeCallableFactory.createBidiStreamingCallable( callIntList, StreamingCallSettings.<Integer, Integer>newBuilder().build(), clientContext); AccumulatingBidiObserver observer = new AccumulatingBidiObserver(Arrays.asList(3, 4, 5)); callable.call(observer); assertThat(observer.getResponses()).containsExactly(0, 1, 2).inOrder(); assertThat(callIntList.getActualRequests()).containsExactly(3, 4, 5).inOrder(); }
@Test public void testFutureCallContextPropagation() throws Exception { String opName = "testFutureCallContextPropagation"; Color resp = getColor(0.5f); Currency meta1 = Currency.getInstance("UAH"); Currency meta2 = Currency.getInstance("USD"); OperationSnapshot initialOperation = getOperation(opName, null, null, null, false); OperationSnapshot resultOperation = getOperation(opName, resp, null, meta2, true); UnaryCallable<Integer, OperationSnapshot> initialCallable = mockGetOpSnapshotCallable(StatusCode.Code.OK, initialOperation); LongRunningClient longRunningClient = Mockito.mock(LongRunningClient.class); @SuppressWarnings("unchecked") UnaryCallable<String, OperationSnapshot> getOpCallable = Mockito.mock(UnaryCallable.class); ArgumentCaptor<ApiCallContext> callContextCaptor = ArgumentCaptor.forClass(ApiCallContext.class); Mockito.when(longRunningClient.getOperationCallable()).thenReturn(getOpCallable); Mockito.when(getOpCallable.futureCall(Mockito.<String>any(), callContextCaptor.capture())) .thenReturn(ApiFutures.immediateFuture(resultOperation)); OperationCallable<Integer, Color, Currency> callable = FakeCallableFactory.createOperationCallable( initialCallable, callSettings, initialContext, longRunningClient); ApiCallContext callContext = FakeCallContext.createDefault().withTimeout(Duration.ofMillis(10)); callable.futureCall(2, callContext).get(10, TimeUnit.SECONDS); assertThat(callContextCaptor.getValue().getTimeout()).isEqualTo(Duration.ofMillis(10)); }
@Test public void testUnknownStatusCode() { thrown.expect(RuntimeException.class); ImmutableSet<StatusCode.Code> retryable = ImmutableSet.of(); Mockito.when(callInt.futureCall((Integer) Mockito.any(), (ApiCallContext) Mockito.any())) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(new RuntimeException("unknown"))); UnaryCallSettings<Integer, Integer> callSettings = UnaryCallSettings.<Integer, Integer>newUnaryCallSettingsBuilder() .setRetryableCodes(retryable) .build(); UnaryCallable<Integer, Integer> callable = FakeCallableFactory.createUnaryCallable(callInt, callSettings, clientContext); callable.call(1); }
@Test(expected = ValidationException.class) public void pagedFixedSizeCollectionTooManyElements() { Mockito.when(callIntList.futureCall((Integer) Mockito.any(), (ApiCallContext) Mockito.any())) .thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1, 2))) .thenReturn(ApiFutures.immediateFuture(Arrays.asList(3, 4))) .thenReturn(ApiFutures.immediateFuture(Collections.<Integer>emptyList())); FakeCallableFactory.createPagedCallable( callIntList, PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(), clientContext) .call(0) .expandToFixedSizeCollection(4); }
@Test public void blockingServerStreaming() { ServerStreamingStashCallable<Integer, Integer> callIntList = new ServerStreamingStashCallable<>(Arrays.asList(0, 1, 2)); ServerStreamingCallable<Integer, Integer> callable = FakeCallableFactory.createServerStreamingCallable( callIntList, StreamingCallSettings.<Integer, Integer>newBuilder().build(), clientContext); Truth.assertThat(ImmutableList.copyOf(callable.call(0))).containsExactly(0, 1, 2).inOrder(); Truth.assertThat(callIntList.getActualRequest()).isEqualTo(0); }
@Test public void batchingDisabled() throws Exception { BatchingSettings batchingSettings = BatchingSettings.newBuilder().setIsEnabled(false).build(); BatchingCallSettings<LabeledIntList, List<Integer>> batchingCallSettings = BatchingCallSettings.newBuilder(SQUARER_BATCHING_DESC) .setBatchingSettings(batchingSettings) .build(); UnaryCallable<LabeledIntList, List<Integer>> callable = FakeCallableFactory.createBatchingCallable( callLabeledIntSquarer, batchingCallSettings, clientContext); ApiFuture<List<Integer>> f1 = callable.futureCall(new LabeledIntList("one", 1, 2)); ApiFuture<List<Integer>> f2 = callable.futureCall(new LabeledIntList("one", 3, 4)); Truth.assertThat(f1.get()).isEqualTo(Arrays.asList(1, 4)); Truth.assertThat(f2.get()).isEqualTo(Arrays.asList(9, 16)); }
@Test public void nonPaged() { ArgumentCaptor<Integer> requestCapture = ArgumentCaptor.forClass(Integer.class); Mockito.when(callIntList.futureCall(requestCapture.capture(), (ApiCallContext) Mockito.any())) .thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1, 2))) .thenReturn(ApiFutures.immediateFuture(Arrays.asList(3, 4))) .thenReturn(ApiFutures.immediateFuture(Collections.<Integer>emptyList())); UnaryCallable<Integer, List<Integer>> callable = FakeCallableFactory.createUnpagedCallable( callIntList, PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(), clientContext); Truth.assertThat(ImmutableList.copyOf(callable.call(0))).containsExactly(0, 1, 2).inOrder(); Truth.assertThat(ImmutableList.copyOf(callable.call(2))).containsExactly(3, 4).inOrder(); Truth.assertThat(ImmutableList.copyOf(callable.call(4))).isEmpty(); Truth.assertThat(requestCapture.getAllValues()).containsExactly(0, 2, 4).inOrder(); }
@Test public void clientStreaming() { ClientStreamingStashCallable<Integer, Integer> callIntList = new ClientStreamingStashCallable<>(100); ClientStreamingCallable<Integer, Integer> callable = FakeCallableFactory.createClientStreamingCallable( callIntList, StreamingCallSettings.<Integer, Integer>newBuilder().build(), clientContext); AccumulatingStreamObserver responseObserver = new AccumulatingStreamObserver(); ApiStreamObserver<Integer> requestObserver = callable.clientStreamingCall(responseObserver); requestObserver.onNext(0); requestObserver.onNext(2); requestObserver.onNext(4); requestObserver.onCompleted(); Truth.assertThat(ImmutableList.copyOf(responseObserver.getValues())) .containsExactly(100) .inOrder(); Truth.assertThat(callIntList.getActualRequests()).containsExactly(0, 2, 4).inOrder(); }
@Test public void retryOnStatusUnknown() { Throwable throwable = new UnknownException(null, FakeStatusCode.of(StatusCode.Code.UNKNOWN), true); Mockito.when(callInt.futureCall((Integer) Mockito.any(), (ApiCallContext) Mockito.any())) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(throwable)) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(throwable)) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(throwable)) .thenReturn(ApiFutures.<Integer>immediateFuture(2)); UnaryCallSettings<Integer, Integer> callSettings = createSettings(FAST_RETRY_SETTINGS); UnaryCallable<Integer, Integer> callable = FakeCallableFactory.createUnaryCallable(callInt, callSettings, clientContext); Truth.assertThat(callable.call(1)).isEqualTo(2); }
@Test(expected = ValidationException.class) public void pagedFixedSizeCollectionTooSmallCollectionSize() { Mockito.when(callIntList.futureCall((Integer) Mockito.any(), (ApiCallContext) Mockito.any())) .thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1))) .thenReturn(ApiFutures.immediateFuture(Collections.<Integer>emptyList())); FakeCallableFactory.createPagedCallable( callIntList, PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(), clientContext) .call(0) .expandToFixedSizeCollection(2); } }
@Test public void testFirstElementCall() { ServerStreamingStashCallable<Integer, Integer> callIntList = new ServerStreamingStashCallable<>(Arrays.asList(0, 1, 2)); ServerStreamingCallable<Integer, Integer> streamingCallable = FakeCallableFactory.createServerStreamingCallable( callIntList, StreamingCallSettings.<Integer, Integer>newBuilder().build(), clientContext); UnaryCallable<Integer, Integer> callable = streamingCallable.first(); Truth.assertThat(callable.call(0)).isEqualTo(0); Truth.assertThat(callIntList.getActualRequest()).isEqualTo(0); }
public void batchingWithBlockingCallThreshold() throws Exception { BatchingSettings batchingSettings = BatchingSettings.newBuilder() .setDelayThreshold(Duration.ofSeconds(1)) .setElementCountThreshold(2L) .build(); BatchingCallSettings<LabeledIntList, List<Integer>> batchingCallSettings = BatchingCallSettings.newBuilder(SQUARER_BATCHING_DESC) .setBatchingSettings(batchingSettings) .build(); UnaryCallable<LabeledIntList, List<Integer>> callable = FakeCallableFactory.createBatchingCallable( callLabeledIntSquarer, batchingCallSettings, clientContext); ApiFuture<List<Integer>> f1 = callable.futureCall(new LabeledIntList("one", 1)); ApiFuture<List<Integer>> f2 = callable.futureCall(new LabeledIntList("one", 3)); Truth.assertThat(f1.get()).isEqualTo(Arrays.asList(1)); Truth.assertThat(f2.get()).isEqualTo(Arrays.asList(9)); }
@Test public void testCall() { Color resp = getColor(1.0f); Currency meta = Currency.getInstance("UAH"); OperationSnapshot resultOperation = getOperation("testCall", resp, null, meta, true); UnaryCallable<Integer, OperationSnapshot> initialCallable = mockGetOpSnapshotCallable(StatusCode.Code.OK, resultOperation); LongRunningClient longRunningClient = new UnsupportedOperationApi(); OperationCallable<Integer, Color, Currency> callable = FakeCallableFactory.createOperationCallable( initialCallable, callSettings, initialContext, longRunningClient); Color response = callable.call(2, FakeCallContext.createDefault()); Truth.assertThat(response).isEqualTo(resp); assertThat(executor.getIterationsCount()).isEqualTo(0); }
@Test public void retry() { Throwable throwable = new UnavailableException(null, FakeStatusCode.of(StatusCode.Code.UNAVAILABLE), true); Mockito.when(callInt.futureCall((Integer) Mockito.any(), (ApiCallContext) Mockito.any())) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(throwable)) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(throwable)) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(throwable)) .thenReturn(ApiFutures.<Integer>immediateFuture(2)); UnaryCallSettings<Integer, Integer> callSettings = createSettings(FAST_RETRY_SETTINGS); UnaryCallable<Integer, Integer> callable = FakeCallableFactory.createUnaryCallable(callInt, callSettings, clientContext); Truth.assertThat(callable.call(1)).isEqualTo(2); }
@Test public void paged() { ArgumentCaptor<Integer> requestCapture = ArgumentCaptor.forClass(Integer.class); Mockito.when(callIntList.futureCall(requestCapture.capture(), (ApiCallContext) Mockito.any())) .thenReturn(ApiFutures.immediateFuture(Arrays.asList(0, 1, 2))) .thenReturn(ApiFutures.immediateFuture(Arrays.asList(3, 4))) .thenReturn(ApiFutures.immediateFuture(Collections.<Integer>emptyList())); UnaryCallable<Integer, ListIntegersPagedResponse> callable = FakeCallableFactory.createPagedCallable( callIntList, PagedCallSettings.newBuilder(new ListIntegersPagedResponseFactory()).build(), clientContext); Truth.assertThat(ImmutableList.copyOf(callable.call(0).iterateAll())) .containsExactly(0, 1, 2, 3, 4) .inOrder(); Truth.assertThat(requestCapture.getAllValues()).containsExactly(0, 2, 4).inOrder(); }
/** * Create a callable object that represents a simple call to a paged API method. Designed for use * by generated code. * * @param innerCallable the callable that performs the work * @param pagedCallSettings {@link PagedCallSettings} to configure the method-level settings with. * @param clientContext {@link ClientContext} to use to connect to the service. * @return {@link UnaryCallable} callable object. */ public static <RequestT, ResponseT, PagedListResponseT> UnaryCallable<RequestT, ResponseT> createUnpagedCallable( UnaryCallable<RequestT, ResponseT> innerCallable, PagedCallSettings<RequestT, ResponseT, PagedListResponseT> pagedCallSettings, ClientContext clientContext) { UnaryCallable<RequestT, ResponseT> callable = createBaseUnaryCallable(innerCallable, pagedCallSettings, clientContext); return callable.withDefaultCallContext(FakeCallContext.create(clientContext)); }
@Test public void testAllElementCall() { ServerStreamingStashCallable<Integer, Integer> callIntList = new ServerStreamingStashCallable<>(Arrays.asList(0, 1, 2)); ServerStreamingCallable<Integer, Integer> streamingCallable = FakeCallableFactory.createServerStreamingCallable( callIntList, StreamingCallSettings.<Integer, Integer>newBuilder().build(), clientContext); UnaryCallable<Integer, List<Integer>> callable = streamingCallable.all(); Truth.assertThat(callable.call(0)).containsExactly(0, 1, 2).inOrder(); Truth.assertThat(callIntList.getActualRequest()).isEqualTo(0); }
@Test public void batching() throws Exception { BatchingSettings batchingSettings = BatchingSettings.newBuilder() .setDelayThreshold(Duration.ofSeconds(1)) .setElementCountThreshold(2L) .build(); BatchingCallSettings<LabeledIntList, List<Integer>> batchingCallSettings = BatchingCallSettings.newBuilder(SQUARER_BATCHING_DESC) .setBatchingSettings(batchingSettings) .build(); UnaryCallable<LabeledIntList, List<Integer>> callable = FakeCallableFactory.createBatchingCallable( callLabeledIntSquarer, batchingCallSettings, clientContext); ApiFuture<List<Integer>> f1 = callable.futureCall(new LabeledIntList("one", 1, 2)); ApiFuture<List<Integer>> f2 = callable.futureCall(new LabeledIntList("one", 3, 4)); Truth.assertThat(f1.get()).isEqualTo(Arrays.asList(1, 4)); Truth.assertThat(f2.get()).isEqualTo(Arrays.asList(9, 16)); }
@Test public void bidiStreaming_BidiStream() { BidiStreamingStashCallable<Integer, Integer> callIntList = new BidiStreamingStashCallable<>(Arrays.asList(0, 1, 2)); BidiStreamingCallable<Integer, Integer> callable = FakeCallableFactory.createBidiStreamingCallable( callIntList, StreamingCallSettings.<Integer, Integer>newBuilder().build(), clientContext); BidiStream<Integer, Integer> stream = callIntList.call(); stream.send(3); stream.send(4); stream.send(5); stream.closeSend(); assertThat(callIntList.getActualRequests()).containsExactly(3, 4, 5).inOrder(); assertThat(stream).containsExactly(0, 1, 2).inOrder(); }