Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: impl/memory/memcache_test.go

Issue 1270063003: Make the rest of the services have a similar raw/user interface structure. (Closed) Base URL: https://github.com/luci/gae.git@add_datastore
Patch Set: address comments Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « impl/memory/memcache.go ('k') | impl/memory/taskqueue.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package memory 5 package memory
6 6
7 import ( 7 import (
8 "testing" 8 "testing"
9 "time" 9 "time"
10 10
11 mcS "github.com/luci/gae/service/memcache" 11 mcS "github.com/luci/gae/service/memcache"
12 "github.com/luci/luci-go/common/clock/testclock" 12 "github.com/luci/luci-go/common/clock/testclock"
13 . "github.com/smartystreets/goconvey/convey" 13 . "github.com/smartystreets/goconvey/convey"
14 "golang.org/x/net/context" 14 "golang.org/x/net/context"
15 ) 15 )
16 16
17 func TestMemcache(t *testing.T) { 17 func TestMemcache(t *testing.T) {
18 t.Parallel() 18 t.Parallel()
19 19
20 Convey("memcache", t, func() { 20 Convey("memcache", t, func() {
21 now := time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC) 21 now := time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)
22 c, tc := testclock.UseTime(context.Background(), now) 22 c, tc := testclock.UseTime(context.Background(), now)
23 c = Use(c) 23 c = Use(c)
24 mc := mcS.Get(c) 24 mc := mcS.Get(c)
25 25
26 Convey("implements MCSingleReadWriter", func() { 26 Convey("implements MCSingleReadWriter", func() {
27 Convey("Add", func() { 27 Convey("Add", func() {
28 » » » » itm := &mcItem{ 28 » » » » itm := (mc.NewItem("sup").
29 » » » » » key: "sup", 29 » » » » » SetValue([]byte("cool")).
30 » » » » » value: []byte("cool"), 30 » » » » » SetExpiration(time.Second))
31 » » » » » expiration: time.Second, 31 » » » » So(mc.Add(itm), ShouldBeNil)
32 » » » » }
33 » » » » err := mc.Add(itm)
34 » » » » So(err, ShouldBeNil)
35 Convey("which rejects objects already there", fu nc() { 32 Convey("which rejects objects already there", fu nc() {
36 » » » » » err := mc.Add(itm) 33 » » » » » So(mc.Add(itm), ShouldEqual, mcS.ErrNotS tored)
37 » » » » » So(err, ShouldEqual, mcS.ErrNotStored)
38 }) 34 })
39 }) 35 })
40 36
41 Convey("Get", func() { 37 Convey("Get", func() {
42 itm := &mcItem{ 38 itm := &mcItem{
43 key: "sup", 39 key: "sup",
44 value: []byte("cool"), 40 value: []byte("cool"),
45 expiration: time.Second, 41 expiration: time.Second,
46 } 42 }
47 » » » » err := mc.Add(itm) 43 » » » » So(mc.Add(itm), ShouldBeNil)
48 » » » » So(err, ShouldBeNil)
49 44
50 testItem := &mcItem{ 45 testItem := &mcItem{
51 key: "sup", 46 key: "sup",
52 value: []byte("cool"), 47 value: []byte("cool"),
53 CasID: 1, 48 CasID: 1,
54 } 49 }
55 » » » » i, err := mc.Get("sup") 50 » » » » getItm := &mcItem{
56 » » » » So(err, ShouldBeNil) 51 » » » » » key: "sup",
57 » » » » So(i, ShouldResemble, testItem) 52 » » » » }
53 » » » » So(mc.Get(getItm), ShouldBeNil)
54 » » » » So(getItm, ShouldResemble, testItem)
58 55
59 Convey("which can expire", func() { 56 Convey("which can expire", func() {
60 tc.Add(time.Second * 4) 57 tc.Add(time.Second * 4)
61 » » » » » i, err := mc.Get("sup") 58 » » » » » getItm := &mcItem{key: "sup"}
62 » » » » » So(err, ShouldEqual, mcS.ErrCacheMiss) 59 » » » » » So(mc.Get(getItm), ShouldEqual, mcS.ErrC acheMiss)
63 » » » » » So(i, ShouldBeNil) 60 » » » » » So(getItm, ShouldResemble, &mcItem{key: "sup"})
64 }) 61 })
65 }) 62 })
66 63
67 Convey("Delete", func() { 64 Convey("Delete", func() {
68 Convey("works if it's there", func() { 65 Convey("works if it's there", func() {
69 itm := &mcItem{ 66 itm := &mcItem{
70 key: "sup", 67 key: "sup",
71 value: []byte("cool"), 68 value: []byte("cool"),
72 expiration: time.Second, 69 expiration: time.Second,
73 } 70 }
74 » » » » » err := mc.Add(itm) 71 » » » » » So(mc.Add(itm), ShouldBeNil)
75 » » » » » So(err, ShouldBeNil)
76 72
77 » » » » » err = mc.Delete("sup") 73 » » » » » So(mc.Delete("sup"), ShouldBeNil)
78 » » » » » So(err, ShouldBeNil)
79 74
80 » » » » » i, err := mc.Get("sup") 75 » » » » » So(mc.Get(mc.NewItem("sup")), ShouldEqua l, mcS.ErrCacheMiss)
81 » » » » » So(err, ShouldEqual, mcS.ErrCacheMiss)
82 » » » » » So(i, ShouldBeNil)
83 }) 76 })
84 77
85 Convey("but not if it's not there", func() { 78 Convey("but not if it's not there", func() {
86 » » » » » err := mc.Delete("sup") 79 » » » » » So(mc.Delete("sup"), ShouldEqual, mcS.Er rCacheMiss)
87 » » » » » So(err, ShouldEqual, mcS.ErrCacheMiss)
88 }) 80 })
89 }) 81 })
90 82
91 Convey("Set", func() { 83 Convey("Set", func() {
92 itm := &mcItem{ 84 itm := &mcItem{
93 key: "sup", 85 key: "sup",
94 value: []byte("cool"), 86 value: []byte("cool"),
95 expiration: time.Second, 87 expiration: time.Second,
96 } 88 }
97 » » » » err := mc.Add(itm) 89 » » » » So(mc.Add(itm), ShouldBeNil)
98 » » » » So(err, ShouldBeNil)
99 90
100 itm.SetValue([]byte("newp")) 91 itm.SetValue([]byte("newp"))
101 » » » » err = mc.Set(itm) 92 » » » » So(mc.Set(itm), ShouldBeNil)
102 » » » » So(err, ShouldBeNil)
103 93
104 testItem := &mcItem{ 94 testItem := &mcItem{
105 key: "sup", 95 key: "sup",
106 value: []byte("newp"), 96 value: []byte("newp"),
107 CasID: 2, 97 CasID: 2,
108 } 98 }
109 » » » » i, err := mc.Get("sup") 99 » » » » getItm := mc.NewItem("sup")
100 » » » » So(mc.Get(getItm), ShouldBeNil)
101 » » » » So(getItm, ShouldResemble, testItem)
102
103 » » » » Convey("Flush works too", func() {
104 » » » » » mc.Flush()
105 » » » » » So(mc.Get(getItm), ShouldEqual, mcS.ErrC acheMiss)
106 » » » » })
107 » » » })
108
109 » » » Convey("Increment", func() {
110 » » » » val, err := mc.Increment("num", 7, 2)
110 So(err, ShouldBeNil) 111 So(err, ShouldBeNil)
111 » » » » So(i, ShouldResemble, testItem) 112 » » » » So(val, ShouldEqual, 9)
113
114 » » » » Convey("IncrementExisting", func() {
115 » » » » » val, err := mc.IncrementExisting("num", -2)
116 » » » » » So(err, ShouldBeNil)
117 » » » » » So(val, ShouldEqual, 7)
118
119 » » » » » val, err = mc.IncrementExisting("num", - 100)
120 » » » » » So(err, ShouldBeNil)
121 » » » » » So(val, ShouldEqual, 0)
122
123 » » » » » _, err = mc.IncrementExisting("noexist", 2)
124 » » » » » So(err, ShouldEqual, mcS.ErrCacheMiss)
125
126 » » » » » So(mc.Set(mc.NewItem("text").SetValue([] byte("hello world, hooman!"))), ShouldBeNil)
127
128 » » » » » _, err = mc.IncrementExisting("text", 2)
129 » » » » » So(err.Error(), ShouldContainSubstring, "got invalid current value")
130 » » » » })
112 }) 131 })
113 132
114 Convey("CompareAndSwap", func() { 133 Convey("CompareAndSwap", func() {
115 itm := mcS.Item(&mcItem{ 134 itm := mcS.Item(&mcItem{
116 key: "sup", 135 key: "sup",
117 value: []byte("cool"), 136 value: []byte("cool"),
118 expiration: time.Second * 2, 137 expiration: time.Second * 2,
119 }) 138 })
120 » » » » err := mc.Add(itm) 139 » » » » So(mc.Add(itm), ShouldBeNil)
121 » » » » So(err, ShouldBeNil)
122 140
123 Convey("works after a Get", func() { 141 Convey("works after a Get", func() {
124 » » » » » itm, err = mc.Get("sup") 142 » » » » » itm = mc.NewItem("sup")
125 » » » » » So(err, ShouldBeNil) 143 » » » » » So(mc.Get(itm), ShouldBeNil)
126 So(itm.(*mcItem).CasID, ShouldEqual, 1) 144 So(itm.(*mcItem).CasID, ShouldEqual, 1)
127 145
128 itm.SetValue([]byte("newp")) 146 itm.SetValue([]byte("newp"))
129 » » » » » err = mc.CompareAndSwap(itm) 147 » » » » » So(mc.CompareAndSwap(itm), ShouldBeNil)
130 » » » » » So(err, ShouldBeNil)
131 }) 148 })
132 149
133 Convey("but fails if you don't", func() { 150 Convey("but fails if you don't", func() {
134 itm.SetValue([]byte("newp")) 151 itm.SetValue([]byte("newp"))
135 » » » » » err = mc.CompareAndSwap(itm) 152 » » » » » So(mc.CompareAndSwap(itm), ShouldEqual, mcS.ErrCASConflict)
136 » » » » » So(err, ShouldEqual, mcS.ErrCASConflict)
137 }) 153 })
138 154
139 Convey("and fails if the item is expired/gone", func() { 155 Convey("and fails if the item is expired/gone", func() {
140 tc.Add(3 * time.Second) 156 tc.Add(3 * time.Second)
141 itm.SetValue([]byte("newp")) 157 itm.SetValue([]byte("newp"))
142 » » » » » err = mc.CompareAndSwap(itm) 158 » » » » » So(mc.CompareAndSwap(itm), ShouldEqual, mcS.ErrNotStored)
143 » » » » » So(err, ShouldEqual, mcS.ErrNotStored)
144 }) 159 })
145 }) 160 })
146 }) 161 })
147 162
148 Convey("check that the internal implementation is sane", func() { 163 Convey("check that the internal implementation is sane", func() {
149 curTime := now 164 curTime := now
150 err := mc.Add(&mcItem{ 165 err := mc.Add(&mcItem{
151 key: "sup", 166 key: "sup",
152 value: []byte("cool"), 167 value: []byte("cool"),
153 expiration: time.Second * 2, 168 expiration: time.Second * 2,
154 }) 169 })
155 170
156 » » » mci := mc.(*memcacheImpl) 171 » » » mc.Get(mc.NewItem("sup"))
172 » » » mc.Get(mc.NewItem("sup"))
173 » » » mc.Get(mc.NewItem("sup"))
174 » » » mc.Get(mc.NewItem("sup"))
175 » » » mc.Get(mc.NewItem("wot"))
176
177 » » » mci := mc.Raw().(*memcacheImpl)
157 178
158 So(err, ShouldBeNil) 179 So(err, ShouldBeNil)
159 » » » So(len(mci.data.items), ShouldEqual, 1) 180 » » » stats, err := mc.Stats()
181 » » » So(err, ShouldBeNil)
182 » » » So(stats.Items, ShouldEqual, 1)
183 » » » So(stats.Bytes, ShouldEqual, 4)
184 » » » So(stats.Hits, ShouldEqual, 4)
185 » » » So(stats.Misses, ShouldEqual, 1)
186 » » » So(stats.ByteHits, ShouldEqual, 4*4)
160 So(mci.data.casID, ShouldEqual, 1) 187 So(mci.data.casID, ShouldEqual, 1)
161 So(mci.data.items["sup"], ShouldResemble, &mcItem{ 188 So(mci.data.items["sup"], ShouldResemble, &mcItem{
162 key: "sup", 189 key: "sup",
163 value: []byte("cool"), 190 value: []byte("cool"),
164 expiration: time.Duration(curTime.Add(time.Secon d * 2).UnixNano()), 191 expiration: time.Duration(curTime.Add(time.Secon d * 2).UnixNano()),
165 CasID: 1, 192 CasID: 1,
166 }) 193 })
167 194
168 » » » el, err := mc.Get("sup") 195 » » » getItm := mc.NewItem("sup")
169 » » » So(err, ShouldBeNil) 196 » » » So(mc.Get(getItm), ShouldBeNil)
170 So(len(mci.data.items), ShouldEqual, 1) 197 So(len(mci.data.items), ShouldEqual, 1)
171 So(mci.data.casID, ShouldEqual, 1) 198 So(mci.data.casID, ShouldEqual, 1)
172 199
173 testItem := &mcItem{ 200 testItem := &mcItem{
174 key: "sup", 201 key: "sup",
175 value: []byte("cool"), 202 value: []byte("cool"),
176 CasID: 1, 203 CasID: 1,
177 } 204 }
178 » » » So(el, ShouldResemble, testItem) 205 » » » So(getItm, ShouldResemble, testItem)
179 }) 206 })
180 207
181 }) 208 })
182 } 209 }
OLDNEW
« no previous file with comments | « impl/memory/memcache.go ('k') | impl/memory/taskqueue.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698