OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 package dscache | |
6 | |
7 import ( | |
8 "fmt" | |
9 "math/rand" | |
10 "testing" | |
11 "time" | |
12 | |
13 "github.com/luci/gae/impl/memory" | |
14 "github.com/luci/gae/service/datastore" | |
15 "github.com/luci/gae/service/memcache" | |
16 "github.com/luci/luci-go/common/clock" | |
17 "github.com/luci/luci-go/common/clock/testclock" | |
18 "github.com/luci/luci-go/common/mathrand" | |
19 . "github.com/smartystreets/goconvey/convey" | |
20 "golang.org/x/net/context" | |
21 ) | |
22 | |
23 type object struct { | |
24 ID int64 `gae:"$id"` | |
25 | |
26 Value string | |
27 } | |
28 | |
29 func TestDSCache(t *testing.T) { | |
30 t.Parallel() | |
31 | |
32 zeroTime, err := time.Parse("2006-01-02T15:04:05.999999999Z", "2006-01-0 2T15:04:05.999999999Z") | |
33 if err != nil { | |
34 panic(err) | |
35 } | |
36 | |
37 Convey("Test dscache", t, func() { | |
38 c := mathrand.Set(context.Background(), rand.New(rand.NewSource( 1))) | |
39 clk := testclock.New(zeroTime) | |
40 c = clock.Set(c, clk) | |
41 c = memory.Use(c) | |
42 dsUnder := datastore.Get(c) | |
43 ds := datastore.Get(FilterRDS(c)) | |
44 mc := memcache.Get(c) | |
45 | |
46 itmFor := func(i int, k datastore.Key) memcache.Item { | |
47 return mc.NewItem(fmt.Sprintf(KeyFormat, i, mkKeySuffix( k))) | |
48 } | |
49 | |
50 So(dsUnder, ShouldNotBeNil) | |
51 So(ds, ShouldNotBeNil) | |
52 So(mc, ShouldNotBeNil) | |
53 | |
54 Convey("basically works", func() { | |
55 o := object{ID: 1, Value: "hi"} | |
56 So(ds.Put(&o), ShouldBeNil) | |
57 | |
58 o = object{ID: 1} | |
59 So(dsUnder.Get(&o), ShouldBeNil) | |
60 So(o.Value, ShouldEqual, "hi") | |
61 | |
62 itm := itmFor(0, ds.KeyForObj(&o)) | |
63 So(mc.Get(itm), ShouldEqual, memcache.ErrCacheMiss) | |
64 | |
65 o = object{ID: 1} | |
66 So(ds.Get(&o), ShouldBeNil) | |
67 So(o.Value, ShouldEqual, "hi") | |
68 So(mc.Get(itm), ShouldBeNil) | |
69 So(itm.Value(), ShouldResemble, | |
70 []byte("\x00\x80\x80W1[\x8fW(\x80\x80\x06i5@")) | |
71 | |
72 Convey("now we don't need the datastore!", func() { | |
73 o := object{ID: 1} | |
74 | |
75 // delete it, bypassing the cache filter. Don't do this in production | |
76 // unless you want a crappy cache. | |
77 So(dsUnder.Delete(ds.KeyForObj(&o)), ShouldBeNil ) | |
78 | |
79 itm := itmFor(0, ds.KeyForObj(&o)) | |
80 So(mc.Get(itm), ShouldBeNil) | |
81 So(itm.Value(), ShouldResemble, | |
82 []byte("\x00\x80\x80W1[\x8fW(\x80\x80\x0 6i5@")) | |
iannucci
2015/08/04 05:26:17
for reference, the equivalent gob encoding is 57 b
| |
83 | |
84 So(ds.Get(&o), ShouldBeNil) | |
85 So(o.Value, ShouldEqual, "hi") | |
86 }) | |
87 | |
88 Convey("deleting it properly records that", func() { | |
89 o := object{ID: 1} | |
90 So(ds.Delete(ds.KeyForObj(&o)), ShouldBeNil) | |
91 | |
92 itm := itmFor(0, ds.KeyForObj(&o)) | |
93 So(mc.Get(itm), ShouldEqual, memcache.ErrCacheMi ss) | |
94 So(ds.Get(&o), ShouldEqual, datastore.ErrNoSuchE ntity) | |
95 | |
96 So(mc.Get(itm), ShouldBeNil) | |
97 So(itm.Value(), ShouldResemble, []byte{}) | |
98 | |
99 // this one hits memcache | |
100 So(ds.Get(&o), ShouldEqual, datastore.ErrNoSuchE ntity) | |
101 }) | |
102 }) | |
103 }) | |
104 } | |
OLD | NEW |