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

     1  package mongo
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/globalsign/mgo"
    10  	"github.com/golang/mock/gomock"
    11  	"github.com/lingyao2333/mo-zero/core/breaker"
    12  	"github.com/lingyao2333/mo-zero/core/logx"
    13  	"github.com/lingyao2333/mo-zero/core/stores/mongo/internal"
    14  	"github.com/lingyao2333/mo-zero/core/stringx"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  var errDummy = errors.New("dummy")
    19  
    20  func TestKeepPromise_accept(t *testing.T) {
    21  	p := new(mockPromise)
    22  	kp := keepablePromise{
    23  		promise: p,
    24  		log:     func(error) {},
    25  	}
    26  	assert.Nil(t, kp.accept(nil))
    27  	assert.Equal(t, mgo.ErrNotFound, kp.accept(mgo.ErrNotFound))
    28  }
    29  
    30  func TestKeepPromise_keep(t *testing.T) {
    31  	tests := []struct {
    32  		err      error
    33  		accepted bool
    34  		reason   string
    35  	}{
    36  		{
    37  			err:      nil,
    38  			accepted: true,
    39  			reason:   "",
    40  		},
    41  		{
    42  			err:      mgo.ErrNotFound,
    43  			accepted: true,
    44  			reason:   "",
    45  		},
    46  		{
    47  			err:      errors.New("any"),
    48  			accepted: false,
    49  			reason:   "any",
    50  		},
    51  	}
    52  
    53  	for _, test := range tests {
    54  		t.Run(stringx.RandId(), func(t *testing.T) {
    55  			p := new(mockPromise)
    56  			kp := keepablePromise{
    57  				promise: p,
    58  				log:     func(error) {},
    59  			}
    60  			assert.Equal(t, test.err, kp.keep(test.err))
    61  			assert.Equal(t, test.accepted, p.accepted)
    62  			assert.Equal(t, test.reason, p.reason)
    63  		})
    64  	}
    65  }
    66  
    67  func TestNewCollection(t *testing.T) {
    68  	col := newCollection(&mgo.Collection{
    69  		Database: nil,
    70  		Name:     "foo",
    71  		FullName: "bar",
    72  	}, breaker.GetBreaker("localhost"))
    73  	assert.Equal(t, "bar", col.(*decoratedCollection).name)
    74  }
    75  
    76  func TestCollectionFind(t *testing.T) {
    77  	ctrl := gomock.NewController(t)
    78  	defer ctrl.Finish()
    79  
    80  	var query mgo.Query
    81  	col := internal.NewMockMgoCollection(ctrl)
    82  	col.EXPECT().Find(gomock.Any()).Return(&query)
    83  	c := decoratedCollection{
    84  		collection: col,
    85  		brk:        breaker.NewBreaker(),
    86  	}
    87  	actual := c.Find(nil)
    88  	switch v := actual.(type) {
    89  	case promisedQuery:
    90  		assert.Equal(t, &query, v.Query)
    91  		assert.Equal(t, errDummy, v.promise.keep(errDummy))
    92  	default:
    93  		t.Fail()
    94  	}
    95  	c.brk = new(dropBreaker)
    96  	actual = c.Find(nil)
    97  	assert.Equal(t, rejectedQuery{}, actual)
    98  }
    99  
   100  func TestCollectionFindId(t *testing.T) {
   101  	ctrl := gomock.NewController(t)
   102  	defer ctrl.Finish()
   103  
   104  	var query mgo.Query
   105  	col := internal.NewMockMgoCollection(ctrl)
   106  	col.EXPECT().FindId(gomock.Any()).Return(&query)
   107  	c := decoratedCollection{
   108  		collection: col,
   109  		brk:        breaker.NewBreaker(),
   110  	}
   111  	actual := c.FindId(nil)
   112  	switch v := actual.(type) {
   113  	case promisedQuery:
   114  		assert.Equal(t, &query, v.Query)
   115  		assert.Equal(t, errDummy, v.promise.keep(errDummy))
   116  	default:
   117  		t.Fail()
   118  	}
   119  	c.brk = new(dropBreaker)
   120  	actual = c.FindId(nil)
   121  	assert.Equal(t, rejectedQuery{}, actual)
   122  }
   123  
   124  func TestCollectionInsert(t *testing.T) {
   125  	ctrl := gomock.NewController(t)
   126  	defer ctrl.Finish()
   127  
   128  	col := internal.NewMockMgoCollection(ctrl)
   129  	col.EXPECT().Insert(nil, nil).Return(errDummy)
   130  	c := decoratedCollection{
   131  		collection: col,
   132  		brk:        breaker.NewBreaker(),
   133  	}
   134  	err := c.Insert(nil, nil)
   135  	assert.Equal(t, errDummy, err)
   136  	c.brk = new(dropBreaker)
   137  	err = c.Insert(nil, nil)
   138  	assert.Equal(t, errDummy, err)
   139  }
   140  
   141  func TestCollectionPipe(t *testing.T) {
   142  	ctrl := gomock.NewController(t)
   143  	defer ctrl.Finish()
   144  
   145  	var pipe mgo.Pipe
   146  	col := internal.NewMockMgoCollection(ctrl)
   147  	col.EXPECT().Pipe(gomock.Any()).Return(&pipe)
   148  	c := decoratedCollection{
   149  		collection: col,
   150  		brk:        breaker.NewBreaker(),
   151  	}
   152  	actual := c.Pipe(nil)
   153  	switch v := actual.(type) {
   154  	case promisedPipe:
   155  		assert.Equal(t, &pipe, v.Pipe)
   156  		assert.Equal(t, errDummy, v.promise.keep(errDummy))
   157  	default:
   158  		t.Fail()
   159  	}
   160  	c.brk = new(dropBreaker)
   161  	actual = c.Pipe(nil)
   162  	assert.Equal(t, rejectedPipe{}, actual)
   163  }
   164  
   165  func TestCollectionRemove(t *testing.T) {
   166  	ctrl := gomock.NewController(t)
   167  	defer ctrl.Finish()
   168  
   169  	col := internal.NewMockMgoCollection(ctrl)
   170  	col.EXPECT().Remove(gomock.Any()).Return(errDummy)
   171  	c := decoratedCollection{
   172  		collection: col,
   173  		brk:        breaker.NewBreaker(),
   174  	}
   175  	err := c.Remove(nil)
   176  	assert.Equal(t, errDummy, err)
   177  	c.brk = new(dropBreaker)
   178  	err = c.Remove(nil)
   179  	assert.Equal(t, errDummy, err)
   180  }
   181  
   182  func TestCollectionRemoveAll(t *testing.T) {
   183  	ctrl := gomock.NewController(t)
   184  	defer ctrl.Finish()
   185  
   186  	col := internal.NewMockMgoCollection(ctrl)
   187  	col.EXPECT().RemoveAll(gomock.Any()).Return(nil, errDummy)
   188  	c := decoratedCollection{
   189  		collection: col,
   190  		brk:        breaker.NewBreaker(),
   191  	}
   192  	_, err := c.RemoveAll(nil)
   193  	assert.Equal(t, errDummy, err)
   194  	c.brk = new(dropBreaker)
   195  	_, err = c.RemoveAll(nil)
   196  	assert.Equal(t, errDummy, err)
   197  }
   198  
   199  func TestCollectionRemoveId(t *testing.T) {
   200  	ctrl := gomock.NewController(t)
   201  	defer ctrl.Finish()
   202  
   203  	col := internal.NewMockMgoCollection(ctrl)
   204  	col.EXPECT().RemoveId(gomock.Any()).Return(errDummy)
   205  	c := decoratedCollection{
   206  		collection: col,
   207  		brk:        breaker.NewBreaker(),
   208  	}
   209  	err := c.RemoveId(nil)
   210  	assert.Equal(t, errDummy, err)
   211  	c.brk = new(dropBreaker)
   212  	err = c.RemoveId(nil)
   213  	assert.Equal(t, errDummy, err)
   214  }
   215  
   216  func TestCollectionUpdate(t *testing.T) {
   217  	ctrl := gomock.NewController(t)
   218  	defer ctrl.Finish()
   219  
   220  	col := internal.NewMockMgoCollection(ctrl)
   221  	col.EXPECT().Update(gomock.Any(), gomock.Any()).Return(errDummy)
   222  	c := decoratedCollection{
   223  		collection: col,
   224  		brk:        breaker.NewBreaker(),
   225  	}
   226  	err := c.Update(nil, nil)
   227  	assert.Equal(t, errDummy, err)
   228  	c.brk = new(dropBreaker)
   229  	err = c.Update(nil, nil)
   230  	assert.Equal(t, errDummy, err)
   231  }
   232  
   233  func TestCollectionUpdateId(t *testing.T) {
   234  	ctrl := gomock.NewController(t)
   235  	defer ctrl.Finish()
   236  
   237  	col := internal.NewMockMgoCollection(ctrl)
   238  	col.EXPECT().UpdateId(gomock.Any(), gomock.Any()).Return(errDummy)
   239  	c := decoratedCollection{
   240  		collection: col,
   241  		brk:        breaker.NewBreaker(),
   242  	}
   243  	err := c.UpdateId(nil, nil)
   244  	assert.Equal(t, errDummy, err)
   245  	c.brk = new(dropBreaker)
   246  	err = c.UpdateId(nil, nil)
   247  	assert.Equal(t, errDummy, err)
   248  }
   249  
   250  func TestCollectionUpsert(t *testing.T) {
   251  	ctrl := gomock.NewController(t)
   252  	defer ctrl.Finish()
   253  
   254  	col := internal.NewMockMgoCollection(ctrl)
   255  	col.EXPECT().Upsert(gomock.Any(), gomock.Any()).Return(nil, errDummy)
   256  	c := decoratedCollection{
   257  		collection: col,
   258  		brk:        breaker.NewBreaker(),
   259  	}
   260  	_, err := c.Upsert(nil, nil)
   261  	assert.Equal(t, errDummy, err)
   262  	c.brk = new(dropBreaker)
   263  	_, err = c.Upsert(nil, nil)
   264  	assert.Equal(t, errDummy, err)
   265  }
   266  
   267  func Test_logDuration(t *testing.T) {
   268  	ctrl := gomock.NewController(t)
   269  	defer ctrl.Finish()
   270  
   271  	col := internal.NewMockMgoCollection(ctrl)
   272  	c := decoratedCollection{
   273  		collection: col,
   274  		brk:        breaker.NewBreaker(),
   275  	}
   276  
   277  	var buf strings.Builder
   278  	w := logx.NewWriter(&buf)
   279  	o := logx.Reset()
   280  	logx.SetWriter(w)
   281  
   282  	defer func() {
   283  		logx.Reset()
   284  		logx.SetWriter(o)
   285  	}()
   286  
   287  	buf.Reset()
   288  	c.logDuration("foo", time.Millisecond, nil, "bar")
   289  	assert.Contains(t, buf.String(), "foo")
   290  	assert.Contains(t, buf.String(), "bar")
   291  
   292  	buf.Reset()
   293  	c.logDuration("foo", time.Millisecond, errors.New("bar"), make(chan int))
   294  	assert.Contains(t, buf.String(), "bar")
   295  
   296  	buf.Reset()
   297  	c.logDuration("foo", slowThreshold.Load()+time.Millisecond, errors.New("bar"))
   298  	assert.Contains(t, buf.String(), "bar")
   299  	assert.Contains(t, buf.String(), "slowcall")
   300  
   301  	buf.Reset()
   302  	c.logDuration("foo", slowThreshold.Load()+time.Millisecond, nil)
   303  	assert.Contains(t, buf.String(), "foo")
   304  	assert.Contains(t, buf.String(), "slowcall")
   305  }
   306  
   307  type mockPromise struct {
   308  	accepted bool
   309  	reason   string
   310  }
   311  
   312  func (p *mockPromise) Accept() {
   313  	p.accepted = true
   314  }
   315  
   316  func (p *mockPromise) Reject(reason string) {
   317  	p.reason = reason
   318  }
   319  
   320  type dropBreaker struct{}
   321  
   322  func (d *dropBreaker) Name() string {
   323  	return "dummy"
   324  }
   325  
   326  func (d *dropBreaker) Allow() (breaker.Promise, error) {
   327  	return nil, errDummy
   328  }
   329  
   330  func (d *dropBreaker) Do(req func() error) error {
   331  	return nil
   332  }
   333  
   334  func (d *dropBreaker) DoWithAcceptable(req func() error, acceptable breaker.Acceptable) error {
   335  	return errDummy
   336  }
   337  
   338  func (d *dropBreaker) DoWithFallback(req func() error, fallback func(err error) error) error {
   339  	return nil
   340  }
   341  
   342  func (d *dropBreaker) DoWithFallbackAcceptable(req func() error, fallback func(err error) error,
   343  	acceptable breaker.Acceptable) error {
   344  	return nil
   345  }