16
16
package com .google .cloud .bigquery .storage .v1 ;
17
17
18
18
import static com .google .common .truth .Truth .assertThat ;
19
+ import static org .junit .Assert .assertEquals ;
20
+ import static org .junit .Assert .assertThrows ;
21
+ import static org .junit .Assert .assertTrue ;
19
22
20
23
import com .google .api .core .ApiFuture ;
21
24
import com .google .api .gax .batching .FlowController ;
28
31
import com .google .cloud .bigquery .storage .v1 .ConnectionWorker .Load ;
29
32
import com .google .protobuf .DescriptorProtos ;
30
33
import com .google .protobuf .Int64Value ;
34
+ import io .grpc .StatusRuntimeException ;
31
35
import java .io .IOException ;
36
+ import java .time .Duration ;
32
37
import java .util .ArrayList ;
33
38
import java .util .Arrays ;
34
39
import java .util .List ;
@@ -52,6 +57,7 @@ public class ConnectionWorkerTest {
52
57
@ Before
53
58
public void setUp () throws Exception {
54
59
testBigQueryWrite = new FakeBigQueryWrite ();
60
+ ConnectionWorker .setMaxInflightQueueWaitTime (300000 );
55
61
serviceHelper =
56
62
new MockServiceHelper (
57
63
UUID .randomUUID ().toString (), Arrays .<MockGrpcService >asList (testBigQueryWrite ));
@@ -281,6 +287,63 @@ public void testAppendInSameStream_switchSchema() throws Exception {
281
287
}
282
288
}
283
289
290
+ @ Test
291
+ public void testAppendButInflightQueueFull () throws Exception {
292
+ ConnectionWorker connectionWorker =
293
+ new ConnectionWorker (
294
+ TEST_STREAM_1 ,
295
+ createProtoSchema ("foo" ),
296
+ 6 ,
297
+ 100000 ,
298
+ Duration .ofSeconds (100 ),
299
+ FlowController .LimitExceededBehavior .Block ,
300
+ TEST_TRACE_ID ,
301
+ client .getSettings ());
302
+ testBigQueryWrite .setResponseSleep (org .threeten .bp .Duration .ofSeconds (1 ));
303
+ ConnectionWorker .setMaxInflightQueueWaitTime (500 );
304
+ ProtoSchema schema1 = createProtoSchema ("foo" );
305
+
306
+ long appendCount = 6 ;
307
+ for (int i = 0 ; i < appendCount ; i ++) {
308
+ testBigQueryWrite .addResponse (createAppendResponse (i ));
309
+ }
310
+
311
+ // In total insert 6 requests, since the max queue size is 5 we will stuck at the 6th request.
312
+ List <ApiFuture <AppendRowsResponse >> futures = new ArrayList <>();
313
+ for (int i = 0 ; i < appendCount ; i ++) {
314
+ long startTime = System .currentTimeMillis ();
315
+ // At the last request we wait more than 500 millisecond for inflight quota.
316
+ if (i == 5 ) {
317
+ assertThrows (
318
+ StatusRuntimeException .class ,
319
+ () -> {
320
+ sendTestMessage (
321
+ connectionWorker ,
322
+ TEST_STREAM_1 ,
323
+ schema1 ,
324
+ createFooProtoRows (new String [] {String .valueOf (5 )}),
325
+ 5 );
326
+ });
327
+ long timeDiff = System .currentTimeMillis () - startTime ;
328
+ assertEquals (connectionWorker .getLoad ().inFlightRequestsCount (), 5 );
329
+ assertTrue (timeDiff > 500 );
330
+ } else {
331
+ futures .add (
332
+ sendTestMessage (
333
+ connectionWorker ,
334
+ TEST_STREAM_1 ,
335
+ schema1 ,
336
+ createFooProtoRows (new String [] {String .valueOf (i )}),
337
+ i ));
338
+ assertEquals (connectionWorker .getLoad ().inFlightRequestsCount (), i + 1 );
339
+ }
340
+ }
341
+
342
+ for (int i = 0 ; i < appendCount - 1 ; i ++) {
343
+ assertEquals (i , futures .get (i ).get ().getAppendResult ().getOffset ().getValue ());
344
+ }
345
+ }
346
+
284
347
private AppendRowsResponse createAppendResponse (long offset ) {
285
348
return AppendRowsResponse .newBuilder ()
286
349
.setAppendResult (
0 commit comments