Skip to content

Commit b9d57dd

Browse files
committed
Merge branch 'master' into feature/godriver-3544-metadata-on-demand
2 parents 8b483fd + 8fb0643 commit b9d57dd

27 files changed

+715
-218
lines changed

.evergreen/config.yml

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,10 +1741,6 @@ axes:
17411741
display_name: "4.2"
17421742
variables:
17431743
VERSION: "4.2"
1744-
- id: "4.0"
1745-
display_name: "4.0"
1746-
variables:
1747-
VERSION: "4.0"
17481744
- id: "rapid"
17491745
display_name: "rapid"
17501746
variables:
@@ -2170,19 +2166,6 @@ buildvariants:
21702166
tasks:
21712167
- name: ".goleak"
21722168

2173-
- matrix_name: "tests-rhel-40-with-snappy-support"
2174-
tags: ["pullrequest"]
2175-
matrix_spec: { version: ["4.0"], os-ssl-40: ["rhel87-64"] }
2176-
display_name: "${version} ${os-ssl-40}"
2177-
tasks:
2178-
- name: ".test !.enterprise-auth !.zlib !.zstd"
2179-
2180-
- matrix_name: "tests-windows-40-with-snappy-support"
2181-
matrix_spec: { version: ["4.0"], os-ssl-40: ["windows-64"] }
2182-
display_name: "${version} ${os-ssl-40}"
2183-
tasks:
2184-
- name: ".test !.enterprise-auth !.zlib !.zstd"
2185-
21862169
- matrix_name: "tests-rhel-44-plus-zlib-zstd-support"
21872170
tags: ["pullrequest"]
21882171
matrix_spec: { version: ["4.2", "4.4", "5.0", "6.0", "7.0", "8.0"], os-ssl-40: ["rhel87-64"] }

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The MongoDB Go driver follows [semantic versioning](https://semver.org/) for its
2424

2525
- Go 1.19 or higher. We aim to support the latest versions of Go.
2626
- Go 1.23 or higher is required to run the driver test suite.
27-
- MongoDB 4.0 and higher.
27+
- MongoDB 4.2 and higher.
2828

2929
## Installation
3030

internal/docexamples/examples_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,8 @@ func TestDocumentationExamples(t *testing.T) {
131131
docexamples.ChangeStreamExamples(mt.T, csdb)
132132
})
133133

134-
// Causal consistency examples cannot run on 4.0.
135-
// TODO(GODRIVER-2238): Remove version filtering once failures on 4.0 sharded clusters are fixed.
136-
mtOpts = mtest.NewOptions().MinServerVersion("4.2").Topologies(mtest.ReplicaSet)
137-
mt.RunOpts("CausalConsistencyExamples/post4.2", mtOpts, func(mt *mtest.T) {
138-
docexamples.CausalConsistencyExamples(mt.Client)
139-
})
140-
mtOpts = mtest.NewOptions().MaxServerVersion("4.0").Topologies(mtest.ReplicaSet)
141-
mt.RunOpts("CausalConsistencyExamples/pre4.0", mtOpts, func(mt *mtest.T) {
134+
mtOpts = mtest.NewOptions().Topologies(mtest.ReplicaSet)
135+
mt.RunOpts("CausalConsistencyExamples", mtOpts, func(mt *mtest.T) {
142136
docexamples.CausalConsistencyExamples(mt.Client)
143137
})
144138
}

internal/driverutil/description.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
)
2222

2323
const (
24-
MinWireVersion = 7
24+
MinWireVersion = 8
2525
MaxWireVersion = 25
2626
)
2727

internal/integration/change_stream_test.go

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -259,34 +259,6 @@ func TestChangeStream_ReplicaSet(t *testing.T) {
259259
assert.Nil(mt, cs.Err(), "change stream error: %v", cs.Err())
260260
})
261261

