Skip to content

Commit

Permalink
Add MongoDB integration tests for maxTimeMS in find, aggregate
Browse files Browse the repository at this point in the history
…and `getMore` (#2953)

Closes #1808.
  • Loading branch information
chilagrow authored Jul 10, 2023
1 parent 040b9ed commit eb2943e
Show file tree
Hide file tree
Showing 6 changed files with 714 additions and 12 deletions.
12 changes: 4 additions & 8 deletions integration/aggregate_documents_compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func testAggregateCommandCompat(t *testing.T, testCases map[string]aggregateComm
t.Run(targetCollection.Name(), func(t *testing.T) {
t.Helper()

var targetRes, compatRes []bson.D
var targetRes, compatRes bson.D
targetErr := targetCollection.Database().RunCommand(ctx, command).Decode(&targetRes)
compatErr := compatCollection.Database().RunCommand(ctx, command).Decode(&compatRes)

Expand All @@ -223,8 +223,7 @@ func testAggregateCommandCompat(t *testing.T, testCases map[string]aggregateComm
return
}
require.NoError(t, compatErr, "compat error; target returned no error")

AssertEqualDocumentsSlice(t, compatRes, targetRes)
AssertEqualDocuments(t, compatRes, targetRes)

if len(targetRes) > 0 || len(compatRes) > 0 {
nonEmptyResults = true
Expand Down Expand Up @@ -280,16 +279,13 @@ func TestAggregateCommandCompat(t *testing.T) {
},
resultType: emptyResult,
},
"MaxTimeMSNegative": {
"MaxTimeMSDoubleWholeNumber": {
command: bson.D{
{"aggregate", "collection-name"},
{"pipeline", bson.A{}},
{"maxTimeMS", int64(-1)},
{"cursor", bson.D{}},
{"maxTimeMS", float64(1000)},
},
resultType: emptyResult,
// compat and target return an error from the driver
// > cannot decode document into []primitive.D
},
}

Expand Down
193 changes: 193 additions & 0 deletions integration/aggregate_documents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package integration

import (
"math"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -661,6 +662,198 @@ func TestAggregateUnsetErrors(t *testing.T) {
}
}

func TestAggregateCommandMaxTimeMSErrors(t *testing.T) {
t.Parallel()
ctx, collection := setup.Setup(t)

for name, tc := range map[string]struct { //nolint:vet // used for testing only
command bson.D // required, command to run

err *mongo.CommandError // required, expected error from MongoDB
altMessage string // optional, alternative error message for FerretDB, ignored if empty
skip string // optional, skip test with a specified reason
}{
"NegativeLong": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", int64(-1)},
},
err: &mongo.CommandError{
Code: 51024,
Name: "Location51024",
Message: "BSON field 'maxTimeMS' value must be >= 0, actual value '-1'",
},
},
"MaxLong": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", math.MaxInt64},
},
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "9223372036854775807 value for maxTimeMS is out of range",
},
},
"Double": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", 1000.5},
},
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "maxTimeMS has non-integral value",
},
},
"NegativeDouble": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", -14245345234123245.55},
},
err: &mongo.CommandError{
Code: 51024,
Name: "Location51024",
Message: "BSON field 'maxTimeMS' value must be >= 0, actual value '-14245345234123246'",
},
altMessage: "BSON field 'maxTimeMS' value must be >= 0, actual value '-1.424534523412325e+16'",
},
"BigDouble": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", math.MaxFloat64},
},
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "9223372036854775807 value for maxTimeMS is out of range",
},
altMessage: "1.797693134862316e+308 value for maxTimeMS is out of range",
},
"BigNegativeDouble": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", -math.MaxFloat64},
},
err: &mongo.CommandError{
Code: 51024,
Name: "Location51024",
Message: "BSON field 'maxTimeMS' value must be >= 0, actual value '-9223372036854775808'",
},
altMessage: "BSON field 'maxTimeMS' value must be >= 0, actual value '-1.797693134862316e+308'",
},
"NegativeInt32": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", -1123123},
},
err: &mongo.CommandError{
Code: 51024,
Name: "Location51024",
Message: "BSON field 'maxTimeMS' value must be >= 0, actual value '-1123123'",
},
},
"MaxIntPlus": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", math.MaxInt32 + 1},
},
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "2147483648 value for maxTimeMS is out of range",
},
},
"Null": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", nil},
},
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "maxTimeMS must be a number",
},
},
"String": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", "string"},
},
err: &mongo.CommandError{
Code: 14,
Name: "TypeMismatch",
Message: "BSON field 'aggregate.maxTimeMS' is the wrong type 'string', expected types '[long, int, decimal, double']",
},
altMessage: "BSON field 'aggregate.maxTimeMS' is the wrong type 'string', expected types '[long, int, decimal, double]'",
},
"Array": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", bson.A{int32(42), "foo", nil}},
},
err: &mongo.CommandError{
Code: 14,
Name: "TypeMismatch",
Message: "BSON field 'aggregate.maxTimeMS' is the wrong type 'array', expected types '[long, int, decimal, double']",
},
altMessage: "BSON field 'aggregate.maxTimeMS' is the wrong type 'array', expected types '[long, int, decimal, double]'",
},
"Document": {
command: bson.D{
{"aggregate", collection.Name()},
{"pipeline", bson.A{}},
{"cursor", bson.D{}},
{"maxTimeMS", bson.D{{"foo", int32(42)}}},
},
err: &mongo.CommandError{
Code: 14,
Name: "TypeMismatch",
Message: "BSON field 'aggregate.maxTimeMS' is the wrong type 'object', expected types '[long, int, decimal, double']",
},
altMessage: "BSON field 'aggregate.maxTimeMS' is the wrong type 'object', expected types '[long, int, decimal, double]'",
},
} {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
if tc.skip != "" {
t.Skip(tc.skip)
}

t.Parallel()

require.NotNil(t, tc.err, "err must not be nil")

var res bson.D
err := collection.Database().RunCommand(ctx, tc.command).Decode(&res)
AssertEqualAltCommandError(t, *tc.err, tc.altMessage, err)
require.Nil(t, res)
})
}
}

func TestAggregateCommandCursor(t *testing.T) {
t.Parallel()
ctx, collection := setup.Setup(t)
Expand Down
Loading

0 comments on commit eb2943e

Please sign in to comment.