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

Side by Side Diff: filter/dscache/dscache_test.go

Issue 1354333002: Fix memcache.Interface.Get to return a memcache.Item (Closed) Base URL: https://github.com/luci/gae.git@fix_meta_serialize
Patch Set: Created 5 years, 3 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
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 dscache 5 package dscache
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "encoding/binary" 9 "encoding/binary"
10 "errors" 10 "errors"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 Convey("Test dscache", t, func() { 60 Convey("Test dscache", t, func() {
61 c := mathrand.Set(context.Background(), rand.New(rand.NewSource( 1))) 61 c := mathrand.Set(context.Background(), rand.New(rand.NewSource( 1)))
62 clk := testclock.New(zeroTime) 62 clk := testclock.New(zeroTime)
63 c = clock.Set(c, clk) 63 c = clock.Set(c, clk)
64 c = memory.Use(c) 64 c = memory.Use(c)
65 65
66 dsUnder := datastore.Get(c) 66 dsUnder := datastore.Get(c)
67 mc := memcache.Get(c) 67 mc := memcache.Get(c)
68 68
69 itmFor := func(i int, k *datastore.Key) memcache.Item {
70 return mc.NewItem(MakeMemcacheKey(i, k))
71 }
72
73 shardsForKey := func(k *datastore.Key) int { 69 shardsForKey := func(k *datastore.Key) int {
74 last := k.Last() 70 last := k.Last()
75 if last.Kind == "shardObj" { 71 if last.Kind == "shardObj" {
76 return int(last.IntID) 72 return int(last.IntID)
77 } 73 }
78 if last.Kind == "noCacheObj" { 74 if last.Kind == "noCacheObj" {
79 return 0 75 return 0
80 } 76 }
81 return DefaultShards 77 return DefaultShards
82 } 78 }
(...skipping 18 matching lines...) Expand all
101 } 97 }
102 encoded := append([]byte{0}, serialize.ToBytes(p m)...) 98 encoded := append([]byte{0}, serialize.ToBytes(p m)...)
103 99
104 o := object{ID: 1, Value: "hi"} 100 o := object{ID: 1, Value: "hi"}
105 So(ds.Put(&o), ShouldBeNil) 101 So(ds.Put(&o), ShouldBeNil)
106 102
107 o = object{ID: 1} 103 o = object{ID: 1}
108 So(dsUnder.Get(&o), ShouldBeNil) 104 So(dsUnder.Get(&o), ShouldBeNil)
109 So(o.Value, ShouldEqual, "hi") 105 So(o.Value, ShouldEqual, "hi")
110 106
111 » » » » itm := itmFor(0, ds.KeyForObj(&o)) 107 » » » » itm, err := mc.Get(MakeMemcacheKey(0, ds.KeyForO bj(&o)))
112 » » » » So(mc.Get(itm), ShouldEqual, memcache.ErrCacheMi ss) 108 » » » » So(err, ShouldEqual, memcache.ErrCacheMiss)
113 109
114 o = object{ID: 1} 110 o = object{ID: 1}
115 So(ds.Get(&o), ShouldBeNil) 111 So(ds.Get(&o), ShouldBeNil)
116 So(o.Value, ShouldEqual, "hi") 112 So(o.Value, ShouldEqual, "hi")
117 » » » » So(mc.Get(itm), ShouldBeNil) 113
114 » » » » itm, err = mc.Get(itm.Key())
115 » » » » So(err, ShouldBeNil)
118 So(itm.Value(), ShouldResemble, encoded) 116 So(itm.Value(), ShouldResemble, encoded)
119 117
120 Convey("now we don't need the datastore!", func( ) { 118 Convey("now we don't need the datastore!", func( ) {
121 o := object{ID: 1} 119 o := object{ID: 1}
122 120
123 // delete it, bypassing the cache filter . Don't do this in production 121 // delete it, bypassing the cache filter . Don't do this in production
124 // unless you want a crappy cache. 122 // unless you want a crappy cache.
125 So(dsUnder.Delete(ds.KeyForObj(&o)), Sho uldBeNil) 123 So(dsUnder.Delete(ds.KeyForObj(&o)), Sho uldBeNil)
126 124
127 » » » » » itm := itmFor(0, ds.KeyForObj(&o)) 125 » » » » » itm, err := mc.Get(MakeMemcacheKey(0, ds .KeyForObj(&o)))
128 » » » » » So(mc.Get(itm), ShouldBeNil) 126 » » » » » So(err, ShouldBeNil)
129 So(itm.Value(), ShouldResemble, encoded) 127 So(itm.Value(), ShouldResemble, encoded)
130 128
131 So(ds.Get(&o), ShouldBeNil) 129 So(ds.Get(&o), ShouldBeNil)
132 So(o.Value, ShouldEqual, "hi") 130 So(o.Value, ShouldEqual, "hi")
133 }) 131 })
134 132
135 Convey("deleting it properly records that fact, however", func() { 133 Convey("deleting it properly records that fact, however", func() {
136 o := object{ID: 1} 134 o := object{ID: 1}
137 So(ds.Delete(ds.KeyForObj(&o)), ShouldBe Nil) 135 So(ds.Delete(ds.KeyForObj(&o)), ShouldBe Nil)
138 136
139 » » » » » itm := itmFor(0, ds.KeyForObj(&o)) 137 » » » » » itm, err := mc.Get(MakeMemcacheKey(0, ds .KeyForObj(&o)))
140 » » » » » So(mc.Get(itm), ShouldEqual, memcache.Er rCacheMiss) 138 » » » » » So(err, ShouldEqual, memcache.ErrCacheMi ss)
141 So(ds.Get(&o), ShouldEqual, datastore.Er rNoSuchEntity) 139 So(ds.Get(&o), ShouldEqual, datastore.Er rNoSuchEntity)
142 140
143 » » » » » So(mc.Get(itm), ShouldBeNil) 141 » » » » » itm, err = mc.Get(itm.Key())
142 » » » » » So(err, ShouldBeNil)
144 So(itm.Value(), ShouldResemble, []byte{} ) 143 So(itm.Value(), ShouldResemble, []byte{} )
145 144
146 // this one hits memcache 145 // this one hits memcache
147 So(ds.Get(&o), ShouldEqual, datastore.Er rNoSuchEntity) 146 So(ds.Get(&o), ShouldEqual, datastore.Er rNoSuchEntity)
148 }) 147 })
149 }) 148 })
150 149
151 Convey("compression works", func() { 150 Convey("compression works", func() {
152 o := object{ID: 2, Value: `¯\_(ツ)_/¯`} 151 o := object{ID: 2, Value: `¯\_(ツ)_/¯`}
153 data := make([]byte, 4000) 152 data := make([]byte, 4000)
154 for i := range data { 153 for i := range data {
155 const alpha = "ABCDEFGHIJKLMNOPQRSTUVWXY Zabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()" 154 const alpha = "ABCDEFGHIJKLMNOPQRSTUVWXY Zabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"
156 data[i] = alpha[i%len(alpha)] 155 data[i] = alpha[i%len(alpha)]
157 } 156 }
158 o.BigData = data 157 o.BigData = data
159 158
160 So(ds.Put(&o), ShouldBeNil) 159 So(ds.Put(&o), ShouldBeNil)
161 So(ds.Get(&o), ShouldBeNil) 160 So(ds.Get(&o), ShouldBeNil)
162 161
163 » » » » itm := itmFor(0, ds.KeyForObj(&o)) 162 » » » » itm, err := mc.Get(MakeMemcacheKey(0, ds.KeyForO bj(&o)))
164 » » » » So(mc.Get(itm), ShouldBeNil) 163 » » » » So(err, ShouldBeNil)
165 164
166 So(itm.Value()[0], ShouldEqual, ZlibCompression) 165 So(itm.Value()[0], ShouldEqual, ZlibCompression)
167 So(len(itm.Value()), ShouldEqual, 653) // a bit smaller than 4k 166 So(len(itm.Value()), ShouldEqual, 653) // a bit smaller than 4k
168 167
169 // ensure the next Get comes from the cache 168 // ensure the next Get comes from the cache
170 So(dsUnder.Delete(ds.KeyForObj(&o)), ShouldBeNil ) 169 So(dsUnder.Delete(ds.KeyForObj(&o)), ShouldBeNil )
171 170
172 o = object{ID: 2} 171 o = object{ID: 2}
173 So(ds.Get(&o), ShouldBeNil) 172 So(ds.Get(&o), ShouldBeNil)
174 So(o.Value, ShouldEqual, `¯\_(ツ)_/¯`) 173 So(o.Value, ShouldEqual, `¯\_(ツ)_/¯`)
(...skipping 16 matching lines...) Expand all
191 o := &object{ID: 1} 190 o := &object{ID: 1}
192 So(ds.Get(o), ShouldBeNil) 191 So(ds.Get(o), ShouldBeNil)
193 So(o.Value, ShouldEqual, "else") 192 So(o.Value, ShouldEqual, "else")
194 o.Value = "txn" 193 o.Value = "txn"
195 So(ds.Put(o), ShouldBeNil) 194 So(ds.Put(o), ShouldBeNil)
196 195
197 So(ds.Delete(ds.KeyForObj(&objec t{ID: 2})), ShouldBeNil) 196 So(ds.Delete(ds.KeyForObj(&objec t{ID: 2})), ShouldBeNil)
198 return nil 197 return nil
199 }, &datastore.TransactionOptions{XG: tru e}), ShouldBeNil) 198 }, &datastore.TransactionOptions{XG: tru e}), ShouldBeNil)
200 199
201 » » » » » So(mc.Get(itmFor(0, ds.KeyForObj(&object {ID: 1}))), 200 » » » » » _, err := mc.Get(MakeMemcacheKey(0, ds.K eyForObj(&object{ID: 1})))
202 » » » » » » ShouldEqual, memcache.ErrCacheMi ss) 201 » » » » » So(err, ShouldEqual, memcache.ErrCacheMi ss)
203 » » » » » So(mc.Get(itmFor(0, ds.KeyForObj(&object {ID: 2}))), 202 » » » » » _, err = mc.Get(MakeMemcacheKey(0, ds.Ke yForObj(&object{ID: 2})))
204 » » » » » » ShouldEqual, memcache.ErrCacheMi ss) 203 » » » » » So(err, ShouldEqual, memcache.ErrCacheMi ss)
205 o := &object{ID: 1} 204 o := &object{ID: 1}
206 So(ds.Get(o), ShouldBeNil) 205 So(ds.Get(o), ShouldBeNil)
207 So(o.Value, ShouldEqual, "txn") 206 So(o.Value, ShouldEqual, "txn")
208 }) 207 })
209 208
210 Convey("errors don't invalidate", func() { 209 Convey("errors don't invalidate", func() {
211 // populate an object @ ID1 210 // populate an object @ ID1
212 So(ds.Put(&object{ID: 1, Value: "somethi ng"}), ShouldBeNil) 211 So(ds.Put(&object{ID: 1, Value: "somethi ng"}), ShouldBeNil)
213 So(ds.Get(&object{ID: 1}), ShouldBeNil) 212 So(ds.Get(&object{ID: 1}), ShouldBeNil)
214 So(numMemcacheItems(), ShouldEqual, 1) 213 So(numMemcacheItems(), ShouldEqual, 1)
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 type model struct { 274 type model struct {
276 ID int64 `gae:"$id"` 275 ID int64 `gae:"$id"`
277 DSCacheExp int64 `gae:"$dscache. expiration,7"` 276 DSCacheExp int64 `gae:"$dscache. expiration,7"`
278 277
279 Value string 278 Value string
280 } 279 }
281 280
282 So(ds.Put(&model{ID: 1, Value: "mooo"}), ShouldBeNil) 281 So(ds.Put(&model{ID: 1, Value: "mooo"}), ShouldBeNil)
283 So(ds.Get(&model{ID: 1}), ShouldBeNil) 282 So(ds.Get(&model{ID: 1}), ShouldBeNil)
284 283
285 » » » » » itm := itmFor(0, ds.KeyForObj(&model{ID: 1})) 284 » » » » » itm, err := mc.Get(MakeMemcacheKey(0, ds .KeyForObj(&model{ID: 1})))
286 » » » » » So(mc.Get(itm), ShouldBeNil) 285 » » » » » So(err, ShouldBeNil)
287 286
288 clk.Add(10 * time.Second) 287 clk.Add(10 * time.Second)
289 » » » » » So(mc.Get(itm), ShouldEqual, memcache.Er rCacheMiss) 288 » » » » » _, err = mc.Get(itm.Key())
289 » » » » » So(err, ShouldEqual, memcache.ErrCacheMi ss)
290 }) 290 })
291 }) 291 })
292 292
293 Convey("screw cases", func() { 293 Convey("screw cases", func() {
294 Convey("memcache contains bogus value (simulated failed AddMulti)", func() { 294 Convey("memcache contains bogus value (simulated failed AddMulti)", func() {
295 o := &object{ID: 1, Value: "spleen"} 295 o := &object{ID: 1, Value: "spleen"}
296 So(ds.Put(o), ShouldBeNil) 296 So(ds.Put(o), ShouldBeNil)
297 297
298 sekret := []byte("I am a banana") 298 sekret := []byte("I am a banana")
299 » » » » » itm := itmFor(0, ds.KeyForObj(o)).SetVal ue(sekret) 299 » » » » » itm := mc.NewItem(MakeMemcacheKey(0, ds. KeyForObj(o))).SetValue(sekret)
300 So(mc.Set(itm), ShouldBeNil) 300 So(mc.Set(itm), ShouldBeNil)
301 301
302 o = &object{ID: 1} 302 o = &object{ID: 1}
303 So(ds.Get(o), ShouldBeNil) 303 So(ds.Get(o), ShouldBeNil)
304 So(o.Value, ShouldEqual, "spleen") 304 So(o.Value, ShouldEqual, "spleen")
305 305
306 » » » » » So(mc.Get(itm), ShouldBeNil) 306 » » » » » itm, err := mc.Get(itm.Key())
307 » » » » » So(err, ShouldBeNil)
307 So(itm.Flags(), ShouldEqual, ItemUKNONWN ) 308 So(itm.Flags(), ShouldEqual, ItemUKNONWN )
308 So(itm.Value(), ShouldResemble, sekret) 309 So(itm.Value(), ShouldResemble, sekret)
309 }) 310 })
310 311
311 Convey("memcache contains bogus value (corrupt e ntry)", func() { 312 Convey("memcache contains bogus value (corrupt e ntry)", func() {
312 o := &object{ID: 1, Value: "spleen"} 313 o := &object{ID: 1, Value: "spleen"}
313 So(ds.Put(o), ShouldBeNil) 314 So(ds.Put(o), ShouldBeNil)
314 315
315 sekret := []byte("I am a banana") 316 sekret := []byte("I am a banana")
316 » » » » » itm := (itmFor(0, ds.KeyForObj(o)). 317 » » » » » itm := (mc.NewItem(MakeMemcacheKey(0, ds .KeyForObj(o))).
317 SetValue(sekret). 318 SetValue(sekret).
318 SetFlags(uint32(ItemHasData))) 319 SetFlags(uint32(ItemHasData)))
319 So(mc.Set(itm), ShouldBeNil) 320 So(mc.Set(itm), ShouldBeNil)
320 321
321 o = &object{ID: 1} 322 o = &object{ID: 1}
322 So(ds.Get(o), ShouldBeNil) 323 So(ds.Get(o), ShouldBeNil)
323 So(o.Value, ShouldEqual, "spleen") 324 So(o.Value, ShouldEqual, "spleen")
324 325
325 » » » » » So(mc.Get(itm), ShouldBeNil) 326 » » » » » itm, err := mc.Get(itm.Key())
327 » » » » » So(err, ShouldBeNil)
326 So(itm.Flags(), ShouldEqual, ItemHasData ) 328 So(itm.Flags(), ShouldEqual, ItemHasData )
327 So(itm.Value(), ShouldResemble, sekret) 329 So(itm.Value(), ShouldResemble, sekret)
328 }) 330 })
329 331
330 Convey("other entity has the lock", func() { 332 Convey("other entity has the lock", func() {
331 o := &object{ID: 1, Value: "spleen"} 333 o := &object{ID: 1, Value: "spleen"}
332 So(ds.Put(o), ShouldBeNil) 334 So(ds.Put(o), ShouldBeNil)
333 335
334 sekret := []byte("r@vmarod!#)%9T") 336 sekret := []byte("r@vmarod!#)%9T")
335 » » » » » itm := (itmFor(0, ds.KeyForObj(o)). 337 » » » » » itm := (mc.NewItem(MakeMemcacheKey(0, ds .KeyForObj(o))).
336 SetValue(sekret). 338 SetValue(sekret).
337 SetFlags(uint32(ItemHasLock))) 339 SetFlags(uint32(ItemHasLock)))
338 So(mc.Set(itm), ShouldBeNil) 340 So(mc.Set(itm), ShouldBeNil)
339 341
340 o = &object{ID: 1} 342 o = &object{ID: 1}
341 So(ds.Get(o), ShouldBeNil) 343 So(ds.Get(o), ShouldBeNil)
342 So(o.Value, ShouldEqual, "spleen") 344 So(o.Value, ShouldEqual, "spleen")
343 345
344 » » » » » So(mc.Get(itm), ShouldBeNil) 346 » » » » » itm, err := mc.Get(itm.Key())
347 » » » » » So(err, ShouldBeNil)
345 So(itm.Flags(), ShouldEqual, ItemHasLock ) 348 So(itm.Flags(), ShouldEqual, ItemHasLock )
346 So(itm.Value(), ShouldResemble, sekret) 349 So(itm.Value(), ShouldResemble, sekret)
347 }) 350 })
348 351
349 Convey("massive entities can't be cached", func( ) { 352 Convey("massive entities can't be cached", func( ) {
350 o := &object{ID: 1, Value: "spleen"} 353 o := &object{ID: 1, Value: "spleen"}
351 mr := mathrand.Get(c) 354 mr := mathrand.Get(c)
352 numRounds := (internalValueSizeLimit / 8 ) * 2 355 numRounds := (internalValueSizeLimit / 8 ) * 2
353 buf := bytes.Buffer{} 356 buf := bytes.Buffer{}
354 for i := 0; i < numRounds; i++ { 357 for i := 0; i < numRounds; i++ {
355 So(binary.Write(&buf, binary.Lit tleEndian, mr.Int63()), ShouldBeNil) 358 So(binary.Write(&buf, binary.Lit tleEndian, mr.Int63()), ShouldBeNil)
356 } 359 }
357 o.BigData = buf.Bytes() 360 o.BigData = buf.Bytes()
358 So(ds.Put(o), ShouldBeNil) 361 So(ds.Put(o), ShouldBeNil)
359 362
360 o.BigData = nil 363 o.BigData = nil
361 So(ds.Get(o), ShouldBeNil) 364 So(ds.Get(o), ShouldBeNil)
362 365
363 » » » » » itm := itmFor(0, ds.KeyForObj(o)) 366 » » » » » itm, err := mc.Get(MakeMemcacheKey(0, ds .KeyForObj(o)))
364 » » » » » So(mc.Get(itm), ShouldBeNil) 367 » » » » » So(err, ShouldBeNil)
365 368
366 // Is locked until the next put, forcing all access to the datastore. 369 // Is locked until the next put, forcing all access to the datastore.
367 So(itm.Value(), ShouldResemble, []byte{} ) 370 So(itm.Value(), ShouldResemble, []byte{} )
368 So(itm.Flags(), ShouldEqual, ItemHasLock ) 371 So(itm.Flags(), ShouldEqual, ItemHasLock )
369 372
370 o.BigData = []byte("hi :)") 373 o.BigData = []byte("hi :)")
371 So(ds.Put(o), ShouldBeNil) 374 So(ds.Put(o), ShouldBeNil)
372 So(ds.Get(o), ShouldBeNil) 375 So(ds.Get(o), ShouldBeNil)
373 376
374 » » » » » So(mc.Get(itm), ShouldBeNil) 377 » » » » » itm, err = mc.Get(itm.Key())
378 » » » » » So(err, ShouldBeNil)
375 So(itm.Flags(), ShouldEqual, ItemHasData ) 379 So(itm.Flags(), ShouldEqual, ItemHasData )
376 }) 380 })
377 381
378 Convey("failure on Setting memcache locks is a h ard stop", func() { 382 Convey("failure on Setting memcache locks is a h ard stop", func() {
379 c, fb := featureBreaker.FilterMC(c, nil) 383 c, fb := featureBreaker.FilterMC(c, nil)
380 fb.BreakFeatures(nil, "SetMulti") 384 fb.BreakFeatures(nil, "SetMulti")
381 ds := datastore.Get(c) 385 ds := datastore.Get(c)
382 So(ds.Put(&object{ID: 1}).Error(), Shoul dContainSubstring, "SetMulti") 386 So(ds.Put(&object{ID: 1}).Error(), Shoul dContainSubstring, "SetMulti")
383 }) 387 })
384 388
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 InstanceEnabledStatic = false 452 InstanceEnabledStatic = false
449 defer func() { 453 defer func() {
450 InstanceEnabledStatic = true 454 InstanceEnabledStatic = true
451 }() 455 }()
452 456
453 c := context.Background() 457 c := context.Background()
454 newC := FilterRDS(c, nil) 458 newC := FilterRDS(c, nil)
455 So(newC, ShouldEqual, c) 459 So(newC, ShouldEqual, c)
456 }) 460 })
457 } 461 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698