Skip to content

Commit e8ba1a8

Browse files
committed
test(bigquery): add comprehensive unit tests for ArrowDeserializer.loadArrowRows streaming and pagination
1 parent fac0d0c commit e8ba1a8

1 file changed

Lines changed: 166 additions & 0 deletions

File tree

java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/ArrowDeserializerTest.java

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,21 @@
1717
package com.google.cloud.bigquery;
1818

1919
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.assertFalse;
2021
import static org.junit.jupiter.api.Assertions.assertNull;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
2123
import static org.junit.jupiter.api.Assertions.fail;
2224

25+
import com.google.cloud.bigquery.storage.v1.ReadRowsResponse;
2326
import com.google.common.collect.ImmutableList;
2427
import com.google.common.io.BaseEncoding;
28+
import com.google.protobuf.ByteString;
2529
import java.io.ByteArrayOutputStream;
2630
import java.io.IOException;
2731
import java.nio.channels.Channels;
2832
import java.nio.charset.StandardCharsets;
33+
import java.util.ArrayList;
34+
import java.util.Arrays;
2935
import java.util.List;
3036
import org.apache.arrow.memory.BufferAllocator;
3137
import org.apache.arrow.memory.RootAllocator;
@@ -194,6 +200,166 @@ public void testSchemaMismatchThrowsException() {
194200
}
195201
}
196202

