OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package count | 5 package count |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "testing" | 9 "testing" |
10 | 10 |
11 "github.com/luci/gae/filter/featureBreaker" | 11 "github.com/luci/gae/filter/featureBreaker" |
12 "github.com/luci/gae/impl/memory" | 12 "github.com/luci/gae/impl/memory" |
13 » "github.com/luci/gae/service/datastore" | 13 » ds "github.com/luci/gae/service/datastore" |
14 "github.com/luci/gae/service/info" | 14 "github.com/luci/gae/service/info" |
15 "github.com/luci/gae/service/mail" | 15 "github.com/luci/gae/service/mail" |
16 "github.com/luci/gae/service/memcache" | 16 "github.com/luci/gae/service/memcache" |
17 "github.com/luci/gae/service/taskqueue" | 17 "github.com/luci/gae/service/taskqueue" |
18 "github.com/luci/gae/service/user" | 18 "github.com/luci/gae/service/user" |
19 . "github.com/luci/luci-go/common/testing/assertions" | 19 . "github.com/luci/luci-go/common/testing/assertions" |
20 . "github.com/smartystreets/goconvey/convey" | 20 . "github.com/smartystreets/goconvey/convey" |
21 "golang.org/x/net/context" | 21 "golang.org/x/net/context" |
22 ) | 22 ) |
23 | 23 |
(...skipping 22 matching lines...) Expand all Loading... |
46 func TestCount(t *testing.T) { | 46 func TestCount(t *testing.T) { |
47 t.Parallel() | 47 t.Parallel() |
48 | 48 |
49 Convey("Test Count filter", t, func() { | 49 Convey("Test Count filter", t, func() { |
50 c, fb := featureBreaker.FilterRDS(memory.Use(context.Background(
)), nil) | 50 c, fb := featureBreaker.FilterRDS(memory.Use(context.Background(
)), nil) |
51 c, ctr := FilterRDS(c) | 51 c, ctr := FilterRDS(c) |
52 | 52 |
53 So(c, ShouldNotBeNil) | 53 So(c, ShouldNotBeNil) |
54 So(ctr, ShouldNotBeNil) | 54 So(ctr, ShouldNotBeNil) |
55 | 55 |
56 » » ds := datastore.Get(c) | 56 » » vals := []ds.PropertyMap{{ |
57 » » vals := []datastore.PropertyMap{{ | 57 » » » "Val": ds.MkProperty(100), |
58 » » » "Val": datastore.MkProperty(100), | 58 » » » "$key": ds.MkPropertyNI(ds.NewKey(c, "Kind", "", 1, nil)
), |
59 » » » "$key": datastore.MkPropertyNI(ds.NewKey("Kind", "", 1,
nil)), | |
60 }} | 59 }} |
61 | 60 |
62 Convey("Calling a ds function should reflect in counter", func()
{ | 61 Convey("Calling a ds function should reflect in counter", func()
{ |
63 » » » So(ds.PutMulti(vals), ShouldBeNil) | 62 » » » So(ds.Put(c, vals), ShouldBeNil) |
64 So(ctr.PutMulti.Successes(), ShouldEqual, 1) | 63 So(ctr.PutMulti.Successes(), ShouldEqual, 1) |
65 | 64 |
66 Convey("effects are cumulative", func() { | 65 Convey("effects are cumulative", func() { |
67 » » » » So(ds.PutMulti(vals), ShouldBeNil) | 66 » » » » So(ds.Put(c, vals), ShouldBeNil) |
68 So(ctr.PutMulti.Successes(), ShouldEqual, 2) | 67 So(ctr.PutMulti.Successes(), ShouldEqual, 2) |
69 | 68 |
70 Convey("even within transactions", func() { | 69 Convey("even within transactions", func() { |
71 » » » » » die(ds.RunInTransaction(func(c context.C
ontext) error { | 70 » » » » » die(ds.RunInTransaction(c, func(c contex
t.Context) error { |
72 » » » » » » ds := datastore.Get(c) | 71 » » » » » » So(ds.Put(c, append(vals, vals[0
])), ShouldBeNil) |
73 » » » » » » So(ds.PutMulti(append(vals, vals
[0])), ShouldBeNil) | |
74 return nil | 72 return nil |
75 }, nil)) | 73 }, nil)) |
76 }) | 74 }) |
77 }) | 75 }) |
78 }) | 76 }) |
79 | 77 |
80 Convey("errors count against errors", func() { | 78 Convey("errors count against errors", func() { |
81 fb.BreakFeatures(nil, "GetMulti") | 79 fb.BreakFeatures(nil, "GetMulti") |
82 | 80 |
83 » » » So(ds.GetMulti(vals), ShouldErrLike, `"GetMulti" is brok
en`) | 81 » » » So(ds.Get(c, vals), ShouldErrLike, `"GetMulti" is broken
`) |
84 So(ctr.GetMulti.Errors(), ShouldEqual, 1) | 82 So(ctr.GetMulti.Errors(), ShouldEqual, 1) |
85 | 83 |
86 fb.UnbreakFeatures("GetMulti") | 84 fb.UnbreakFeatures("GetMulti") |
87 | 85 |
88 » » » So(ds.PutMulti(vals), ShouldBeNil) | 86 » » » So(ds.Put(c, vals), ShouldBeNil) |
89 | 87 |
90 » » » die(ds.GetMulti(vals)) | 88 » » » die(ds.Get(c, vals)) |
91 So(ctr.GetMulti.Errors(), ShouldEqual, 1) | 89 So(ctr.GetMulti.Errors(), ShouldEqual, 1) |
92 So(ctr.GetMulti.Successes(), ShouldEqual, 1) | 90 So(ctr.GetMulti.Successes(), ShouldEqual, 1) |
93 So(ctr.GetMulti.Total(), ShouldEqual, 2) | 91 So(ctr.GetMulti.Total(), ShouldEqual, 2) |
94 }) | 92 }) |
95 | 93 |
96 Convey(`datastore.Stop does not count as an error`, func() { | 94 Convey(`datastore.Stop does not count as an error`, func() { |
97 » » » fb.BreakFeatures(datastore.Stop, "GetMulti") | 95 » » » fb.BreakFeatures(ds.Stop, "GetMulti") |
98 | 96 |
99 » » » So(ds.GetMulti(vals), ShouldBeNil) | 97 » » » So(ds.Get(c, vals), ShouldBeNil) |
100 So(ctr.GetMulti.Successes(), ShouldEqual, 1) | 98 So(ctr.GetMulti.Successes(), ShouldEqual, 1) |
101 So(ctr.GetMulti.Errors(), ShouldEqual, 0) | 99 So(ctr.GetMulti.Errors(), ShouldEqual, 0) |
102 So(ctr.GetMulti.Total(), ShouldEqual, 1) | 100 So(ctr.GetMulti.Total(), ShouldEqual, 1) |
103 }) | 101 }) |
104 }) | 102 }) |
105 | 103 |
106 Convey("works for memcache", t, func() { | 104 Convey("works for memcache", t, func() { |
107 c, ctr := FilterMC(memory.Use(context.Background())) | 105 c, ctr := FilterMC(memory.Use(context.Background())) |
108 So(c, ShouldNotBeNil) | 106 So(c, ShouldNotBeNil) |
109 So(ctr, ShouldNotBeNil) | 107 So(ctr, ShouldNotBeNil) |
110 mc := memcache.Get(c) | |
111 | 108 |
112 » » die(mc.Set(mc.NewItem("hello").SetValue([]byte("sup")))) | 109 » » die(memcache.Set(c, memcache.NewItem(c, "hello").SetValue([]byte
("sup")))) |
113 | 110 |
114 » » _, err := mc.Get("Wat") | 111 » » _, err := memcache.GetKey(c, "Wat") |
115 So(err, ShouldNotBeNil) | 112 So(err, ShouldNotBeNil) |
116 | 113 |
117 » » _, err = mc.Get("hello") | 114 » » _, err = memcache.GetKey(c, "hello") |
118 die(err) | 115 die(err) |
119 | 116 |
120 So(ctr.SetMulti, shouldHaveSuccessesAndErrors, 1, 0) | 117 So(ctr.SetMulti, shouldHaveSuccessesAndErrors, 1, 0) |
121 So(ctr.GetMulti, shouldHaveSuccessesAndErrors, 2, 0) | 118 So(ctr.GetMulti, shouldHaveSuccessesAndErrors, 2, 0) |
122 So(ctr.NewItem, shouldHaveSuccessesAndErrors, 3, 0) | 119 So(ctr.NewItem, shouldHaveSuccessesAndErrors, 3, 0) |
123 }) | 120 }) |
124 | 121 |
125 Convey("works for taskqueue", t, func() { | 122 Convey("works for taskqueue", t, func() { |
126 c, ctr := FilterTQ(memory.Use(context.Background())) | 123 c, ctr := FilterTQ(memory.Use(context.Background())) |
127 So(c, ShouldNotBeNil) | 124 So(c, ShouldNotBeNil) |
128 So(ctr, ShouldNotBeNil) | 125 So(ctr, ShouldNotBeNil) |
129 tq := taskqueue.Get(c) | |
130 | 126 |
131 » » die(tq.Add(&taskqueue.Task{Name: "wat"}, "")) | 127 » » die(taskqueue.Add(c, "", &taskqueue.Task{Name: "wat"})) |
132 » » So(tq.Add(&taskqueue.Task{Name: "wat"}, "DNE_QUEUE"), | 128 » » So(taskqueue.Add(c, "DNE_QUEUE", &taskqueue.Task{Name: "wat"}), |
133 ShouldErrLike, "UNKNOWN_QUEUE") | 129 ShouldErrLike, "UNKNOWN_QUEUE") |
134 | 130 |
135 So(ctr.AddMulti, shouldHaveSuccessesAndErrors, 1, 1) | 131 So(ctr.AddMulti, shouldHaveSuccessesAndErrors, 1, 1) |
136 }) | 132 }) |
137 | 133 |
138 Convey("works for global info", t, func() { | 134 Convey("works for global info", t, func() { |
139 c, fb := featureBreaker.FilterGI(memory.Use(context.Background()
), nil) | 135 c, fb := featureBreaker.FilterGI(memory.Use(context.Background()
), nil) |
140 c, ctr := FilterGI(c) | 136 c, ctr := FilterGI(c) |
141 So(c, ShouldNotBeNil) | 137 So(c, ShouldNotBeNil) |
142 So(ctr, ShouldNotBeNil) | 138 So(ctr, ShouldNotBeNil) |
143 | 139 |
144 » » gi := info.Get(c) | 140 » » _, err := info.Namespace(c, "foo") |
145 | |
146 » » _, err := gi.Namespace("foo") | |
147 die(err) | 141 die(err) |
148 fb.BreakFeatures(nil, "Namespace") | 142 fb.BreakFeatures(nil, "Namespace") |
149 » » _, err = gi.Namespace("boom") | 143 » » _, err = info.Namespace(c, "boom") |
150 So(err, ShouldErrLike, `"Namespace" is broken`) | 144 So(err, ShouldErrLike, `"Namespace" is broken`) |
151 | 145 |
152 So(ctr.Namespace, shouldHaveSuccessesAndErrors, 1, 1) | 146 So(ctr.Namespace, shouldHaveSuccessesAndErrors, 1, 1) |
153 }) | 147 }) |
154 | 148 |
155 Convey("works for user", t, func() { | 149 Convey("works for user", t, func() { |
156 c, fb := featureBreaker.FilterUser(memory.Use(context.Background
()), nil) | 150 c, fb := featureBreaker.FilterUser(memory.Use(context.Background
()), nil) |
157 c, ctr := FilterUser(c) | 151 c, ctr := FilterUser(c) |
158 So(c, ShouldNotBeNil) | 152 So(c, ShouldNotBeNil) |
159 So(ctr, ShouldNotBeNil) | 153 So(ctr, ShouldNotBeNil) |
160 | 154 |
161 » » u := user.Get(c) | 155 » » _, err := user.CurrentOAuth(c, "foo") |
162 | |
163 » » _, err := u.CurrentOAuth("foo") | |
164 die(err) | 156 die(err) |
165 fb.BreakFeatures(nil, "CurrentOAuth") | 157 fb.BreakFeatures(nil, "CurrentOAuth") |
166 » » _, err = u.CurrentOAuth("foo") | 158 » » _, err = user.CurrentOAuth(c, "foo") |
167 So(err, ShouldErrLike, `"CurrentOAuth" is broken`) | 159 So(err, ShouldErrLike, `"CurrentOAuth" is broken`) |
168 | 160 |
169 So(ctr.CurrentOAuth, shouldHaveSuccessesAndErrors, 1, 1) | 161 So(ctr.CurrentOAuth, shouldHaveSuccessesAndErrors, 1, 1) |
170 }) | 162 }) |
171 | 163 |
172 Convey("works for mail", t, func() { | 164 Convey("works for mail", t, func() { |
173 c, fb := featureBreaker.FilterMail(memory.Use(context.Background
()), nil) | 165 c, fb := featureBreaker.FilterMail(memory.Use(context.Background
()), nil) |
174 c, ctr := FilterMail(c) | 166 c, ctr := FilterMail(c) |
175 So(c, ShouldNotBeNil) | 167 So(c, ShouldNotBeNil) |
176 So(ctr, ShouldNotBeNil) | 168 So(ctr, ShouldNotBeNil) |
177 | 169 |
178 » » m := mail.Get(c) | 170 » » err := mail.Send(c, &mail.Message{ |
179 | |
180 » » err := m.Send(&mail.Message{ | |
181 Sender: "admin@example.com", | 171 Sender: "admin@example.com", |
182 To: []string{"coolDood@example.com"}, | 172 To: []string{"coolDood@example.com"}, |
183 Body: "hi", | 173 Body: "hi", |
184 }) | 174 }) |
185 die(err) | 175 die(err) |
186 | 176 |
187 fb.BreakFeatures(nil, "Send") | 177 fb.BreakFeatures(nil, "Send") |
188 » » err = m.Send(&mail.Message{ | 178 » » err = mail.Send(c, &mail.Message{ |
189 Sender: "admin@example.com", | 179 Sender: "admin@example.com", |
190 To: []string{"coolDood@example.com"}, | 180 To: []string{"coolDood@example.com"}, |
191 Body: "hi", | 181 Body: "hi", |
192 }) | 182 }) |
193 So(err, ShouldErrLike, `"Send" is broken`) | 183 So(err, ShouldErrLike, `"Send" is broken`) |
194 | 184 |
195 So(ctr.Send, shouldHaveSuccessesAndErrors, 1, 1) | 185 So(ctr.Send, shouldHaveSuccessesAndErrors, 1, 1) |
196 }) | 186 }) |
197 } | 187 } |
198 | 188 |
199 func ExampleFilterRDS() { | 189 func ExampleFilterRDS() { |
200 // Set up your context using a base service implementation (memory or pr
od) | 190 // Set up your context using a base service implementation (memory or pr
od) |
201 c := memory.Use(context.Background()) | 191 c := memory.Use(context.Background()) |
202 | 192 |
203 // Apply the counter.FilterRDS | 193 // Apply the counter.FilterRDS |
204 c, counter := FilterRDS(c) | 194 c, counter := FilterRDS(c) |
205 | 195 |
206 // functions use ds from the context like normal... they don't need to k
now | 196 // functions use ds from the context like normal... they don't need to k
now |
207 // that there are any filters at all. | 197 // that there are any filters at all. |
208 someCalledFunc := func(c context.Context) { | 198 someCalledFunc := func(c context.Context) { |
209 » » ds := datastore.Get(c) | 199 » » vals := []ds.PropertyMap{{ |
210 » » vals := []datastore.PropertyMap{{ | 200 » » » "FieldName": ds.MkProperty(100), |
211 » » » "FieldName": datastore.MkProperty(100), | 201 » » » "$key": ds.MkProperty(ds.NewKey(c, "Kind", "", 1, n
il))}, |
212 » » » "$key": datastore.MkProperty(ds.NewKey("Kind", "",
1, nil))}, | |
213 } | 202 } |
214 » » if err := ds.PutMulti(vals); err != nil { | 203 » » if err := ds.Put(c, vals); err != nil { |
215 panic(err) | 204 panic(err) |
216 } | 205 } |
217 } | 206 } |
218 | 207 |
219 // Using the other function. | 208 // Using the other function. |
220 someCalledFunc(c) | 209 someCalledFunc(c) |
221 someCalledFunc(c) | 210 someCalledFunc(c) |
222 | 211 |
223 // Then we can see what happened! | 212 // Then we can see what happened! |
224 fmt.Printf("%d\n", counter.PutMulti.Successes()) | 213 fmt.Printf("%d\n", counter.PutMulti.Successes()) |
225 // Output: | 214 // Output: |
226 // 2 | 215 // 2 |
227 } | 216 } |
OLD | NEW |