262-
startAtOpTimeOpts := mtest.NewOptions().MinServerVersion("4.0").MaxServerVersion("4.0.6")
263-
mt.RunOpts("include startAtOperationTime", startAtOpTimeOpts, func(mt *mtest.T) {
264-
// $changeStream stage for ChangeStream against a server >=4.0 and <4.0.7 that has not received any results yet
265-
// MUST include a startAtOperationTime option when resuming a changestream.
266-
267-
cs, err := mt.Coll.Watch(context.Background(), mongo.Pipeline{})
268-
assert.Nil(mt, err, "Watch error: %v", err)
269-
defer closeStream(cs)
270-
271-
generateEvents(mt, 1)
272-
// kill cursor to force resumable error
273-
killChangeStreamCursor(mt, cs)
274-
275-
mt.ClearEvents()
276-
// change stream should resume once and get new change
277-
assert.True(mt, cs.Next(context.Background()), "expected Next to return true, got false")
278-
// Next should cause getMore, killCursors, and aggregate to run
279-
assert.NotNil(mt, mt.GetStartedEvent(), "expected getMore event, got nil")
280-
assert.NotNil(mt, mt.GetStartedEvent(), "expected killCursors event, got nil")
281-
aggEvent := mt.GetStartedEvent()
282-
assert.NotNil(mt, aggEvent, "expected aggregate event, got nil")
283-
assert.Equal(mt, "aggregate", aggEvent.CommandName, "expected command name 'aggregate', got '%v'", aggEvent.CommandName)
284-
285-
// check for startAtOperationTime in pipeline
286-
csStage := aggEvent.Command.Lookup("pipeline").Array().Index(0).Document() // $changeStream stage
287-
_, err = csStage.Lookup("$changeStream").Document().LookupErr("startAtOperationTime")
288-
assert.Nil(mt, err, "startAtOperationTime not included in aggregate command")
289-
})
290262
mt.RunOpts("decode does not panic", noClientOpts, func(mt *mtest.T) {
291263
testCases := []struct {
292264
name string
@@ -418,53 +390,6 @@ func TestChangeStream_ReplicaSet(t *testing.T) {
418390
})
419391
}
420392
})
421-
422-
noPbrtOpts := mtest.NewOptions().MaxServerVersion("4.0.6")
423-
mt.RunOpts("without PBRT support", noPbrtOpts, func(mt *mtest.T) {
424-
collName := mt.Coll.Name()
425-
dbName := mt.Coll.Database().Name()
426-
cs, err := mt.Coll.Watch(context.Background(), mongo.Pipeline{})
427-
assert.Nil(mt, err, "Watch error: %v", err)
428-
defer closeStream(cs)
429-
430-
compareResumeTokens(mt, cs, nil) // should be no resume token because no PBRT
431-
numEvents := 5
432-
generateEvents(mt, numEvents)
433-
// iterate once to get a resume token
434-
assert.True(mt, cs.Next(context.Background()), "expected Next to return true, got false")
435-
token := cs.ResumeToken()
436-
assert.NotNil(mt, token, "expected resume token, got nil")
437-
438-
testCases := []struct {
439-
name string
440-
opts *options.ChangeStreamOptionsBuilder
441-
iterateStream bool // whether or not resulting change stream should be iterated
442-
initialToken bson.Raw
443-
numDocsExpected int
444-
}{
445-
{"resumeAfter", options.ChangeStream().SetResumeAfter(token), true, token, numEvents - 1},
446-
{"no options", nil, false, nil, 0},
447-
}
448-
for _, tc := range testCases {
449-
mt.Run(tc.name, func(mt *mtest.T) {
450-
coll := mt.Client.Database(dbName).Collection(collName)
451-
cs, err := coll.Watch(context.Background(), mongo.Pipeline{}, tc.opts)
452-
assert.Nil(mt, err, "Watch error: %v", err)
453-
defer closeStream(cs)
454-
455-
compareResumeTokens(mt, cs, tc.initialToken)
456-
if !tc.iterateStream {
457-
return
458-
}
459-
460-
for i := 0; i < tc.numDocsExpected; i++ {
461-
assert.True(mt, cs.Next(context.Background()), "expected Next to return true, got false")
462-
// current resume token should always equal _id of current document
463-
compareResumeTokens(mt, cs, cs.Current.Lookup("_id").Document())
464-
}
465-
})
466-
}
467-
})
468393
})
469394
})
470395
mt.RunOpts("try next", noClientOpts, func(mt *mtest.T) {
@@ -826,17 +751,6 @@ func generateEvents(mt *mtest.T, numEvents int) {
826751
}
827752
}
828753

829-
func killChangeStreamCursor(mt *mtest.T, cs *mongo.ChangeStream) {
830-
mt.Helper()
831-
832-
db := mt.Coll.Database().Client().Database("admin")
833-
err := db.RunCommand(context.Background(), bson.D{
834-
{"killCursors", mt.Coll.Name()},
835-
{"cursors", bson.A{cs.ID()}},
836-
}).Err()
837-
assert.Nil(mt, err, "killCursors error: %v", err)
838-
}
839-
840754
// returns pbrt, operationTime from aggregate command response
841755
func getAggregateResponseInfo(mt *mtest.T) (bson.Raw, bson.Timestamp) {
842756
mt.Helper()

internal/integration/client_test.go

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
3535
"go.mongodb.org/mongo-driver/v2/x/mongo/driver"
3636
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
37+
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/xoptions"
3738
"golang.org/x/sync/errgroup"
3839
)
3940

@@ -849,11 +850,96 @@ func TestClient_BulkWrite(t *testing.T) {
849850
}
850851

851852
_, err := mt.Client.BulkWrite(context.Background(), writes)
852-
require.NoError(t, err)
853-
assert.Equal(t, 2, bulkWrites, "expected %d bulkWrites, got %d", 2, bulkWrites)
853+
require.NoError(mt, err)
854+
assert.Equal(mt, 2, bulkWrites, "expected %d bulkWrites, got %d", 2, bulkWrites)
854855
})
855856
}
856857

