conn_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. package memcache
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. test "go-common/library/cache/memcache/test"
  7. "testing"
  8. "time"
  9. "github.com/bouk/monkey"
  10. "github.com/gogo/protobuf/proto"
  11. )
  12. var s = []string{"test", "test1"}
  13. var c Conn
  14. var item = &Item{
  15. Key: "test",
  16. Value: []byte("test"),
  17. Flags: FlagRAW,
  18. Expiration: 60,
  19. cas: 0,
  20. }
  21. var item2 = &Item{
  22. Key: "test1",
  23. Value: []byte("test"),
  24. Flags: 0,
  25. Expiration: 1000,
  26. cas: 0,
  27. }
  28. var item3 = &Item{
  29. Key: "test2",
  30. Value: []byte("0"),
  31. Flags: 0,
  32. Expiration: 60,
  33. cas: 0,
  34. }
  35. type TestItem struct {
  36. Name string
  37. Age int
  38. }
  39. func (t *TestItem) Compare(nt *TestItem) bool {
  40. return t.Name == nt.Name && t.Age == nt.Age
  41. }
  42. func prepareEnv(t *testing.T) {
  43. if c != nil {
  44. return
  45. }
  46. var err error
  47. cnop := DialConnectTimeout(time.Duration(2 * time.Second))
  48. rdop := DialReadTimeout(time.Duration(2 * time.Second))
  49. wrop := DialWriteTimeout(time.Duration(2 * time.Second))
  50. c, err = Dial("tcp", testMemcacheAddr, cnop, rdop, wrop)
  51. if err != nil {
  52. t.Errorf("Dial() error(%v)", err)
  53. t.FailNow()
  54. }
  55. c.Delete("test")
  56. c.Delete("test1")
  57. c.Delete("test2")
  58. }
  59. func TestRaw(t *testing.T) {
  60. prepareEnv(t)
  61. if err := c.Set(item); err != nil {
  62. t.Errorf("conn.Store() error(%v)", err)
  63. }
  64. }
  65. func TestAdd(t *testing.T) {
  66. var (
  67. key = "test_add"
  68. item = &Item{
  69. Key: key,
  70. Value: []byte("0"),
  71. Flags: 0,
  72. Expiration: 60,
  73. cas: 0,
  74. }
  75. )
  76. prepareEnv(t)
  77. c.Delete(key)
  78. if err := c.Add(item); err != nil {
  79. t.Errorf("c.Add() error(%v)", err)
  80. }
  81. if err := c.Add(item); err != ErrNotStored {
  82. t.Errorf("c.Add() error(%v)", err)
  83. }
  84. }
  85. func TestSetErr(t *testing.T) {
  86. prepareEnv(t)
  87. //set
  88. st := &TestItem{Name: "jsongzip", Age: 10}
  89. itemx := &Item{Key: "jsongzip", Object: st}
  90. if err := c.Set(itemx); err != ErrItem {
  91. t.Errorf("conn.Set() error(%v)", err)
  92. }
  93. }
  94. func TestSetErr2(t *testing.T) {
  95. prepareEnv(t)
  96. //set
  97. itemx := &Item{Key: "jsongzip", Flags: FlagJSON | FlagGzip}
  98. if err := c.Set(itemx); err != ErrItem {
  99. t.Errorf("conn.Set() error(%v)", err)
  100. }
  101. }
  102. func TestSetErr3(t *testing.T) {
  103. prepareEnv(t)
  104. //set
  105. itemx := &Item{Key: "jsongzip", Value: []byte("test"), Flags: FlagJSON}
  106. if err := c.Set(itemx); err != ErrItem {
  107. t.Errorf("conn.Set() error(%v)", err)
  108. }
  109. }
  110. func TestJSONGzip(t *testing.T) {
  111. prepareEnv(t)
  112. //set
  113. st := &TestItem{Name: "jsongzip", Age: 10}
  114. itemx := &Item{Key: "jsongzip", Object: st, Flags: FlagJSON | FlagGzip}
  115. if err := c.Set(itemx); err != nil {
  116. t.Errorf("conn.Set() error(%v)", err)
  117. }
  118. if r, err := c.Get("jsongzip"); err != nil {
  119. t.Errorf("conn.Get() error(%v)", err)
  120. } else {
  121. var nst TestItem
  122. scanAndCompare(t, r, st, &nst)
  123. }
  124. }
  125. func TestJSON(t *testing.T) {
  126. prepareEnv(t)
  127. st := &TestItem{Name: "json", Age: 10}
  128. itemx := &Item{Key: "json", Object: st, Flags: FlagJSON}
  129. if err := c.Set(itemx); err != nil {
  130. t.Errorf("conn.Set() error(%v)", err)
  131. }
  132. if r, err := c.Get("json"); err != nil {
  133. t.Errorf("conn.Get() error(%v)", err)
  134. } else {
  135. var nst TestItem
  136. scanAndCompare(t, r, st, &nst)
  137. }
  138. }
  139. func BenchmarkJSON(b *testing.B) {
  140. st := &TestItem{Name: "json", Age: 10}
  141. itemx := &Item{Key: "json", Object: st, Flags: FlagJSON}
  142. var (
  143. eb bytes.Buffer
  144. je *json.Encoder
  145. ir bytes.Reader
  146. jd *json.Decoder
  147. jr reader
  148. nst test.TestItem
  149. )
  150. jd = json.NewDecoder(&jr)
  151. je = json.NewEncoder(&eb)
  152. eb.Grow(_encodeBuf)
  153. // NOTE reuse bytes.Buffer internal buf
  154. // DON'T concurrency call Scan
  155. b.ResetTimer()
  156. for i := 0; i < b.N; i++ {
  157. eb.Reset()
  158. if err := je.Encode(itemx.Object); err != nil {
  159. return
  160. }
  161. data := eb.Bytes()
  162. ir.Reset(data)
  163. jr.Reset(&ir)
  164. jd.Decode(&nst)
  165. }
  166. }
  167. func BenchmarkProtobuf(b *testing.B) {
  168. st := &test.TestItem{Name: "protobuf", Age: 10}
  169. itemx := &Item{Key: "protobuf", Object: st, Flags: FlagJSON}
  170. var (
  171. eb bytes.Buffer
  172. nst test.TestItem
  173. ped *proto.Buffer
  174. )
  175. ped = proto.NewBuffer(eb.Bytes())
  176. eb.Grow(_encodeBuf)
  177. b.ResetTimer()
  178. for i := 0; i < b.N; i++ {
  179. ped.Reset()
  180. pb, ok := itemx.Object.(proto.Message)
  181. if !ok {
  182. return
  183. }
  184. if err := ped.Marshal(pb); err != nil {
  185. return
  186. }
  187. data := ped.Bytes()
  188. ped.SetBuf(data)
  189. ped.Unmarshal(&nst)
  190. }
  191. }
  192. func TestGob(t *testing.T) {
  193. prepareEnv(t)
  194. st := &TestItem{Name: "gob", Age: 10}
  195. itemx := &Item{Key: "gob", Object: st, Flags: FlagGOB}
  196. if err := c.Set(itemx); err != nil {
  197. t.Errorf("conn.Set() error(%v)", err)
  198. }
  199. if r, err := c.Get("gob"); err != nil {
  200. t.Errorf("conn.Get() error(%v)", err)
  201. } else {
  202. var nst TestItem
  203. scanAndCompare(t, r, st, &nst)
  204. }
  205. }
  206. func TestGobGzip(t *testing.T) {
  207. prepareEnv(t)
  208. st := &TestItem{Name: "gobgzip", Age: 10}
  209. itemx := &Item{Key: "gobgzip", Object: st, Flags: FlagGOB | FlagGzip}
  210. if err := c.Set(itemx); err != nil {
  211. t.Errorf("conn.Set() error(%v)", err)
  212. }
  213. if r, err := c.Get("gobgzip"); err != nil {
  214. t.Errorf("conn.Get() error(%v)", err)
  215. } else {
  216. var nst TestItem
  217. scanAndCompare(t, r, st, &nst)
  218. }
  219. }
  220. func TestGzip(t *testing.T) {
  221. prepareEnv(t)
  222. st := &TestItem{Name: "gzip", Age: 123}
  223. itemx := &Item{Key: "gzip", Object: st, Flags: FlagGOB | FlagGzip}
  224. if err := c.Set(itemx); err != nil {
  225. t.Errorf("conn.Set() error(%v)", err)
  226. }
  227. if r, err := c.Get("gzip"); err != nil {
  228. t.Errorf("conn.Get() error(%v)", err)
  229. } else {
  230. var nst TestItem
  231. scanAndCompare(t, r, st, &nst)
  232. }
  233. }
  234. func TestProtobuf(t *testing.T) {
  235. prepareEnv(t)
  236. var (
  237. err error
  238. // value []byte
  239. r *Item
  240. nst test.TestItem
  241. )
  242. st := &test.TestItem{Name: "proto", Age: 3021}
  243. itemx := &Item{Key: "proto", Object: st, Flags: FlagProtobuf}
  244. if err = c.Set(itemx); err != nil {
  245. t.Errorf("conn.Set() error(%v)", err)
  246. }
  247. if r, err = c.Get("proto"); err != nil {
  248. t.Errorf("conn.Get() error(%v)", err)
  249. }
  250. if err = c.Scan(r, &nst); err != nil {
  251. t.Errorf("decode() error(%v)", err)
  252. t.FailNow()
  253. } else {
  254. scanAndCompare2(t, r, st, &nst)
  255. }
  256. }
  257. func TestProtobufGzip(t *testing.T) {
  258. prepareEnv(t)
  259. var (
  260. err error
  261. // value []byte
  262. r *Item
  263. nst test.TestItem
  264. )
  265. st := &test.TestItem{Name: "protogzip", Age: 3021}
  266. itemx := &Item{Key: "protogzip", Object: st, Flags: FlagProtobuf | FlagGzip}
  267. if err = c.Set(itemx); err != nil {
  268. t.Errorf("conn.Set() error(%v)", err)
  269. }
  270. if r, err = c.Get("protogzip"); err != nil {
  271. t.Errorf("conn.Get() error(%v)", err)
  272. }
  273. if err = c.Scan(r, &nst); err != nil {
  274. t.Errorf("decode() error(%v)", err)
  275. t.FailNow()
  276. } else {
  277. scanAndCompare2(t, r, st, &nst)
  278. }
  279. }
  280. func TestGet(t *testing.T) {
  281. prepareEnv(t)
  282. // get
  283. if r, err := c.Get("test"); err != nil {
  284. t.Errorf("conn.Get() error(%v)", err)
  285. } else if r.Key != "test" || !bytes.Equal(r.Value, []byte("test")) || r.Flags != 0 {
  286. t.Error("conn.Get() error, value")
  287. }
  288. }
  289. func TestGetHasErr(t *testing.T) {
  290. prepareEnv(t)
  291. st := &TestItem{Name: "json", Age: 10}
  292. itemx := &Item{Key: "test", Object: st, Flags: FlagJSON}
  293. c.Set(itemx)
  294. expected := errors.New("some error")
  295. monkey.Patch(scanGetReply, func(line []byte, item *Item) (size int, err error) {
  296. return 0, expected
  297. })
  298. if _, err := c.Get("test"); err.Error() != expected.Error() {
  299. t.Errorf("conn.Get() unexpected error(%v)", err)
  300. }
  301. if err := c.(*conn).err; err.Error() != expected.Error() {
  302. t.Errorf("unexpected error(%v)", err)
  303. }
  304. }
  305. func TestGet2(t *testing.T) {
  306. prepareEnv(t)
  307. // get not exist
  308. if _, err := c.Get("not_exist"); err != ErrNotFound {
  309. t.Errorf("conn.Get() error(%v)", err)
  310. }
  311. }
  312. func TestGetMulti(t *testing.T) {
  313. prepareEnv(t)
  314. // getMulti
  315. if _, err := c.GetMulti(s); err != nil {
  316. t.Errorf("conn.GetMulti() error(%v)", err)
  317. }
  318. }
  319. func TestGetMulti2(t *testing.T) {
  320. prepareEnv(t)
  321. //set
  322. if err := c.Set(item); err != nil {
  323. t.Errorf("conn.Set() error(%v)", err)
  324. }
  325. if err := c.Set(item2); err != nil {
  326. t.Errorf("conn.Set() error(%v)", err)
  327. }
  328. if res, err := c.GetMulti(s); err != nil {
  329. t.Errorf("conn.Get() error(%v)", err)
  330. } else {
  331. if len(res) != 2 {
  332. t.Error("conn.Get() error, length", len(res))
  333. }
  334. reply := res["test"]
  335. compareItem2(t, reply, item)
  336. reply = res["test1"]
  337. compareItem2(t, reply, item2)
  338. }
  339. }
  340. func TestIncrement(t *testing.T) {
  341. // set
  342. if err := c.Set(item3); err != nil {
  343. t.Errorf("conn.Set() error(%v)", err)
  344. }
  345. // incr
  346. if d, err := c.Increment("test2", 4); err != nil {
  347. t.Errorf("conn.Set() error(%v)", err)
  348. } else {
  349. if d != 4 {
  350. t.Error("conn.IncrDecr value error")
  351. }
  352. }
  353. }
  354. func TestDecrement(t *testing.T) {
  355. // decr
  356. if d, err := c.Decrement("test2", 3); err != nil {
  357. t.Errorf("conn.Store() error(%v)", err)
  358. } else {
  359. if d != 1 {
  360. t.Error("conn.IncrDecr value error", d)
  361. }
  362. }
  363. }
  364. func TestTouch(t *testing.T) {
  365. // touch
  366. if err := c.Touch("test2", 1); err != nil {
  367. t.Errorf("conn.Touch error(%v)", err)
  368. }
  369. }
  370. func TestCompareAndSwap(t *testing.T) {
  371. prepareEnv(t)
  372. if err := c.Set(item3); err != nil {
  373. t.Errorf("conn.Set() error(%v)", err)
  374. }
  375. //cas
  376. if r, err := c.Get("test2"); err != nil {
  377. t.Errorf("conn.Get() error(%v)", err)
  378. } else {
  379. r.Value = []byte("fuck")
  380. if err := c.CompareAndSwap(r); err != nil {
  381. t.Errorf("conn.CompareAndSwap() error(%v)", err)
  382. }
  383. if r, err := c.Get("test2"); err != nil {
  384. t.Errorf("conn.Get() error(%v)", err)
  385. } else {
  386. itemx := &Item{Key: "test2", Value: []byte("fuck"), Flags: 0}
  387. compareItem2(t, r, itemx)
  388. }
  389. }
  390. }
  391. func TestReplace(t *testing.T) {
  392. prepareEnv(t)
  393. if err := c.Set(item); err != nil {
  394. t.Errorf("conn.Set() error(%v)", err)
  395. }
  396. if r, err := c.Get("test"); err != nil {
  397. t.Errorf("conn.Get() error(%v)", err)
  398. } else {
  399. r.Value = []byte("go")
  400. if err := c.Replace(r); err != nil {
  401. t.Errorf("conn.CompareAndSwap() error(%v)", err)
  402. }
  403. if r, err := c.Get("test"); err != nil {
  404. t.Errorf("conn.Get() error(%v)", err)
  405. } else {
  406. itemx := &Item{Key: "test", Value: []byte("go"), Flags: 0}
  407. compareItem2(t, r, itemx)
  408. }
  409. }
  410. }
  411. func scanAndCompare(t *testing.T, item *Item, st *TestItem, nst *TestItem) {
  412. if err := c.Scan(item, nst); err != nil {
  413. t.Errorf("decode() error(%v)", err)
  414. t.FailNow()
  415. }
  416. if !st.Compare(nst) {
  417. t.Errorf("st: %v, use of closed network connection nst: %v", st, &nst)
  418. t.FailNow()
  419. }
  420. }
  421. func scanAndCompare2(t *testing.T, item *Item, st *test.TestItem, nst *test.TestItem) {
  422. if err := c.Scan(item, nst); err != nil {
  423. t.Errorf("decode() error(%v)", err)
  424. t.FailNow()
  425. }
  426. if st.Age != nst.Age || st.Name != nst.Name {
  427. t.Errorf("st: %v, use of closed network connection nst: %v", st, &nst)
  428. t.FailNow()
  429. }
  430. }
  431. func compareItem2(t *testing.T, r, item *Item) {
  432. if r.Key != item.Key || !bytes.Equal(r.Value, item.Value) || r.Flags != item.Flags {
  433. t.Error("conn.Get() error, value")
  434. }
  435. }
  436. func Test_legalKey(t *testing.T) {
  437. type args struct {
  438. key string
  439. }
  440. tests := []struct {
  441. name string
  442. args args
  443. want bool
  444. }{
  445. {
  446. name: "test empty key",
  447. want: false,
  448. },
  449. {
  450. name: "test too large key",
  451. args: args{func() string {
  452. var data []byte
  453. for i := 0; i < 255; i++ {
  454. data = append(data, 'k')
  455. }
  456. return string(data)
  457. }()},
  458. want: false,
  459. },
  460. {
  461. name: "test invalid char",
  462. args: args{"hello world"},
  463. want: false,
  464. },
  465. {
  466. name: "test invalid char",
  467. args: args{string([]byte{0x7f})},
  468. want: false,
  469. },
  470. {
  471. name: "test normal key",
  472. args: args{"hello"},
  473. want: true,
  474. },
  475. }
  476. for _, tt := range tests {
  477. t.Run(tt.name, func(t *testing.T) {
  478. if got := legalKey(tt.args.key); got != tt.want {
  479. t.Errorf("legalKey() = %v, want %v", got, tt.want)
  480. }
  481. })
  482. }
  483. }