Skip to content

Commit 564802b

Browse files
authored
test: fix flaky HttpJsonDirectServerStreamingCallableTest.testOnResponseError (#2444)
* increase timeout from 2s to 30s to reduce the chance of DEADLINE_EXCEEDED before the NOT_FOUND message is received * keep separate low timeout for the testDeadlineExceededServerStreaming test * remove mockService reset to speedup tests, as it's no longer necessary Fixes: #1842.
1 parent b0a57b7 commit 564802b

File tree

1 file changed

+50
-51
lines changed

1 file changed

+50
-51
lines changed

gax-java/gax-httpjson/src/test/java/com/google/api/gax/httpjson/HttpJsonDirectServerStreamingCallableTest.java

+50-51
Original file line numberDiff line numberDiff line change
@@ -72,63 +72,65 @@
7272

7373
@RunWith(JUnit4.class)
7474
public class HttpJsonDirectServerStreamingCallableTest {
75-
private static final ApiMethodDescriptor<Color, Money> METHOD_SERVER_STREAMING_RECOGNIZE =
76-
ApiMethodDescriptor.<Color, Money>newBuilder()
77-
.setFullMethodName("google.cloud.v1.Fake/ServerStreamingRecognize")
78-
.setHttpMethod("POST")
79-
.setRequestFormatter(
80-
ProtoMessageRequestFormatter.<Color>newBuilder()
81-
.setPath(
82-
"/fake/v1/recognize/{blue}",
83-
request -> {
84-
Map<String, String> fields = new HashMap<>();
85-
ProtoRestSerializer<Field> serializer = ProtoRestSerializer.create();
86-
serializer.putPathParam(fields, "blue", request.getBlue());
87-
return fields;
88-
})
89-
.setQueryParamsExtractor(
90-
request -> {
91-
Map<String, List<String>> fields = new HashMap<>();
92-
ProtoRestSerializer<Field> serializer = ProtoRestSerializer.create();
93-
serializer.putQueryParam(fields, "red", request.getRed());
94-
return fields;
95-
})
96-
.setRequestBodyExtractor(
97-
request ->
98-
ProtoRestSerializer.create()
99-
.toBody(
100-
"*", request.toBuilder().clearBlue().clearRed().build(), false))
101-
.build())
102-
.setResponseParser(
103-
ProtoMessageResponseParser.<Money>newBuilder()
104-
.setDefaultInstance(Money.getDefaultInstance())
105-
.build())
106-
.setType(MethodType.SERVER_STREAMING)
107-
.build();
108-
109-
private MockHttpService mockService;
110-
11175
private static final Color DEFAULT_REQUEST = Color.newBuilder().setRed(0.5f).build();
11276
private static final Color ASYNC_REQUEST = DEFAULT_REQUEST.toBuilder().setGreen(1000).build();
11377
private static final Color ERROR_REQUEST = Color.newBuilder().setRed(-1).build();
11478
private static final Money DEFAULT_RESPONSE =
11579
Money.newBuilder().setCurrencyCode("USD").setUnits(127).build();
11680
private static final Money DEFAULTER_RESPONSE =
11781
Money.newBuilder().setCurrencyCode("UAH").setUnits(255).build();
118-
private static final int AWAIT_TERMINATION_SECONDS = 10;
11982

12083
private ServerStreamingCallSettings<Color, Money> streamingCallSettings;
12184
private ServerStreamingCallable<Color, Money> streamingCallable;
12285

12386
private ManagedHttpJsonChannel channel;
12487
private ClientContext clientContext;
12588
private ExecutorService executorService;
89+
private MockHttpService mockService;
90+
ApiMethodDescriptor<Color, Money> methodServerStreamingRecognize;
12691

12792
@Before
12893
public void initialize() throws IOException {
129-
mockService =
94+
initialize(Duration.ofSeconds(30));
95+
}
96+
97+
public void initialize(Duration timeout) throws IOException {
98+
this.methodServerStreamingRecognize =
99+
ApiMethodDescriptor.<Color, Money>newBuilder()
100+
.setFullMethodName("google.cloud.v1.Fake/ServerStreamingRecognize")
101+
.setHttpMethod("POST")
102+
.setRequestFormatter(
103+
ProtoMessageRequestFormatter.<Color>newBuilder()
104+
.setPath(
105+
"/fake/v1/recognize/{blue}",
106+
request -> {
107+
Map<String, String> fields = new HashMap<>();
108+
ProtoRestSerializer<Field> serializer = ProtoRestSerializer.create();
109+
serializer.putPathParam(fields, "blue", request.getBlue());
110+
return fields;
111+
})
112+
.setQueryParamsExtractor(
113+
request -> {
114+
Map<String, List<String>> fields = new HashMap<>();
115+
ProtoRestSerializer<Field> serializer = ProtoRestSerializer.create();
116+
serializer.putQueryParam(fields, "red", request.getRed());
117+
return fields;
118+
})
119+
.setRequestBodyExtractor(
120+
request ->
121+
ProtoRestSerializer.create()
122+
.toBody(
123+
"*", request.toBuilder().clearBlue().clearRed().build(), false))
124+
.build())
125+
.setResponseParser(
126+
ProtoMessageResponseParser.<Money>newBuilder()
127+
.setDefaultInstance(Money.getDefaultInstance())
128+
.build())
129+
.setType(MethodType.SERVER_STREAMING)
130+
.build();
131+
this.mockService =
130132
new MockHttpService(
131-
Collections.singletonList(METHOD_SERVER_STREAMING_RECOGNIZE), "google.com:443");
133+
Collections.singletonList(methodServerStreamingRecognize), "google.com:443");
132134
executorService = Executors.newFixedThreadPool(2);
133135
channel =
134136
new ManagedHttpJsonInterceptorChannel(
@@ -148,28 +150,22 @@ public void initialize() throws IOException {
148150
.setTransportChannel(HttpJsonTransportChannel.create(channel))
149151
.setDefaultCallContext(
150152
HttpJsonCallContext.of(channel, HttpJsonCallOptions.DEFAULT)
151-
.withTimeout(Duration.ofSeconds(3))
153+
.withTimeout(timeout)
152154
.withEndpointContext(endpointContext))
153155
.build();
154156

155157
streamingCallSettings = ServerStreamingCallSettings.<Color, Money>newBuilder().build();
156158
streamingCallable =
157159
HttpJsonCallableFactory.createServerStreamingCallable(
158-
HttpJsonCallSettings.create(METHOD_SERVER_STREAMING_RECOGNIZE),
160+
HttpJsonCallSettings.create(methodServerStreamingRecognize),
159161
streamingCallSettings,
160162
clientContext);
161-
162-
mockService.reset();
163163
}
164164

165165
@After
166166
public void destroy() throws InterruptedException {
167167
executorService.shutdown();
168168
channel.shutdown();
169-
170-
executorService.awaitTermination(AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS);
171-
channel.awaitTermination(AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS);
172-
mockService.reset();
173169
}
174170

175171
@Test
@@ -178,7 +174,7 @@ public void testBadContext() {
178174
// Create a local callable with a bad context
179175
ServerStreamingCallable<Color, Money> streamingCallable =
180176
HttpJsonCallableFactory.createServerStreamingCallable(
181-
HttpJsonCallSettings.create(METHOD_SERVER_STREAMING_RECOGNIZE),
177+
HttpJsonCallSettings.create(this.methodServerStreamingRecognize),
182178
streamingCallSettings,
183179
clientContext
184180
.toBuilder()
@@ -337,9 +333,12 @@ public void testBlockingServerStreaming() {
337333

338334
// This test ensures that the server-side streaming does not exceed the timeout value
339335
@Test
340-
public void testDeadlineExceededServerStreaming() throws InterruptedException {
336+
public void testDeadlineExceededServerStreaming() throws InterruptedException, IOException {
337+
// set a low timeout to trigger deadline-exceeded sooner
338+
initialize(Duration.ofSeconds(1));
339+
341340
mockService.addResponse(
342-
new Money[] {DEFAULT_RESPONSE, DEFAULTER_RESPONSE}, java.time.Duration.ofSeconds(5));
341+
new Money[] {DEFAULT_RESPONSE, DEFAULTER_RESPONSE}, java.time.Duration.ofSeconds(30));
343342
Color request = Color.newBuilder().setRed(0.5f).build();
344343
CountDownLatch latch = new CountDownLatch(1);
345344
MoneyObserver moneyObserver = new MoneyObserver(false, latch);
@@ -349,7 +348,7 @@ public void testDeadlineExceededServerStreaming() throws InterruptedException {
349348
moneyObserver.controller.request(2);
350349
// Set the latch's await time to above the context's timeout value to ensure that
351350
// the latch has been released.
352-
Truth.assertThat(latch.await(5000, TimeUnit.MILLISECONDS)).isTrue();
351+
Truth.assertThat(latch.await(30, TimeUnit.SECONDS)).isTrue();
353352

354353
Truth.assertThat(moneyObserver.error).isInstanceOf(DeadlineExceededException.class);
355354
Truth.assertThat(moneyObserver.error).hasMessageThat().isEqualTo("Deadline exceeded");

0 commit comments

Comments
 (0)