Skip to content

Commit 922979e

Browse files
Copilotbbernays
andauthored
test: add regression test for empty WriteTableBatch guard
Agent-Logs-Url: https://github.com/cloudquery/plugin-sdk/sessions/68c913bf-a3a7-4ceb-8d10-daeb3fcbb260 Co-authored-by: bbernays <30294676+bbernays@users.noreply.github.com>
1 parent 59d61d6 commit 922979e

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

writers/batchwriter/batchwriter_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,57 @@ func TestBatchUpserts(t *testing.T) {
233233
}
234234
}
235235

236+
// noEmptyBatchClient wraps testBatchClient and fails the test if WriteTableBatch
237+
// is called with an empty messages slice.
238+
type noEmptyBatchClient struct {
239+
testBatchClient
240+
t *testing.T
241+
}
242+
243+
func (c *noEmptyBatchClient) WriteTableBatch(ctx context.Context, name string, messages message.WriteInserts) error {
244+
if len(messages) == 0 {
245+
// Use t.Error (not t.Fatal) because this may be called from a worker goroutine.
246+
c.t.Error("WriteTableBatch called with empty messages slice")
247+
return nil
248+
}
249+
return c.testBatchClient.WriteTableBatch(ctx, name, messages)
250+
}
251+
252+
// TestBatchNoEmptyFlush is a regression test ensuring WriteTableBatch is never called with
253+
// an empty messages slice. This can happen when batchSizeBytes is so small that no row fits
254+
// in the initial batch (SliceRecord returns add==nil while toFlush is non-empty), which
255+
// previously caused send() to call WriteTableBatch with an empty resources slice.
256+
func TestBatchNoEmptyFlush(t *testing.T) {
257+
ctx := context.Background()
258+
259+
testClient := &noEmptyBatchClient{t: t}
260+
// batchSizeBytes=1 ensures that no single row fits in the initial batch:
261+
// SliceRecord returns add==nil, toFlush=[one record per row], rest=nil.
262+
wr, err := New(testClient, WithBatchSizeBytes(1))
263+
if err != nil {
264+
t.Fatal(err)
265+
}
266+
267+
table := schema.Table{Name: "table1", Columns: []schema.Column{{Name: "id", Type: arrow.PrimitiveTypes.Int64}}}
268+
const numRows = 5
269+
record := getRecord(table.ToArrowSchema(), numRows)
270+
if err := wr.writeAll(ctx, []message.WriteMessage{&message.WriteInsert{Record: record}}); err != nil {
271+
t.Fatal(err)
272+
}
273+
274+
if err := wr.Flush(ctx); err != nil {
275+
t.Fatal(err)
276+
}
277+
if err := wr.Close(ctx); err != nil {
278+
t.Fatal(err)
279+
}
280+
281+
// All rows must have been written via at least one non-empty batch.
282+
if testClient.InsertsLen() == 0 {
283+
t.Fatalf("expected at least 1 insert message, got 0")
284+
}
285+
}
286+
236287
func getRecord(sc *arrow.Schema, rows int) arrow.RecordBatch {
237288
builder := array.NewRecordBuilder(memory.DefaultAllocator, sc)
238289
defer builder.Release()

0 commit comments

Comments
 (0)