138 lines
4.7 KiB
Go
138 lines
4.7 KiB
Go
// Copyright (C) MongoDB, Inc. 2022-present.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
package driver
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"go.mongodb.org/mongo-driver/internal/testutil/assert"
|
|
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
|
|
)
|
|
|
|
func TestBatches(t *testing.T) {
|
|
t.Run("Valid", func(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
batches *Batches
|
|
want bool
|
|
}{
|
|
{"nil", nil, false},
|
|
{"missing identifier", &Batches{}, false},
|
|
{"no documents", &Batches{Identifier: "documents"}, false},
|
|
{"valid", &Batches{Identifier: "documents", Documents: make([]bsoncore.Document, 5)}, true},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
want := tc.want
|
|
got := tc.batches.Valid()
|
|
if got != want {
|
|
t.Errorf("Did not get expected result from Valid. got %t; want %t", got, want)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
t.Run("ClearBatch", func(t *testing.T) {
|
|
batches := &Batches{Identifier: "documents", Current: make([]bsoncore.Document, 2, 10)}
|
|
if len(batches.Current) != 2 {
|
|
t.Fatalf("Length of current batch should be 2, but is %d", len(batches.Current))
|
|
}
|
|
batches.ClearBatch()
|
|
if len(batches.Current) != 0 {
|
|
t.Fatalf("Length of current batch should be 0, but is %d", len(batches.Current))
|
|
}
|
|
})
|
|
t.Run("AdvanceBatch", func(t *testing.T) {
|
|
documents := make([]bsoncore.Document, 0)
|
|
for i := 0; i < 5; i++ {
|
|
doc := make(bsoncore.Document, 100)
|
|
documents = append(documents, doc)
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
batches *Batches
|
|
maxCount int
|
|
targetBatchSize int
|
|
maxDocSize int
|
|
err error
|
|
want *Batches
|
|
}{
|
|
{
|
|
"current batch non-zero",
|
|
&Batches{Current: make([]bsoncore.Document, 2, 10)},
|
|
0, 0, 0, nil,
|
|
&Batches{Current: make([]bsoncore.Document, 2, 10)},
|
|
},
|
|
{
|
|
// all of the documents in the batch fit in targetBatchSize so the batch is created successfully
|
|
"documents fit in targetBatchSize",
|
|
&Batches{Documents: documents},
|
|
10, 600, 1000, nil,
|
|
&Batches{Documents: documents[:0], Current: documents[0:]},
|
|
},
|
|
{
|
|
// the first doc is bigger than targetBatchSize but smaller than maxDocSize so it is taken alone
|
|
"first document larger than targetBatchSize, smaller than maxDocSize",
|
|
&Batches{Documents: documents},
|
|
10, 5, 100, nil,
|
|
&Batches{Documents: documents[1:], Current: documents[:1]},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := tc.batches.AdvanceBatch(tc.maxCount, tc.targetBatchSize, tc.maxDocSize)
|
|
if !cmp.Equal(err, tc.err, cmp.Comparer(compareErrors)) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, tc.err)
|
|
}
|
|
if !cmp.Equal(tc.batches, tc.want) {
|
|
t.Errorf("Batches is not in correct state after AdvanceBatch. got %v; want %v", tc.batches, tc.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("middle document larger than targetBatchSize, smaller than maxDocSize", func(t *testing.T) {
|
|
// a batch is made but one document is too big, so everything before it is taken.
|
|
// on the second call to AdvanceBatch, only the large document is taken
|
|
|
|
middleLargeDoc := make([]bsoncore.Document, 0)
|
|
for i := 0; i < 5; i++ {
|
|
doc := make(bsoncore.Document, 100)
|
|
middleLargeDoc = append(middleLargeDoc, doc)
|
|
}
|
|
largeDoc := make(bsoncore.Document, 900)
|
|
middleLargeDoc[2] = largeDoc
|
|
batches := &Batches{Documents: middleLargeDoc}
|
|
maxCount := 10
|
|
targetSize := 600
|
|
maxDocSize := 1000
|
|
|
|
// first batch should take first 2 docs (size 100 each)
|
|
err := batches.AdvanceBatch(maxCount, targetSize, maxDocSize)
|
|
assert.Nil(t, err, "AdvanceBatch error: %v", err)
|
|
want := &Batches{Current: middleLargeDoc[:2], Documents: middleLargeDoc[2:]}
|
|
assert.Equal(t, want, batches, "expected batches %v, got %v", want, batches)
|
|
|
|
// second batch should take single large doc (size 900)
|
|
batches.ClearBatch()
|
|
err = batches.AdvanceBatch(maxCount, targetSize, maxDocSize)
|
|
assert.Nil(t, err, "AdvanceBatch error: %v", err)
|
|
want = &Batches{Current: middleLargeDoc[2:3], Documents: middleLargeDoc[3:]}
|
|
assert.Equal(t, want, batches, "expected batches %v, got %v", want, batches)
|
|
|
|
// last batch should take last 2 docs (size 100 each)
|
|
batches.ClearBatch()
|
|
err = batches.AdvanceBatch(maxCount, targetSize, maxDocSize)
|
|
assert.Nil(t, err, "AdvanceBatch error: %v", err)
|
|
want = &Batches{Current: middleLargeDoc[3:], Documents: middleLargeDoc[:0]}
|
|
assert.Equal(t, want, batches, "expected batches %v, got %v", want, batches)
|
|
})
|
|
})
|
|
}
|