Skip to content

Commit 342467d

Browse files
committed
test: fix flakes in HttpJsonDirectServerStreamingCallableTest
The flakes seem to stem from parallel execution and the resulting race conditions around static member variables, particularly the `mockService`. Attempting to fix this by using a separate `mockService` for each test. Fixes: #1905. Fixes: #2107. Fixes: #1876. Fixes: #2083. Fixes: #1842. Fixes: #1587. Fixes: #1684.
1 parent 9916540 commit 342467d

File tree

1 file changed

+27
-29
lines changed

1 file changed

+27
-29
lines changed

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

+27-29
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,8 @@
6262
import java.util.concurrent.Executors;
6363
import java.util.concurrent.TimeUnit;
6464
import org.junit.After;
65-
import org.junit.AfterClass;
6665
import org.junit.Assert;
67-
import org.junit.BeforeClass;
66+
import org.junit.Before;
6867
import org.junit.Test;
6968
import org.junit.runner.RunWith;
7069
import org.junit.runners.JUnit4;
@@ -107,9 +106,7 @@ public class HttpJsonDirectServerStreamingCallableTest {
107106
.setType(MethodType.SERVER_STREAMING)
108107
.build();
109108

110-
private static final MockHttpService MOCK_SERVICE =
111-
new MockHttpService(
112-
Collections.singletonList(METHOD_SERVER_STREAMING_RECOGNIZE), "google.com:443");
109+
private MockHttpService mockService;
113110

114111
private static final Color DEFAULT_REQUEST = Color.newBuilder().setRed(0.5f).build();
115112
private static final Color ASYNC_REQUEST = DEFAULT_REQUEST.toBuilder().setGreen(1000).build();
@@ -120,22 +117,25 @@ public class HttpJsonDirectServerStreamingCallableTest {
120117
Money.newBuilder().setCurrencyCode("UAH").setUnits(255).build();
121118
private static final int AWAIT_TERMINATION_SECONDS = 10;
122119

123-
private static ServerStreamingCallSettings<Color, Money> streamingCallSettings;
124-
private static ServerStreamingCallable<Color, Money> streamingCallable;
120+
private ServerStreamingCallSettings<Color, Money> streamingCallSettings;
121+
private ServerStreamingCallable<Color, Money> streamingCallable;
125122

126-
private static ManagedHttpJsonChannel channel;
127-
private static ClientContext clientContext;
128-
private static ExecutorService executorService;
123+
private ManagedHttpJsonChannel channel;
124+
private ClientContext clientContext;
125+
private ExecutorService executorService;
129126

130-
@BeforeClass
131-
public static void initialize() throws IOException {
127+
@Before
128+
public void initialize() throws IOException {
129+
mockService =
130+
new MockHttpService(
131+
Collections.singletonList(METHOD_SERVER_STREAMING_RECOGNIZE), "google.com:443");
132132
executorService = Executors.newFixedThreadPool(2);
133133
channel =
134134
new ManagedHttpJsonInterceptorChannel(
135135
ManagedHttpJsonChannel.newBuilder()
136136
.setEndpoint("google.com:443")
137137
.setExecutor(executorService)
138-
.setHttpTransport(MOCK_SERVICE)
138+
.setHttpTransport(mockService)
139139
.build(),
140140
new HttpJsonHeaderInterceptor(Collections.singletonMap("header-key", "headerValue")));
141141
EndpointContext endpointContext = Mockito.mock(EndpointContext.class);
@@ -158,25 +158,23 @@ public static void initialize() throws IOException {
158158
HttpJsonCallSettings.create(METHOD_SERVER_STREAMING_RECOGNIZE),
159159
streamingCallSettings,
160160
clientContext);
161+
162+
mockService.reset();
161163
}
162164

163-
@AfterClass
164-
public static void destroy() throws InterruptedException {
165+
@After
166+
public void destroy() throws InterruptedException {
165167
executorService.shutdown();
166168
channel.shutdown();
167169

168170
executorService.awaitTermination(AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS);
169171
channel.awaitTermination(AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS);
170-
}
171-
172-
@After
173-
public void tearDown() throws InterruptedException {
174-
MOCK_SERVICE.reset();
172+
mockService.reset();
175173
}
176174

177175
@Test
178176
public void testBadContext() {
179-
MOCK_SERVICE.addResponse(new Money[] {DEFAULT_RESPONSE});
177+
mockService.addResponse(new Money[] {DEFAULT_RESPONSE});
180178
// Create a local callable with a bad context
181179
ServerStreamingCallable<Color, Money> streamingCallable =
182180
HttpJsonCallableFactory.createServerStreamingCallable(
@@ -202,7 +200,7 @@ public void testBadContext() {
202200

203201
@Test
204202
public void testServerStreamingStart() throws InterruptedException {
205-
MOCK_SERVICE.addResponse(new Money[] {DEFAULT_RESPONSE});
203+
mockService.addResponse(new Money[] {DEFAULT_RESPONSE});
206204
CountDownLatch latch = new CountDownLatch(1);
207205
MoneyObserver moneyObserver = new MoneyObserver(true, latch);
208206

@@ -217,7 +215,7 @@ public void testServerStreamingStart() throws InterruptedException {
217215

218216
@Test
219217
public void testServerStreaming() throws InterruptedException {
220-
MOCK_SERVICE.addResponse(new Money[] {DEFAULT_RESPONSE, DEFAULTER_RESPONSE});
218+
mockService.addResponse(new Money[] {DEFAULT_RESPONSE, DEFAULTER_RESPONSE});
221219
CountDownLatch latch = new CountDownLatch(3);
222220
MoneyObserver moneyObserver = new MoneyObserver(true, latch);
223221

@@ -231,7 +229,7 @@ public void testServerStreaming() throws InterruptedException {
231229

232230
@Test
233231
public void testManualFlowControl() throws Exception {
234-
MOCK_SERVICE.addResponse(new Money[] {DEFAULT_RESPONSE});
232+
mockService.addResponse(new Money[] {DEFAULT_RESPONSE});
235233
CountDownLatch latch = new CountDownLatch(2);
236234
MoneyObserver moneyObserver = new MoneyObserver(false, latch);
237235

@@ -251,7 +249,7 @@ public void testManualFlowControl() throws Exception {
251249

252250
@Test
253251
public void testCancelClientCall() throws Exception {
254-
MOCK_SERVICE.addResponse(new Money[] {DEFAULT_RESPONSE});
252+
mockService.addResponse(new Money[] {DEFAULT_RESPONSE});
255253
CountDownLatch latch = new CountDownLatch(1);
256254
MoneyObserver moneyObserver = new MoneyObserver(false, latch);
257255

@@ -267,7 +265,7 @@ public void testCancelClientCall() throws Exception {
267265

268266
@Test
269267
public void testOnResponseError() throws Throwable {
270-
MOCK_SERVICE.addException(404, new RuntimeException("some error"));
268+
mockService.addException(404, new RuntimeException("some error"));
271269

272270
CountDownLatch latch = new CountDownLatch(1);
273271
MoneyObserver moneyObserver = new MoneyObserver(true, latch);
@@ -292,7 +290,7 @@ public void testOnResponseError() throws Throwable {
292290

293291
@Test
294292
public void testObserverErrorCancelsCall() throws Throwable {
295-
MOCK_SERVICE.addResponse(new Money[] {DEFAULT_RESPONSE});
293+
mockService.addResponse(new Money[] {DEFAULT_RESPONSE});
296294
final RuntimeException expectedCause = new RuntimeException("some error");
297295
final SettableApiFuture<Throwable> actualErrorF = SettableApiFuture.create();
298296

@@ -332,7 +330,7 @@ protected void onCompleteImpl() {
332330

333331
@Test
334332
public void testBlockingServerStreaming() {
335-
MOCK_SERVICE.addResponse(new Money[] {DEFAULT_RESPONSE});
333+
mockService.addResponse(new Money[] {DEFAULT_RESPONSE});
336334
Color request = Color.newBuilder().setRed(0.5f).build();
337335
ServerStream<Money> response = streamingCallable.call(request);
338336
List<Money> responseData = Lists.newArrayList(response);
@@ -344,7 +342,7 @@ public void testBlockingServerStreaming() {
344342
// This test ensures that the server-side streaming does not exceed the timeout value
345343
@Test
346344
public void testDeadlineExceededServerStreaming() throws InterruptedException {
347-
MOCK_SERVICE.addResponse(
345+
mockService.addResponse(
348346
new Money[] {DEFAULT_RESPONSE, DEFAULTER_RESPONSE}, java.time.Duration.ofSeconds(5));
349347
Color request = Color.newBuilder().setRed(0.5f).build();
350348
CountDownLatch latch = new CountDownLatch(1);

0 commit comments

Comments
 (0)