203+
@Test
204+
public void testLoadArrowRows_multiBatchStream() throws IOException {
205+
try (BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE)) {
206+
ReadRowsResponse r1 =
207+
createReadRowsResponse(Arrays.asList(1, 2), Arrays.asList("item1", "item2"), allocator);
208+
ReadRowsResponse r2 =
209+
createReadRowsResponse(Arrays.asList(3, 4), Arrays.asList("item3", "item4"), allocator);
210+
211+
org.apache.arrow.vector.types.pojo.Schema arrowSchema = createSimpleArrowSchema();
212+
Schema bqSchema = ArrowDeserializer.arrowSchemaToBigQuerySchema(arrowSchema);
213+
214+
List<FieldValueList> rowBatch = new ArrayList<>();
215+
boolean hasMore =
216+
ArrowDeserializer.loadArrowRows(
217+
Arrays.asList(r1, r2).iterator(),
218+
arrowSchema,
219+
null,
220+
bqSchema,
221+
rowBatch,
222+
10L,
223+
0L,
224+
10L);
225+
226+
assertFalse(hasMore);
227+
assertEquals(4, rowBatch.size());
228+
assertEquals("1", rowBatch.get(0).get("id").getStringValue());
229+
assertEquals("item1", rowBatch.get(0).get("name").getStringValue());
230+
assertEquals("4", rowBatch.get(3).get("id").getStringValue());
231+
assertEquals("item4", rowBatch.get(3).get("name").getStringValue());
232+
}
233+
}
234+
235+
@Test
236+
public void testLoadArrowRows_respectsPageSize() throws IOException {
237+
try (BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE)) {
238+
ReadRowsResponse r1 =
239+
createReadRowsResponse(Arrays.asList(1, 2), Arrays.asList("item1", "item2"), allocator);
240+
ReadRowsResponse r2 =
241+
createReadRowsResponse(Arrays.asList(3, 4), Arrays.asList("item3", "item4"), allocator);
242+
243+
org.apache.arrow.vector.types.pojo.Schema arrowSchema = createSimpleArrowSchema();
244+
Schema bqSchema = ArrowDeserializer.arrowSchemaToBigQuerySchema(arrowSchema);
245+
246+
List<FieldValueList> rowBatch = new ArrayList<>();
247+
boolean hasMore =
248+
ArrowDeserializer.loadArrowRows(
249+
Arrays.asList(r1, r2).iterator(), arrowSchema, null, bqSchema, rowBatch, 2L, 0L, 10L);
250+
251+
assertTrue(hasMore);
252+
assertEquals(2, rowBatch.size());
253+
assertEquals("1", rowBatch.get(0).get("id").getStringValue());
254+
assertEquals("2", rowBatch.get(1).get("id").getStringValue());
255+
}
256+
}
257+
258+
@Test
259+
public void testLoadArrowRows_respectsMaxResults() throws IOException {
260+
try (BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE)) {
261+
ReadRowsResponse r1 =
262+
createReadRowsResponse(Arrays.asList(1, 2), Arrays.asList("item1", "item2"), allocator);
263+
ReadRowsResponse r2 =
264+
createReadRowsResponse(Arrays.asList(3, 4), Arrays.asList("item3", "item4"), allocator);
265+
266+
org.apache.arrow.vector.types.pojo.Schema arrowSchema = createSimpleArrowSchema();
267+
Schema bqSchema = ArrowDeserializer.arrowSchemaToBigQuerySchema(arrowSchema);
268+
269+
List<FieldValueList> rowBatch = new ArrayList<>();
270+
boolean hasMore =
271+
ArrowDeserializer.loadArrowRows(
272+
Arrays.asList(r1, r2).iterator(), arrowSchema, null, bqSchema, rowBatch, 10L, 0L, 3L);
273+
274+
assertFalse(hasMore);
275+
assertEquals(3, rowBatch.size());
276+
assertEquals("1", rowBatch.get(0).get("id").getStringValue());
277+
assertEquals("2", rowBatch.get(1).get("id").getStringValue());
278+
assertEquals("3", rowBatch.get(2).get("id").getStringValue());
279+
}
280+
}
281+
282+
@Test
283+
public void testLoadArrowRows_unconsumedBatchRowsSignalHasMore() throws IOException {
284+
try (BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE)) {
285+
ReadRowsResponse r1 =
286+
createReadRowsResponse(
287+
Arrays.asList(1, 2, 3, 4),
288+
Arrays.asList("item1", "item2", "item3", "item4"),
289+
allocator);
290+
291+
org.apache.arrow.vector.types.pojo.Schema arrowSchema = createSimpleArrowSchema();
292+
Schema bqSchema = ArrowDeserializer.arrowSchemaToBigQuerySchema(arrowSchema);
293+
294+
List<FieldValueList> rowBatch = new ArrayList<>();
295+
boolean hasMore =
296+
ArrowDeserializer.loadArrowRows(
297+
Arrays.asList(r1).iterator(), arrowSchema, null, bqSchema, rowBatch, 2L, 0L, 10L);
298+
299+
assertTrue(hasMore);
300+
assertEquals(2, rowBatch.size());
301+
assertEquals("1", rowBatch.get(0).get("id").getStringValue());
302+
assertEquals("2", rowBatch.get(1).get("id").getStringValue());
303+
}
304+
}
305+
306+
@Test
307+
public void testLoadArrowRows_nullSchemaReturnsFalse() throws IOException {
308+
List<FieldValueList> rowBatch = new ArrayList<>();
309+
boolean hasMore =
310+
ArrowDeserializer.loadArrowRows(
311+
Arrays.<ReadRowsResponse>asList().iterator(),
312+
null,
313+
null,
314+
Schema.of(),
315+
rowBatch,
316+
10L,
317+
0L,
318+
10L);
319+
assertFalse(hasMore);
320+
}
321+
322+
private static org.apache.arrow.vector.types.pojo.Schema createSimpleArrowSchema() {
323+
org.apache.arrow.vector.types.pojo.Field intField =
324+
new org.apache.arrow.vector.types.pojo.Field(
325+
"id", FieldType.nullable(new ArrowType.Int(32, true)), null);
326+
org.apache.arrow.vector.types.pojo.Field strField =
327+
new org.apache.arrow.vector.types.pojo.Field(
328+
"name", FieldType.nullable(new ArrowType.Utf8()), null);
329+
return new org.apache.arrow.vector.types.pojo.Schema(ImmutableList.of(intField, strField));
330+
}
331+
332+
private ReadRowsResponse createReadRowsResponse(
333+
List<Integer> ids, List<String> names, BufferAllocator allocator) throws IOException {
334+
IntVector intVector = new IntVector("id", allocator);
335+
intVector.allocateNew(ids.size());
336+
for (int i = 0; i < ids.size(); i++) {
337+
intVector.set(i, ids.get(i));
338+
}
339+
intVector.setValueCount(ids.size());
340+
341+
VarCharVector nameVector = new VarCharVector("name", allocator);
342+
nameVector.allocateNew(names.size());
343+
for (int i = 0; i < names.size(); i++) {
344+
nameVector.set(i, names.get(i).getBytes(StandardCharsets.UTF_8));
345+
}
346+
nameVector.setValueCount(names.size());
347+
348+
List<FieldVector> vectors = ImmutableList.of(intVector, nameVector);
349+
try (VectorSchemaRoot root = new VectorSchemaRoot(vectors)) {
350+
byte[] bytes = serializeVectorSchemaRoot(root, allocator);
351+
com.google.cloud.bigquery.storage.v1.ArrowRecordBatch protoBatch =
352+
com.google.cloud.bigquery.storage.v1.ArrowRecordBatch.newBuilder()
353+
.setSerializedRecordBatch(ByteString.copyFrom(bytes))
354+
.build();
355+
return ReadRowsResponse.newBuilder().setArrowRecordBatch(protoBatch).build();
356+
} finally {
357+
for (FieldVector vector : vectors) {
358+
vector.close();
359+
}
360+
}
361+
}
362+
197363
private byte[] serializeVectorSchemaRoot(VectorSchemaRoot root, BufferAllocator allocator)
198364
throws IOException {
199365
ByteArrayOutputStream out = new ByteArrayOutputStream();

0 commit comments

Comments
 (0)