github.com/lingyao2333/mo-zero@v1.4.1/core/stores/mon/collection_test.go (about)

     1  package mon
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/lingyao2333/mo-zero/core/breaker"
    10  	"github.com/lingyao2333/mo-zero/core/logx"
    11  	"github.com/lingyao2333/mo-zero/core/stringx"
    12  	"github.com/lingyao2333/mo-zero/core/timex"
    13  	"github.com/stretchr/testify/assert"
    14  	"go.mongodb.org/mongo-driver/bson"
    15  	"go.mongodb.org/mongo-driver/bson/primitive"
    16  	"go.mongodb.org/mongo-driver/mongo"
    17  	"go.mongodb.org/mongo-driver/mongo/integration/mtest"
    18  	mopt "go.mongodb.org/mongo-driver/mongo/options"
    19  )
    20  
    21  var errDummy = errors.New("dummy")
    22  
    23  func TestKeepPromise_accept(t *testing.T) {
    24  	p := new(mockPromise)
    25  	kp := keepablePromise{
    26  		promise: p,
    27  		log:     func(error) {},
    28  	}
    29  	assert.Nil(t, kp.accept(nil))
    30  	assert.Equal(t, ErrNotFound, kp.accept(ErrNotFound))
    31  }
    32  
    33  func TestKeepPromise_keep(t *testing.T) {
    34  	tests := []struct {
    35  		err      error
    36  		accepted bool
    37  		reason   string
    38  	}{
    39  		{
    40  			err:      nil,
    41  			accepted: true,
    42  			reason:   "",
    43  		},
    44  		{
    45  			err:      ErrNotFound,
    46  			accepted: true,
    47  			reason:   "",
    48  		},
    49  		{
    50  			err:      errors.New("any"),
    51  			accepted: false,
    52  			reason:   "any",
    53  		},
    54  	}
    55  
    56  	for _, test := range tests {
    57  		t.Run(stringx.RandId(), func(t *testing.T) {
    58  			p := new(mockPromise)
    59  			kp := keepablePromise{
    60  				promise: p,
    61  				log:     func(error) {},
    62  			}
    63  			assert.Equal(t, test.err, kp.keep(test.err))
    64  			assert.Equal(t, test.accepted, p.accepted)
    65  			assert.Equal(t, test.reason, p.reason)
    66  		})
    67  	}
    68  }
    69  
    70  func TestNewCollection(t *testing.T) {
    71  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
    72  	defer mt.Close()
    73  	mt.Run("test", func(mt *mtest.T) {
    74  		coll := mt.Coll
    75  		assert.NotNil(t, coll)
    76  		col := newCollection(coll, breaker.GetBreaker("localhost"))
    77  		assert.Equal(t, t.Name()+"/test", col.(*decoratedCollection).name)
    78  	})
    79  }
    80  
    81  func TestCollection_Aggregate(t *testing.T) {
    82  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
    83  	defer mt.Close()
    84  	mt.Run("test", func(mt *mtest.T) {
    85  		coll := mt.Coll
    86  		assert.NotNil(t, coll)
    87  		col := newCollection(coll, breaker.GetBreaker("localhost"))
    88  		ns := mt.Coll.Database().Name() + "." + mt.Coll.Name()
    89  		aggRes := mtest.CreateCursorResponse(1, ns, mtest.FirstBatch)
    90  		mt.AddMockResponses(aggRes)
    91  		assert.Equal(t, t.Name()+"/test", col.(*decoratedCollection).name)
    92  		cursor, err := col.Aggregate(context.Background(), mongo.Pipeline{}, mopt.Aggregate())
    93  		assert.Nil(t, err)
    94  		cursor.Close(context.Background())
    95  	})
    96  }
    97  
    98  func TestCollection_BulkWrite(t *testing.T) {
    99  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   100  	defer mt.Close()
   101  
   102  	mt.Run("test", func(mt *mtest.T) {
   103  		c := decoratedCollection{
   104  			Collection: mt.Coll,
   105  			brk:        breaker.NewBreaker(),
   106  		}
   107  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "ok", Value: 1}}...))
   108  		res, err := c.BulkWrite(context.Background(), []mongo.WriteModel{
   109  			mongo.NewInsertOneModel().SetDocument(bson.D{{Key: "foo", Value: 1}}),
   110  		})
   111  		assert.Nil(t, err)
   112  		assert.NotNil(t, res)
   113  		c.brk = new(dropBreaker)
   114  		_, err = c.BulkWrite(context.Background(), []mongo.WriteModel{
   115  			mongo.NewInsertOneModel().SetDocument(bson.D{{Key: "foo", Value: 1}}),
   116  		})
   117  		assert.Equal(t, errDummy, err)
   118  	})
   119  }
   120  
   121  func TestCollection_CountDocuments(t *testing.T) {
   122  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   123  	defer mt.Close()
   124  
   125  	mt.Run("test", func(mt *mtest.T) {
   126  		c := decoratedCollection{
   127  			Collection: mt.Coll,
   128  			brk:        breaker.NewBreaker(),
   129  		}
   130  		mt.AddMockResponses(mtest.CreateCursorResponse(
   131  			1,
   132  			"DBName.CollectionName",
   133  			mtest.FirstBatch,
   134  			bson.D{
   135  				{Key: "n", Value: 1},
   136  			}))
   137  		res, err := c.CountDocuments(context.Background(), bson.D{})
   138  		assert.Nil(t, err)
   139  		assert.Equal(t, int64(1), res)
   140  
   141  		c.brk = new(dropBreaker)
   142  		_, err = c.CountDocuments(context.Background(), bson.D{{Key: "foo", Value: 1}})
   143  		assert.Equal(t, errDummy, err)
   144  	})
   145  }
   146  
   147  func TestDecoratedCollection_DeleteMany(t *testing.T) {
   148  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   149  	defer mt.Close()
   150  
   151  	mt.Run("test", func(mt *mtest.T) {
   152  		c := decoratedCollection{
   153  			Collection: mt.Coll,
   154  			brk:        breaker.NewBreaker(),
   155  		}
   156  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...))
   157  		res, err := c.DeleteMany(context.Background(), bson.D{})
   158  		assert.Nil(t, err)
   159  		assert.Equal(t, int64(1), res.DeletedCount)
   160  
   161  		c.brk = new(dropBreaker)
   162  		_, err = c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: 1}})
   163  		assert.Equal(t, errDummy, err)
   164  	})
   165  }
   166  
   167  func TestCollection_Distinct(t *testing.T) {
   168  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   169  	defer mt.Close()
   170  
   171  	mt.Run("test", func(mt *mtest.T) {
   172  		c := decoratedCollection{
   173  			Collection: mt.Coll,
   174  			brk:        breaker.NewBreaker(),
   175  		}
   176  		mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "values", Value: []int{1}}})
   177  		resp, err := c.Distinct(context.Background(), "foo", bson.D{})
   178  		assert.Nil(t, err)
   179  		assert.Equal(t, 1, len(resp))
   180  
   181  		c.brk = new(dropBreaker)
   182  		_, err = c.Distinct(context.Background(), "foo", bson.D{{Key: "foo", Value: 1}})
   183  		assert.Equal(t, errDummy, err)
   184  	})
   185  }
   186  
   187  func TestCollection_EstimatedDocumentCount(t *testing.T) {
   188  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   189  	defer mt.Close()
   190  
   191  	mt.Run("test", func(mt *mtest.T) {
   192  		c := decoratedCollection{
   193  			Collection: mt.Coll,
   194  			brk:        breaker.NewBreaker(),
   195  		}
   196  		mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "n", Value: 1}})
   197  		res, err := c.EstimatedDocumentCount(context.Background())
   198  		assert.Nil(t, err)
   199  		assert.Equal(t, int64(1), res)
   200  
   201  		c.brk = new(dropBreaker)
   202  		_, err = c.EstimatedDocumentCount(context.Background())
   203  		assert.Equal(t, errDummy, err)
   204  	})
   205  }
   206  
   207  func TestCollection_Find(t *testing.T) {
   208  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   209  	defer mt.Close()
   210  
   211  	mt.Run("test", func(mt *mtest.T) {
   212  		c := decoratedCollection{
   213  			Collection: mt.Coll,
   214  			brk:        breaker.NewBreaker(),
   215  		}
   216  		find := mtest.CreateCursorResponse(
   217  			1,
   218  			"DBName.CollectionName",
   219  			mtest.FirstBatch,
   220  			bson.D{
   221  				{Key: "name", Value: "John"},
   222  			})
   223  		getMore := mtest.CreateCursorResponse(
   224  			1,
   225  			"DBName.CollectionName",
   226  			mtest.NextBatch,
   227  			bson.D{
   228  				{Key: "name", Value: "Mary"},
   229  			})
   230  		killCursors := mtest.CreateCursorResponse(
   231  			0,
   232  			"DBName.CollectionName",
   233  			mtest.NextBatch)
   234  		mt.AddMockResponses(find, getMore, killCursors)
   235  		filter := bson.D{{Key: "x", Value: 1}}
   236  		cursor, err := c.Find(context.Background(), filter, mopt.Find())
   237  		assert.Nil(t, err)
   238  		defer cursor.Close(context.Background())
   239  
   240  		var val []struct {
   241  			ID   primitive.ObjectID `bson:"_id"`
   242  			Name string             `bson:"name"`
   243  		}
   244  		assert.Nil(t, cursor.All(context.Background(), &val))
   245  		assert.Equal(t, 2, len(val))
   246  		assert.Equal(t, "John", val[0].Name)
   247  		assert.Equal(t, "Mary", val[1].Name)
   248  
   249  		c.brk = new(dropBreaker)
   250  		_, err = c.Find(context.Background(), filter, mopt.Find())
   251  		assert.Equal(t, errDummy, err)
   252  	})
   253  }
   254  
   255  func TestCollection_FindOne(t *testing.T) {
   256  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   257  	defer mt.Close()
   258  
   259  	mt.Run("test", func(mt *mtest.T) {
   260  		c := decoratedCollection{
   261  			Collection: mt.Coll,
   262  			brk:        breaker.NewBreaker(),
   263  		}
   264  		find := mtest.CreateCursorResponse(
   265  			1,
   266  			"DBName.CollectionName",
   267  			mtest.FirstBatch,
   268  			bson.D{
   269  				{Key: "name", Value: "John"},
   270  			})
   271  		getMore := mtest.CreateCursorResponse(
   272  			1,
   273  			"DBName.CollectionName",
   274  			mtest.NextBatch,
   275  			bson.D{
   276  				{Key: "name", Value: "Mary"},
   277  			})
   278  		killCursors := mtest.CreateCursorResponse(
   279  			0,
   280  			"DBName.CollectionName",
   281  			mtest.NextBatch)
   282  		mt.AddMockResponses(find, getMore, killCursors)
   283  		filter := bson.D{{Key: "x", Value: 1}}
   284  		resp, err := c.FindOne(context.Background(), filter)
   285  		assert.Nil(t, err)
   286  		var val struct {
   287  			ID   primitive.ObjectID `bson:"_id"`
   288  			Name string             `bson:"name"`
   289  		}
   290  		assert.Nil(t, resp.Decode(&val))
   291  		assert.Equal(t, "John", val.Name)
   292  
   293  		c.brk = new(dropBreaker)
   294  		_, err = c.FindOne(context.Background(), filter)
   295  		assert.Equal(t, errDummy, err)
   296  	})
   297  }
   298  
   299  func TestCollection_FindOneAndDelete(t *testing.T) {
   300  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   301  	defer mt.Close()
   302  
   303  	mt.Run("test", func(mt *mtest.T) {
   304  		c := decoratedCollection{
   305  			Collection: mt.Coll,
   306  			brk:        breaker.NewBreaker(),
   307  		}
   308  		filter := bson.D{}
   309  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{}...))
   310  		_, err := c.FindOneAndDelete(context.Background(), filter, mopt.FindOneAndDelete())
   311  		assert.Equal(t, mongo.ErrNoDocuments, err)
   312  
   313  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{
   314  			{Key: "value", Value: bson.D{{Key: "name", Value: "John"}}},
   315  		}...))
   316  		resp, err := c.FindOneAndDelete(context.Background(), filter, mopt.FindOneAndDelete())
   317  		assert.Nil(t, err)
   318  		var val struct {
   319  			Name string `bson:"name"`
   320  		}
   321  		assert.Nil(t, resp.Decode(&val))
   322  		assert.Equal(t, "John", val.Name)
   323  
   324  		c.brk = new(dropBreaker)
   325  		_, err = c.FindOneAndDelete(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
   326  		assert.Equal(t, errDummy, err)
   327  	})
   328  }
   329  
   330  func TestCollection_FindOneAndReplace(t *testing.T) {
   331  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   332  	defer mt.Close()
   333  
   334  	mt.Run("test", func(mt *mtest.T) {
   335  		c := decoratedCollection{
   336  			Collection: mt.Coll,
   337  			brk:        breaker.NewBreaker(),
   338  		}
   339  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{}...))
   340  		filter := bson.D{{Key: "x", Value: 1}}
   341  		replacement := bson.D{{Key: "x", Value: 2}}
   342  		opts := mopt.FindOneAndReplace().SetUpsert(true)
   343  		_, err := c.FindOneAndReplace(context.Background(), filter, replacement, opts)
   344  		assert.Equal(t, mongo.ErrNoDocuments, err)
   345  		mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "value", Value: bson.D{
   346  			{Key: "name", Value: "John"},
   347  		}}})
   348  		resp, err := c.FindOneAndReplace(context.Background(), filter, replacement, opts)
   349  		assert.Nil(t, err)
   350  		var val struct {
   351  			Name string `bson:"name"`
   352  		}
   353  		assert.Nil(t, resp.Decode(&val))
   354  		assert.Equal(t, "John", val.Name)
   355  
   356  		c.brk = new(dropBreaker)
   357  		_, err = c.FindOneAndReplace(context.Background(), filter, replacement, opts)
   358  		assert.Equal(t, errDummy, err)
   359  	})
   360  }
   361  
   362  func TestCollection_FindOneAndUpdate(t *testing.T) {
   363  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   364  	defer mt.Close()
   365  
   366  	mt.Run("test", func(mt *mtest.T) {
   367  		c := decoratedCollection{
   368  			Collection: mt.Coll,
   369  			brk:        breaker.NewBreaker(),
   370  		}
   371  		mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}})
   372  		filter := bson.D{{Key: "x", Value: 1}}
   373  		update := bson.D{{Key: "$x", Value: 2}}
   374  		opts := mopt.FindOneAndUpdate().SetUpsert(true)
   375  		_, err := c.FindOneAndUpdate(context.Background(), filter, update, opts)
   376  		assert.Equal(t, mongo.ErrNoDocuments, err)
   377  
   378  		mt.AddMockResponses(bson.D{{Key: "ok", Value: 1}, {Key: "value", Value: bson.D{
   379  			{Key: "name", Value: "John"},
   380  		}}})
   381  		resp, err := c.FindOneAndUpdate(context.Background(), filter, update, opts)
   382  		assert.Nil(t, err)
   383  		var val struct {
   384  			Name string `bson:"name"`
   385  		}
   386  		assert.Nil(t, resp.Decode(&val))
   387  		assert.Equal(t, "John", val.Name)
   388  
   389  		c.brk = new(dropBreaker)
   390  		_, err = c.FindOneAndUpdate(context.Background(), filter, update, opts)
   391  		assert.Equal(t, errDummy, err)
   392  	})
   393  }
   394  
   395  func TestCollection_InsertOne(t *testing.T) {
   396  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   397  	defer mt.Close()
   398  
   399  	mt.Run("test", func(mt *mtest.T) {
   400  		c := decoratedCollection{
   401  			Collection: mt.Coll,
   402  			brk:        breaker.NewBreaker(),
   403  		}
   404  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "ok", Value: 1}}...))
   405  		res, err := c.InsertOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
   406  		assert.Nil(t, err)
   407  		assert.NotNil(t, res)
   408  
   409  		c.brk = new(dropBreaker)
   410  		_, err = c.InsertOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
   411  		assert.Equal(t, errDummy, err)
   412  	})
   413  }
   414  
   415  func TestCollection_InsertMany(t *testing.T) {
   416  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   417  	defer mt.Close()
   418  
   419  	mt.Run("test", func(mt *mtest.T) {
   420  		c := decoratedCollection{
   421  			Collection: mt.Coll,
   422  			brk:        breaker.NewBreaker(),
   423  		}
   424  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "ok", Value: 1}}...))
   425  		res, err := c.InsertMany(context.Background(), []interface{}{
   426  			bson.D{{Key: "foo", Value: "bar"}},
   427  			bson.D{{Key: "foo", Value: "baz"}},
   428  		})
   429  		assert.Nil(t, err)
   430  		assert.NotNil(t, res)
   431  		assert.Equal(t, 2, len(res.InsertedIDs))
   432  
   433  		c.brk = new(dropBreaker)
   434  		_, err = c.InsertMany(context.Background(), []interface{}{bson.D{{Key: "foo", Value: "bar"}}})
   435  		assert.Equal(t, errDummy, err)
   436  	})
   437  }
   438  
   439  func TestCollection_DeleteOne(t *testing.T) {
   440  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   441  	defer mt.Close()
   442  
   443  	mt.Run("test", func(mt *mtest.T) {
   444  		c := decoratedCollection{
   445  			Collection: mt.Coll,
   446  			brk:        breaker.NewBreaker(),
   447  		}
   448  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...))
   449  		res, err := c.DeleteOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
   450  		assert.Nil(t, err)
   451  		assert.Equal(t, int64(1), res.DeletedCount)
   452  
   453  		c.brk = new(dropBreaker)
   454  		_, err = c.DeleteOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
   455  		assert.Equal(t, errDummy, err)
   456  	})
   457  }
   458  
   459  func TestCollection_DeleteMany(t *testing.T) {
   460  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   461  	defer mt.Close()
   462  
   463  	mt.Run("test", func(mt *mtest.T) {
   464  		c := decoratedCollection{
   465  			Collection: mt.Coll,
   466  			brk:        breaker.NewBreaker(),
   467  		}
   468  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...))
   469  		res, err := c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
   470  		assert.Nil(t, err)
   471  		assert.Equal(t, int64(1), res.DeletedCount)
   472  
   473  		c.brk = new(dropBreaker)
   474  		_, err = c.DeleteMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}})
   475  		assert.Equal(t, errDummy, err)
   476  	})
   477  }
   478  
   479  func TestCollection_ReplaceOne(t *testing.T) {
   480  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   481  	defer mt.Close()
   482  
   483  	mt.Run("test", func(mt *mtest.T) {
   484  		c := decoratedCollection{
   485  			Collection: mt.Coll,
   486  			brk:        breaker.NewBreaker(),
   487  		}
   488  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...))
   489  		res, err := c.ReplaceOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
   490  			bson.D{{Key: "foo", Value: "baz"}},
   491  		)
   492  		assert.Nil(t, err)
   493  		assert.Equal(t, int64(1), res.MatchedCount)
   494  
   495  		c.brk = new(dropBreaker)
   496  		_, err = c.ReplaceOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
   497  			bson.D{{Key: "foo", Value: "baz"}})
   498  		assert.Equal(t, errDummy, err)
   499  	})
   500  }
   501  
   502  func TestCollection_UpdateOne(t *testing.T) {
   503  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   504  	defer mt.Close()
   505  
   506  	mt.Run("test", func(mt *mtest.T) {
   507  		c := decoratedCollection{
   508  			Collection: mt.Coll,
   509  			brk:        breaker.NewBreaker(),
   510  		}
   511  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...))
   512  		resp, err := c.UpdateOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
   513  			bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
   514  		assert.Nil(t, err)
   515  		assert.Equal(t, int64(1), resp.MatchedCount)
   516  
   517  		c.brk = new(dropBreaker)
   518  		_, err = c.UpdateOne(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
   519  			bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
   520  		assert.Equal(t, errDummy, err)
   521  	})
   522  }
   523  
   524  func TestCollection_UpdateByID(t *testing.T) {
   525  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   526  	defer mt.Close()
   527  
   528  	mt.Run("test", func(mt *mtest.T) {
   529  		c := decoratedCollection{
   530  			Collection: mt.Coll,
   531  			brk:        breaker.NewBreaker(),
   532  		}
   533  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...))
   534  		resp, err := c.UpdateByID(context.Background(), primitive.NewObjectID(),
   535  			bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
   536  		assert.Nil(t, err)
   537  		assert.Equal(t, int64(1), resp.MatchedCount)
   538  
   539  		c.brk = new(dropBreaker)
   540  		_, err = c.UpdateByID(context.Background(), primitive.NewObjectID(),
   541  			bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
   542  		assert.Equal(t, errDummy, err)
   543  	})
   544  }
   545  
   546  func TestCollection_UpdateMany(t *testing.T) {
   547  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   548  	defer mt.Close()
   549  
   550  	mt.Run("test", func(mt *mtest.T) {
   551  		c := decoratedCollection{
   552  			Collection: mt.Coll,
   553  			brk:        breaker.NewBreaker(),
   554  		}
   555  		mt.AddMockResponses(mtest.CreateSuccessResponse(bson.D{{Key: "n", Value: 1}}...))
   556  		resp, err := c.UpdateMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
   557  			bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
   558  		assert.Nil(t, err)
   559  		assert.Equal(t, int64(1), resp.MatchedCount)
   560  
   561  		c.brk = new(dropBreaker)
   562  		_, err = c.UpdateMany(context.Background(), bson.D{{Key: "foo", Value: "bar"}},
   563  			bson.D{{Key: "$set", Value: bson.D{{Key: "baz", Value: "qux"}}}})
   564  		assert.Equal(t, errDummy, err)
   565  	})
   566  }
   567  
   568  func TestDecoratedCollection_LogDuration(t *testing.T) {
   569  	mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
   570  	defer mt.Close()
   571  	c := decoratedCollection{
   572  		Collection: mt.Coll,
   573  		brk:        breaker.NewBreaker(),
   574  	}
   575  
   576  	var buf strings.Builder
   577  	w := logx.NewWriter(&buf)
   578  	o := logx.Reset()
   579  	logx.SetWriter(w)
   580  
   581  	defer func() {
   582  		logx.Reset()
   583  		logx.SetWriter(o)
   584  	}()
   585  
   586  	buf.Reset()
   587  	c.logDuration(context.Background(), "foo", timex.Now(), nil, "bar")
   588  	assert.Contains(t, buf.String(), "foo")
   589  	assert.Contains(t, buf.String(), "bar")
   590  
   591  	buf.Reset()
   592  	c.logDuration(context.Background(), "foo", timex.Now(), errors.New("bar"), make(chan int))
   593  	assert.Contains(t, buf.String(), "foo")
   594  	assert.Contains(t, buf.String(), "bar")
   595  
   596  	buf.Reset()
   597  	c.logDuration(context.Background(), "foo", timex.Now(), nil, make(chan int))
   598  	assert.Contains(t, buf.String(), "foo")
   599  
   600  	buf.Reset()
   601  	c.logDuration(context.Background(), "foo", timex.Now()-slowThreshold.Load()*2,
   602  		nil, make(chan int))
   603  	assert.Contains(t, buf.String(), "foo")
   604  	assert.Contains(t, buf.String(), "slowcall")
   605  
   606  	buf.Reset()
   607  	c.logDuration(context.Background(), "foo", timex.Now()-slowThreshold.Load()*2,
   608  		errors.New("bar"), make(chan int))
   609  	assert.Contains(t, buf.String(), "foo")
   610  	assert.Contains(t, buf.String(), "bar")
   611  	assert.Contains(t, buf.String(), "slowcall")
   612  
   613  	buf.Reset()
   614  	c.logDuration(context.Background(), "foo", timex.Now()-slowThreshold.Load()*2,
   615  		errors.New("bar"))
   616  	assert.Contains(t, buf.String(), "foo")
   617  	assert.Contains(t, buf.String(), "slowcall")
   618  
   619  	buf.Reset()
   620  	c.logDuration(context.Background(), "foo", timex.Now()-slowThreshold.Load()*2, nil)
   621  	assert.Contains(t, buf.String(), "foo")
   622  	assert.Contains(t, buf.String(), "slowcall")
   623  }
   624  
   625  type mockPromise struct {
   626  	accepted bool
   627  	reason   string
   628  }
   629  
   630  func (p *mockPromise) Accept() {
   631  	p.accepted = true
   632  }
   633  
   634  func (p *mockPromise) Reject(reason string) {
   635  	p.reason = reason
   636  }
   637  
   638  type dropBreaker struct{}
   639  
   640  func (d *dropBreaker) Name() string {
   641  	return "dummy"
   642  }
   643  
   644  func (d *dropBreaker) Allow() (breaker.Promise, error) {
   645  	return nil, errDummy
   646  }
   647  
   648  func (d *dropBreaker) Do(_ func() error) error {
   649  	return nil
   650  }
   651  
   652  func (d *dropBreaker) DoWithAcceptable(_ func() error, _ breaker.Acceptable) error {
   653  	return errDummy
   654  }
   655  
   656  func (d *dropBreaker) DoWithFallback(_ func() error, _ func(err error) error) error {
   657  	return nil
   658  }
   659  
   660  func (d *dropBreaker) DoWithFallbackAcceptable(_ func() error, _ func(err error) error,
   661  	_ breaker.Acceptable) error {
   662  	return nil
   663  }