File: batches_test.go

package info (click to toggle)
golang-mongodb-mongo-driver 1.8.4%2Bds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-backports
  • size: 18,520 kB
  • sloc: perl: 533; ansic: 491; python: 432; makefile: 187; sh: 72
file content (131 lines) | stat: -rw-r--r-- 4,522 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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)
		})
	})
}