update:github.com/mongodb/mongo-go-driver v2.0 Migration (#4687)

This commit is contained in:
me-cs
2025-08-09 21:21:53 +08:00
committed by GitHub
parent f36e5fed35
commit b41b1b00df
22 changed files with 2515 additions and 1174 deletions

View File

@@ -1,3 +1,4 @@
//go:generate mockgen -package mon -destination collection_inserter_mock.go -source bulkinserter.go collectionInserter
package mon package mon
import ( import (
@@ -6,7 +7,8 @@ import (
"github.com/zeromicro/go-zero/core/executors" "github.com/zeromicro/go-zero/core/executors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
) )
const ( const (
@@ -27,10 +29,7 @@ type (
// NewBulkInserter returns a BulkInserter. // NewBulkInserter returns a BulkInserter.
func NewBulkInserter(coll Collection, interval ...time.Duration) (*BulkInserter, error) { func NewBulkInserter(coll Collection, interval ...time.Duration) (*BulkInserter, error) {
cloneColl, err := coll.Clone() cloneColl := coll.Clone()
if err != nil {
return nil, err
}
inserter := &dbInserter{ inserter := &dbInserter{
collection: cloneColl, collection: cloneColl,
@@ -64,8 +63,16 @@ func (bi *BulkInserter) SetResultHandler(handler ResultHandler) {
}) })
} }
type collectionInserter interface {
InsertMany(
ctx context.Context,
documents interface{},
opts ...options.Lister[options.InsertManyOptions],
) (*mongo.InsertManyResult, error)
}
type dbInserter struct { type dbInserter struct {
collection *mongo.Collection collection collectionInserter
documents []any documents []any
resultHandler ResultHandler resultHandler ResultHandler
} }

View File

@@ -1,26 +1,131 @@
package mon package mon
import ( import (
"errors"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/mongo" "go.uber.org/mock/gomock"
"go.mongodb.org/mongo-driver/mongo/integration/mtest"
) )
func TestBulkInserter(t *testing.T) { func TestBulkInserter_InsertAndFlush(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "ok", Value: 1}}...)) mockCollection := NewMockCollection(ctrl)
bulk, err := NewBulkInserter(createModel(mt).Collection) mockCollection.EXPECT().Clone().Return(&mongo.Collection{})
assert.Equal(t, err, nil) bulkInserter, err := NewBulkInserter(mockCollection, time.Second)
bulk.SetResultHandler(func(result *mongo.InsertManyResult, err error) { assert.NoError(t, err)
assert.Nil(t, err) bulkInserter.SetResultHandler(func(result *mongo.InsertManyResult, err error) {
assert.Equal(t, 2, len(result.InsertedIDs)) assert.Nil(t, err)
}) assert.Equal(t, 2, len(result.InsertedIDs))
bulk.Insert(bson.D{{Key: "foo", Value: "bar"}})
bulk.Insert(bson.D{{Key: "foo", Value: "baz"}})
bulk.Flush()
}) })
doc := map[string]interface{}{"name": "test"}
bulkInserter.Insert(doc)
bulkInserter.Flush()
}
func TestBulkInserter_SetResultHandler(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockCollection := NewMockCollection(ctrl)
mockCollection.EXPECT().Clone().Return(nil)
bulkInserter, err := NewBulkInserter(mockCollection)
assert.NoError(t, err)
mockHandler := func(result *mongo.InsertManyResult, err error) {}
bulkInserter.SetResultHandler(mockHandler)
}
func TestDbInserter_RemoveAll(t *testing.T) {
inserter := &dbInserter{}
inserter.documents = []interface{}{}
docs := inserter.RemoveAll()
assert.NotNil(t, docs)
assert.Empty(t, inserter.documents)
}
func Test_dbInserter_Execute(t *testing.T) {
type fields struct {
collection collectionInserter
documents []any
resultHandler ResultHandler
}
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockCollection := NewMockcollectionInserter(ctrl)
type args struct {
objs any
}
tests := []struct {
name string
fields fields
args args
mock func()
}{
{
name: "empty doc",
fields: fields{
collection: nil,
documents: nil,
resultHandler: nil,
},
args: args{
objs: make([]any, 0),
},
mock: func() {},
},
{
name: "result handler",
fields: fields{
collection: mockCollection,
resultHandler: func(result *mongo.InsertManyResult, err error) {
assert.NotNil(t, err)
},
},
args: args{
objs: make([]any, 1),
},
mock: func() {
mockCollection.EXPECT().InsertMany(gomock.Any(), gomock.Any()).Return(&mongo.InsertManyResult{}, errors.New("error"))
},
},
{
name: "normal error handler",
fields: fields{
collection: mockCollection,
resultHandler: nil,
},
args: args{
objs: make([]any, 1),
},
mock: func() {
mockCollection.EXPECT().InsertMany(gomock.Any(), gomock.Any()).Return(&mongo.InsertManyResult{}, errors.New("error"))
},
},
{
name: "no error",
fields: fields{
collection: mockCollection,
resultHandler: nil,
},
args: args{
objs: make([]any, 1),
},
mock: func() {
mockCollection.EXPECT().InsertMany(gomock.Any(), gomock.Any()).Return(&mongo.InsertManyResult{}, nil)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mock()
in := &dbInserter{
collection: tt.fields.collection,
documents: tt.fields.documents,
resultHandler: tt.fields.resultHandler,
}
in.Execute(tt.args.objs)
})
}
} }

View File

