|
38 | 38 | import com.google.api.core.ApiFutures;
|
39 | 39 | import com.google.api.gax.grpc.testing.LocalChannelProvider;
|
40 | 40 | import com.google.api.gax.retrying.RetrySettings;
|
| 41 | +import com.google.api.gax.rpc.ApiCallContext; |
41 | 42 | import com.google.cloud.ByteArray;
|
42 | 43 | import com.google.cloud.NoCredentials;
|
43 | 44 | import com.google.cloud.Timestamp;
|
|
51 | 52 | import com.google.cloud.spanner.ReadContext.QueryAnalyzeMode;
|
52 | 53 | import com.google.cloud.spanner.SessionPool.PooledSessionFuture;
|
53 | 54 | import com.google.cloud.spanner.SpannerException.ResourceNotFoundException;
|
| 55 | +import com.google.cloud.spanner.SpannerOptions.CallContextConfigurator; |
54 | 56 | import com.google.cloud.spanner.SpannerOptions.SpannerCallContextTimeoutConfigurator;
|
55 | 57 | import com.google.cloud.spanner.Type.Code;
|
56 | 58 | import com.google.cloud.spanner.connection.RandomResultSetGenerator;
|
|
77 | 79 | import com.google.spanner.v1.TypeAnnotationCode;
|
78 | 80 | import com.google.spanner.v1.TypeCode;
|
79 | 81 | import io.grpc.Context;
|
| 82 | +import io.grpc.MethodDescriptor; |
80 | 83 | import io.grpc.Server;
|
81 | 84 | import io.grpc.Status;
|
82 | 85 | import io.grpc.StatusRuntimeException;
|
@@ -2963,6 +2966,63 @@ public void testStatementWithBytesArrayParameter() {
|
2963 | 2966 | }
|
2964 | 2967 | }
|
2965 | 2968 |
|
| 2969 | + @Test |
| 2970 | + public void testStreamWaitTimeout() { |
| 2971 | + DatabaseClient client = |
| 2972 | + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); |
| 2973 | + // Add a wait time to the mock server. Note that the test won't actually wait 100ms, as it uses |
| 2974 | + // a 1ns time out. |
| 2975 | + mockSpanner.setExecuteStreamingSqlExecutionTime( |
| 2976 | + SimulatedExecutionTime.ofMinimumAndRandomTime(100, 0)); |
| 2977 | + // Create a custom call configuration that uses a 1 nanosecond stream timeout value. This will |
| 2978 | + // always time out, as a call to the mock server will always take more than 1 nanosecond. |
| 2979 | + CallContextConfigurator configurator = |
| 2980 | + new CallContextConfigurator() { |
| 2981 | + @Override |
| 2982 | + public <ReqT, RespT> ApiCallContext configure( |
| 2983 | + ApiCallContext context, ReqT request, MethodDescriptor<ReqT, RespT> method) { |
| 2984 | + return context.withStreamWaitTimeout(Duration.ofNanos(1L)); |
| 2985 | + } |
| 2986 | + }; |
| 2987 | + Context context = |
| 2988 | + Context.current().withValue(SpannerOptions.CALL_CONTEXT_CONFIGURATOR_KEY, configurator); |
| 2989 | + context.run( |
| 2990 | + () -> { |
| 2991 | + try (ResultSet resultSet = client.singleUse().executeQuery(SELECT1)) { |
| 2992 | + SpannerException exception = assertThrows(SpannerException.class, resultSet::next); |
| 2993 | + assertEquals(ErrorCode.DEADLINE_EXCEEDED, exception.getErrorCode()); |
| 2994 | + assertTrue( |
| 2995 | + exception.getMessage(), exception.getMessage().contains("stream wait timeout")); |
| 2996 | + } |
| 2997 | + }); |
| 2998 | + } |
| 2999 | + |
| 3000 | + @Test |
| 3001 | + public void testZeroStreamWaitTimeout() { |
| 3002 | + DatabaseClient client = |
| 3003 | + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); |
| 3004 | + // Create a custom call configuration that sets the stream timeout to zero. |
| 3005 | + // This should disable the timeout. |
| 3006 | + CallContextConfigurator configurator = |
| 3007 | + new CallContextConfigurator() { |
| 3008 | + @Override |
| 3009 | + public <ReqT, RespT> ApiCallContext configure( |
| 3010 | + ApiCallContext context, ReqT request, MethodDescriptor<ReqT, RespT> method) { |
| 3011 | + return context.withStreamWaitTimeout(Duration.ZERO); |
| 3012 | + } |
| 3013 | + }; |
| 3014 | + Context context = |
| 3015 | + Context.current().withValue(SpannerOptions.CALL_CONTEXT_CONFIGURATOR_KEY, configurator); |
| 3016 | + context.run( |
| 3017 | + () -> { |
| 3018 | + try (ResultSet resultSet = client.singleUse().executeQuery(SELECT1)) { |
| 3019 | + // A zero timeout should not cause a timeout, and instead be ignored. |
| 3020 | + assertTrue(resultSet.next()); |
| 3021 | + assertFalse(resultSet.next()); |
| 3022 | + } |
| 3023 | + }); |
| 3024 | + } |
| 3025 | + |
2966 | 3026 | static void assertAsString(String expected, ResultSet resultSet, int col) {
|
2967 | 3027 | assertEquals(expected, resultSet.getValue(col).getAsString());
|
2968 | 3028 | assertEquals(ImmutableList.of(expected), resultSet.getValue(col).getAsStringList());
|
|
0 commit comments