memcache_test.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Copyright 2014 Google Inc. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package memcache
  5. import (
  6. "fmt"
  7. "testing"
  8. "google.golang.org/appengine"
  9. "google.golang.org/appengine/internal/aetesting"
  10. pb "google.golang.org/appengine/internal/memcache"
  11. )
  12. var errRPC = fmt.Errorf("RPC error")
  13. func TestGetRequest(t *testing.T) {
  14. serviceCalled := false
  15. apiKey := "lyric"
  16. c := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, _ *pb.MemcacheGetResponse) error {
  17. // Test request.
  18. if n := len(req.Key); n != 1 {
  19. t.Errorf("got %d want 1", n)
  20. return nil
  21. }
  22. if k := string(req.Key[0]); k != apiKey {
  23. t.Errorf("got %q want %q", k, apiKey)
  24. }
  25. serviceCalled = true
  26. return nil
  27. })
  28. // Test the "forward" path from the API call parameters to the
  29. // protobuf request object. (The "backward" path from the
  30. // protobuf response object to the API call response,
  31. // including the error response, are handled in the next few
  32. // tests).
  33. Get(c, apiKey)
  34. if !serviceCalled {
  35. t.Error("Service was not called as expected")
  36. }
  37. }
  38. func TestGetResponseHit(t *testing.T) {
  39. key := "lyric"
  40. value := "Where the buffalo roam"
  41. c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
  42. res.Item = []*pb.MemcacheGetResponse_Item{
  43. {Key: []byte(key), Value: []byte(value)},
  44. }
  45. return nil
  46. })
  47. apiItem, err := Get(c, key)
  48. if apiItem == nil || apiItem.Key != key || string(apiItem.Value) != value {
  49. t.Errorf("got %q, %q want {%q,%q}, nil", apiItem, err, key, value)
  50. }
  51. }
  52. func TestGetResponseMiss(t *testing.T) {
  53. c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
  54. // don't fill in any of the response
  55. return nil
  56. })
  57. _, err := Get(c, "something")
  58. if err != ErrCacheMiss {
  59. t.Errorf("got %v want ErrCacheMiss", err)
  60. }
  61. }
  62. func TestGetResponseRPCError(t *testing.T) {
  63. c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
  64. return errRPC
  65. })
  66. if _, err := Get(c, "something"); err != errRPC {
  67. t.Errorf("got %v want errRPC", err)
  68. }
  69. }
  70. func TestAddRequest(t *testing.T) {
  71. var apiItem = &Item{
  72. Key: "lyric",
  73. Value: []byte("Oh, give me a home"),
  74. }
  75. serviceCalled := false
  76. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(req *pb.MemcacheSetRequest, _ *pb.MemcacheSetResponse) error {
  77. // Test request.
  78. pbItem := req.Item[0]
  79. if k := string(pbItem.Key); k != apiItem.Key {
  80. t.Errorf("got %q want %q", k, apiItem.Key)
  81. }
  82. if v := string(apiItem.Value); v != string(pbItem.Value) {
  83. t.Errorf("got %q want %q", v, string(pbItem.Value))
  84. }
  85. if p := *pbItem.SetPolicy; p != pb.MemcacheSetRequest_ADD {
  86. t.Errorf("got %v want %v", p, pb.MemcacheSetRequest_ADD)
  87. }
  88. serviceCalled = true
  89. return nil
  90. })
  91. Add(c, apiItem)
  92. if !serviceCalled {
  93. t.Error("Service was not called as expected")
  94. }
  95. }
  96. func TestAddResponseStored(t *testing.T) {
  97. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
  98. res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_STORED}
  99. return nil
  100. })
  101. if err := Add(c, &Item{}); err != nil {
  102. t.Errorf("got %v want nil", err)
  103. }
  104. }
  105. func TestAddResponseNotStored(t *testing.T) {
  106. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
  107. res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_NOT_STORED}
  108. return nil
  109. })
  110. if err := Add(c, &Item{}); err != ErrNotStored {
  111. t.Errorf("got %v want ErrNotStored", err)
  112. }
  113. }
  114. func TestAddResponseError(t *testing.T) {
  115. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
  116. res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_ERROR}
  117. return nil
  118. })
  119. if err := Add(c, &Item{}); err != ErrServerError {
  120. t.Errorf("got %v want ErrServerError", err)
  121. }
  122. }
  123. func TestAddResponseRPCError(t *testing.T) {
  124. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
  125. return errRPC
  126. })
  127. if err := Add(c, &Item{}); err != errRPC {
  128. t.Errorf("got %v want errRPC", err)
  129. }
  130. }
  131. func TestSetRequest(t *testing.T) {
  132. var apiItem = &Item{
  133. Key: "lyric",
  134. Value: []byte("Where the buffalo roam"),
  135. }
  136. serviceCalled := false
  137. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(req *pb.MemcacheSetRequest, _ *pb.MemcacheSetResponse) error {
  138. // Test request.
  139. if n := len(req.Item); n != 1 {
  140. t.Errorf("got %d want 1", n)
  141. return nil
  142. }
  143. pbItem := req.Item[0]
  144. if k := string(pbItem.Key); k != apiItem.Key {
  145. t.Errorf("got %q want %q", k, apiItem.Key)
  146. }
  147. if v := string(pbItem.Value); v != string(apiItem.Value) {
  148. t.Errorf("got %q want %q", v, string(apiItem.Value))
  149. }
  150. if p := *pbItem.SetPolicy; p != pb.MemcacheSetRequest_SET {
  151. t.Errorf("got %v want %v", p, pb.MemcacheSetRequest_SET)
  152. }
  153. serviceCalled = true
  154. return nil
  155. })
  156. Set(c, apiItem)
  157. if !serviceCalled {
  158. t.Error("Service was not called as expected")
  159. }
  160. }
  161. func TestSetResponse(t *testing.T) {
  162. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
  163. res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_STORED}
  164. return nil
  165. })
  166. if err := Set(c, &Item{}); err != nil {
  167. t.Errorf("got %v want nil", err)
  168. }
  169. }
  170. func TestSetResponseError(t *testing.T) {
  171. c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
  172. res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_ERROR}
  173. return nil
  174. })
  175. if err := Set(c, &Item{}); err != ErrServerError {
  176. t.Errorf("got %v want ErrServerError", err)
  177. }
  178. }
  179. func TestNamespaceResetting(t *testing.T) {
  180. namec := make(chan *string, 1)
  181. c0 := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
  182. namec <- req.NameSpace
  183. return errRPC
  184. })
  185. // Check that wrapping c0 in a namespace twice works correctly.
  186. c1, err := appengine.Namespace(c0, "A")
  187. if err != nil {
  188. t.Fatalf("appengine.Namespace: %v", err)
  189. }
  190. c2, err := appengine.Namespace(c1, "") // should act as the original context
  191. if err != nil {
  192. t.Fatalf("appengine.Namespace: %v", err)
  193. }
  194. Get(c0, "key")
  195. if ns := <-namec; ns != nil {
  196. t.Errorf(`Get with c0: ns = %q, want nil`, *ns)
  197. }
  198. Get(c1, "key")
  199. if ns := <-namec; ns == nil {
  200. t.Error(`Get with c1: ns = nil, want "A"`)
  201. } else if *ns != "A" {
  202. t.Errorf(`Get with c1: ns = %q, want "A"`, *ns)
  203. }
  204. Get(c2, "key")
  205. if ns := <-namec; ns != nil {
  206. t.Errorf(`Get with c2: ns = %q, want nil`, *ns)
  207. }
  208. }
  209. func TestGetMultiEmpty(t *testing.T) {
  210. serviceCalled := false
  211. c := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, _ *pb.MemcacheGetResponse) error {
  212. serviceCalled = true
  213. return nil
  214. })
  215. // Test that the Memcache service is not called when
  216. // GetMulti is passed an empty slice of keys.
  217. GetMulti(c, []string{})
  218. if serviceCalled {
  219. t.Error("Service was called but should not have been")
  220. }
  221. }