@@ -5,8 +5,8 @@ import (
"io" "io"
"github.com/zeromicro/go-zero/core/syncx" "github.com/zeromicro/go-zero/core/syncx"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/v2/mongo"
mopt "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/options"
) )
var clientManager = syncx.NewResourceManager() var clientManager = syncx.NewResourceManager()
@@ -29,13 +29,13 @@ func Inject(key string, client *mongo.Client) {
func getClient(url string, opts ...Option) (*mongo.Client, error) { func getClient(url string, opts ...Option) (*mongo.Client, error) {
val, err := clientManager.GetResource(url, func() (io.Closer, error) { val, err := clientManager.GetResource(url, func() (io.Closer, error) {
o := mopt.Client().ApplyURI(url) o := options.Client().ApplyURI(url)
opts = append([]Option{defaultTimeoutOption()}, opts...) opts = append([]Option{defaultTimeoutOption()}, opts...)
for _, opt := range opts { for _, opt := range opts {
opt(o) opt(o)
} }
cli, err := mongo.Connect(context.Background(), o) cli, err := mongo.Connect(o)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -4,19 +4,13 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/mongo/integration/mtest" "go.mongodb.org/mongo-driver/v2/mongo"
) )
func init() {
_ = mtest.Setup()
}
func TestClientManger_getClient(t *testing.T) { func TestClientManger_getClient(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) c := &mongo.Client{}
mt.Run("test", func(mt *mtest.T) { Inject("foo", c)
Inject(mtest.ClusterURI(), mt.Client) cli, err := getClient("foo")
cli, err := getClient(mtest.ClusterURI()) assert.Nil(t, err)
assert.Nil(t, err) assert.Equal(t, c, cli)
assert.Equal(t, mt.Client, cli)
})
} }

View File

@@ -1,3 +1,4 @@
//go:generate mockgen -package mon -destination collection_mock.go -source collection.go Collection,monCollection
package mon package mon
import ( import (
@@ -8,9 +9,9 @@ import (
"github.com/zeromicro/go-zero/core/breaker" "github.com/zeromicro/go-zero/core/breaker"
"github.com/zeromicro/go-zero/core/errorx" "github.com/zeromicro/go-zero/core/errorx"
"github.com/zeromicro/go-zero/core/timex" "github.com/zeromicro/go-zero/core/timex"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/v2/mongo"
mopt "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/options"
"go.mongodb.org/mongo-driver/x/mongo/driver/session" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session"
) )
const ( const (
@@ -47,79 +48,79 @@ type (
// Collection defines a MongoDB collection. // Collection defines a MongoDB collection.
Collection interface { Collection interface {
// Aggregate executes an aggregation pipeline. // Aggregate executes an aggregation pipeline.
Aggregate(ctx context.Context, pipeline any, opts ...*mopt.AggregateOptions) ( Aggregate(ctx context.Context, pipeline any, opts ...options.Lister[options.AggregateOptions]) (
*mongo.Cursor, error) *mongo.Cursor, error)
// BulkWrite performs a bulk write operation. // BulkWrite performs a bulk write operation.
BulkWrite(ctx context.Context, models []mongo.WriteModel, opts ...*mopt.BulkWriteOptions) ( BulkWrite(ctx context.Context, models []mongo.WriteModel, opts ...options.Lister[options.BulkWriteOptions]) (
*mongo.BulkWriteResult, error) *mongo.BulkWriteResult, error)
// Clone creates a copy of this collection with the same settings. // Clone creates a copy of this collection with the same settings.
Clone(opts ...*mopt.CollectionOptions) (*mongo.Collection, error) Clone(opts ...options.Lister[options.CollectionOptions]) *mongo.Collection
// CountDocuments returns the number of documents in the collection that match the filter. // CountDocuments returns the number of documents in the collection that match the filter.
CountDocuments(ctx context.Context, filter any, opts ...*mopt.CountOptions) (int64, error) CountDocuments(ctx context.Context, filter any, opts ...options.Lister[options.CountOptions]) (int64, error)
// Database returns the database that this collection is a part of. // Database returns the database that this collection is a part of.
Database() *mongo.Database Database() *mongo.Database
// DeleteMany deletes documents from the collection that match the filter. // DeleteMany deletes documents from the collection that match the filter.
DeleteMany(ctx context.Context, filter any, opts ...*mopt.DeleteOptions) ( DeleteMany(ctx context.Context, filter any, opts ...options.Lister[options.DeleteManyOptions]) (
*mongo.DeleteResult, error) *mongo.DeleteResult, error)
// DeleteOne deletes at most one document from the collection that matches the filter. // DeleteOne deletes at most one document from the collection that matches the filter.
DeleteOne(ctx context.Context, filter any, opts ...*mopt.DeleteOptions) ( DeleteOne(ctx context.Context, filter any, opts ...options.Lister[options.DeleteOneOptions]) (
*mongo.DeleteResult, error) *mongo.DeleteResult, error)
// Distinct returns a list of distinct values for the given key across the collection. // Distinct returns a list of distinct values for the given key across the collection.
Distinct(ctx context.Context, fieldName string, filter any, Distinct(ctx context.Context, fieldName string, filter any,
opts ...*mopt.DistinctOptions) ([]any, error) opts ...options.Lister[options.DistinctOptions]) (*mongo.DistinctResult, error)
// Drop drops this collection from database. // Drop drops this collection from database.
Drop(ctx context.Context) error Drop(ctx context.Context, opts ...options.Lister[options.DropCollectionOptions]) error
// EstimatedDocumentCount returns an estimate of the count of documents in a collection // EstimatedDocumentCount returns an estimate of the count of documents in a collection
// using collection metadata. // using collection metadata.
EstimatedDocumentCount(ctx context.Context, opts ...*mopt.EstimatedDocumentCountOptions) (int64, error) EstimatedDocumentCount(ctx context.Context, opts ...options.Lister[options.EstimatedDocumentCountOptions]) (int64, error)
// Find finds the documents matching the provided filter. // Find finds the documents matching the provided filter.
Find(ctx context.Context, filter any, opts ...*mopt.FindOptions) (*mongo.Cursor, error) Find(ctx context.Context, filter any, opts ...options.Lister[options.FindOptions]) (*mongo.Cursor, error)
// FindOne returns up to one document that matches the provided filter. // FindOne returns up to one document that matches the provided filter.
FindOne(ctx context.Context, filter any, opts ...*mopt.FindOneOptions) ( FindOne(ctx context.Context, filter any, opts ...options.Lister[options.FindOneOptions]) (
*mongo.SingleResult, error) *mongo.SingleResult, error)
// FindOneAndDelete returns at most one document that matches the filter. If the filter // FindOneAndDelete returns at most one document that matches the filter. If the filter
// matches multiple documents, only the first document is deleted. // matches multiple documents, only the first document is deleted.
FindOneAndDelete(ctx context.Context, filter any, opts ...*mopt.FindOneAndDeleteOptions) ( FindOneAndDelete(ctx context.Context, filter any, opts ...options.Lister[options.FindOneAndDeleteOptions]) (
*mongo.SingleResult, error) *mongo.SingleResult, error)
// FindOneAndReplace returns at most one document that matches the filter. If the filter // FindOneAndReplace returns at most one document that matches the filter. If the filter
// matches multiple documents, FindOneAndReplace returns the first document in the // matches multiple documents, FindOneAndReplace returns the first document in the
// collection that matches the filter. // collection that matches the filter.
FindOneAndReplace(ctx context.Context, filter, replacement any, FindOneAndReplace(ctx context.Context, filter, replacement any,
opts ...*mopt.FindOneAndReplaceOptions) (*mongo.SingleResult, error) opts ...options.Lister[options.FindOneAndReplaceOptions]) (*mongo.SingleResult, error)
// FindOneAndUpdate returns at most one document that matches the filter. If the filter // FindOneAndUpdate returns at most one document that matches the filter. If the filter
// matches multiple documents, FindOneAndUpdate returns the first document in the // matches multiple documents, FindOneAndUpdate returns the first document in the
// collection that matches the filter. // collection that matches the filter.
FindOneAndUpdate(ctx context.Context, filter, update any, FindOneAndUpdate(ctx context.Context, filter, update any,
opts ...*mopt.FindOneAndUpdateOptions) (*mongo.SingleResult, error) opts ...options.Lister[options.FindOneAndUpdateOptions]) (*mongo.SingleResult, error)
// Indexes returns the index view for this collection. // Indexes returns the index view for this collection.
Indexes() mongo.IndexView Indexes() mongo.IndexView
// InsertMany inserts the provided documents. // InsertMany inserts the provided documents.
InsertMany(ctx context.Context, documents []any, opts ...*mopt.InsertManyOptions) ( InsertMany(ctx context.Context, documents []any, opts ...options.Lister[options.InsertManyOptions]) (
*mongo.InsertManyResult, error) *mongo.InsertManyResult, error)
// InsertOne inserts the provided document. // InsertOne inserts the provided document.
InsertOne(ctx context.Context, document any, opts ...*mopt.InsertOneOptions) ( InsertOne(ctx context.Context, document any, opts ...options.Lister[options.InsertOneOptions]) (
*mongo.InsertOneResult, error) *mongo.InsertOneResult, error)
// ReplaceOne replaces at most one document that matches the filter. // ReplaceOne replaces at most one document that matches the filter.
ReplaceOne(ctx context.Context, filter, replacement any, ReplaceOne(ctx context.Context, filter, replacement any,
opts ...*mopt.ReplaceOptions) (*mongo.UpdateResult, error) opts ...options.Lister[options.ReplaceOptions]) (*mongo.UpdateResult, error)
// UpdateByID updates a single document matching the provided filter. // UpdateByID updates a single document matching the provided filter.
UpdateByID(ctx context.Context, id, update any, UpdateByID(ctx context.Context, id, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error)
// UpdateMany updates the provided documents. // UpdateMany updates the provided documents.
UpdateMany(ctx context.Context, filter, update any, UpdateMany(ctx context.Context, filter, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) opts ...options.Lister[options.UpdateManyOptions]) (*mongo.UpdateResult, error)
// UpdateOne updates a single document matching the provided filter. // UpdateOne updates a single document matching the provided filter.
UpdateOne(ctx context.Context, filter, update any, UpdateOne(ctx context.Context, filter, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error)
// Watch returns a change stream cursor used to receive notifications of changes to the collection. // Watch returns a change stream cursor used to receive notifications of changes to the collection.
Watch(ctx context.Context, pipeline any, opts ...*mopt.ChangeStreamOptions) ( Watch(ctx context.Context, pipeline any, opts ...options.Lister[options.ChangeStreamOptions]) (
*mongo.ChangeStream, error) *mongo.ChangeStream, error)
} }
decoratedCollection struct { decoratedCollection struct {
*mongo.Collection Collection monCollection
name string name string
brk breaker.Breaker brk breaker.Breaker
} }
keepablePromise struct { keepablePromise struct {
@@ -136,8 +137,16 @@ func newCollection(collection *mongo.Collection, brk breaker.Breaker) Collection
} }
} }
func newTestCollection(collection monCollection, brk breaker.Breaker) *decoratedCollection {
return &decoratedCollection{
Collection: collection,
name: "test",
brk: brk,
}
}
func (c *decoratedCollection) Aggregate(ctx context.Context, pipeline any, func (c *decoratedCollection) Aggregate(ctx context.Context, pipeline any,
opts ...*mopt.AggregateOptions) (cur *mongo.Cursor, err error) { opts ...options.Lister[options.AggregateOptions]) (cur *mongo.Cursor, err error) {
ctx, span := startSpan(ctx, aggregate) ctx, span := startSpan(ctx, aggregate)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -157,7 +166,7 @@ func (c *decoratedCollection) Aggregate(ctx context.Context, pipeline any,
} }
func (c *decoratedCollection) BulkWrite(ctx context.Context, models []mongo.WriteModel, func (c *decoratedCollection) BulkWrite(ctx context.Context, models []mongo.WriteModel,
opts ...*mopt.BulkWriteOptions) (res *mongo.BulkWriteResult, err error) { opts ...options.Lister[options.BulkWriteOptions]) (res *mongo.BulkWriteResult, err error) {
ctx, span := startSpan(ctx, bulkWrite) ctx, span := startSpan(ctx, bulkWrite)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -177,7 +186,7 @@ func (c *decoratedCollection) BulkWrite(ctx context.Context, models []mongo.Writ
} }
func (c *decoratedCollection) CountDocuments(ctx context.Context, filter any, func (c *decoratedCollection) CountDocuments(ctx context.Context, filter any,
opts ...*mopt.CountOptions) (count int64, err error) { opts ...options.Lister[options.CountOptions]) (count int64, err error) {
ctx, span := startSpan(ctx, countDocuments) ctx, span := startSpan(ctx, countDocuments)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -197,7 +206,7 @@ func (c *decoratedCollection) CountDocuments(ctx context.Context, filter any,
} }
func (c *decoratedCollection) DeleteMany(ctx context.Context, filter any, func (c *decoratedCollection) DeleteMany(ctx context.Context, filter any,
opts ...*mopt.DeleteOptions) (res *mongo.DeleteResult, err error) { opts ...options.Lister[options.DeleteManyOptions]) (res *mongo.DeleteResult, err error) {
ctx, span := startSpan(ctx, deleteMany) ctx, span := startSpan(ctx, deleteMany)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -217,7 +226,7 @@ func (c *decoratedCollection) DeleteMany(ctx context.Context, filter any,
} }
func (c *decoratedCollection) DeleteOne(ctx context.Context, filter any, func (c *decoratedCollection) DeleteOne(ctx context.Context, filter any,
opts ...*mopt.DeleteOptions) (res *mongo.DeleteResult, err error) { opts ...options.Lister[options.DeleteOneOptions]) (res *mongo.DeleteResult, err error) {
ctx, span := startSpan(ctx, deleteOne) ctx, span := startSpan(ctx, deleteOne)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -237,7 +246,7 @@ func (c *decoratedCollection) DeleteOne(ctx context.Context, filter any,
} }
func (c *decoratedCollection) Distinct(ctx context.Context, fieldName string, filter any, func (c *decoratedCollection) Distinct(ctx context.Context, fieldName string, filter any,
opts ...*mopt.DistinctOptions) (val []any, err error) { opts ...options.Lister[options.DistinctOptions]) (res *mongo.DistinctResult, err error) {
ctx, span := startSpan(ctx, distinct) ctx, span := startSpan(ctx, distinct)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -249,7 +258,8 @@ func (c *decoratedCollection) Distinct(ctx context.Context, fieldName string, fi
c.logDurationSimple(ctx, distinct, startTime, err) c.logDurationSimple(ctx, distinct, startTime, err)
}() }()
val, err = c.Collection.Distinct(ctx, fieldName, filter, opts...) res = c.Collection.Distinct(ctx, fieldName, filter, opts...)
err = res.Err()
return err return err
}, acceptable) }, acceptable)
@@ -257,7 +267,7 @@ func (c *decoratedCollection) Distinct(ctx context.Context, fieldName string, fi
} }
func (c *decoratedCollection) EstimatedDocumentCount(ctx context.Context, func (c *decoratedCollection) EstimatedDocumentCount(ctx context.Context,
opts ...*mopt.EstimatedDocumentCountOptions) (val int64, err error) { opts ...options.Lister[options.EstimatedDocumentCountOptions]) (val int64, err error) {
ctx, span := startSpan(ctx, estimatedDocumentCount) ctx, span := startSpan(ctx, estimatedDocumentCount)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -277,7 +287,7 @@ func (c *decoratedCollection) EstimatedDocumentCount(ctx context.Context,
} }
func (c *decoratedCollection) Find(ctx context.Context, filter any, func (c *decoratedCollection) Find(ctx context.Context, filter any,
opts ...*mopt.FindOptions) (cur *mongo.Cursor, err error) { opts ...options.Lister[options.FindOptions]) (cur *mongo.Cursor, err error) {
ctx, span := startSpan(ctx, find) ctx, span := startSpan(ctx, find)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -297,7 +307,7 @@ func (c *decoratedCollection) Find(ctx context.Context, filter any,
} }
func (c *decoratedCollection) FindOne(ctx context.Context, filter any, func (c *decoratedCollection) FindOne(ctx context.Context, filter any,
opts ...*mopt.FindOneOptions) (res *mongo.SingleResult, err error) { opts ...options.Lister[options.FindOneOptions]) (res *mongo.SingleResult, err error) {
ctx, span := startSpan(ctx, findOne) ctx, span := startSpan(ctx, findOne)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -318,7 +328,7 @@ func (c *decoratedCollection) FindOne(ctx context.Context, filter any,
} }
func (c *decoratedCollection) FindOneAndDelete(ctx context.Context, filter any, func (c *decoratedCollection) FindOneAndDelete(ctx context.Context, filter any,
opts ...*mopt.FindOneAndDeleteOptions) (res *mongo.SingleResult, err error) { opts ...options.Lister[options.FindOneAndDeleteOptions]) (res *mongo.SingleResult, err error) {
ctx, span := startSpan(ctx, findOneAndDelete) ctx, span := startSpan(ctx, findOneAndDelete)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -339,7 +349,7 @@ func (c *decoratedCollection) FindOneAndDelete(ctx context.Context, filter any,
} }
func (c *decoratedCollection) FindOneAndReplace(ctx context.Context, filter any, func (c *decoratedCollection) FindOneAndReplace(ctx context.Context, filter any,
replacement any, opts ...*mopt.FindOneAndReplaceOptions) ( replacement any, opts ...options.Lister[options.FindOneAndReplaceOptions]) (
res *mongo.SingleResult, err error) { res *mongo.SingleResult, err error) {
ctx, span := startSpan(ctx, findOneAndReplace) ctx, span := startSpan(ctx, findOneAndReplace)
defer func() { defer func() {
@@ -361,7 +371,7 @@ func (c *decoratedCollection) FindOneAndReplace(ctx context.Context, filter any,
} }
func (c *decoratedCollection) FindOneAndUpdate(ctx context.Context, filter, update any, func (c *decoratedCollection) FindOneAndUpdate(ctx context.Context, filter, update any,
opts ...*mopt.FindOneAndUpdateOptions) (res *mongo.SingleResult, err error) { opts ...options.Lister[options.FindOneAndUpdateOptions]) (res *mongo.SingleResult, err error) {
ctx, span := startSpan(ctx, findOneAndUpdate) ctx, span := startSpan(ctx, findOneAndUpdate)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -382,7 +392,7 @@ func (c *decoratedCollection) FindOneAndUpdate(ctx context.Context, filter, upda
} }
func (c *decoratedCollection) InsertMany(ctx context.Context, documents []any, func (c *decoratedCollection) InsertMany(ctx context.Context, documents []any,
opts ...*mopt.InsertManyOptions) (res *mongo.InsertManyResult, err error) { opts ...options.Lister[options.InsertManyOptions]) (res *mongo.InsertManyResult, err error) {
ctx, span := startSpan(ctx, insertMany) ctx, span := startSpan(ctx, insertMany)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -402,7 +412,7 @@ func (c *decoratedCollection) InsertMany(ctx context.Context, documents []any,
} }
func (c *decoratedCollection) InsertOne(ctx context.Context, document any, func (c *decoratedCollection) InsertOne(ctx context.Context, document any,
opts ...*mopt.InsertOneOptions) (res *mongo.InsertOneResult, err error) { opts ...options.Lister[options.InsertOneOptions]) (res *mongo.InsertOneResult, err error) {
ctx, span := startSpan(ctx, insertOne) ctx, span := startSpan(ctx, insertOne)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -422,7 +432,7 @@ func (c *decoratedCollection) InsertOne(ctx context.Context, document any,
} }
func (c *decoratedCollection) ReplaceOne(ctx context.Context, filter, replacement any, func (c *decoratedCollection) ReplaceOne(ctx context.Context, filter, replacement any,
opts ...*mopt.ReplaceOptions) (res *mongo.UpdateResult, err error) { opts ...options.Lister[options.ReplaceOptions]) (res *mongo.UpdateResult, err error) {
ctx, span := startSpan(ctx, replaceOne) ctx, span := startSpan(ctx, replaceOne)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -442,7 +452,7 @@ func (c *decoratedCollection) ReplaceOne(ctx context.Context, filter, replacemen
} }
func (c *decoratedCollection) UpdateByID(ctx context.Context, id, update any, func (c *decoratedCollection) UpdateByID(ctx context.Context, id, update any,
opts ...*mopt.UpdateOptions) (res *mongo.UpdateResult, err error) { opts ...options.Lister[options.UpdateOneOptions]) (res *mongo.UpdateResult, err error) {
ctx, span := startSpan(ctx, updateByID) ctx, span := startSpan(ctx, updateByID)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -462,7 +472,7 @@ func (c *decoratedCollection) UpdateByID(ctx context.Context, id, update any,
} }
func (c *decoratedCollection) UpdateMany(ctx context.Context, filter, update any, func (c *decoratedCollection) UpdateMany(ctx context.Context, filter, update any,
opts ...*mopt.UpdateOptions) (res *mongo.UpdateResult, err error) { opts ...options.Lister[options.UpdateManyOptions]) (res *mongo.UpdateResult, err error) {
ctx, span := startSpan(ctx, updateMany) ctx, span := startSpan(ctx, updateMany)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -482,7 +492,7 @@ func (c *decoratedCollection) UpdateMany(ctx context.Context, filter, update any
} }
func (c *decoratedCollection) UpdateOne(ctx context.Context, filter, update any, func (c *decoratedCollection) UpdateOne(ctx context.Context, filter, update any,
opts ...*mopt.UpdateOptions) (res *mongo.UpdateResult, err error) { opts ...options.Lister[options.UpdateOneOptions]) (res *mongo.UpdateResult, err error) {
ctx, span := startSpan(ctx, updateOne) ctx, span := startSpan(ctx, updateOne)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -501,6 +511,27 @@ func (c *decoratedCollection) UpdateOne(ctx context.Context, filter, update any,
return return
} }
func (c *decoratedCollection) Clone(opts ...options.Lister[options.CollectionOptions]) *mongo.Collection {
return c.Collection.Clone(opts...)
}
func (c *decoratedCollection) Database() *mongo.Database {
return c.Collection.Database()
}
func (c *decoratedCollection) Drop(ctx context.Context, opts ...options.Lister[options.DropCollectionOptions]) error {
return c.Collection.Drop(ctx, opts...)
}
func (c *decoratedCollection) Indexes() mongo.IndexView {
return c.Collection.Indexes()
}
func (c *decoratedCollection) Watch(ctx context.Context, pipeline any, opts ...options.Lister[options.ChangeStreamOptions]) (
*mongo.ChangeStream, error) {
return c.Collection.Watch(ctx, pipeline, opts...)
}
func (c *decoratedCollection) logDuration(ctx context.Context, method string, func (c *decoratedCollection) logDuration(ctx context.Context, method string,
startTime time.Duration, err error, docs ...any) { startTime time.Duration, err error, docs ...any) {
logDurationWithDocs(ctx, c.name, method, startTime, err, docs...) logDurationWithDocs(ctx, c.name, method, startTime, err, docs...)
@@ -546,3 +577,73 @@ func isDupKeyError(err error) bool {
return e.HasErrorCode(duplicateKeyCode) return e.HasErrorCode(duplicateKeyCode)
} }
type (
// monCollection defines a MongoDB collection, used for unit test
monCollection interface {
// Aggregate executes an aggregation pipeline.
Aggregate(ctx context.Context, pipeline any, opts ...options.Lister[options.AggregateOptions]) (
*mongo.Cursor, error)
// BulkWrite performs a bulk write operation.
BulkWrite(ctx context.Context, models []mongo.WriteModel, opts ...options.Lister[options.BulkWriteOptions]) (
*mongo.BulkWriteResult, error)
// Clone creates a copy of this collection with the same settings.
Clone(opts ...options.Lister[options.CollectionOptions]) *mongo.Collection
// CountDocuments returns the number of documents in the collection that match the filter.
CountDocuments(ctx context.Context, filter any, opts ...options.Lister[options.CountOptions]) (int64, error)
// Database returns the database that this collection is a part of.
Database() *mongo.Database
// DeleteMany deletes documents from the collection that match the filter.
DeleteMany(ctx context.Context, filter any, opts ...options.Lister[options.DeleteManyOptions]) (
*mongo.DeleteResult, error)
// DeleteOne deletes at most one document from the collection that matches the filter.
DeleteOne(ctx context.Context, filter any, opts ...options.Lister[options.DeleteOneOptions]) (
*mongo.DeleteResult, error)
// Distinct returns a list of distinct values for the given key across the collection.
Distinct(ctx context.Context, fieldName string, filter any,
opts ...options.Lister[options.DistinctOptions]) *mongo.DistinctResult
// Drop drops this collection from database.
Drop(ctx context.Context, opts ...options.Lister[options.DropCollectionOptions]) error
// EstimatedDocumentCount returns an estimate of the count of documents in a collection
// using collection metadata.
EstimatedDocumentCount(ctx context.Context, opts ...options.Lister[options.EstimatedDocumentCountOptions]) (int64, error)
// Find finds the documents matching the provided filter.
Find(ctx context.Context, filter any, opts ...options.Lister[options.FindOptions]) (*mongo.Cursor, error)
// FindOne returns up to one document that matches the provided filter.
FindOne(ctx context.Context, filter any, opts ...options.Lister[options.FindOneOptions]) *mongo.SingleResult
// FindOneAndDelete returns at most one document that matches the filter. If the filter
// matches multiple documents, only the first document is deleted.
FindOneAndDelete(ctx context.Context, filter any, opts ...options.Lister[options.FindOneAndDeleteOptions]) *mongo.SingleResult
// FindOneAndReplace returns at most one document that matches the filter. If the filter
// matches multiple documents, FindOneAndReplace returns the first document in the
// collection that matches the filter.
FindOneAndReplace(ctx context.Context, filter, replacement any,
opts ...options.Lister[options.FindOneAndReplaceOptions]) *mongo.SingleResult
// FindOneAndUpdate returns at most one document that matches the filter. If the filter
// matches multiple documents, FindOneAndUpdate returns the first document in the
// collection that matches the filter.
FindOneAndUpdate(ctx context.Context, filter, update any,
opts ...options.Lister[options.FindOneAndUpdateOptions]) *mongo.SingleResult
// Indexes returns the index view for this collection.
Indexes() mongo.IndexView
// InsertMany inserts the provided documents.
InsertMany(ctx context.Context, documents interface{}, opts ...options.Lister[options.InsertManyOptions]) (*mongo.InsertManyResult, error)
// InsertOne inserts the provided document.
InsertOne(ctx context.Context, document any, opts ...options.Lister[options.InsertOneOptions]) (*mongo.InsertOneResult, error)
// ReplaceOne replaces at most one document that matches the filter.
ReplaceOne(ctx context.Context, filter, replacement any,
opts ...options.Lister[options.ReplaceOptions]) (*mongo.UpdateResult, error)
// UpdateByID updates a single document matching the provided filter.
UpdateByID(ctx context.Context, id, update any,
opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error)
// UpdateMany updates the provided documents.
UpdateMany(ctx context.Context, filter, update any,
opts ...options.Lister[options.UpdateManyOptions]) (*mongo.UpdateResult, error)
// UpdateOne updates a single document matching the provided filter.
UpdateOne(ctx context.Context, filter, update any,
opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error)
// Watch returns a change stream cursor used to receive notifications of changes to the collection.
Watch(ctx context.Context, pipeline any, opts ...options.Lister[options.ChangeStreamOptions]) (
*mongo.ChangeStream, error)
}
)

View File

@@ -0,0 +1,63 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: bulkinserter.go
//
// Generated by this command:
//
// mockgen -package mon -destination collection_inserter_mock.go -source bulkinserter.go collectionInserter
//
// Package mon is a generated GoMock package.
package mon
import (
context "context"
reflect "reflect"
mongo "go.mongodb.org/mongo-driver/v2/mongo"
options "go.mongodb.org/mongo-driver/v2/mongo/options"
gomock "go.uber.org/mock/gomock"
)
// MockcollectionInserter is a mock of collectionInserter interface.
type MockcollectionInserter struct {
ctrl *gomock.Controller
recorder *MockcollectionInserterMockRecorder
isgomock struct{}
}
// MockcollectionInserterMockRecorder is the mock recorder for MockcollectionInserter.
type MockcollectionInserterMockRecorder struct {
mock *MockcollectionInserter
}
// NewMockcollectionInserter creates a new mock instance.
func NewMockcollectionInserter(ctrl *gomock.Controller) *MockcollectionInserter {
mock := &MockcollectionInserter{ctrl: ctrl}
mock.recorder = &MockcollectionInserterMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockcollectionInserter) EXPECT() *MockcollectionInserterMockRecorder {
return m.recorder
}
// InsertMany mocks base method.
func (m *MockcollectionInserter) InsertMany(ctx context.Context, documents any, opts ...options.Lister[options.InsertManyOptions]) (*mongo.InsertManyResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, documents}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "InsertMany", varargs...)
ret0, _ := ret[0].(*mongo.InsertManyResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertMany indicates an expected call of InsertMany.
func (mr *MockcollectionInserterMockRecorder) InsertMany(ctx, documents any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, documents}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertMany", reflect.TypeOf((*MockcollectionInserter)(nil).InsertMany), varargs...)
}

View File

@@ -0,0 +1,952 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: collection.go
//
// Generated by this command:
//
// mockgen -package mon -destination collection_mock.go -source collection.go Collection,monCollection
//
// Package mon is a generated GoMock package.
package mon
import (
context "context"
reflect "reflect"
mongo "go.mongodb.org/mongo-driver/v2/mongo"
options "go.mongodb.org/mongo-driver/v2/mongo/options"
gomock "go.uber.org/mock/gomock"
)
// MockCollection is a mock of Collection interface.
type MockCollection struct {
ctrl *gomock.Controller
recorder *MockCollectionMockRecorder
isgomock struct{}
}
// MockCollectionMockRecorder is the mock recorder for MockCollection.
type MockCollectionMockRecorder struct {
mock *MockCollection
}
// NewMockCollection creates a new mock instance.
func NewMockCollection(ctrl *gomock.Controller) *MockCollection {
mock := &MockCollection{ctrl: ctrl}
mock.recorder = &MockCollectionMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockCollection) EXPECT() *MockCollectionMockRecorder {
return m.recorder
}
// Aggregate mocks base method.
func (m *MockCollection) Aggregate(ctx context.Context, pipeline any, opts ...options.Lister[options.AggregateOptions]) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, pipeline}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Aggregate", varargs...)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Aggregate indicates an expected call of Aggregate.
func (mr *MockCollectionMockRecorder) Aggregate(ctx, pipeline any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, pipeline}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Aggregate", reflect.TypeOf((*MockCollection)(nil).Aggregate), varargs...)
}
// BulkWrite mocks base method.
func (m *MockCollection) BulkWrite(ctx context.Context, models []mongo.WriteModel, opts ...options.Lister[options.BulkWriteOptions]) (*mongo.BulkWriteResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, models}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "BulkWrite", varargs...)
ret0, _ := ret[0].(*mongo.BulkWriteResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BulkWrite indicates an expected call of BulkWrite.
func (mr *MockCollectionMockRecorder) BulkWrite(ctx, models any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, models}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BulkWrite", reflect.TypeOf((*MockCollection)(nil).BulkWrite), varargs...)
}
// Clone mocks base method.
func (m *MockCollection) Clone(opts ...options.Lister[options.CollectionOptions]) *mongo.Collection {
m.ctrl.T.Helper()
varargs := []any{}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Clone", varargs...)
ret0, _ := ret[0].(*mongo.Collection)
return ret0
}
// Clone indicates an expected call of Clone.
func (mr *MockCollectionMockRecorder) Clone(opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clone", reflect.TypeOf((*MockCollection)(nil).Clone), opts...)
}
// CountDocuments mocks base method.
func (m *MockCollection) CountDocuments(ctx context.Context, filter any, opts ...options.Lister[options.CountOptions]) (int64, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "CountDocuments", varargs...)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CountDocuments indicates an expected call of CountDocuments.
func (mr *MockCollectionMockRecorder) CountDocuments(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CountDocuments", reflect.TypeOf((*MockCollection)(nil).CountDocuments), varargs...)
}
// Database mocks base method.
func (m *MockCollection) Database() *mongo.Database {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Database")
ret0, _ := ret[0].(*mongo.Database)
return ret0
}
// Database indicates an expected call of Database.
func (mr *MockCollectionMockRecorder) Database() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Database", reflect.TypeOf((*MockCollection)(nil).Database))
}
// DeleteMany mocks base method.
func (m *MockCollection) DeleteMany(ctx context.Context, filter any, opts ...options.Lister[options.DeleteManyOptions]) (*mongo.DeleteResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "DeleteMany", varargs...)
ret0, _ := ret[0].(*mongo.DeleteResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DeleteMany indicates an expected call of DeleteMany.
func (mr *MockCollectionMockRecorder) DeleteMany(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMany", reflect.TypeOf((*MockCollection)(nil).DeleteMany), varargs...)
}
// DeleteOne mocks base method.
func (m *MockCollection) DeleteOne(ctx context.Context, filter any, opts ...options.Lister[options.DeleteOneOptions]) (*mongo.DeleteResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "DeleteOne", varargs...)
ret0, _ := ret[0].(*mongo.DeleteResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DeleteOne indicates an expected call of DeleteOne.
func (mr *MockCollectionMockRecorder) DeleteOne(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOne", reflect.TypeOf((*MockCollection)(nil).DeleteOne), varargs...)
}
// Distinct mocks base method.
func (m *MockCollection) Distinct(ctx context.Context, fieldName string, filter any, opts ...options.Lister[options.DistinctOptions]) (*mongo.DistinctResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, fieldName, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Distinct", varargs...)
ret0, _ := ret[0].(*mongo.DistinctResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Distinct indicates an expected call of Distinct.
func (mr *MockCollectionMockRecorder) Distinct(ctx, fieldName, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, fieldName, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Distinct", reflect.TypeOf((*MockCollection)(nil).Distinct), varargs...)
}
// Drop mocks base method.
func (m *MockCollection) Drop(ctx context.Context, opts ...options.Lister[options.DropCollectionOptions]) error {
m.ctrl.T.Helper()
varargs := []any{ctx}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Drop", varargs...)
ret0, _ := ret[0].(error)
return ret0
}
// Drop indicates an expected call of Drop.
func (mr *MockCollectionMockRecorder) Drop(ctx any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Drop", reflect.TypeOf((*MockCollection)(nil).Drop), varargs...)
}
// EstimatedDocumentCount mocks base method.
func (m *MockCollection) EstimatedDocumentCount(ctx context.Context, opts ...options.Lister[options.EstimatedDocumentCountOptions]) (int64, error) {
m.ctrl.T.Helper()
varargs := []any{ctx}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "EstimatedDocumentCount", varargs...)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EstimatedDocumentCount indicates an expected call of EstimatedDocumentCount.
func (mr *MockCollectionMockRecorder) EstimatedDocumentCount(ctx any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimatedDocumentCount", reflect.TypeOf((*MockCollection)(nil).EstimatedDocumentCount), varargs...)
}
// Find mocks base method.
func (m *MockCollection) Find(ctx context.Context, filter any, opts ...options.Lister[options.FindOptions]) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Find", varargs...)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Find indicates an expected call of Find.
func (mr *MockCollectionMockRecorder) Find(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Find", reflect.TypeOf((*MockCollection)(nil).Find), varargs...)
}
// FindOne mocks base method.
func (m *MockCollection) FindOne(ctx context.Context, filter any, opts ...options.Lister[options.FindOneOptions]) (*mongo.SingleResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOne", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindOne indicates an expected call of FindOne.
func (mr *MockCollectionMockRecorder) FindOne(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockCollection)(nil).FindOne), varargs...)
}
// FindOneAndDelete mocks base method.
func (m *MockCollection) FindOneAndDelete(ctx context.Context, filter any, opts ...options.Lister[options.FindOneAndDeleteOptions]) (*mongo.SingleResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOneAndDelete", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindOneAndDelete indicates an expected call of FindOneAndDelete.
func (mr *MockCollectionMockRecorder) FindOneAndDelete(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneAndDelete", reflect.TypeOf((*MockCollection)(nil).FindOneAndDelete), varargs...)
}
// FindOneAndReplace mocks base method.
func (m *MockCollection) FindOneAndReplace(ctx context.Context, filter, replacement any, opts ...options.Lister[options.FindOneAndReplaceOptions]) (*mongo.SingleResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, replacement}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOneAndReplace", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindOneAndReplace indicates an expected call of FindOneAndReplace.
func (mr *MockCollectionMockRecorder) FindOneAndReplace(ctx, filter, replacement any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, replacement}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneAndReplace", reflect.TypeOf((*MockCollection)(nil).FindOneAndReplace), varargs...)
}
// FindOneAndUpdate mocks base method.
func (m *MockCollection) FindOneAndUpdate(ctx context.Context, filter, update any, opts ...options.Lister[options.FindOneAndUpdateOptions]) (*mongo.SingleResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOneAndUpdate", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindOneAndUpdate indicates an expected call of FindOneAndUpdate.
func (mr *MockCollectionMockRecorder) FindOneAndUpdate(ctx, filter, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneAndUpdate", reflect.TypeOf((*MockCollection)(nil).FindOneAndUpdate), varargs...)
}
// Indexes mocks base method.
func (m *MockCollection) Indexes() mongo.IndexView {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Indexes")
ret0, _ := ret[0].(mongo.IndexView)
return ret0
}
// Indexes indicates an expected call of Indexes.
func (mr *MockCollectionMockRecorder) Indexes() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Indexes", reflect.TypeOf((*MockCollection)(nil).Indexes))
}
// InsertMany mocks base method.
func (m *MockCollection) InsertMany(ctx context.Context, documents []any, opts ...options.Lister[options.InsertManyOptions]) (*mongo.InsertManyResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, documents}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "InsertMany", varargs...)
ret0, _ := ret[0].(*mongo.InsertManyResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertMany indicates an expected call of InsertMany.
func (mr *MockCollectionMockRecorder) InsertMany(ctx, documents any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, documents}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertMany", reflect.TypeOf((*MockCollection)(nil).InsertMany), varargs...)
}
// InsertOne mocks base method.
func (m *MockCollection) InsertOne(ctx context.Context, document any, opts ...options.Lister[options.InsertOneOptions]) (*mongo.InsertOneResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, document}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "InsertOne", varargs...)
ret0, _ := ret[0].(*mongo.InsertOneResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertOne indicates an expected call of InsertOne.
func (mr *MockCollectionMockRecorder) InsertOne(ctx, document any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, document}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertOne", reflect.TypeOf((*MockCollection)(nil).InsertOne), varargs...)
}
// ReplaceOne mocks base method.
func (m *MockCollection) ReplaceOne(ctx context.Context, filter, replacement any, opts ...options.Lister[options.ReplaceOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, replacement}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ReplaceOne", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ReplaceOne indicates an expected call of ReplaceOne.
func (mr *MockCollectionMockRecorder) ReplaceOne(ctx, filter, replacement any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, replacement}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceOne", reflect.TypeOf((*MockCollection)(nil).ReplaceOne), varargs...)
}
// UpdateByID mocks base method.
func (m *MockCollection) UpdateByID(ctx context.Context, id, update any, opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, id, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpdateByID", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateByID indicates an expected call of UpdateByID.
func (mr *MockCollectionMockRecorder) UpdateByID(ctx, id, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, id, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateByID", reflect.TypeOf((*MockCollection)(nil).UpdateByID), varargs...)
}
// UpdateMany mocks base method.
func (m *MockCollection) UpdateMany(ctx context.Context, filter, update any, opts ...options.Lister[options.UpdateManyOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpdateMany", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateMany indicates an expected call of UpdateMany.
func (mr *MockCollectionMockRecorder) UpdateMany(ctx, filter, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMany", reflect.TypeOf((*MockCollection)(nil).UpdateMany), varargs...)
}
// UpdateOne mocks base method.
func (m *MockCollection) UpdateOne(ctx context.Context, filter, update any, opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpdateOne", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateOne indicates an expected call of UpdateOne.
func (mr *MockCollectionMockRecorder) UpdateOne(ctx, filter, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateOne", reflect.TypeOf((*MockCollection)(nil).UpdateOne), varargs...)
}
// Watch mocks base method.
func (m *MockCollection) Watch(ctx context.Context, pipeline any, opts ...options.Lister[options.ChangeStreamOptions]) (*mongo.ChangeStream, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, pipeline}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Watch", varargs...)
ret0, _ := ret[0].(*mongo.ChangeStream)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Watch indicates an expected call of Watch.
func (mr *MockCollectionMockRecorder) Watch(ctx, pipeline any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, pipeline}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockCollection)(nil).Watch), varargs...)
}
// MockmonCollection is a mock of monCollection interface.
type MockmonCollection struct {
ctrl *gomock.Controller
recorder *MockmonCollectionMockRecorder
isgomock struct{}
}
// MockmonCollectionMockRecorder is the mock recorder for MockmonCollection.
type MockmonCollectionMockRecorder struct {
mock *MockmonCollection
}
// NewMockmonCollection creates a new mock instance.
func NewMockmonCollection(ctrl *gomock.Controller) *MockmonCollection {
mock := &MockmonCollection{ctrl: ctrl}
mock.recorder = &MockmonCollectionMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockmonCollection) EXPECT() *MockmonCollectionMockRecorder {
return m.recorder
}
// Aggregate mocks base method.
func (m *MockmonCollection) Aggregate(ctx context.Context, pipeline any, opts ...options.Lister[options.AggregateOptions]) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, pipeline}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Aggregate", varargs...)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Aggregate indicates an expected call of Aggregate.
func (mr *MockmonCollectionMockRecorder) Aggregate(ctx, pipeline any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, pipeline}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Aggregate", reflect.TypeOf((*MockmonCollection)(nil).Aggregate), varargs...)
}
// BulkWrite mocks base method.
func (m *MockmonCollection) BulkWrite(ctx context.Context, models []mongo.WriteModel, opts ...options.Lister[options.BulkWriteOptions]) (*mongo.BulkWriteResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, models}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "BulkWrite", varargs...)
ret0, _ := ret[0].(*mongo.BulkWriteResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// BulkWrite indicates an expected call of BulkWrite.
func (mr *MockmonCollectionMockRecorder) BulkWrite(ctx, models any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, models}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BulkWrite", reflect.TypeOf((*MockmonCollection)(nil).BulkWrite), varargs...)
}
// Clone mocks base method.
func (m *MockmonCollection) Clone(opts ...options.Lister[options.CollectionOptions]) *mongo.Collection {
m.ctrl.T.Helper()
varargs := []any{}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Clone", varargs...)
ret0, _ := ret[0].(*mongo.Collection)
return ret0
}
// Clone indicates an expected call of Clone.
func (mr *MockmonCollectionMockRecorder) Clone(opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clone", reflect.TypeOf((*MockmonCollection)(nil).Clone), opts...)
}
// CountDocuments mocks base method.
func (m *MockmonCollection) CountDocuments(ctx context.Context, filter any, opts ...options.Lister[options.CountOptions]) (int64, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "CountDocuments", varargs...)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CountDocuments indicates an expected call of CountDocuments.
func (mr *MockmonCollectionMockRecorder) CountDocuments(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CountDocuments", reflect.TypeOf((*MockmonCollection)(nil).CountDocuments), varargs...)
}
// Database mocks base method.
func (m *MockmonCollection) Database() *mongo.Database {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Database")
ret0, _ := ret[0].(*mongo.Database)
return ret0
}
// Database indicates an expected call of Database.
func (mr *MockmonCollectionMockRecorder) Database() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Database", reflect.TypeOf((*MockmonCollection)(nil).Database))
}
// DeleteMany mocks base method.
func (m *MockmonCollection) DeleteMany(ctx context.Context, filter any, opts ...options.Lister[options.DeleteManyOptions]) (*mongo.DeleteResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "DeleteMany", varargs...)
ret0, _ := ret[0].(*mongo.DeleteResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DeleteMany indicates an expected call of DeleteMany.
func (mr *MockmonCollectionMockRecorder) DeleteMany(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMany", reflect.TypeOf((*MockmonCollection)(nil).DeleteMany), varargs...)
}
// DeleteOne mocks base method.
func (m *MockmonCollection) DeleteOne(ctx context.Context, filter any, opts ...options.Lister[options.DeleteOneOptions]) (*mongo.DeleteResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "DeleteOne", varargs...)
ret0, _ := ret[0].(*mongo.DeleteResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DeleteOne indicates an expected call of DeleteOne.
func (mr *MockmonCollectionMockRecorder) DeleteOne(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOne", reflect.TypeOf((*MockmonCollection)(nil).DeleteOne), varargs...)
}
// Distinct mocks base method.
func (m *MockmonCollection) Distinct(ctx context.Context, fieldName string, filter any, opts ...options.Lister[options.DistinctOptions]) *mongo.DistinctResult {
m.ctrl.T.Helper()
varargs := []any{ctx, fieldName, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Distinct", varargs...)
ret0, _ := ret[0].(*mongo.DistinctResult)
return ret0
}
// Distinct indicates an expected call of Distinct.
func (mr *MockmonCollectionMockRecorder) Distinct(ctx, fieldName, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, fieldName, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Distinct", reflect.TypeOf((*MockmonCollection)(nil).Distinct), varargs...)
}
// Drop mocks base method.
func (m *MockmonCollection) Drop(ctx context.Context, opts ...options.Lister[options.DropCollectionOptions]) error {
m.ctrl.T.Helper()
varargs := []any{ctx}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Drop", varargs...)
ret0, _ := ret[0].(error)
return ret0
}
// Drop indicates an expected call of Drop.
func (mr *MockmonCollectionMockRecorder) Drop(ctx any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Drop", reflect.TypeOf((*MockmonCollection)(nil).Drop), varargs...)
}
// EstimatedDocumentCount mocks base method.
func (m *MockmonCollection) EstimatedDocumentCount(ctx context.Context, opts ...options.Lister[options.EstimatedDocumentCountOptions]) (int64, error) {
m.ctrl.T.Helper()
varargs := []any{ctx}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "EstimatedDocumentCount", varargs...)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EstimatedDocumentCount indicates an expected call of EstimatedDocumentCount.
func (mr *MockmonCollectionMockRecorder) EstimatedDocumentCount(ctx any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimatedDocumentCount", reflect.TypeOf((*MockmonCollection)(nil).EstimatedDocumentCount), varargs...)
}
// Find mocks base method.
func (m *MockmonCollection) Find(ctx context.Context, filter any, opts ...options.Lister[options.FindOptions]) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Find", varargs...)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Find indicates an expected call of Find.
func (mr *MockmonCollectionMockRecorder) Find(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Find", reflect.TypeOf((*MockmonCollection)(nil).Find), varargs...)
}
// FindOne mocks base method.
func (m *MockmonCollection) FindOne(ctx context.Context, filter any, opts ...options.Lister[options.FindOneOptions]) *mongo.SingleResult {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOne", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
return ret0
}
// FindOne indicates an expected call of FindOne.
func (mr *MockmonCollectionMockRecorder) FindOne(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockmonCollection)(nil).FindOne), varargs...)
}
// FindOneAndDelete mocks base method.
func (m *MockmonCollection) FindOneAndDelete(ctx context.Context, filter any, opts ...options.Lister[options.FindOneAndDeleteOptions]) *mongo.SingleResult {
m.ctrl.T.Helper()
varargs := []any{ctx, filter}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOneAndDelete", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
return ret0
}
// FindOneAndDelete indicates an expected call of FindOneAndDelete.
func (mr *MockmonCollectionMockRecorder) FindOneAndDelete(ctx, filter any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneAndDelete", reflect.TypeOf((*MockmonCollection)(nil).FindOneAndDelete), varargs...)
}
// FindOneAndReplace mocks base method.
func (m *MockmonCollection) FindOneAndReplace(ctx context.Context, filter, replacement any, opts ...options.Lister[options.FindOneAndReplaceOptions]) *mongo.SingleResult {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, replacement}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOneAndReplace", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
return ret0
}
// FindOneAndReplace indicates an expected call of FindOneAndReplace.
func (mr *MockmonCollectionMockRecorder) FindOneAndReplace(ctx, filter, replacement any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, replacement}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneAndReplace", reflect.TypeOf((*MockmonCollection)(nil).FindOneAndReplace), varargs...)
}
// FindOneAndUpdate mocks base method.
func (m *MockmonCollection) FindOneAndUpdate(ctx context.Context, filter, update any, opts ...options.Lister[options.FindOneAndUpdateOptions]) *mongo.SingleResult {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FindOneAndUpdate", varargs...)
ret0, _ := ret[0].(*mongo.SingleResult)
return ret0
}
// FindOneAndUpdate indicates an expected call of FindOneAndUpdate.
func (mr *MockmonCollectionMockRecorder) FindOneAndUpdate(ctx, filter, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneAndUpdate", reflect.TypeOf((*MockmonCollection)(nil).FindOneAndUpdate), varargs...)
}
// Indexes mocks base method.
func (m *MockmonCollection) Indexes() mongo.IndexView {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Indexes")
ret0, _ := ret[0].(mongo.IndexView)
return ret0
}
// Indexes indicates an expected call of Indexes.
func (mr *MockmonCollectionMockRecorder) Indexes() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Indexes", reflect.TypeOf((*MockmonCollection)(nil).Indexes))
}
// InsertMany mocks base method.
func (m *MockmonCollection) InsertMany(ctx context.Context, documents any, opts ...options.Lister[options.InsertManyOptions]) (*mongo.InsertManyResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, documents}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "InsertMany", varargs...)
ret0, _ := ret[0].(*mongo.InsertManyResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertMany indicates an expected call of InsertMany.
func (mr *MockmonCollectionMockRecorder) InsertMany(ctx, documents any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, documents}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertMany", reflect.TypeOf((*MockmonCollection)(nil).InsertMany), varargs...)
}
// InsertOne mocks base method.
func (m *MockmonCollection) InsertOne(ctx context.Context, document any, opts ...options.Lister[options.InsertOneOptions]) (*mongo.InsertOneResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, document}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "InsertOne", varargs...)
ret0, _ := ret[0].(*mongo.InsertOneResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertOne indicates an expected call of InsertOne.
func (mr *MockmonCollectionMockRecorder) InsertOne(ctx, document any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, document}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertOne", reflect.TypeOf((*MockmonCollection)(nil).InsertOne), varargs...)
}
// ReplaceOne mocks base method.
func (m *MockmonCollection) ReplaceOne(ctx context.Context, filter, replacement any, opts ...options.Lister[options.ReplaceOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, replacement}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ReplaceOne", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ReplaceOne indicates an expected call of ReplaceOne.
func (mr *MockmonCollectionMockRecorder) ReplaceOne(ctx, filter, replacement any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, replacement}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceOne", reflect.TypeOf((*MockmonCollection)(nil).ReplaceOne), varargs...)
}
// UpdateByID mocks base method.
func (m *MockmonCollection) UpdateByID(ctx context.Context, id, update any, opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, id, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpdateByID", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateByID indicates an expected call of UpdateByID.
func (mr *MockmonCollectionMockRecorder) UpdateByID(ctx, id, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, id, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateByID", reflect.TypeOf((*MockmonCollection)(nil).UpdateByID), varargs...)
}
// UpdateMany mocks base method.
func (m *MockmonCollection) UpdateMany(ctx context.Context, filter, update any, opts ...options.Lister[options.UpdateManyOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpdateMany", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateMany indicates an expected call of UpdateMany.
func (mr *MockmonCollectionMockRecorder) UpdateMany(ctx, filter, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMany", reflect.TypeOf((*MockmonCollection)(nil).UpdateMany), varargs...)
}
// UpdateOne mocks base method.
func (m *MockmonCollection) UpdateOne(ctx context.Context, filter, update any, opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, filter, update}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpdateOne", varargs...)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateOne indicates an expected call of UpdateOne.
func (mr *MockmonCollectionMockRecorder) UpdateOne(ctx, filter, update any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, filter, update}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateOne", reflect.TypeOf((*MockmonCollection)(nil).UpdateOne), varargs...)
}
// Watch mocks base method.
func (m *MockmonCollection) Watch(ctx context.Context, pipeline any, opts ...options.Lister[options.ChangeStreamOptions]) (*mongo.ChangeStream, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, pipeline}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Watch", varargs...)
ret0, _ := ret[0].(*mongo.ChangeStream)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Watch indicates an expected call of Watch.
func (mr *MockmonCollectionMockRecorder) Watch(ctx, pipeline any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, pipeline}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockmonCollection)(nil).Watch), varargs...)
}

View File

@@ -10,12 +10,10 @@ import (
"github.com/zeromicro/go-zero/core/logx/logtest" "github.com/zeromicro/go-zero/core/logx/logtest"
"github.com/zeromicro/go-zero/core/stringx" "github.com/zeromicro/go-zero/core/stringx"
"github.com/zeromicro/go-zero/core/timex" "github.com/zeromicro/go-zero/core/timex"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/mongo" mopt "go.mongodb.org/mongo-driver/v2/mongo/options"
"go.mongodb.org/mongo-driver/mongo/integration/mtest" "go.uber.org/mock/gomock"
mopt "go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/x/mongo/driver/session"
) )
var errDummy = errors.New("dummy") var errDummy = errors.New("dummy")
@@ -68,471 +66,345 @@ func TestKeepPromise_keep(t *testing.T) {
} }
func TestNewCollection(t *testing.T) { func TestNewCollection(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) _ = newCollection(&mongo.Collection{}, breaker.GetBreaker("localhost"))
mt.Run("test", func(mt *mtest.T) {
coll := mt.Coll
assert.NotNil(t, coll)
col := newCollection(coll, breaker.GetBreaker("localhost"))
assert.Equal(t, t.Name()+"/test", col.(*decoratedCollection).name)
})
} }
func TestCollection_Aggregate(t *testing.T) { func TestCollection_Aggregate(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
coll := mt.Coll mockCollection := NewMockmonCollection(ctrl)
assert.NotNil(t, coll) mockCollection.EXPECT().Aggregate(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.Cursor{}, nil)
col := newCollection(coll, breaker.GetBreaker("localhost")) c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
ns := mt.Coll.Database().Name() + "." + mt.Coll.Name() _, err := c.Aggregate(context.Background(), []interface{}{}, mopt.Aggregate())
aggRes := mtest.CreateCursorResponse(1, ns, mtest.FirstBatch) assert.Nil(t, err)
mt.AddMockResponses(aggRes)
assert.Equal(t, t.Name()+"/test", col.(*decoratedCollection).name)
cursor, err := col.Aggregate(context.Background(), mongo.Pipeline{}, mopt.Aggregate())
assert.Nil(t, err)
cursor.Close(context.Background())
})
} }
func TestCollection_BulkWrite(t *testing.T) { func TestCollection_BulkWrite(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().BulkWrite(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.BulkWriteResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.BulkWrite(context.Background(), []mongo.WriteModel{
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "ok", Value: 1}}...)) mongo.NewInsertOneModel().SetDocument(bson.D{{Key: "foo", Value: 1}}),
res, err := c.BulkWrite(context.Background(), []mongo.WriteModel{
mongo.NewInsertOneModel().SetDocument(bson.D{{Key: "foo", Value: 1}}),
})
assert.Nil(t, err)
assert.NotNil(t, res)
c.brk = new(dropBreaker)
_, err = c.BulkWrite(context.Background(), []mongo.WriteModel{
mongo.NewInsertOneModel().SetDocument(bson.D{{Key: "foo", Value: 1}}),
})
assert.Equal(t, errDummy, err)
}) })
assert.Nil(t, err)
c.brk = new(dropBreaker)
_, err = c.BulkWrite(context.Background(), []mongo.WriteModel{
mongo.NewInsertOneModel().SetDocument(bson.D{{Key: "foo", Value: 1}}),
})
assert.Equal(t, errDummy, err)
} }
func TestCollection_CountDocuments(t *testing.T) { func TestCollection_CountDocuments(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().CountDocuments(gomock.Any(), gomock.Any(), gomock.Any()).Return(int64(0), nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} res, err := c.CountDocuments(context.Background(), bson.D{})
mt.AddMockResponses(mtest.CreateCursorResponse( assert.Nil(t, err)
1, assert.Equal(t, int64(0), res)
"DBName.CollectionName", c.brk = new(dropBreaker)
mtest.FirstBatch, _, err = c.CountDocuments(context.Background(), bson.D{{Key: "foo", Value: 1}})
bson.D{ assert.Equal(t, errDummy, err)
{Key: "n", Value: 1},
}))
res, err := c.CountDocuments(context.Background(), bson.D{})
assert.Nil(t, err)
assert.Equal(t, int64(1), res)
c.brk = new(dropBreaker)
_, err = c.CountDocuments(context.Background(), bson.D{{Key: "foo", Value: 1}})
assert.Equal(t, errDummy, err)
})
} }
func TestDecoratedCollection_DeleteMany(t *testing.T) { func TestDecoratedCollection_DeleteMany(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().DeleteMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.DeleteMany(context.Background(), bson.D{})
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) assert.Nil(t, err)
res, err := c.DeleteMany(context.Background(), bson.D{}) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: 1}})
assert.Equal(t, int64(1), res.DeletedCount) assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: 1}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_Distinct(t *testing.T) { func TestCollection_Distinct(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().Distinct(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DistinctResult{})
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.Distinct(context.Background(), "foo", bson.D{})
mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "values", Value: []int{1}}}) assert.Nil(t, err)
resp, err := c.Distinct(context.Background(), "foo", bson.D{}) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.Distinct(context.Background(), "foo", bson.D{{Key: "foo", Value: 1}})
assert.Equal(t, 1, len(resp)) assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.Distinct(context.Background(), "foo", bson.D{{Key: "foo", Value: 1}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_EstimatedDocumentCount(t *testing.T) { func TestCollection_EstimatedDocumentCount(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().EstimatedDocumentCount(gomock.Any(), gomock.Any()).Return(int64(0), nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.EstimatedDocumentCount(context.Background())
mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "n", Value: 1}}) assert.Nil(t, err)
res, err := c.EstimatedDocumentCount(context.Background()) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.EstimatedDocumentCount(context.Background())
assert.Equal(t, int64(1), res) assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.EstimatedDocumentCount(context.Background())
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_Find(t *testing.T) { func TestCollection_Find(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().Find(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.Cursor{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} filter := bson.D{{Key: "x", Value: 1}}
find := mtest.CreateCursorResponse( _, err := c.Find(context.Background(), filter, mopt.Find())
1, assert.Nil(t, err)
"DBName.CollectionName", c.brk = new(dropBreaker)
mtest.FirstBatch, _, err = c.Find(context.Background(), filter, mopt.Find())
bson.D{ assert.Equal(t, errDummy, err)
{Key: "name", Value: "John"},
})
getMore := mtest.CreateCursorResponse(
1,
"DBName.CollectionName",
mtest.NextBatch,
bson.D{
{Key: "name", Value: "Mary"},
})
killCursors := mtest.CreateCursorResponse(
0,
"DBName.CollectionName",
mtest.NextBatch)
mt.AddMockResponses(find, getMore, killCursors)
filter := bson.D{{Key: "x", Value: 1}}
cursor, err := c.Find(context.Background(), filter, mopt.Find())
assert.Nil(t, err)
defer cursor.Close(context.Background())
var val []struct {
ID primitive.ObjectID `bson:"_id"`
Name string `bson:"name"`
}
assert.Nil(t, cursor.All(context.Background(), &val))
assert.Equal(t, 2, len(val))
assert.Equal(t, "John", val[0].Name)
assert.Equal(t, "Mary", val[1].Name)
c.brk = new(dropBreaker)
_, err = c.Find(context.Background(), filter, mopt.Find())
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_FindOne(t *testing.T) { func TestCollection_FindOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().FindOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.SingleResult{})
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} filter := bson.D{{Key: "x", Value: 1}}
find := mtest.CreateCursorResponse( _, err := c.FindOne(context.Background(), filter)
1, assert.Equal(t, mongo.ErrNoDocuments, err)
"DBName.CollectionName", c.brk = new(dropBreaker)
mtest.FirstBatch, _, err = c.FindOne(context.Background(), filter)
bson.D{ assert.Equal(t, errDummy, err)
{Key: "name", Value: "John"},
})
getMore := mtest.CreateCursorResponse(
1,
"DBName.CollectionName",
mtest.NextBatch,
bson.D{
{Key: "name", Value: "Mary"},
})
killCursors := mtest.CreateCursorResponse(
0,
"DBName.CollectionName",
mtest.NextBatch)
mt.AddMockResponses(find, getMore, killCursors)
filter := bson.D{{Key: "x", Value: 1}}
resp, err := c.FindOne(context.Background(), filter)
assert.Nil(t, err)
var val struct {
ID primitive.ObjectID `bson:"_id"`
Name string `bson:"name"`
}
assert.Nil(t, resp.Decode(&val))
assert.Equal(t, "John", val.Name)
c.brk = new(dropBreaker)
_, err = c.FindOne(context.Background(), filter)
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_FindOneAndDelete(t *testing.T) { func TestCollection_FindOneAndDelete(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().FindOneAndDelete(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.SingleResult{})
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} filter := bson.D{}
filter := bson.D{} mockCollection.EXPECT().FindOneAndDelete(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.SingleResult{})
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{}...)) _, err := c.FindOneAndDelete(context.Background(), filter, mopt.FindOneAndDelete())
_, err := c.FindOneAndDelete(context.Background(), filter, mopt.FindOneAndDelete()) assert.Equal(t, mongo.ErrNoDocuments, err)
assert.Equal(t, mongo.ErrNoDocuments, err) _, err = c.FindOneAndDelete(context.Background(), filter, mopt.FindOneAndDelete())
assert.Equal(t, mongo.ErrNoDocuments, err)
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ c.brk = new(dropBreaker)
{Key: "value", Value: bson.D{{Key: "name", Value: "John"}}}, _, err = c.FindOneAndDelete(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
}...)) assert.Equal(t, errDummy, err)
resp, err := c.FindOneAndDelete(context.Background(), filter, mopt.FindOneAndDelete())
assert.Nil(t, err)
var val struct {
Name string `bson:"name"`
}
assert.Nil(t, resp.Decode(&val))
assert.Equal(t, "John", val.Name)
c.brk = new(dropBreaker)
_, err = c.FindOneAndDelete(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_FindOneAndReplace(t *testing.T) { func TestCollection_FindOneAndReplace(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().FindOneAndReplace(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.SingleResult{})
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} filter := bson.D{{Key: "x", Value: 1}}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{}...)) replacement := bson.D{{Key: "x", Value: 2}}
filter := bson.D{{Key: "x", Value: 1}} opts := mopt.FindOneAndReplace().SetUpsert(true)
replacement := bson.D{{Key: "x", Value: 2}} mockCollection.EXPECT().FindOneAndReplace(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.SingleResult{})
opts := mopt.FindOneAndReplace().SetUpsert(true) _, err := c.FindOneAndReplace(context.Background(), filter, replacement, opts)
_, err := c.FindOneAndReplace(context.Background(), filter, replacement, opts) assert.Equal(t, mongo.ErrNoDocuments, err)
assert.Equal(t, mongo.ErrNoDocuments, err) _, err = c.FindOneAndReplace(context.Background(), filter, replacement, opts)
mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "value", Value: bson.D{ assert.Equal(t, mongo.ErrNoDocuments, err)
{Key: "name", Value: "John"}, c.brk = new(dropBreaker)
}}}) _, err = c.FindOneAndReplace(context.Background(), filter, replacement, opts)
resp, err := c.FindOneAndReplace(context.Background(), filter, replacement, opts) assert.Equal(t, errDummy, err)
assert.Nil(t, err)
var val struct {
Name string `bson:"name"`
}
assert.Nil(t, resp.Decode(&val))
assert.Equal(t, "John", val.Name)
c.brk = new(dropBreaker)
_, err = c.FindOneAndReplace(context.Background(), filter, replacement, opts)
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_FindOneAndUpdate(t *testing.T) { func TestCollection_FindOneAndUpdate(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().FindOneAndUpdate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.SingleResult{})
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} filter := bson.D{{Key: "x", Value: 1}}
mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}}) update := bson.D{{Key: "$x", Value: 2}}
filter := bson.D{{Key: "x", Value: 1}} mockCollection.EXPECT().FindOneAndUpdate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.SingleResult{})
update := bson.D{{Key: "$x", Value: 2}} opts := mopt.FindOneAndUpdate().SetUpsert(true)
opts := mopt.FindOneAndUpdate().SetUpsert(true) _, err := c.FindOneAndUpdate(context.Background(), filter, update, opts)
_, err := c.FindOneAndUpdate(context.Background(), filter, update, opts) assert.Equal(t, mongo.ErrNoDocuments, err)
assert.Equal(t, mongo.ErrNoDocuments, err) _, err = c.FindOneAndUpdate(context.Background(), filter, update, opts)
assert.Equal(t, mongo.ErrNoDocuments, err)
mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "value", Value: bson.D{ c.brk = new(dropBreaker)
{Key: "name", Value: "John"}, _, err = c.FindOneAndUpdate(context.Background(), filter, update, opts)
}}}) assert.Equal(t, errDummy, err)
resp, err := c.FindOneAndUpdate(context.Background(), filter, update, opts)
assert.Nil(t, err)
var val struct {
Name string `bson:"name"`
}
assert.Nil(t, resp.Decode(&val))
assert.Equal(t, "John", val.Name)
c.brk = new(dropBreaker)
_, err = c.FindOneAndUpdate(context.Background(), filter, update, opts)
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_InsertOne(t *testing.T) { func TestCollection_InsertOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().InsertOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.InsertOneResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} res, err := c.InsertOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "ok", Value: 1}}...)) assert.Nil(t, err)
res, err := c.InsertOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}}) assert.NotNil(t, res)
assert.Nil(t, err) c.brk = new(dropBreaker)
assert.NotNil(t, res) _, err = c.InsertOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.InsertOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_InsertMany(t *testing.T) { func TestCollection_InsertMany(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().InsertMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.InsertManyResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.InsertMany(context.Background(), []any{
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "ok", Value: 1}}...)) bson.D{{Key: "foo", Value: "bar"}},
res, err := c.InsertMany(context.Background(), []any{ bson.D{{Key: "foo", Value: "baz"}},
bson.D{{Key: "foo", Value: "bar"}},
bson.D{{Key: "foo", Value: "baz"}},
})
assert.Nil(t, err)
assert.NotNil(t, res)
assert.Equal(t, 2, len(res.InsertedIDs))
c.brk = new(dropBreaker)
_, err = c.InsertMany(context.Background(), []any{bson.D{{Key: "foo", Value: "bar"}}})
assert.Equal(t, errDummy, err)
}) })
assert.Nil(t, err)
c.brk = new(dropBreaker)
_, err = c.InsertMany(context.Background(), []any{bson.D{{Key: "foo", Value: "bar"}}})
assert.Equal(t, errDummy, err)
} }
func TestCollection_DeleteOne(t *testing.T) { func TestCollection_DeleteOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().DeleteOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.DeleteOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) assert.Nil(t, err)
res, err := c.DeleteOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}}) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.DeleteOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, int64(1), res.DeletedCount) assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.DeleteOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_DeleteMany(t *testing.T) { func TestCollection_DeleteMany(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().DeleteMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) assert.Nil(t, err)
res, err := c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}}) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, int64(1), res.DeletedCount) assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_ReplaceOne(t *testing.T) { func TestCollection_ReplaceOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().ReplaceOne(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.ReplaceOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) bson.D{{Key: "foo", Value: "baz"}},
res, err := c.ReplaceOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}}, )
bson.D{{Key: "foo", Value: "baz"}}, assert.Nil(t, err)
) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.ReplaceOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
assert.Equal(t, int64(1), res.MatchedCount) bson.D{{Key: "foo", Value: "baz"}})
assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.ReplaceOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
bson.D{{Key: "foo", Value: "baz"}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_UpdateOne(t *testing.T) { func TestCollection_UpdateOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().UpdateOne(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.UpdateOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
resp, err := c.UpdateOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}}, assert.Nil(t, err)
bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}}) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.UpdateOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
assert.Equal(t, int64(1), resp.MatchedCount) bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.UpdateOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_UpdateByID(t *testing.T) { func TestCollection_UpdateByID(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().UpdateByID(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.UpdateByID(context.Background(), bson.NewObjectID(),
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
resp, err := c.UpdateByID(context.Background(), primitive.NewObjectID(), assert.Nil(t, err)
bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}}) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.UpdateByID(context.Background(), bson.NewObjectID(),
assert.Equal(t, int64(1), resp.MatchedCount) bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
assert.Equal(t, errDummy, err)
c.brk = new(dropBreaker)
_, err = c.UpdateByID(context.Background(), primitive.NewObjectID(),
bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
assert.Equal(t, errDummy, err)
})
} }
func TestCollection_UpdateMany(t *testing.T) { func TestCollection_UpdateMany(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
c := decoratedCollection{ mockCollection := NewMockmonCollection(ctrl)
Collection: mt.Coll, mockCollection.EXPECT().UpdateMany(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
} _, err := c.UpdateMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
resp, err := c.UpdateMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}}, assert.Nil(t, err)
bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}}) c.brk = new(dropBreaker)
assert.Nil(t, err) _, err = c.UpdateMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
assert.Equal(t, int64(1), resp.MatchedCount) bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
assert.Equal(t, errDummy, err)
}
c.brk = new(dropBreaker) func TestCollection_Watch(t *testing.T) {
_, err = c.UpdateMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}}, ctrl := gomock.NewController(t)
bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}}) defer ctrl.Finish()
assert.Equal(t, errDummy, err) mockCollection := NewMockmonCollection(ctrl)
}) mockCollection.EXPECT().Watch(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.ChangeStream{}, nil)
c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
_, err := c.Watch(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Nil(t, err)
}
func TestCollection_Clone(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockCollection := NewMockmonCollection(ctrl)
mockCollection.EXPECT().Clone(gomock.Any()).Return(nil)
c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
cc := c.Clone()
assert.Nil(t, cc)
}
func TestCollection_Database(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockCollection := NewMockmonCollection(ctrl)
mockCollection.EXPECT().Database().Return(nil)
c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
db := c.Database()
assert.Nil(t, db)
}
func TestCollection_Drop(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockCollection := NewMockmonCollection(ctrl)
mockCollection.EXPECT().Drop(gomock.Any()).Return(nil)
c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
err := c.Drop(context.Background())
assert.Nil(t, err)
}
func TestCollection_Indexes(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockCollection := NewMockmonCollection(ctrl)
idx := mongo.IndexView{}
mockCollection.EXPECT().Indexes().Return(idx)
c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
index := c.Indexes()
assert.Equal(t, index, idx)
} }
func TestDecoratedCollection_LogDuration(t *testing.T) { func TestDecoratedCollection_LogDuration(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
c := decoratedCollection{ defer ctrl.Finish()
Collection: mt.Coll, mockCollection := NewMockmonCollection(ctrl)
brk: breaker.NewBreaker(), c := newTestCollection(mockCollection, breaker.GetBreaker("localhost"))
}
buf := logtest.NewCollector(t) buf := logtest.NewCollector(t)
@@ -585,14 +457,6 @@ func TestAcceptable(t *testing.T) {
{"NilDocument", mongo.ErrNilDocument, true}, {"NilDocument", mongo.ErrNilDocument, true},
{"NilCursor", mongo.ErrNilCursor, true}, {"NilCursor", mongo.ErrNilCursor, true},
{"EmptySlice", mongo.ErrEmptySlice, true}, {"EmptySlice", mongo.ErrEmptySlice, true},
{"SessionEnded", session.ErrSessionEnded, true},
{"NoTransactStarted", session.ErrNoTransactStarted, true},
{"TransactInProgress", session.ErrTransactInProgress, true},
{"AbortAfterCommit", session.ErrAbortAfterCommit, true},
{"AbortTwice", session.ErrAbortTwice, true},
{"CommitAfterAbort", session.ErrCommitAfterAbort, true},
{"UnackWCUnsupported", session.ErrUnackWCUnsupported, true},
{"SnapshotTransaction", session.ErrSnapshotTransaction, true},
{"DuplicateKeyError", mongo.WriteException{WriteErrors: []mongo.WriteError{{Code: duplicateKeyCode}}}, true}, {"DuplicateKeyError", mongo.WriteException{WriteErrors: []mongo.WriteError{{Code: duplicateKeyCode}}}, true},
{"OtherError", errors.New("other error"), false}, {"OtherError", errors.New("other error"), false},
} }

View File

@@ -0,0 +1,19 @@
# Migrating from 1.x to 2.0
To upgrade imports of the Go Driver from v1 to v2, we recommend using [marwan-at-work/mod
](https://github.com/marwan-at-work/mod):
```
mod upgrade --mod-name=go.mongodb.org/mongo-driver
```
# Notice
After completing the mod upgrade, code changes are typically unnecessary in the vast majority of cases. However, if your project references packages including but not limited to those listed below, you'll need to manually replace them, as these libraries are no longer present in the v2 version.
```go
go.mongodb.org/mongo-driver/bson/bsonrw => go.mongodb.org/mongo-driver/v2/bson
go.mongodb.org/mongo-driver/bson/bsoncodec => go.mongodb.org/mongo-driver/v2/bson
go.mongodb.org/mongo-driver/bson/primitive => go.mongodb.org/mongo-driver/v2/bson
```
See the following resources to learn more about upgrading from version 1.x to 2.0.:
https://raw.githubusercontent.com/mongodb/mongo-go-driver/refs/heads/master/docs/migration-2.0.md

View File

@@ -1,3 +1,4 @@
//go:generate mockgen -package mon -destination model_mock.go -source model.go monClient monSession
package mon package mon
import ( import (
@@ -7,8 +8,8 @@ import (
"github.com/zeromicro/go-zero/core/breaker" "github.com/zeromicro/go-zero/core/breaker"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/timex" "github.com/zeromicro/go-zero/core/timex"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/v2/mongo"
mopt "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/options"
) )
const ( const (
@@ -24,15 +25,15 @@ type (
Model struct { Model struct {
Collection Collection
name string name string
cli *mongo.Client cli monClient
brk breaker.Breaker brk breaker.Breaker
opts []Option opts []Option
} }
wrappedSession struct { WrappedSession struct {
mongo.Session session monSession
name string name string
brk breaker.Breaker brk breaker.Breaker
} }
) )
@@ -61,6 +62,17 @@ func newModel(name string, cli *mongo.Client, coll Collection, brk breaker.Break
return &Model{ return &Model{
name: name, name: name,
Collection: coll, Collection: coll,
cli: &mockMonClient{c: cli},
brk: brk,
opts: opts,
}
}
func newTestModel(name string, cli monClient, coll monCollection, brk breaker.Breaker,
opts ...Option) *Model {
return &Model{
name: name,
Collection: newTestCollection(coll, breaker.GetBreaker("localhost")),
cli: cli, cli: cli,
brk: brk, brk: brk,
opts: opts, opts: opts,
@@ -68,7 +80,7 @@ func newModel(name string, cli *mongo.Client, coll Collection, brk breaker.Break
} }
// StartSession starts a new session. // StartSession starts a new session.
func (m *Model) StartSession(opts ...*mopt.SessionOptions) (sess mongo.Session, err error) { func (m *Model) StartSession(opts ...options.Lister[options.SessionOptions]) (sess *WrappedSession, err error) {
starTime := timex.Now() starTime := timex.Now()
defer func() { defer func() {
logDuration(context.Background(), m.name, startSession, starTime, err) logDuration(context.Background(), m.name, startSession, starTime, err)
@@ -79,15 +91,15 @@ func (m *Model) StartSession(opts ...*mopt.SessionOptions) (sess mongo.Session,
return nil, sessionErr return nil, sessionErr
} }
return &wrappedSession{ return &WrappedSession{
Session: session, session: session,
name: m.name, name: m.name,
brk: m.brk, brk: m.brk,
}, nil }, nil
} }
// Aggregate executes an aggregation pipeline. // Aggregate executes an aggregation pipeline.
func (m *Model) Aggregate(ctx context.Context, v, pipeline any, opts ...*mopt.AggregateOptions) error { func (m *Model) Aggregate(ctx context.Context, v, pipeline any, opts ...options.Lister[options.AggregateOptions]) error {
cur, err := m.Collection.Aggregate(ctx, pipeline, opts...) cur, err := m.Collection.Aggregate(ctx, pipeline, opts...)
if err != nil { if err != nil {
return err return err
@@ -98,7 +110,7 @@ func (m *Model) Aggregate(ctx context.Context, v, pipeline any, opts ...*mopt.Ag
} }
// DeleteMany deletes documents that match the filter. // DeleteMany deletes documents that match the filter.
func (m *Model) DeleteMany(ctx context.Context, filter any, opts ...*mopt.DeleteOptions) (int64, error) { func (m *Model) DeleteMany(ctx context.Context, filter any, opts ...options.Lister[options.DeleteManyOptions]) (int64, error) {
res, err := m.Collection.DeleteMany(ctx, filter, opts...) res, err := m.Collection.DeleteMany(ctx, filter, opts...)
if err != nil { if err != nil {
return 0, err return 0, err
@@ -108,7 +120,7 @@ func (m *Model) DeleteMany(ctx context.Context, filter any, opts ...*mopt.Delete
} }
// DeleteOne deletes the first document that matches the filter. // DeleteOne deletes the first document that matches the filter.
func (m *Model) DeleteOne(ctx context.Context, filter any, opts ...*mopt.DeleteOptions) (int64, error) { func (m *Model) DeleteOne(ctx context.Context, filter any, opts ...options.Lister[options.DeleteOneOptions]) (int64, error) {
res, err := m.Collection.DeleteOne(ctx, filter, opts...) res, err := m.Collection.DeleteOne(ctx, filter, opts...)
if err != nil { if err != nil {
return 0, err return 0, err
@@ -118,7 +130,7 @@ func (m *Model) DeleteOne(ctx context.Context, filter any, opts ...*mopt.DeleteO
} }
// Find finds documents that match the filter. // Find finds documents that match the filter.
func (m *Model) Find(ctx context.Context, v, filter any, opts ...*mopt.FindOptions) error { func (m *Model) Find(ctx context.Context, v, filter any, opts ...options.Lister[options.FindOptions]) error {
cur, err := m.Collection.Find(ctx, filter, opts...) cur, err := m.Collection.Find(ctx, filter, opts...)
if err != nil { if err != nil {
return err return err
@@ -129,7 +141,7 @@ func (m *Model) Find(ctx context.Context, v, filter any, opts ...*mopt.FindOptio
} }
// FindOne finds the first document that matches the filter. // FindOne finds the first document that matches the filter.
func (m *Model) FindOne(ctx context.Context, v, filter any, opts ...*mopt.FindOneOptions) error { func (m *Model) FindOne(ctx context.Context, v, filter any, opts ...options.Lister[options.FindOneOptions]) error {
res, err := m.Collection.FindOne(ctx, filter, opts...) res, err := m.Collection.FindOne(ctx, filter, opts...)
if err != nil { if err != nil {
return err return err
@@ -140,7 +152,7 @@ func (m *Model) FindOne(ctx context.Context, v, filter any, opts ...*mopt.FindOn
// FindOneAndDelete finds a single document and deletes it. // FindOneAndDelete finds a single document and deletes it.
func (m *Model) FindOneAndDelete(ctx context.Context, v, filter any, func (m *Model) FindOneAndDelete(ctx context.Context, v, filter any,
opts ...*mopt.FindOneAndDeleteOptions) error { opts ...options.Lister[options.FindOneAndDeleteOptions]) error {
res, err := m.Collection.FindOneAndDelete(ctx, filter, opts...) res, err := m.Collection.FindOneAndDelete(ctx, filter, opts...)
if err != nil { if err != nil {
return err return err
@@ -151,7 +163,7 @@ func (m *Model) FindOneAndDelete(ctx context.Context, v, filter any,
// FindOneAndReplace finds a single document and replaces it. // FindOneAndReplace finds a single document and replaces it.
func (m *Model) FindOneAndReplace(ctx context.Context, v, filter, replacement any, func (m *Model) FindOneAndReplace(ctx context.Context, v, filter, replacement any,
opts ...*mopt.FindOneAndReplaceOptions) error { opts ...options.Lister[options.FindOneAndReplaceOptions]) error {
res, err := m.Collection.FindOneAndReplace(ctx, filter, replacement, opts...) res, err := m.Collection.FindOneAndReplace(ctx, filter, replacement, opts...)
if err != nil { if err != nil {
return err return err
@@ -162,7 +174,7 @@ func (m *Model) FindOneAndReplace(ctx context.Context, v, filter, replacement an
// FindOneAndUpdate finds a single document and updates it. // FindOneAndUpdate finds a single document and updates it.
func (m *Model) FindOneAndUpdate(ctx context.Context, v, filter, update any, func (m *Model) FindOneAndUpdate(ctx context.Context, v, filter, update any,
opts ...*mopt.FindOneAndUpdateOptions) error { opts ...options.Lister[options.FindOneAndUpdateOptions]) error {
res, err := m.Collection.FindOneAndUpdate(ctx, filter, update, opts...) res, err := m.Collection.FindOneAndUpdate(ctx, filter, update, opts...)
if err != nil { if err != nil {
return err return err
@@ -171,8 +183,8 @@ func (m *Model) FindOneAndUpdate(ctx context.Context, v, filter, update any,
return res.Decode(v) return res.Decode(v)
} }
// AbortTransaction implements the mongo.Session interface. // AbortTransaction implements the mongo.session interface.
func (w *wrappedSession) AbortTransaction(ctx context.Context) (err error) { func (w *WrappedSession) AbortTransaction(ctx context.Context) (err error) {
ctx, span := startSpan(ctx, abortTransaction) ctx, span := startSpan(ctx, abortTransaction)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -184,12 +196,12 @@ func (w *wrappedSession) AbortTransaction(ctx context.Context) (err error) {
logDuration(ctx, w.name, abortTransaction, starTime, err) logDuration(ctx, w.name, abortTransaction, starTime, err)
}() }()
return w.Session.AbortTransaction(ctx) return w.session.AbortTransaction(ctx)
}, acceptable) }, acceptable)
} }
// CommitTransaction implements the mongo.Session interface. // CommitTransaction implements the mongo.session interface.
func (w *wrappedSession) CommitTransaction(ctx context.Context) (err error) { func (w *WrappedSession) CommitTransaction(ctx context.Context) (err error) {
ctx, span := startSpan(ctx, commitTransaction) ctx, span := startSpan(ctx, commitTransaction)
defer func() { defer func() {
endSpan(span, err) endSpan(span, err)
@@ -201,15 +213,15 @@ func (w *wrappedSession) CommitTransaction(ctx context.Context) (err error) {
logDuration(ctx, w.name, commitTransaction, starTime, err) logDuration(ctx, w.name, commitTransaction, starTime, err)
}() }()
return w.Session.CommitTransaction(ctx) return w.session.CommitTransaction(ctx)
}, acceptable) }, acceptable)
} }
// WithTransaction implements the mongo.Session interface. // WithTransaction implements the mongo.session interface.
func (w *wrappedSession) WithTransaction( func (w *WrappedSession) WithTransaction(
ctx context.Context, ctx context.Context,
fn func(sessCtx mongo.SessionContext) (any, error), fn func(sessCtx context.Context) (any, error),
opts ...*mopt.TransactionOptions, opts ...options.Lister[options.TransactionOptions],
) (res any, err error) { ) (res any, err error) {
ctx, span := startSpan(ctx, withTransaction) ctx, span := startSpan(ctx, withTransaction)
defer func() { defer func() {
@@ -222,15 +234,15 @@ func (w *wrappedSession) WithTransaction(
logDuration(ctx, w.name, withTransaction, starTime, err) logDuration(ctx, w.name, withTransaction, starTime, err)
}() }()
res, err = w.Session.WithTransaction(ctx, fn, opts...) res, err = w.session.WithTransaction(ctx, fn, opts...)
return err return err
}, acceptable) }, acceptable)
return return
} }
// EndSession implements the mongo.Session interface. // EndSession implements the mongo.session interface.
func (w *wrappedSession) EndSession(ctx context.Context) { func (w *WrappedSession) EndSession(ctx context.Context) {
var err error var err error
ctx, span := startSpan(ctx, endSession) ctx, span := startSpan(ctx, endSession)
defer func() { defer func() {
@@ -243,7 +255,29 @@ func (w *wrappedSession) EndSession(ctx context.Context) {
logDuration(ctx, w.name, endSession, starTime, err) logDuration(ctx, w.name, endSession, starTime, err)
}() }()
w.Session.EndSession(ctx) w.session.EndSession(ctx)
return nil return nil
}, acceptable) }, acceptable)
} }
type (
//for unit test
monClient interface {
StartSession(opts ...options.Lister[options.SessionOptions]) (monSession, error)
}
monSession interface {
AbortTransaction(ctx context.Context) error
CommitTransaction(ctx context.Context) error
EndSession(ctx context.Context)
WithTransaction(ctx context.Context, fn func(sessCtx context.Context) (any, error),
opts ...options.Lister[options.TransactionOptions]) (any, error)
}
)
type mockMonClient struct {
c *mongo.Client
}
func (m *mockMonClient) StartSession(opts ...options.Lister[options.SessionOptions]) (monSession, error) {
return m.c.StartSession(opts...)
}

View File

@@ -0,0 +1,145 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: model.go
//
// Generated by this command:
//
// mockgen -package mon -destination model_mock.go -source model.go monClient monSession
//
// Package mon is a generated GoMock package.
package mon
import (
context "context"
reflect "reflect"
options "go.mongodb.org/mongo-driver/v2/mongo/options"
gomock "go.uber.org/mock/gomock"
)
// MockmonClient is a mock of monClient interface.
type MockmonClient struct {
ctrl *gomock.Controller
recorder *MockmonClientMockRecorder
isgomock struct{}
}
// MockmonClientMockRecorder is the mock recorder for MockmonClient.
type MockmonClientMockRecorder struct {
mock *MockmonClient
}
// NewMockmonClient creates a new mock instance.
func NewMockmonClient(ctrl *gomock.Controller) *MockmonClient {
mock := &MockmonClient{ctrl: ctrl}
mock.recorder = &MockmonClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockmonClient) EXPECT() *MockmonClientMockRecorder {
return m.recorder
}
// StartSession mocks base method.
func (m *MockmonClient) StartSession(opts ...options.Lister[options.SessionOptions]) (monSession, error) {
m.ctrl.T.Helper()
varargs := []any{}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "StartSession", varargs...)
ret0, _ := ret[0].(monSession)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// StartSession indicates an expected call of StartSession.
func (mr *MockmonClientMockRecorder) StartSession(opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartSession", reflect.TypeOf((*MockmonClient)(nil).StartSession), opts...)
}
// MockmonSession is a mock of monSession interface.
type MockmonSession struct {
ctrl *gomock.Controller
recorder *MockmonSessionMockRecorder
isgomock struct{}
}
// MockmonSessionMockRecorder is the mock recorder for MockmonSession.
type MockmonSessionMockRecorder struct {
mock *MockmonSession
}
// NewMockmonSession creates a new mock instance.
func NewMockmonSession(ctrl *gomock.Controller) *MockmonSession {
mock := &MockmonSession{ctrl: ctrl}
mock.recorder = &MockmonSessionMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockmonSession) EXPECT() *MockmonSessionMockRecorder {
return m.recorder
}
// AbortTransaction mocks base method.
func (m *MockmonSession) AbortTransaction(ctx context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AbortTransaction", ctx)
ret0, _ := ret[0].(error)
return ret0
}
// AbortTransaction indicates an expected call of AbortTransaction.
func (mr *MockmonSessionMockRecorder) AbortTransaction(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortTransaction", reflect.TypeOf((*MockmonSession)(nil).AbortTransaction), ctx)
}
// CommitTransaction mocks base method.
func (m *MockmonSession) CommitTransaction(ctx context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CommitTransaction", ctx)
ret0, _ := ret[0].(error)
return ret0
}
// CommitTransaction indicates an expected call of CommitTransaction.
func (mr *MockmonSessionMockRecorder) CommitTransaction(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitTransaction", reflect.TypeOf((*MockmonSession)(nil).CommitTransaction), ctx)
}
// EndSession mocks base method.
func (m *MockmonSession) EndSession(ctx context.Context) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "EndSession", ctx)
}
// EndSession indicates an expected call of EndSession.
func (mr *MockmonSessionMockRecorder) EndSession(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EndSession", reflect.TypeOf((*MockmonSession)(nil).EndSession), ctx)
}
// WithTransaction mocks base method.
func (m *MockmonSession) WithTransaction(ctx context.Context, fn func(context.Context) (any, error), opts ...options.Lister[options.TransactionOptions]) (any, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, fn}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "WithTransaction", varargs...)
ret0, _ := ret[0].(any)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// WithTransaction indicates an expected call of WithTransaction.
func (mr *MockmonSessionMockRecorder) WithTransaction(ctx, fn any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, fn}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithTransaction", reflect.TypeOf((*MockmonSession)(nil).WithTransaction), varargs...)
}

View File

@@ -2,224 +2,231 @@ package mon
import ( import (
"context" "context"
"errors"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson" "github.com/zeromicro/go-zero/core/breaker"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/mongo/integration/mtest" "go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest"
"go.uber.org/mock/gomock"
) )
func TestModel_StartSession(t *testing.T) { func TestModel_StartSession(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
sess, err := m.StartSession() mockedMonClient := NewMockmonClient(ctrl)
assert.Nil(t, err) mockMonSession := NewMockmonSession(ctrl)
defer sess.EndSession(context.Background()) warpSession := &WrappedSession{
session: mockMonSession,
name: "",
brk: breaker.GetBreaker("localhost"),
}
_, err = sess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (any, error) { m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
_ = sessCtx.StartTransaction() mockedMonClient.EXPECT().StartSession(gomock.Any()).Return(warpSession, errors.New("error"))
sessCtx.Client().Database("1") _, err := m.StartSession()
sessCtx.EndSession(context.Background()) assert.NotNil(t, err)
return nil, nil mockedMonClient.EXPECT().StartSession(gomock.Any()).Return(warpSession, nil)
}) sess, err := m.StartSession()
assert.Nil(t, err) assert.Nil(t, err)
assert.NoError(t, sess.CommitTransaction(context.Background())) defer sess.EndSession(context.Background())
assert.Error(t, sess.AbortTransaction(context.Background())) mockMonSession.EXPECT().WithTransaction(gomock.Any(), gomock.Any()).Return(nil, nil)
mockMonSession.EXPECT().CommitTransaction(gomock.Any()).Return(nil)
mockMonSession.EXPECT().AbortTransaction(gomock.Any()).Return(nil)
mockMonSession.EXPECT().EndSession(gomock.Any())
_, err = sess.WithTransaction(context.Background(), func(sessCtx context.Context) (any, error) {
//_ = sessCtx.StartTransaction()
//sessCtx.Client().Database("1")
//sessCtx.EndSession(context.Background())
return nil, nil
}) })
assert.Nil(t, err)
assert.NoError(t, sess.CommitTransaction(context.Background()))
assert.NoError(t, sess.AbortTransaction(context.Background()))
} }
func TestModel_Aggregate(t *testing.T) { func TestModel_Aggregate(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
find := mtest.CreateCursorResponse( mockedMonClient := NewMockmonClient(ctrl)
1, cursor, err := mongo.NewCursorFromDocuments([]any{
"DBName.CollectionName", bson.M{
mtest.FirstBatch, "name": "John",
bson.D{ },
{Key: "name", Value: "John"}, bson.M{
}) "name": "Mary",
getMore := mtest.CreateCursorResponse( },
1, }, nil, nil)
"DBName.CollectionName", assert.NoError(t, err)
mtest.NextBatch, mockMonCollection.EXPECT().Aggregate(gomock.Any(), gomock.Any(), gomock.Any()).Return(cursor, nil)
bson.D{ m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
{Key: "name", Value: "Mary"}, var result []bson.M
}) err = m.Aggregate(context.Background(), &result, bson.D{})
killCursors := mtest.CreateCursorResponse( assert.Nil(t, err)
0, assert.Equal(t, 2, len(result))
"DBName.CollectionName", assert.Equal(t, "John", result[0]["name"])
mtest.NextBatch) assert.Equal(t, "Mary", result[1]["name"])
mt.AddMockResponses(find, getMore, killCursors) triggerBreaker(m)
var result []any assert.Equal(t, errDummy, m.Aggregate(context.Background(), &result, bson.D{}))
err := m.Aggregate(context.Background(), &result, mongo.Pipeline{})
assert.Nil(t, err)
assert.Equal(t, 2, len(result))
assert.Equal(t, "John", result[0].(bson.D).Map()["name"])
assert.Equal(t, "Mary", result[1].(bson.D).Map()["name"])
triggerBreaker(m)
assert.Equal(t, errDummy, m.Aggregate(context.Background(), &result, mongo.Pipeline{}))
})
} }
func TestModel_DeleteMany(t *testing.T) { func TestModel_DeleteMany(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) mockedMonClient := NewMockmonClient(ctrl)
val, err := m.DeleteMany(context.Background(), bson.D{}) mockMonCollection.EXPECT().DeleteMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{}, nil)
assert.Nil(t, err) m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
assert.Equal(t, int64(1), val) _, err := m.DeleteMany(context.Background(), bson.D{})
assert.Nil(t, err)
triggerBreaker(m) triggerBreaker(m)
_, err = m.DeleteMany(context.Background(), bson.D{}) _, err = m.DeleteMany(context.Background(), bson.D{})
assert.Equal(t, errDummy, err) assert.Equal(t, errDummy, err)
})
} }
func TestModel_DeleteOne(t *testing.T) { func TestModel_DeleteOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) mockedMonClient := NewMockmonClient(ctrl)
val, err := m.DeleteOne(context.Background(), bson.D{}) mockMonCollection.EXPECT().DeleteOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{}, nil)
assert.Nil(t, err) m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
assert.Equal(t, int64(1), val) _, err := m.DeleteOne(context.Background(), bson.D{})
assert.Nil(t, err)
triggerBreaker(m) triggerBreaker(m)
_, err = m.DeleteOne(context.Background(), bson.D{}) _, err = m.DeleteOne(context.Background(), bson.D{})
assert.Equal(t, errDummy, err) assert.Equal(t, errDummy, err)
})
} }
func TestModel_Find(t *testing.T) { func TestModel_Find(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
find := mtest.CreateCursorResponse( mockedMonClient := NewMockmonClient(ctrl)
1, cursor, err := mongo.NewCursorFromDocuments([]any{
"DBName.CollectionName", bson.M{
mtest.FirstBatch, "name": "John",
bson.D{ },
{Key: "name", Value: "John"}, bson.M{
}) "name": "Mary",
getMore := mtest.CreateCursorResponse( },
1, }, nil, nil)
"DBName.CollectionName", assert.NoError(t, err)
mtest.NextBatch, mockMonCollection.EXPECT().Find(gomock.Any(), gomock.Any(), gomock.Any()).Return(cursor, nil)
bson.D{ m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
{Key: "name", Value: "Mary"}, var result []bson.M
}) err = m.Find(context.Background(), &result, bson.D{})
killCursors := mtest.CreateCursorResponse( assert.Nil(t, err)
0, assert.Equal(t, 2, len(result))
"DBName.CollectionName", assert.Equal(t, "John", result[0]["name"])
mtest.NextBatch) assert.Equal(t, "Mary", result[1]["name"])
mt.AddMockResponses(find, getMore, killCursors) triggerBreaker(m)
var result []any assert.Equal(t, errDummy, m.Find(context.Background(), &result, bson.D{}))
err := m.Find(context.Background(), &result, bson.D{})
assert.Nil(t, err)
assert.Equal(t, 2, len(result))
assert.Equal(t, "John", result[0].(bson.D).Map()["name"])
assert.Equal(t, "Mary", result[1].(bson.D).Map()["name"])
triggerBreaker(m)
assert.Equal(t, errDummy, m.Find(context.Background(), &result, bson.D{}))
})
} }
func TestModel_FindOne(t *testing.T) { func TestModel_FindOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
find := mtest.CreateCursorResponse( mockedMonClient := NewMockmonClient(ctrl)
1, mockMonCollection.EXPECT().FindOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(mongo.NewSingleResultFromDocument(bson.M{"name": "John"}, nil, nil))
"DBName.CollectionName", m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
mtest.FirstBatch, var result bson.M
bson.D{ err := m.FindOne(context.Background(), &result, bson.D{})
{Key: "name", Value: "John"}, assert.Nil(t, err)
}) assert.Equal(t, "John", result["name"])
killCursors := mtest.CreateCursorResponse( triggerBreaker(m)
0, assert.Equal(t, errDummy, m.FindOne(context.Background(), &result, bson.D{}))
"DBName.CollectionName",
mtest.NextBatch)
mt.AddMockResponses(find, killCursors)
var result bson.D
err := m.FindOne(context.Background(), &result, bson.D{})
assert.Nil(t, err)
assert.Equal(t, "John", result.Map()["name"])
triggerBreaker(m)
assert.Equal(t, errDummy, m.FindOne(context.Background(), &result, bson.D{}))
})
} }
func TestModel_FindOneAndDelete(t *testing.T) { func TestModel_FindOneAndDelete(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockedMonClient := NewMockmonClient(ctrl)
{Key: "value", Value: bson.D{{Key: "name", Value: "John"}}}, mockMonCollection.EXPECT().FindOneAndDelete(gomock.Any(), gomock.Any(), gomock.Any()).Return(mongo.NewSingleResultFromDocument(bson.M{"name": "John"}, nil, nil))
}...)) m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
var result bson.D var result bson.M
err := m.FindOneAndDelete(context.Background(), &result, bson.D{}) err := m.FindOneAndDelete(context.Background(), &result, bson.M{})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "John", result.Map()["name"]) assert.Equal(t, "John", result["name"])
triggerBreaker(m)
triggerBreaker(m) assert.Equal(t, errDummy, m.FindOneAndDelete(context.Background(), &result, bson.D{}))
assert.Equal(t, errDummy, m.FindOneAndDelete(context.Background(), &result, bson.D{}))
})
} }
func TestModel_FindOneAndReplace(t *testing.T) { func TestModel_FindOneAndReplace(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockedMonClient := NewMockmonClient(ctrl)
{Key: "value", Value: bson.D{{Key: "name", Value: "John"}}}, mockMonCollection.EXPECT().FindOneAndReplace(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mongo.NewSingleResultFromDocument(bson.M{"name": "John"}, nil, nil))
}...)) m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
var result bson.D var result bson.M
err := m.FindOneAndReplace(context.Background(), &result, bson.D{}, bson.D{ err := m.FindOneAndReplace(context.Background(), &result, bson.D{}, bson.D{
{Key: "name", Value: "Mary"}, {Key: "name", Value: "Mary"},
})
assert.Nil(t, err)
assert.Equal(t, "John", result.Map()["name"])
triggerBreaker(m)
assert.Equal(t, errDummy, m.FindOneAndReplace(context.Background(), &result, bson.D{}, bson.D{
{Key: "name", Value: "Mary"},
}))
}) })
assert.Nil(t, err)
assert.Equal(t, "John", result["name"])
triggerBreaker(m)
assert.Equal(t, errDummy, m.FindOneAndReplace(context.Background(), &result, bson.D{}, bson.D{
{Key: "name", Value: "Mary"},
}))
} }
func TestModel_FindOneAndUpdate(t *testing.T) { func TestModel_FindOneAndUpdate(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(mt) mockMonCollection := NewMockmonCollection(ctrl)
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockedMonClient := NewMockmonClient(ctrl)
{Key: "value", Value: bson.D{{Key: "name", Value: "John"}}}, mockMonCollection.EXPECT().FindOneAndUpdate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mongo.NewSingleResultFromDocument(bson.M{"name": "John"}, nil, nil))
}...)) m := newTestModel("foo", mockedMonClient, mockMonCollection, breaker.GetBreaker("test"))
var result bson.D var result bson.M
err := m.FindOneAndUpdate(context.Background(), &result, bson.D{}, bson.D{ err := m.FindOneAndUpdate(context.Background(), &result, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}}, {Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}},
})
assert.Nil(t, err)
assert.Equal(t, "John", result.Map()["name"])
triggerBreaker(m)
assert.Equal(t, errDummy, m.FindOneAndUpdate(context.Background(), &result, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}},
}))
}) })
} assert.Nil(t, err)
assert.Equal(t, "John", result["name"])
triggerBreaker(m)
assert.Equal(t, errDummy, m.FindOneAndUpdate(context.Background(), &result, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}},
}))
func createModel(mt *mtest.T) *Model {
Inject(mt.Name(), mt.Client)
return MustNewModel(mt.Name(), mt.DB.Name(), mt.Coll.Name())
} }
func triggerBreaker(m *Model) { func triggerBreaker(m *Model) {
m.Collection.(*decoratedCollection).brk = new(dropBreaker) m.Collection.(*decoratedCollection).brk = new(dropBreaker)
} }
func TestMustNewModel(t *testing.T) {
Inject("mongodb://localhost:27017", &mongo.Client{})
MustNewModel("mongodb://localhost:27017", "test", "test")
}
func TestNewModel(t *testing.T) {
NewModel("mongo://localhost:27018", "test", "test")
Inject("mongodb://localhost:27018", &mongo.Client{})
NewModel("mongodb://localhost:27018", "test", "test")
}
func Test_newModel(t *testing.T) {
Inject("mongodb://localhost:27019", &mongo.Client{})
newModel("mongodb://localhost:27019", nil, nil, nil)
}
func Test_mockMonClient_StartSession(t *testing.T) {
md := drivertest.NewMockDeployment()
opts := options.Client()
opts.Deployment = md
client, err := mongo.Connect(opts)
assert.Nil(t, err)
m := mockMonClient{
c: client,
}
_, err = m.StartSession()
assert.Nil(t, err)
}

