collection_test.go 7.9 KB

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