collection_test.go 7.9 KB

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