View File

@@ -5,9 +5,8 @@ import (
"time" "time"
"github.com/zeromicro/go-zero/core/syncx" "github.com/zeromicro/go-zero/core/syncx"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/bson/bsoncodec" "go.mongodb.org/mongo-driver/v2/mongo/options"
mopt "go.mongodb.org/mongo-driver/mongo/options"
) )
const defaultTimeout = time.Second * 3 const defaultTimeout = time.Second * 3
@@ -20,16 +19,16 @@ var (
type ( type (
// Option defines the method to customize a mongo model. // Option defines the method to customize a mongo model.
Option func(opts *options) Option func(opts *clientOptions)
// TypeCodec is a struct that stores specific type Encoder/Decoder. // TypeCodec is a struct that stores specific type Encoder/Decoder.
TypeCodec struct { TypeCodec struct {
ValueType reflect.Type ValueType reflect.Type
Encoder bsoncodec.ValueEncoder Encoder bson.ValueEncoder
Decoder bsoncodec.ValueDecoder Decoder bson.ValueDecoder
} }
options = mopt.ClientOptions clientOptions = options.ClientOptions
) )
// DisableLog disables logging of mongo commands, includes info and slow logs. // DisableLog disables logging of mongo commands, includes info and slow logs.
@@ -50,14 +49,14 @@ func SetSlowThreshold(threshold time.Duration) {
// WithTimeout set the mon client operation timeout. // WithTimeout set the mon client operation timeout.
func WithTimeout(timeout time.Duration) Option { func WithTimeout(timeout time.Duration) Option {
return func(opts *options) { return func(opts *clientOptions) {
opts.SetTimeout(timeout) opts.SetTimeout(timeout)
} }
} }
// WithTypeCodec registers TypeCodecs to convert custom types. // WithTypeCodec registers TypeCodecs to convert custom types.
func WithTypeCodec(typeCodecs ...TypeCodec) Option { func WithTypeCodec(typeCodecs ...TypeCodec) Option {
return func(opts *options) { return func(opts *clientOptions) {
registry := bson.NewRegistry() registry := bson.NewRegistry()
for _, v := range typeCodecs { for _, v := range typeCodecs {
registry.RegisterTypeEncoder(v.ValueType, v.Encoder) registry.RegisterTypeEncoder(v.ValueType, v.Encoder)
@@ -68,7 +67,7 @@ func WithTypeCodec(typeCodecs ...TypeCodec) Option {
} }
func defaultTimeoutOption() Option { func defaultTimeoutOption() Option {
return func(opts *options) { return func(opts *clientOptions) {
opts.SetTimeout(defaultTimeout) opts.SetTimeout(defaultTimeout)
} }
} }

View File

@@ -7,9 +7,8 @@ import (
"time" "time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson/bsoncodec" "go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/bson/bsonrw" mopt "go.mongodb.org/mongo-driver/v2/mongo/options"
mopt "go.mongodb.org/mongo-driver/mongo/options"
) )
func TestSetSlowThreshold(t *testing.T) { func TestSetSlowThreshold(t *testing.T) {
@@ -60,7 +59,7 @@ func TestWithRegistryForTimestampRegisterType(t *testing.T) {
opts := mopt.Client() opts := mopt.Client()
// mongoDateTimeEncoder allow user convert time.Time to primitive.DateTime. // mongoDateTimeEncoder allow user convert time.Time to primitive.DateTime.
var mongoDateTimeEncoder bsoncodec.ValueEncoderFunc = func(ect bsoncodec.EncodeContext, w bsonrw.ValueWriter, value reflect.Value) error { var mongoDateTimeEncoder bson.ValueEncoderFunc = func(ect bson.EncodeContext, w bson.ValueWriter, value reflect.Value) error {
// Use reflect, determine if it can be converted to time.Time. // Use reflect, determine if it can be converted to time.Time.
dec, ok := value.Interface().(time.Time) dec, ok := value.Interface().(time.Time)
if !ok { if !ok {
@@ -70,7 +69,7 @@ func TestWithRegistryForTimestampRegisterType(t *testing.T) {
} }
// mongoDateTimeEncoder allow user convert primitive.DateTime to time.Time. // mongoDateTimeEncoder allow user convert primitive.DateTime to time.Time.
var mongoDateTimeDecoder bsoncodec.ValueDecoderFunc = func(ect bsoncodec.DecodeContext, r bsonrw.ValueReader, value reflect.Value) error { var mongoDateTimeDecoder bson.ValueDecoderFunc = func(ect bson.DecodeContext, r bson.ValueReader, value reflect.Value) error {
primTime, err := r.ReadDateTime() primTime, err := r.ReadDateTime()
if err != nil { if err != nil {
return fmt.Errorf("error reading primitive.DateTime from ValueReader: %v", err) return fmt.Errorf("error reading primitive.DateTime from ValueReader: %v", err)

View File

@@ -5,7 +5,7 @@ import (
"github.com/zeromicro/go-zero/core/errorx" "github.com/zeromicro/go-zero/core/errorx"
"github.com/zeromicro/go-zero/core/trace" "github.com/zeromicro/go-zero/core/trace"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/v2/mongo"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
oteltrace "go.opentelemetry.io/otel/trace" oteltrace "go.opentelemetry.io/otel/trace"

View File

@@ -8,8 +8,8 @@ import (
"github.com/zeromicro/go-zero/core/stores/mon" "github.com/zeromicro/go-zero/core/stores/mon"
"github.com/zeromicro/go-zero/core/stores/redis" "github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/syncx" "github.com/zeromicro/go-zero/core/syncx"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/v2/mongo"
mopt "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/options"
) )
var ( var (
@@ -71,6 +71,27 @@ func newModel(uri, db, collection string, c cache.Cache) (*Model, error) {
}, nil }, nil
} }
// mustNewTestModel returns a test Model with the given cache.
func mustNewTestModel(collection mon.Collection, c cache.CacheConf, opts ...cache.Option) *Model {
return &Model{
Model: &mon.Model{
Collection: collection,
},
cache: cache.New(c, singleFlight, stats, mongo.ErrNoDocuments, opts...),
}
}
// NewNodeModel returns a test Model with a cache node.
func mustNewTestNodeModel(collection mon.Collection, rds *redis.Redis, opts ...cache.Option) *Model {
c := cache.NewNode(rds, singleFlight, stats, mongo.ErrNoDocuments, opts...)
return &Model{
Model: &mon.Model{
Collection: collection,
},
cache: c,
}
}
// DelCache deletes the cache with given keys. // DelCache deletes the cache with given keys.
func (mm *Model) DelCache(ctx context.Context, keys ...string) error { func (mm *Model) DelCache(ctx context.Context, keys ...string) error {
return mm.cache.DelCtx(ctx, keys...) return mm.cache.DelCtx(ctx, keys...)
@@ -78,7 +99,7 @@ func (mm *Model) DelCache(ctx context.Context, keys ...string) error {
// DeleteOne deletes the document with given filter, and remove it from cache. // DeleteOne deletes the document with given filter, and remove it from cache.
func (mm *Model) DeleteOne(ctx context.Context, key string, filter any, func (mm *Model) DeleteOne(ctx context.Context, key string, filter any,
opts ...*mopt.DeleteOptions) (int64, error) { opts ...options.Lister[options.DeleteOneOptions]) (int64, error) {
val, err := mm.Model.DeleteOne(ctx, filter, opts...) val, err := mm.Model.DeleteOne(ctx, filter, opts...)
if err != nil { if err != nil {
return 0, err return 0, err
@@ -93,13 +114,13 @@ func (mm *Model) DeleteOne(ctx context.Context, key string, filter any,
// DeleteOneNoCache deletes the document with given filter. // DeleteOneNoCache deletes the document with given filter.
func (mm *Model) DeleteOneNoCache(ctx context.Context, filter any, func (mm *Model) DeleteOneNoCache(ctx context.Context, filter any,
opts ...*mopt.DeleteOptions) (int64, error) { opts ...options.Lister[options.DeleteOneOptions]) (int64, error) {
return mm.Model.DeleteOne(ctx, filter, opts...) return mm.Model.DeleteOne(ctx, filter, opts...)
} }
// FindOne unmarshals a record into v with given key and query. // FindOne unmarshals a record into v with given key and query.
func (mm *Model) FindOne(ctx context.Context, key string, v, filter any, func (mm *Model) FindOne(ctx context.Context, key string, v, filter any,
opts ...*mopt.FindOneOptions) error { opts ...options.Lister[options.FindOneOptions]) error {
return mm.cache.TakeCtx(ctx, v, key, func(v any) error { return mm.cache.TakeCtx(ctx, v, key, func(v any) error {
return mm.Model.FindOne(ctx, v, filter, opts...) return mm.Model.FindOne(ctx, v, filter, opts...)
}) })
@@ -107,13 +128,13 @@ func (mm *Model) FindOne(ctx context.Context, key string, v, filter any,
// FindOneNoCache unmarshals a record into v with query, without cache. // FindOneNoCache unmarshals a record into v with query, without cache.
func (mm *Model) FindOneNoCache(ctx context.Context, v, filter any, func (mm *Model) FindOneNoCache(ctx context.Context, v, filter any,
opts ...*mopt.FindOneOptions) error { opts ...options.Lister[options.FindOneOptions]) error {
return mm.Model.FindOne(ctx, v, filter, opts...) return mm.Model.FindOne(ctx, v, filter, opts...)
} }
// FindOneAndDelete deletes the document with given filter, and unmarshals it into v. // FindOneAndDelete deletes the document with given filter, and unmarshals it into v.
func (mm *Model) FindOneAndDelete(ctx context.Context, key string, v, filter any, func (mm *Model) FindOneAndDelete(ctx context.Context, key string, v, filter any,
opts ...*mopt.FindOneAndDeleteOptions) error { opts ...options.Lister[options.FindOneAndDeleteOptions]) error {
if err := mm.Model.FindOneAndDelete(ctx, v, filter, opts...); err != nil { if err := mm.Model.FindOneAndDelete(ctx, v, filter, opts...); err != nil {
return err return err
} }
@@ -123,13 +144,13 @@ func (mm *Model) FindOneAndDelete(ctx context.Context, key string, v, filter any
// FindOneAndDeleteNoCache deletes the document with given filter, and unmarshals it into v. // FindOneAndDeleteNoCache deletes the document with given filter, and unmarshals it into v.
func (mm *Model) FindOneAndDeleteNoCache(ctx context.Context, v, filter any, func (mm *Model) FindOneAndDeleteNoCache(ctx context.Context, v, filter any,
opts ...*mopt.FindOneAndDeleteOptions) error { opts ...options.Lister[options.FindOneAndDeleteOptions]) error {
return mm.Model.FindOneAndDelete(ctx, v, filter, opts...) return mm.Model.FindOneAndDelete(ctx, v, filter, opts...)
} }
// FindOneAndReplace replaces the document with given filter with replacement, and unmarshals it into v. // FindOneAndReplace replaces the document with given filter with replacement, and unmarshals it into v.
func (mm *Model) FindOneAndReplace(ctx context.Context, key string, v, filter any, func (mm *Model) FindOneAndReplace(ctx context.Context, key string, v, filter any,
replacement any, opts ...*mopt.FindOneAndReplaceOptions) error { replacement any, opts ...options.Lister[options.FindOneAndReplaceOptions]) error {
if err := mm.Model.FindOneAndReplace(ctx, v, filter, replacement, opts...); err != nil { if err := mm.Model.FindOneAndReplace(ctx, v, filter, replacement, opts...); err != nil {
return err return err
} }
@@ -139,13 +160,13 @@ func (mm *Model) FindOneAndReplace(ctx context.Context, key string, v, filter an
// FindOneAndReplaceNoCache replaces the document with given filter with replacement, and unmarshals it into v. // FindOneAndReplaceNoCache replaces the document with given filter with replacement, and unmarshals it into v.
func (mm *Model) FindOneAndReplaceNoCache(ctx context.Context, v, filter any, func (mm *Model) FindOneAndReplaceNoCache(ctx context.Context, v, filter any,
replacement any, opts ...*mopt.FindOneAndReplaceOptions) error { replacement any, opts ...options.Lister[options.FindOneAndReplaceOptions]) error {
return mm.Model.FindOneAndReplace(ctx, v, filter, replacement, opts...) return mm.Model.FindOneAndReplace(ctx, v, filter, replacement, opts...)
} }
// FindOneAndUpdate updates the document with given filter with update, and unmarshals it into v. // FindOneAndUpdate updates the document with given filter with update, and unmarshals it into v.
func (mm *Model) FindOneAndUpdate(ctx context.Context, key string, v, filter any, func (mm *Model) FindOneAndUpdate(ctx context.Context, key string, v, filter any,
update any, opts ...*mopt.FindOneAndUpdateOptions) error { update any, opts ...options.Lister[options.FindOneAndUpdateOptions]) error {
if err := mm.Model.FindOneAndUpdate(ctx, v, filter, update, opts...); err != nil { if err := mm.Model.FindOneAndUpdate(ctx, v, filter, update, opts...); err != nil {
return err return err
} }
@@ -155,7 +176,7 @@ func (mm *Model) FindOneAndUpdate(ctx context.Context, key string, v, filter any
// FindOneAndUpdateNoCache updates the document with given filter with update, and unmarshals it into v. // FindOneAndUpdateNoCache updates the document with given filter with update, and unmarshals it into v.
func (mm *Model) FindOneAndUpdateNoCache(ctx context.Context, v, filter any, func (mm *Model) FindOneAndUpdateNoCache(ctx context.Context, v, filter any,
update any, opts ...*mopt.FindOneAndUpdateOptions) error { update any, opts ...options.Lister[options.FindOneAndUpdateOptions]) error {
return mm.Model.FindOneAndUpdate(ctx, v, filter, update, opts...) return mm.Model.FindOneAndUpdate(ctx, v, filter, update, opts...)
} }
@@ -166,7 +187,7 @@ func (mm *Model) GetCache(key string, v any) error {
// InsertOne inserts a single document into the collection, and remove the cache placeholder. // InsertOne inserts a single document into the collection, and remove the cache placeholder.
func (mm *Model) InsertOne(ctx context.Context, key string, document any, func (mm *Model) InsertOne(ctx context.Context, key string, document any,
opts ...*mopt.InsertOneOptions) (*mongo.InsertOneResult, error) { opts ...options.Lister[options.InsertOneOptions]) (*mongo.InsertOneResult, error) {
res, err := mm.Model.InsertOne(ctx, document, opts...) res, err := mm.Model.InsertOne(ctx, document, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -181,13 +202,13 @@ func (mm *Model) InsertOne(ctx context.Context, key string, document any,
// InsertOneNoCache inserts a single document into the collection. // InsertOneNoCache inserts a single document into the collection.
func (mm *Model) InsertOneNoCache(ctx context.Context, document any, func (mm *Model) InsertOneNoCache(ctx context.Context, document any,
opts ...*mopt.InsertOneOptions) (*mongo.InsertOneResult, error) { opts ...options.Lister[options.InsertOneOptions]) (*mongo.InsertOneResult, error) {
return mm.Model.InsertOne(ctx, document, opts...) return mm.Model.InsertOne(ctx, document, opts...)
} }
// ReplaceOne replaces a single document in the collection, and remove the cache. // ReplaceOne replaces a single document in the collection, and remove the cache.
func (mm *Model) ReplaceOne(ctx context.Context, key string, filter, replacement any, func (mm *Model) ReplaceOne(ctx context.Context, key string, filter, replacement any,
opts ...*mopt.ReplaceOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.ReplaceOptions]) (*mongo.UpdateResult, error) {
res, err := mm.Model.ReplaceOne(ctx, filter, replacement, opts...) res, err := mm.Model.ReplaceOne(ctx, filter, replacement, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -202,7 +223,7 @@ func (mm *Model) ReplaceOne(ctx context.Context, key string, filter, replacement
// ReplaceOneNoCache replaces a single document in the collection. // ReplaceOneNoCache replaces a single document in the collection.
func (mm *Model) ReplaceOneNoCache(ctx context.Context, filter, replacement any, func (mm *Model) ReplaceOneNoCache(ctx context.Context, filter, replacement any,
opts ...*mopt.ReplaceOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.ReplaceOptions]) (*mongo.UpdateResult, error) {
return mm.Model.ReplaceOne(ctx, filter, replacement, opts...) return mm.Model.ReplaceOne(ctx, filter, replacement, opts...)
} }
@@ -213,7 +234,7 @@ func (mm *Model) SetCache(key string, v any) error {
// UpdateByID updates the document with given id with update, and remove the cache. // UpdateByID updates the document with given id with update, and remove the cache.
func (mm *Model) UpdateByID(ctx context.Context, key string, id, update any, func (mm *Model) UpdateByID(ctx context.Context, key string, id, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
res, err := mm.Model.UpdateByID(ctx, id, update, opts...) res, err := mm.Model.UpdateByID(ctx, id, update, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -228,13 +249,13 @@ func (mm *Model) UpdateByID(ctx context.Context, key string, id, update any,
// UpdateByIDNoCache updates the document with given id with update. // UpdateByIDNoCache updates the document with given id with update.
func (mm *Model) UpdateByIDNoCache(ctx context.Context, id, update any, func (mm *Model) UpdateByIDNoCache(ctx context.Context, id, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
return mm.Model.UpdateByID(ctx, id, update, opts...) return mm.Model.UpdateByID(ctx, id, update, opts...)
} }
// UpdateMany updates the documents that match filter with update, and remove the cache. // UpdateMany updates the documents that match filter with update, and remove the cache.
func (mm *Model) UpdateMany(ctx context.Context, keys []string, filter, update any, func (mm *Model) UpdateMany(ctx context.Context, keys []string, filter, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.UpdateManyOptions]) (*mongo.UpdateResult, error) {
res, err := mm.Model.UpdateMany(ctx, filter, update, opts...) res, err := mm.Model.UpdateMany(ctx, filter, update, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -249,13 +270,13 @@ func (mm *Model) UpdateMany(ctx context.Context, keys []string, filter, update a
// UpdateManyNoCache updates the documents that match filter with update. // UpdateManyNoCache updates the documents that match filter with update.
func (mm *Model) UpdateManyNoCache(ctx context.Context, filter, update any, func (mm *Model) UpdateManyNoCache(ctx context.Context, filter, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.UpdateManyOptions]) (*mongo.UpdateResult, error) {
return mm.Model.UpdateMany(ctx, filter, update, opts...) return mm.Model.UpdateMany(ctx, filter, update, opts...)
} }
// UpdateOne updates the first document that matches filter with update, and remove the cache. // UpdateOne updates the first document that matches filter with update, and remove the cache.
func (mm *Model) UpdateOne(ctx context.Context, key string, filter, update any, func (mm *Model) UpdateOne(ctx context.Context, key string, filter, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
res, err := mm.Model.UpdateOne(ctx, filter, update, opts...) res, err := mm.Model.UpdateOne(ctx, filter, update, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -270,6 +291,6 @@ func (mm *Model) UpdateOne(ctx context.Context, key string, filter, update any,
// UpdateOneNoCache updates the first document that matches filter with update. // UpdateOneNoCache updates the first document that matches filter with update.
func (mm *Model) UpdateOneNoCache(ctx context.Context, filter, update any, func (mm *Model) UpdateOneNoCache(ctx context.Context, filter, update any,
opts ...*mopt.UpdateOptions) (*mongo.UpdateResult, error) { opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error) {
return mm.Model.UpdateOne(ctx, filter, update, opts...) return mm.Model.UpdateOne(ctx, filter, update, opts...)
} }

View File

@@ -8,506 +8,519 @@ import (
"github.com/alicebob/miniredis/v2" "github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/cache" "github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/mon" "github.com/zeromicro/go-zero/core/stores/mon"
"github.com/zeromicro/go-zero/core/stores/redis" "github.com/zeromicro/go-zero/core/stores/redis"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/mongo/integration/mtest" "go.mongodb.org/mongo-driver/v2/mongo"
"go.uber.org/mock/gomock"
) )
func TestNewModel(t *testing.T) { func TestMustNewModel(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) s, err := miniredis.Run()
mt.Run("test", func(mt *mtest.T) { assert.Nil(t, err)
_, err := newModel("foo", mt.DB.Name(), mt.Coll.Name(), nil) original := logx.ExitOnFatal.True()
assert.NotNil(mt, err) logx.ExitOnFatal.Set(false)
defer logx.ExitOnFatal.Set(original)
assert.Panics(t, func() {
MustNewModel("foo", "db", "collectino", cache.CacheConf{
cache.NodeConf{
RedisConf: redis.RedisConf{
Host: s.Addr(),
Type: redis.NodeType,
},
Weight: 100,
}})
}) })
} }
func TestMustNewNodeModel(t *testing.T) {
s, err := miniredis.Run()
assert.Nil(t, err)
original := logx.ExitOnFatal.True()
logx.ExitOnFatal.Set(false)
defer logx.ExitOnFatal.Set(original)
assert.Panics(t, func() {
MustNewNodeModel("foo", "db", "collectino", redis.New(s.Addr()))
})
}
func TestNewModel(t *testing.T) {
s, err := miniredis.Run()
assert.Nil(t, err)
_, err = NewModel("foo", "db", "coll", cache.CacheConf{
cache.NodeConf{
RedisConf: redis.RedisConf{
Host: s.Addr(),
Type: redis.NodeType,
},
Weight: 100,
},
})
assert.Error(t, err)
}
func TestNewNodeModel(t *testing.T) {
_, err := NewNodeModel("foo", "db", "coll", nil)
assert.NotNil(t, err)
}
func TestNewModelWithCache(t *testing.T) {
_, err := NewModelWithCache("foo", "db", "coll", nil)
assert.NotNil(t, err)
}
func Test_newModel(t *testing.T) {
mon.Inject("mongodb://localhost:27018", &mongo.Client{})
model, err := newModel("mongodb://localhost:27018", "db", "collection", nil)
assert.Nil(t, err)
assert.NotNil(t, model)
}
func TestModel_DelCache(t *testing.T) { func TestModel_DelCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(t, mt) mockCollection := mon.NewMockCollection(ctrl)
assert.Nil(t, m.cache.Set("foo", "bar")) m := createModel(t, mockCollection)
assert.Nil(t, m.cache.Set("bar", "baz")) assert.Nil(t, m.cache.Set("foo", "bar"))
assert.Nil(t, m.DelCache(context.Background(), "foo", "bar")) assert.Nil(t, m.cache.Set("bar", "baz"))
var v string assert.Nil(t, m.DelCache(context.Background(), "foo", "bar"))
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v))) var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("bar", &v))) assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
}) assert.True(t, m.cache.IsNotFound(m.cache.Get("bar", &v)))
} }
func TestModel_DeleteOne(t *testing.T) { func TestModel_DeleteOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) mockCollection := mon.NewMockCollection(ctrl)
m := createModel(t, mt) mockCollection.EXPECT().DeleteOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{DeletedCount: 1}, nil)
assert.Nil(t, m.cache.Set("foo", "bar")) m := createModel(t, mockCollection)
val, err := m.DeleteOne(context.Background(), "foo", bson.D{{Key: "foo", Value: "bar"}}) assert.Nil(t, m.cache.Set("foo", "bar"))
assert.Nil(t, err) val, err := m.DeleteOne(context.Background(), "foo", bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, int64(1), val) assert.Nil(t, err)
var v string assert.Equal(t, int64(1), val)
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v))) var v string
_, err = m.DeleteOne(context.Background(), "foo", bson.D{{Key: "foo", Value: "bar"}}) assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
assert.NotNil(t, err) mockCollection.EXPECT().DeleteOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{}, errMocked)
_, err = m.DeleteOne(context.Background(), "foo", bson.D{{Key: "foo", Value: "bar"}})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache} m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) mockCollection.EXPECT().DeleteOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{}, nil)
_, err = m.DeleteOne(context.Background(), "foo", bson.D{{Key: "foo", Value: "bar"}}) _, err = m.DeleteOne(context.Background(), "foo", bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, errMocked, err) assert.Equal(t, errMocked, err)
})
} }
func TestModel_DeleteOneNoCache(t *testing.T) { func TestModel_DeleteOneNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...)) mockCollection := mon.NewMockCollection(ctrl)
m := createModel(t, mt) mockCollection.EXPECT().DeleteOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.DeleteResult{DeletedCount: 1}, nil)
assert.Nil(t, m.cache.Set("foo", "bar")) m := createModel(t, mockCollection)
val, err := m.DeleteOneNoCache(context.Background(), bson.D{{Key: "foo", Value: "bar"}}) assert.Nil(t, m.cache.Set("foo", "bar"))
assert.Nil(t, err) val, err := m.DeleteOneNoCache(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
assert.Equal(t, int64(1), val) assert.Nil(t, err)
var v string assert.Equal(t, int64(1), val)
assert.Nil(t, m.cache.Get("foo", &v)) var v string
}) assert.Nil(t, m.cache.Get("foo", &v))
} }
func TestModel_FindOne(t *testing.T) { func TestModel_FindOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
resp := mtest.CreateCursorResponse( mockCollection := mon.NewMockCollection(ctrl)
1, mockCollection.EXPECT().FindOne(gomock.Any(), gomock.Any(), gomock.Any()).
"DBName.CollectionName", Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
mtest.FirstBatch, m := createModel(t, mockCollection)
bson.D{ var v struct {
{Key: "foo", Value: "bar"}, Foo string `bson:"foo"`
}) }
mt.AddMockResponses(resp) assert.Nil(t, m.FindOne(context.Background(), "foo", &v, bson.D{}))
m := createModel(t, mt) assert.Equal(t, "bar", v.Foo)
var v struct { assert.Nil(t, m.cache.Set("foo", "bar"))
Foo string `bson:"foo"`
}
assert.Nil(t, m.FindOne(context.Background(), "foo", &v, bson.D{}))
assert.Equal(t, "bar", v.Foo)
assert.Nil(t, m.cache.Set("foo", "bar"))
})
} }
func TestModel_FindOneNoCache(t *testing.T) { func TestModel_FindOneNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
resp := mtest.CreateCursorResponse( mockCollection := mon.NewMockCollection(ctrl)
1, mockCollection.EXPECT().FindOne(gomock.Any(), gomock.Any(), gomock.Any()).
"DBName.CollectionName", Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
mtest.FirstBatch, m := createModel(t, mockCollection)
bson.D{ v := struct {
{Key: "foo", Value: "bar"}, Foo string `bson:"foo"`
}) }{}
mt.AddMockResponses(resp) assert.Nil(t, m.FindOneNoCache(context.Background(), &v, bson.D{}))
m := createModel(t, mt) assert.Equal(t, "bar", v.Foo)
v := struct {
Foo string `bson:"foo"`
}{}
assert.Nil(t, m.FindOneNoCache(context.Background(), &v, bson.D{}))
assert.Equal(t, "bar", v.Foo)
})
} }
func TestModel_FindOneAndDelete(t *testing.T) { func TestModel_FindOneAndDelete(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, mockCollection.EXPECT().FindOneAndDelete(gomock.Any(), gomock.Any(), gomock.Any()).
}...)) Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, bson.NewRegistry()), nil)
m := createModel(t, mt) m := createModel(t, mockCollection)
assert.Nil(t, m.cache.Set("foo", "bar")) assert.Nil(t, m.cache.Set("foo", "bar"))
v := struct { v := struct {
Foo string `bson:"foo"` Foo string `bson:"foo"`
}{} }{}
assert.Nil(t, m.FindOneAndDelete(context.Background(), "foo", &v, bson.D{})) assert.Nil(t, m.FindOneAndDelete(context.Background(), "foo", &v, bson.D{}))
assert.Equal(t, "bar", v.Foo) assert.Equal(t, "bar", v.Foo)
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v))) assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
assert.NotNil(t, m.FindOneAndDelete(context.Background(), "foo", &v, bson.D{})) mockCollection.EXPECT().FindOneAndDelete(gomock.Any(), gomock.Any(), gomock.Any()).Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, bson.NewRegistry()), errMocked)
assert.NotNil(t, m.FindOneAndDelete(context.Background(), "foo", &v, bson.D{}))
m.cache = mockedCache{m.cache} m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection.EXPECT().FindOneAndDelete(gomock.Any(), gomock.Any(), gomock.Any()).Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, bson.NewRegistry()), nil)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, assert.Equal(t, errMocked, m.FindOneAndDelete(context.Background(), "foo", &v, bson.D{}))
}...))
assert.Equal(t, errMocked, m.FindOneAndDelete(context.Background(), "foo", &v, bson.D{}))
})
} }
func TestModel_FindOneAndDeleteNoCache(t *testing.T) { func TestModel_FindOneAndDeleteNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, mockCollection.EXPECT().FindOneAndDelete(gomock.Any(), gomock.Any(), gomock.Any()).
}...)) Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
m := createModel(t, mt) m := createModel(t, mockCollection)
v := struct { v := struct {
Foo string `bson:"foo"` Foo string `bson:"foo"`
}{} }{}
assert.Nil(t, m.FindOneAndDeleteNoCache(context.Background(), &v, bson.D{})) assert.Nil(t, m.FindOneAndDeleteNoCache(context.Background(), &v, bson.D{}))
assert.Equal(t, "bar", v.Foo) assert.Equal(t, "bar", v.Foo)
})
} }
func TestModel_FindOneAndReplace(t *testing.T) { func TestModel_FindOneAndReplace(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) assert.Nil(t, m.cache.Set("foo", "bar"))
m := createModel(t, mt) v := struct {
assert.Nil(t, m.cache.Set("foo", "bar")) Foo string `bson:"foo"`
v := struct { }{}
Foo string `bson:"foo"` mockCollection.EXPECT().FindOneAndReplace(gomock.Any(), gomock.Any(), gomock.Any()).
}{} Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
assert.Nil(t, m.FindOneAndReplace(context.Background(), "foo", &v, bson.D{}, bson.D{ assert.Nil(t, m.FindOneAndReplace(context.Background(), "foo", &v, bson.D{}, bson.D{
{Key: "name", Value: "Mary"}, {Key: "name", Value: "Mary"},
})) }))
assert.Equal(t, "bar", v.Foo) assert.Equal(t, "bar", v.Foo)
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v))) assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
assert.NotNil(t, m.FindOneAndReplace(context.Background(), "foo", &v, bson.D{}, bson.D{ mockCollection.EXPECT().FindOneAndReplace(gomock.Any(), gomock.Any(), gomock.Any()).
{Key: "name", Value: "Mary"}, Return(mongo.NewSingleResultFromDocument(bson.M{"name": "Mary"}, nil, nil), errMocked)
})) assert.NotNil(t, m.FindOneAndReplace(context.Background(), "foo", &v, bson.D{}, bson.D{
{Key: "name", Value: "Mary"},
}))
m.cache = mockedCache{m.cache} m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection.EXPECT().FindOneAndReplace(gomock.Any(), gomock.Any(), gomock.Any()).
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
}...)) assert.Equal(t, errMocked, m.FindOneAndReplace(context.Background(), "foo", &v, bson.D{}, bson.D{
assert.Equal(t, errMocked, m.FindOneAndReplace(context.Background(), "foo", &v, bson.D{}, bson.D{ {Key: "name", Value: "Mary"},
{Key: "name", Value: "Mary"}, }))
}))
})
} }
func TestModel_FindOneAndReplaceNoCache(t *testing.T) { func TestModel_FindOneAndReplaceNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) v := struct {
m := createModel(t, mt) Foo string `bson:"foo"`
v := struct { }{}
Foo string `bson:"foo"` mockCollection.EXPECT().FindOneAndReplace(gomock.Any(), gomock.Any(), gomock.Any()).Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
}{} assert.Nil(t, m.FindOneAndReplaceNoCache(context.Background(), &v, bson.D{}, bson.D{
assert.Nil(t, m.FindOneAndReplaceNoCache(context.Background(), &v, bson.D{}, bson.D{ {Key: "name", Value: "Mary"},
{Key: "name", Value: "Mary"}, }))
})) assert.Equal(t, "bar", v.Foo)
assert.Equal(t, "bar", v.Foo)
})
} }
func TestModel_FindOneAndUpdate(t *testing.T) { func TestModel_FindOneAndUpdate(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) assert.Nil(t, m.cache.Set("foo", "bar"))
m := createModel(t, mt) v := struct {
assert.Nil(t, m.cache.Set("foo", "bar")) Foo string `bson:"foo"`
v := struct { }{}
Foo string `bson:"foo"` mockCollection.EXPECT().FindOneAndUpdate(gomock.Any(), gomock.Any(), gomock.Any()).
}{} Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
assert.Nil(t, m.FindOneAndUpdate(context.Background(), "foo", &v, bson.D{}, bson.D{ assert.Nil(t, m.FindOneAndUpdate(context.Background(), "foo", &v, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}}, {Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}},
})) }))
assert.Equal(t, "bar", v.Foo) assert.Equal(t, "bar", v.Foo)
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v))) assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
assert.NotNil(t, m.FindOneAndUpdate(context.Background(), "foo", &v, bson.D{}, bson.D{ mockCollection.EXPECT().FindOneAndUpdate(gomock.Any(), gomock.Any(), gomock.Any()).
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}}, Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), errMocked)
})) assert.NotNil(t, m.FindOneAndUpdate(context.Background(), "foo", &v, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}},
}))
m.cache = mockedCache{m.cache} m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection.EXPECT().FindOneAndUpdate(gomock.Any(), gomock.Any(), gomock.Any()).
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
}...)) assert.Equal(t, errMocked, m.FindOneAndUpdate(context.Background(), "foo", &v, bson.D{}, bson.D{
assert.Equal(t, errMocked, m.FindOneAndUpdate(context.Background(), "foo", &v, bson.D{}, bson.D{ {Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}},
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}}, }))
}))
})
} }
func TestModel_FindOneAndUpdateNoCache(t *testing.T) { func TestModel_FindOneAndUpdateNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) v := struct {
m := createModel(t, mt) Foo string `bson:"foo"`
v := struct { }{}
Foo string `bson:"foo"` mockCollection.EXPECT().FindOneAndUpdate(gomock.Any(), gomock.Any(), gomock.Any()).
}{} Return(mongo.NewSingleResultFromDocument(bson.M{"foo": "bar"}, nil, nil), nil)
assert.Nil(t, m.FindOneAndUpdateNoCache(context.Background(), &v, bson.D{}, bson.D{ assert.Nil(t, m.FindOneAndUpdateNoCache(context.Background(), &v, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}}, {Key: "$set", Value: bson.D{{Key: "name", Value: "Mary"}}},
})) }))
assert.Equal(t, "bar", v.Foo) assert.Equal(t, "bar", v.Foo)
})
} }
func TestModel_GetCache(t *testing.T) { func TestModel_GetCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(t, mt) mockCollection := mon.NewMockCollection(ctrl)
assert.NotNil(t, m.cache) m := createModel(t, mockCollection)
assert.Nil(t, m.cache.Set("foo", "bar")) assert.NotNil(t, m.cache)
var s string assert.Nil(t, m.cache.Set("foo", "bar"))
assert.Nil(t, m.cache.Get("foo", &s)) var s string
assert.Equal(t, "bar", s) assert.Nil(t, m.cache.Get("foo", &s))
}) assert.Equal(t, "bar", s)
} }
func TestModel_InsertOne(t *testing.T) { func TestModel_InsertOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) assert.Nil(t, m.cache.Set("foo", "bar"))
m := createModel(t, mt) mockCollection.EXPECT().InsertOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.InsertOneResult{}, nil)
assert.Nil(t, m.cache.Set("foo", "bar")) resp, err := m.InsertOne(context.Background(), "foo", bson.D{
resp, err := m.InsertOne(context.Background(), "foo", bson.D{ {Key: "name", Value: "Mary"},
{Key: "name", Value: "Mary"},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
_, err = m.InsertOne(context.Background(), "foo", bson.D{
{Key: "name", Value: "Mary"},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}},
}...))
_, err = m.InsertOne(context.Background(), "foo", bson.D{
{Key: "name", Value: "Mary"},
})
assert.Equal(t, errMocked, err)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
mockCollection.EXPECT().InsertOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.InsertOneResult{}, errMocked)
_, err = m.InsertOne(context.Background(), "foo", bson.D{
{Key: "name", Value: "Mary"},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mockCollection.EXPECT().InsertOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.InsertOneResult{}, nil)
_, err = m.InsertOne(context.Background(), "foo", bson.D{
{Key: "name", Value: "Mary"},
})
assert.Equal(t, errMocked, err)
} }
func TestModel_InsertOneNoCache(t *testing.T) { func TestModel_InsertOneNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) mockCollection.EXPECT().InsertOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.InsertOneResult{}, nil)
m := createModel(t, mt) resp, err := m.InsertOneNoCache(context.Background(), bson.D{
resp, err := m.InsertOneNoCache(context.Background(), bson.D{ {Key: "name", Value: "Mary"},
{Key: "name", Value: "Mary"},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
} }
func TestModel_ReplaceOne(t *testing.T) { func TestModel_ReplaceOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) assert.Nil(t, m.cache.Set("foo", "bar"))
m := createModel(t, mt) mockCollection.EXPECT().ReplaceOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
assert.Nil(t, m.cache.Set("foo", "bar")) resp, err := m.ReplaceOne(context.Background(), "foo", bson.D{}, bson.D{
resp, err := m.ReplaceOne(context.Background(), "foo", bson.D{}, bson.D{ {Key: "foo", Value: "baz"},
{Key: "foo", Value: "baz"},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
_, err = m.ReplaceOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "foo", Value: "baz"},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}},
}...))
_, err = m.ReplaceOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "foo", Value: "baz"},
})
assert.Equal(t, errMocked, err)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
mockCollection.EXPECT().ReplaceOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, errMocked)
_, err = m.ReplaceOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "foo", Value: "baz"},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mockCollection.EXPECT().ReplaceOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
_, err = m.ReplaceOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "foo", Value: "baz"},
})
assert.Equal(t, errMocked, err)
} }
func TestModel_ReplaceOneNoCache(t *testing.T) { func TestModel_ReplaceOneNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) mockCollection.EXPECT().ReplaceOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
m := createModel(t, mt) resp, err := m.ReplaceOneNoCache(context.Background(), bson.D{}, bson.D{
resp, err := m.ReplaceOneNoCache(context.Background(), bson.D{}, bson.D{ {Key: "foo", Value: "baz"},
{Key: "foo", Value: "baz"},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
} }
func TestModel_SetCache(t *testing.T) { func TestModel_SetCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
m := createModel(t, mt) mockCollection := mon.NewMockCollection(ctrl)
assert.Nil(t, m.SetCache("foo", "bar")) m := createModel(t, mockCollection)
var v string assert.Nil(t, m.SetCache("foo", "bar"))
assert.Nil(t, m.GetCache("foo", &v)) var v string
assert.Equal(t, "bar", v) assert.Nil(t, m.GetCache("foo", &v))
}) assert.Equal(t, "bar", v)
} }
func TestModel_UpdateByID(t *testing.T) { func TestModel_UpdateByID(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) assert.Nil(t, m.cache.Set("foo", "bar"))
m := createModel(t, mt) mockCollection.EXPECT().UpdateByID(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
assert.Nil(t, m.cache.Set("foo", "bar")) resp, err := m.UpdateByID(context.Background(), "foo", bson.D{}, bson.D{
resp, err := m.UpdateByID(context.Background(), "foo", bson.D{}, bson.D{ {Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
_, err = m.UpdateByID(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}},
}...))
_, err = m.UpdateByID(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Equal(t, errMocked, err)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
mockCollection.EXPECT().UpdateByID(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, errMocked)
_, err = m.UpdateByID(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mockCollection.EXPECT().UpdateByID(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
_, err = m.UpdateByID(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Equal(t, errMocked, err)
} }
func TestModel_UpdateByIDNoCache(t *testing.T) { func TestModel_UpdateByIDNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) mockCollection.EXPECT().UpdateByID(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
m := createModel(t, mt) resp, err := m.UpdateByIDNoCache(context.Background(), bson.D{}, bson.D{
resp, err := m.UpdateByIDNoCache(context.Background(), bson.D{}, bson.D{ {Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
} }
func TestModel_UpdateMany(t *testing.T) { func TestModel_UpdateMany(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) assert.Nil(t, m.cache.Set("foo", "bar"))
m := createModel(t, mt) assert.Nil(t, m.cache.Set("bar", "baz"))
assert.Nil(t, m.cache.Set("foo", "bar")) mockCollection.EXPECT().UpdateMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
assert.Nil(t, m.cache.Set("bar", "baz")) resp, err := m.UpdateMany(context.Background(), []string{"foo", "bar"}, bson.D{}, bson.D{
resp, err := m.UpdateMany(context.Background(), []string{"foo", "bar"}, bson.D{}, bson.D{ {Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
assert.True(t, m.cache.IsNotFound(m.cache.Get("bar", &v)))
_, err = m.UpdateMany(context.Background(), []string{"foo", "bar"}, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}},
}...))
_, err = m.UpdateMany(context.Background(), []string{"foo", "bar"}, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Equal(t, errMocked, err)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
assert.True(t, m.cache.IsNotFound(m.cache.Get("bar", &v)))
mockCollection.EXPECT().UpdateMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, errMocked)
_, err = m.UpdateMany(context.Background(), []string{"foo", "bar"}, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.NotNil(t, err)
m.cache = mockedCache{m.cache}
mockCollection.EXPECT().UpdateMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
_, err = m.UpdateMany(context.Background(), []string{"foo", "bar"}, bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Equal(t, errMocked, err)
} }
func TestModel_UpdateManyNoCache(t *testing.T) { func TestModel_UpdateManyNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) mockCollection.EXPECT().UpdateMany(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
m := createModel(t, mt) resp, err := m.UpdateManyNoCache(context.Background(), bson.D{}, bson.D{
resp, err := m.UpdateManyNoCache(context.Background(), bson.D{}, bson.D{ {Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
} }
func TestModel_UpdateOne(t *testing.T) { func TestModel_UpdateOne(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) assert.Nil(t, m.cache.Set("foo", "bar"))
m := createModel(t, mt) mockCollection.EXPECT().UpdateOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
assert.Nil(t, m.cache.Set("foo", "bar")) resp, err := m.UpdateOne(context.Background(), "foo", bson.D{}, bson.D{
resp, err := m.UpdateOne(context.Background(), "foo", bson.D{}, bson.D{ {Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
_, err = m.UpdateOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.NotNil(t, err)
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}},
}...))
m.cache = mockedCache{m.cache}
_, err = m.UpdateOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Equal(t, errMocked, err)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
var v string
mockCollection.EXPECT().UpdateOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, errMocked)
assert.True(t, m.cache.IsNotFound(m.cache.Get("foo", &v)))
_, err = m.UpdateOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.NotNil(t, err)
mockCollection.EXPECT().UpdateOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
m.cache = mockedCache{m.cache}
_, err = m.UpdateOne(context.Background(), "foo", bson.D{}, bson.D{
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Equal(t, errMocked, err)
} }
func TestModel_UpdateOneNoCache(t *testing.T) { func TestModel_UpdateOneNoCache(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock)) ctrl := gomock.NewController(t)
mt.Run("test", func(mt *mtest.T) { defer ctrl.Finish()
mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{ mockCollection := mon.NewMockCollection(ctrl)
{Key: "value", Value: bson.D{{Key: "foo", Value: "bar"}}}, m := createModel(t, mockCollection)
}...)) mockCollection.EXPECT().UpdateOne(gomock.Any(), gomock.Any(), gomock.Any()).Return(&mongo.UpdateResult{}, nil)
m := createModel(t, mt) resp, err := m.UpdateOneNoCache(context.Background(), bson.D{}, bson.D{
resp, err := m.UpdateOneNoCache(context.Background(), bson.D{}, bson.D{ {Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
{Key: "$set", Value: bson.D{{Key: "foo", Value: "baz"}}},
})
assert.Nil(t, err)
assert.NotNil(t, resp)
}) })
assert.Nil(t, err)
assert.NotNil(t, resp)
} }
func createModel(t *testing.T, mt *mtest.T) *Model { func createModel(t *testing.T, coll mon.Collection) *Model {
s, err := miniredis.Run() s, err := miniredis.Run()
assert.Nil(t, err) assert.Nil(t, err)
mon.Inject(mt.Name(), mt.Client)
if atomic.AddInt32(&index, 1)%2 == 0 { if atomic.AddInt32(&index, 1)%2 == 0 {
return MustNewNodeModel(mt.Name(), mt.DB.Name(), mt.Coll.Name(), redis.New(s.Addr())) return mustNewTestNodeModel(coll, redis.New(s.Addr()))
} else { } else {
return MustNewModel(mt.Name(), mt.DB.Name(), mt.Coll.Name(), cache.CacheConf{ return mustNewTestModel(coll, cache.CacheConf{
cache.NodeConf{ cache.NodeConf{
RedisConf: redis.RedisConf{ RedisConf: redis.RedisConf{
Host: s.Addr(), Host: s.Addr(),

View File

@@ -0,0 +1,19 @@
# Migrating from 1.x to 2.0
To upgrade imports of the Go Driver from v1 to v2, we recommend using [marwan-at-work/mod
](https://github.com/marwan-at-work/mod):
```
mod upgrade --mod-name=go.mongodb.org/mongo-driver
```
# Notice
After completing the mod upgrade, code changes are typically unnecessary in the vast majority of cases. However, if your project references packages including but not limited to those listed below, you'll need to manually replace them, as these libraries are no longer present in the v2 version.
```go
go.mongodb.org/mongo-driver/bson/bsonrw => go.mongodb.org/mongo-driver/v2/bson
go.mongodb.org/mongo-driver/bson/bsoncodec => go.mongodb.org/mongo-driver/v2/bson
go.mongodb.org/mongo-driver/bson/primitive => go.mongodb.org/mongo-driver/v2/bson
```
See the following resources to learn more about upgrading from version 1.x to 2.0.:
https://raw.githubusercontent.com/mongodb/mongo-go-driver/refs/heads/master/docs/migration-2.0.md

6
go.mod
View File

@@ -22,7 +22,7 @@ require (
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
go.etcd.io/etcd/api/v3 v3.5.15 go.etcd.io/etcd/api/v3 v3.5.15
go.etcd.io/etcd/client/v3 v3.5.15 go.etcd.io/etcd/client/v3 v3.5.15
go.mongodb.org/mongo-driver v1.17.4 go.mongodb.org/mongo-driver/v2 v2.2.3
go.opentelemetry.io/otel v1.24.0 go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 go.opentelemetry.io/otel/exporters/jaeger v1.17.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0
@@ -33,6 +33,7 @@ require (
go.opentelemetry.io/otel/trace v1.24.0 go.opentelemetry.io/otel/trace v1.24.0
go.uber.org/automaxprocs v1.6.0 go.uber.org/automaxprocs v1.6.0
go.uber.org/goleak v1.3.0 go.uber.org/goleak v1.3.0
go.uber.org/mock v0.4.0
golang.org/x/net v0.35.0 golang.org/x/net v0.35.0
golang.org/x/sys v0.30.0 golang.org/x/sys v0.30.0
golang.org/x/time v0.10.0 golang.org/x/time v0.10.0
@@ -68,7 +69,7 @@ require (
github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect github.com/go-openapi/swag v0.22.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v1.0.0 // indirect
github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
@@ -88,7 +89,6 @@ require (
github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect

12
go.sum
View File

@@ -66,8 +66,8 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -130,8 +130,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
@@ -202,8 +200,8 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5
go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU= go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU=
go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4= go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4=
go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU= go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU=
go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= go.mongodb.org/mongo-driver/v2 v2.2.3 h1:72uiGYXeSnUEQk37xvV9r067xzFQod4SOeAoOuq3+GM=
go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.mongodb.org/mongo-driver/v2 v2.2.3/go.mod h1:qQkDMhCGWl3FN509DfdPd4GRBLU/41zqF/k8eTRceps=
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
@@ -232,6 +230,8 @@ go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=

View File

@@ -8,9 +8,8 @@ import (
"time" "time"
{{if .Cache}}"github.com/zeromicro/go-zero/core/stores/monc"{{else}}"github.com/zeromicro/go-zero/core/stores/mon"{{end}} {{if .Cache}}"github.com/zeromicro/go-zero/core/stores/monc"{{else}}"github.com/zeromicro/go-zero/core/stores/mon"{{end}}
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/mongo"
) )
{{if .Cache}}var prefix{{.Type}}CacheKey = "{{if .Prefix}}{{.Prefix}}:{{end}}cache:{{.lowerType}}:"{{end}} {{if .Cache}}var prefix{{.Type}}CacheKey = "{{if .Prefix}}{{.Prefix}}:{{end}}cache:{{.lowerType}}:"{{end}}
@@ -33,7 +32,7 @@ func newDefault{{.Type}}Model(conn {{if .Cache}}*monc.Model{{else}}*mon.Model{{e
func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error { func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error {
if data.ID.IsZero() { if data.ID.IsZero() {
data.ID = primitive.NewObjectID() data.ID = bson.NewObjectID()
data.CreateAt = time.Now() data.CreateAt = time.Now()
data.UpdateAt = time.Now() data.UpdateAt = time.Now()
} }
@@ -44,7 +43,7 @@ func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) err
} }
func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) { func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) {
oid, err := primitive.ObjectIDFromHex(id) oid, err := bson.ObjectIDFromHex(id)
if err != nil { if err != nil {
return nil, ErrInvalidObjectId return nil, ErrInvalidObjectId
} }
@@ -70,7 +69,7 @@ func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) (*m
} }
func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) (int64, error) { func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) (int64, error) {
oid, err := primitive.ObjectIDFromHex(id) oid, err := bson.ObjectIDFromHex(id)
if err != nil { if err != nil {
return 0, ErrInvalidObjectId return 0, ErrInvalidObjectId
} }

View File

@@ -3,11 +3,11 @@ package model
import ( import (
"time" "time"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/v2/bson"
) )
type {{.Type}} struct { type {{.Type}} struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` ID bson.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
// TODO: Fill your own fields // TODO: Fill your own fields
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"` UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"` CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`