OLD | NEW |
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 » "github.com/luci/gae" | 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 := gae.GetMC(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 := &mcItem{ |
29 key: "sup", | 29 key: "sup", |
30 value: []byte("cool"), | 30 value: []byte("cool"), |
31 expiration: time.Second, | 31 expiration: time.Second, |
32 } | 32 } |
33 err := mc.Add(itm) | 33 err := mc.Add(itm) |
34 So(err, ShouldBeNil) | 34 So(err, ShouldBeNil) |
35 Convey("which rejects objects already there", fu
nc() { | 35 Convey("which rejects objects already there", fu
nc() { |
36 err := mc.Add(itm) | 36 err := mc.Add(itm) |
37 » » » » » So(err, ShouldEqual, gae.ErrMCNotStored) | 37 » » » » » So(err, ShouldEqual, mcS.ErrNotStored) |
38 }) | 38 }) |
39 }) | 39 }) |
40 | 40 |
41 Convey("Get", func() { | 41 Convey("Get", func() { |
42 itm := &mcItem{ | 42 itm := &mcItem{ |
43 key: "sup", | 43 key: "sup", |
44 value: []byte("cool"), | 44 value: []byte("cool"), |
45 expiration: time.Second, | 45 expiration: time.Second, |
46 } | 46 } |
47 err := mc.Add(itm) | 47 err := mc.Add(itm) |
48 So(err, ShouldBeNil) | 48 So(err, ShouldBeNil) |
49 | 49 |
50 testItem := &mcItem{ | 50 testItem := &mcItem{ |
51 key: "sup", | 51 key: "sup", |
52 value: []byte("cool"), | 52 value: []byte("cool"), |
53 CasID: 1, | 53 CasID: 1, |
54 } | 54 } |
55 i, err := mc.Get("sup") | 55 i, err := mc.Get("sup") |
56 So(err, ShouldBeNil) | 56 So(err, ShouldBeNil) |
57 So(i, ShouldResemble, testItem) | 57 So(i, ShouldResemble, testItem) |
58 | 58 |
59 Convey("which can expire", func() { | 59 Convey("which can expire", func() { |
60 tc.Add(time.Second * 4) | 60 tc.Add(time.Second * 4) |
61 i, err := mc.Get("sup") | 61 i, err := mc.Get("sup") |
62 » » » » » So(err, ShouldEqual, gae.ErrMCCacheMiss) | 62 » » » » » So(err, ShouldEqual, mcS.ErrCacheMiss) |
63 So(i, ShouldBeNil) | 63 So(i, ShouldBeNil) |
64 }) | 64 }) |
65 }) | 65 }) |
66 | 66 |
67 Convey("Delete", func() { | 67 Convey("Delete", func() { |
68 Convey("works if it's there", func() { | 68 Convey("works if it's there", func() { |
69 itm := &mcItem{ | 69 itm := &mcItem{ |
70 key: "sup", | 70 key: "sup", |
71 value: []byte("cool"), | 71 value: []byte("cool"), |
72 expiration: time.Second, | 72 expiration: time.Second, |
73 } | 73 } |
74 err := mc.Add(itm) | 74 err := mc.Add(itm) |
75 So(err, ShouldBeNil) | 75 So(err, ShouldBeNil) |
76 | 76 |
77 err = mc.Delete("sup") | 77 err = mc.Delete("sup") |
78 So(err, ShouldBeNil) | 78 So(err, ShouldBeNil) |
79 | 79 |
80 i, err := mc.Get("sup") | 80 i, err := mc.Get("sup") |
81 » » » » » So(err, ShouldEqual, gae.ErrMCCacheMiss) | 81 » » » » » So(err, ShouldEqual, mcS.ErrCacheMiss) |
82 So(i, ShouldBeNil) | 82 So(i, ShouldBeNil) |
83 }) | 83 }) |
84 | 84 |
85 Convey("but not if it's not there", func() { | 85 Convey("but not if it's not there", func() { |
86 err := mc.Delete("sup") | 86 err := mc.Delete("sup") |
87 » » » » » So(err, ShouldEqual, gae.ErrMCCacheMiss) | 87 » » » » » So(err, ShouldEqual, mcS.ErrCacheMiss) |
88 }) | 88 }) |
89 }) | 89 }) |
90 | 90 |
91 Convey("Set", func() { | 91 Convey("Set", func() { |
92 itm := &mcItem{ | 92 itm := &mcItem{ |
93 key: "sup", | 93 key: "sup", |
94 value: []byte("cool"), | 94 value: []byte("cool"), |
95 expiration: time.Second, | 95 expiration: time.Second, |
96 } | 96 } |
97 err := mc.Add(itm) | 97 err := mc.Add(itm) |
98 So(err, ShouldBeNil) | 98 So(err, ShouldBeNil) |
99 | 99 |
100 itm.SetValue([]byte("newp")) | 100 itm.SetValue([]byte("newp")) |
101 err = mc.Set(itm) | 101 err = mc.Set(itm) |
102 So(err, ShouldBeNil) | 102 So(err, ShouldBeNil) |
103 | 103 |
104 testItem := &mcItem{ | 104 testItem := &mcItem{ |
105 key: "sup", | 105 key: "sup", |
106 value: []byte("newp"), | 106 value: []byte("newp"), |
107 CasID: 2, | 107 CasID: 2, |
108 } | 108 } |
109 i, err := mc.Get("sup") | 109 i, err := mc.Get("sup") |
110 So(err, ShouldBeNil) | 110 So(err, ShouldBeNil) |
111 So(i, ShouldResemble, testItem) | 111 So(i, ShouldResemble, testItem) |
112 }) | 112 }) |
113 | 113 |
114 Convey("CompareAndSwap", func() { | 114 Convey("CompareAndSwap", func() { |
115 » » » » itm := gae.MCItem(&mcItem{ | 115 » » » » itm := mcS.Item(&mcItem{ |
116 key: "sup", | 116 key: "sup", |
117 value: []byte("cool"), | 117 value: []byte("cool"), |
118 expiration: time.Second * 2, | 118 expiration: time.Second * 2, |
119 }) | 119 }) |
120 err := mc.Add(itm) | 120 err := mc.Add(itm) |
121 So(err, ShouldBeNil) | 121 So(err, ShouldBeNil) |
122 | 122 |
123 Convey("works after a Get", func() { | 123 Convey("works after a Get", func() { |
124 itm, err = mc.Get("sup") | 124 itm, err = mc.Get("sup") |
125 So(err, ShouldBeNil) | 125 So(err, ShouldBeNil) |
126 So(itm.(*mcItem).CasID, ShouldEqual, 1) | 126 So(itm.(*mcItem).CasID, ShouldEqual, 1) |
127 | 127 |
128 itm.SetValue([]byte("newp")) | 128 itm.SetValue([]byte("newp")) |
129 err = mc.CompareAndSwap(itm) | 129 err = mc.CompareAndSwap(itm) |
130 So(err, ShouldBeNil) | 130 So(err, ShouldBeNil) |
131 }) | 131 }) |
132 | 132 |
133 Convey("but fails if you don't", func() { | 133 Convey("but fails if you don't", func() { |
134 itm.SetValue([]byte("newp")) | 134 itm.SetValue([]byte("newp")) |
135 err = mc.CompareAndSwap(itm) | 135 err = mc.CompareAndSwap(itm) |
136 » » » » » So(err, ShouldEqual, gae.ErrMCCASConflic
t) | 136 » » » » » So(err, ShouldEqual, mcS.ErrCASConflict) |
137 }) | 137 }) |
138 | 138 |
139 Convey("and fails if the item is expired/gone",
func() { | 139 Convey("and fails if the item is expired/gone",
func() { |
140 tc.Add(3 * time.Second) | 140 tc.Add(3 * time.Second) |
141 itm.SetValue([]byte("newp")) | 141 itm.SetValue([]byte("newp")) |
142 err = mc.CompareAndSwap(itm) | 142 err = mc.CompareAndSwap(itm) |
143 » » » » » So(err, ShouldEqual, gae.ErrMCNotStored) | 143 » » » » » So(err, ShouldEqual, mcS.ErrNotStored) |
144 }) | 144 }) |
145 }) | 145 }) |
146 }) | 146 }) |
147 | 147 |
148 Convey("check that the internal implementation is sane", func()
{ | 148 Convey("check that the internal implementation is sane", func()
{ |
149 curTime := now | 149 curTime := now |
150 err := mc.Add(&mcItem{ | 150 err := mc.Add(&mcItem{ |
151 key: "sup", | 151 key: "sup", |
152 value: []byte("cool"), | 152 value: []byte("cool"), |
153 expiration: time.Second * 2, | 153 expiration: time.Second * 2, |
(...skipping 19 matching lines...) Expand all Loading... |
173 testItem := &mcItem{ | 173 testItem := &mcItem{ |
174 key: "sup", | 174 key: "sup", |
175 value: []byte("cool"), | 175 value: []byte("cool"), |
176 CasID: 1, | 176 CasID: 1, |
177 } | 177 } |
178 So(el, ShouldResemble, testItem) | 178 So(el, ShouldResemble, testItem) |
179 }) | 179 }) |
180 | 180 |
181 }) | 181 }) |
182 } | 182 } |
OLD | NEW |