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 }