Skip to content

Commit

Permalink
Merge branch 'master' into GODRIVER-3066
Browse files Browse the repository at this point in the history
  • Loading branch information
joyjwang authored Oct 11, 2024
2 parents 7438f30 + a3eb9a6 commit ad392e0
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 33 deletions.
5 changes: 5 additions & 0 deletions internal/driverutil/description.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import (
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
)

const (
MinWireVersion = 6
MaxWireVersion = 25
)

func equalWireVersion(wv1, wv2 *description.VersionRange) bool {
if wv1 == nil && wv2 == nil {
return true
Expand Down
5 changes: 3 additions & 2 deletions internal/integration/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"go.mongodb.org/mongo-driver/v2/mongo/options"
"go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest"
)

const (
Expand Down Expand Up @@ -1819,7 +1820,7 @@ func TestCollection(t *testing.T) {
})
mt.RunOpts("insert and delete with batches", mtest.NewOptions().ClientType(mtest.Mock), func(mt *mtest.T) {
// grouped together because delete requires the documents to be inserted
maxBatchCount := int(mtest.MockDescription.MaxBatchCount)
maxBatchCount := int(drivertest.MockDescription.MaxBatchCount)
numDocs := maxBatchCount + 50
var insertModels []mongo.WriteModel
var deleteModels []mongo.WriteModel
Expand Down Expand Up @@ -1870,7 +1871,7 @@ func TestCollection(t *testing.T) {
assert.True(mt, deletes > 1, "expected multiple batches, got %v", deletes)
})
mt.RunOpts("update with batches", mtest.NewOptions().ClientType(mtest.Mock), func(mt *mtest.T) {
maxBatchCount := int(mtest.MockDescription.MaxBatchCount)
maxBatchCount := int(drivertest.MockDescription.MaxBatchCount)
numModels := maxBatchCount + 50
var models []mongo.WriteModel

Expand Down
9 changes: 5 additions & 4 deletions internal/integration/mtest/mongotest.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"go.mongodb.org/mongo-driver/v2/mongo/writeconcern"
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest"
)

var (
Expand Down Expand Up @@ -62,7 +63,7 @@ type T struct {
createClient *bool
createCollection *bool
runOn []RunOnBlock
mockDeployment *mockDeployment // nil if the test is not being run against a mock
mockDeployment *drivertest.MockDeployment // nil if the test is not being run against a mock
mockResponses []bson.D
createdColls []*Collection // collections created in this test
proxyDialer *proxyDialer
Expand Down Expand Up @@ -235,12 +236,12 @@ func (t *T) RunOpts(name string, opts *Options, callback func(mt *T)) {
// AddMockResponses adds responses to be returned by the mock deployment. This should only be used if T is being run
// against a mock deployment.
func (t *T) AddMockResponses(responses ...bson.D) {
t.mockDeployment.addResponses(responses...)
t.mockDeployment.AddResponses(responses...)
}

// ClearMockResponses clears all responses in the mock deployment.
func (t *T) ClearMockResponses() {
t.mockDeployment.clearResponses()
t.mockDeployment.ClearResponses()
}

// GetStartedEvent returns the least recent CommandStartedEvent, or nil if one is not present.
Expand Down Expand Up @@ -661,7 +662,7 @@ func (t *T) createTestClient() {

args.PoolMonitor = nil

t.mockDeployment = newMockDeployment()
t.mockDeployment = drivertest.NewMockDeployment()
args.Deployment = t.mockDeployment

opts := mongoutil.NewOptionsLister(args, nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// 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 mtest
package drivertest

import (
"context"
Expand All @@ -13,12 +13,12 @@ import (

"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/internal/csot"
"go.mongodb.org/mongo-driver/v2/internal/driverutil"
"go.mongodb.org/mongo-driver/v2/mongo/address"
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage"
)

Expand All @@ -42,7 +42,7 @@ var (
SessionTimeoutMinutes: &sessionTimeoutMinutes,
Kind: description.ServerKindRSPrimary,
WireVersion: &description.VersionRange{
Max: topology.SupportedWireVersions.Max,
Max: driverutil.MaxWireVersion,
},
}
)
Expand Down Expand Up @@ -122,60 +122,60 @@ func (*connection) Stale() bool {
return false
}

// mockDeployment wraps a connection and implements the driver.Deployment interface.
type mockDeployment struct {
// MockDeployment wraps a connection and implements the driver.Deployment interface.
type MockDeployment struct {
conn *connection
updates chan description.Topology
}

var _ driver.Deployment = &mockDeployment{}
var _ driver.Server = &mockDeployment{}
var _ driver.Connector = &mockDeployment{}
var _ driver.Disconnector = &mockDeployment{}
var _ driver.Subscriber = &mockDeployment{}
var _ driver.Deployment = &MockDeployment{}
var _ driver.Server = &MockDeployment{}
var _ driver.Connector = &MockDeployment{}
var _ driver.Disconnector = &MockDeployment{}
var _ driver.Subscriber = &MockDeployment{}

// SelectServer implements the Deployment interface. This method does not use the
// description.SelectedServer provided and instead returns itself. The Connections returned from the
// Connection method have a no-op Close method.
func (md *mockDeployment) SelectServer(context.Context, description.ServerSelector) (driver.Server, error) {
func (md *MockDeployment) SelectServer(context.Context, description.ServerSelector) (driver.Server, error) {
return md, nil
}

// GetServerSelectionTimeout returns zero as a server selection timeout is not
// applicable for mock deployments.
func (*mockDeployment) GetServerSelectionTimeout() time.Duration {
func (*MockDeployment) GetServerSelectionTimeout() time.Duration {
return 0
}

// Kind implements the Deployment interface. It always returns description.TopologyKindSingle.
func (md *mockDeployment) Kind() description.TopologyKind {
func (md *MockDeployment) Kind() description.TopologyKind {
return description.TopologyKindSingle
}

// Connection implements the driver.Server interface.
func (md *mockDeployment) Connection(context.Context) (*mnet.Connection, error) {
func (md *MockDeployment) Connection(context.Context) (*mnet.Connection, error) {
return mnet.NewConnection(md.conn), nil
}

// RTTMonitor implements the driver.Server interface.
func (md *mockDeployment) RTTMonitor() driver.RTTMonitor {
func (md *MockDeployment) RTTMonitor() driver.RTTMonitor {
return &csot.ZeroRTTMonitor{}
}

// Connect is a no-op method which implements the driver.Connector interface.
func (md *mockDeployment) Connect() error {
func (md *MockDeployment) Connect() error {
return nil
}

// Disconnect is a no-op method which implements the driver.Disconnector interface {
func (md *mockDeployment) Disconnect(context.Context) error {
func (md *MockDeployment) Disconnect(context.Context) error {
close(md.updates)
return nil
}

// Subscribe returns a subscription from which new topology descriptions can be retrieved.
// Subscribe implements the driver.Subscriber interface.
func (md *mockDeployment) Subscribe() (*driver.Subscription, error) {
func (md *MockDeployment) Subscribe() (*driver.Subscription, error) {
if md.updates == nil {
md.updates = make(chan description.Topology, 1)

Expand All @@ -190,23 +190,24 @@ func (md *mockDeployment) Subscribe() (*driver.Subscription, error) {
}

// Unsubscribe is a no-op method which implements the driver.Subscriber interface.
func (md *mockDeployment) Unsubscribe(*driver.Subscription) error {
func (md *MockDeployment) Unsubscribe(*driver.Subscription) error {
return nil
}

// addResponses adds responses to this mock deployment.
func (md *mockDeployment) addResponses(responses ...bson.D) {
// AddResponses adds responses to this mock deployment.
func (md *MockDeployment) AddResponses(responses ...bson.D) {
md.conn.responses = append(md.conn.responses, responses...)
}

// clearResponses clears all remaining responses in this mock deployment.
func (md *mockDeployment) clearResponses() {
// ClearResponses clears all remaining responses in this mock deployment.
func (md *MockDeployment) ClearResponses() {
md.conn.responses = md.conn.responses[:0]
}

// newMockDeployment returns a mock driver.Deployment that responds with OP_MSG wire messages.
func newMockDeployment(responses ...bson.D) *mockDeployment {
return &mockDeployment{
// NewMockDeployment returns a mock driver.Deployment that responds with OP_MSG wire messages.
// However, for most use cases, we suggest testing with an actual database.
func NewMockDeployment(responses ...bson.D) *MockDeployment {
return &MockDeployment{
conn: &connection{
responses: responses,
},
Expand Down
59 changes: 59 additions & 0 deletions x/mongo/driver/drivertest/opmsg_deployment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (C) MongoDB, Inc. 2017-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 drivertest

import (
"context"
"testing"

"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/internal/assert"
"go.mongodb.org/mongo-driver/v2/internal/require"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)

func TestOPMSGMockDeployment(t *testing.T) {
md := NewMockDeployment()

opts := options.Client()
opts.Opts = append(opts.Opts, func(co *options.ClientOptions) error {
co.Deployment = md

return nil
})
client, err := mongo.Connect(opts)

t.Run("NewMockDeployment connect to client", func(t *testing.T) {
require.NoError(t, err, "unexpected error from connect to mockdeployment")
})
t.Run("AddResponses with one", func(t *testing.T) {
res := bson.D{{"ok", 1}}
md.AddResponses(res)
assert.NotNil(t, md.conn.responses, "expected non-nil responses")
assert.Len(t, md.conn.responses, 1, "expected 1 response, got %v", len(md.conn.responses))
err = client.Ping(context.Background(), nil)
require.NoError(t, err)
})
t.Run("AddResponses with multiple", func(t *testing.T) {
res1 := bson.D{{"ok", 1}}
res2 := bson.D{{"ok", 2}}
res3 := bson.D{{"ok", 3}}
md.AddResponses(res1, res2, res3)
assert.NotNil(t, md.conn.responses, "expected non-nil responses")
assert.Len(t, md.conn.responses, 3, "expected 3 responses, got %v", len(md.conn.responses))
err = client.Ping(context.Background(), nil)
require.NoError(t, err)
})
t.Run("ClearResponses", func(t *testing.T) {
md.ClearResponses()
assert.NotNil(t, md.conn.responses, "expected non-nil responses")
assert.Len(t, md.conn.responses, 0, "expected 0 responses, got %v", len(md.conn.responses))
err = client.Ping(context.Background(), nil)
require.Error(t, err, "expected Ping error, got nil")
})
}
2 changes: 1 addition & 1 deletion x/mongo/driver/topology/fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var (
MinSupportedMongoDBVersion = "3.6"

// SupportedWireVersions is the range of wire versions supported by the driver.
SupportedWireVersions = driverutil.NewVersionRange(6, 25)
SupportedWireVersions = driverutil.NewVersionRange(driverutil.MinWireVersion, driverutil.MaxWireVersion)
)

type fsm struct {
Expand Down

0 comments on commit ad392e0

Please sign in to comment.