858+
func TestClient_BulkWrite_AddCommandFields(t *testing.T) {
859+
newOpts := func(option bson.D) *options.ClientBulkWriteOptionsBuilder {
860+
opts := options.ClientBulkWrite()
861+
err := xoptions.SetInternalClientBulkWriteOptions(opts, "addCommandFields", option)
862+
require.NoError(t, err, "unexpected error: %v", err)
863+
return opts
864+
}
865+
866+
marshalValue := func(val interface{}) bson.RawValue {
867+
t.Helper()
868+
869+
valType, data, err := bson.MarshalValue(val)
870+
require.NoError(t, err, "MarshalValue error: %v", err)
871+
return bson.RawValue{
872+
Type: valType,
873+
Value: data,
874+
}
875+
}
876+
877+
models := []struct {
878+
name string
879+
model mongo.ClientWriteModel
880+
}{
881+
{
882+
name: "insert one",
883+
model: mongo.NewClientInsertOneModel().SetDocument(bson.D{{"x", 1}}),
884+
},
885+
{
886+
name: "update one",
887+
model: mongo.NewClientUpdateOneModel().SetFilter(bson.D{{"x", 1}}).SetUpdate(bson.D{{"$set", bson.D{{"x", 3.14159}}}}),
888+
},
889+
{
890+
name: "update many",
891+
model: mongo.NewClientUpdateManyModel().SetFilter(bson.D{{"x", 1}}).SetUpdate(bson.D{{"$set", bson.D{{"x", 3.14159}}}}),
892+
},
893+
{
894+
name: "replace one",
895+
model: mongo.NewClientReplaceOneModel().SetFilter(bson.D{{"x", 1}}).SetReplacement(bson.D{{"x", 3.14159}}),
896+
},
897+
}
898+
899+
testCases := []struct {
900+
name string
901+
opts *options.ClientBulkWriteOptionsBuilder
902+
expected bson.RawValue
903+
}{
904+
{
905+
name: "empty",
906+
opts: options.ClientBulkWrite(),
907+
expected: bson.RawValue{},
908+
},
909+
{
910+
name: "false",
911+
opts: newOpts(bson.D{{"bypassEmptyTsReplacement", false}}),
912+
expected: marshalValue(false),
913+
},
914+
{
915+
name: "true",
916+
opts: newOpts(bson.D{{"bypassEmptyTsReplacement", true}}),
917+
expected: marshalValue(true),
918+
},
919+
}
920+
921+
mtBulkWriteOpts := mtest.NewOptions().MinServerVersion("8.0").ClientType(mtest.Pinned)
922+
mt := mtest.New(t, noClientOpts)
923+
for _, m := range models {
924+
for _, tc := range testCases {
925+
mt.RunOpts(fmt.Sprintf("%s %s", m.name, tc.name), mtBulkWriteOpts, func(mt *mtest.T) {
926+
mt.Parallel()
927+
928+
writes := []mongo.ClientBulkWrite{{
929+
Database: "foo",
930+
Collection: "bar",
931+
Model: m.model,
932+
}}
933+
_, err := mt.Client.BulkWrite(context.Background(), writes, tc.opts)
934+
require.NoError(mt, err, "BulkWrite error: %v", err)
935+
evt := mt.GetStartedEvent()
936+
val := evt.Command.Lookup("bypassEmptyTsReplacement")
937+
assert.Equal(mt, tc.expected, val, "expected bypassEmptyTsReplacement to be %s", tc.expected.String())
938+
})
939+
}
940+
}
941+
}
942+
857943
func TestClient_BSONOptions(t *testing.T) {
858944
t.Parallel()
859945

0 commit comments

Comments
 (0)