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 "fmt" | 8 "fmt" |
9 » "infra/gae/libs/gae" | 9 » "infra/gae/libs/wrapper" |
| 10 » "infra/libs/clock" |
| 11 » "infra/libs/clock/testclock" |
10 "math/rand" | 12 "math/rand" |
11 "net/http" | 13 "net/http" |
12 "testing" | 14 "testing" |
13 "time" | 15 "time" |
14 | 16 |
15 . "github.com/smartystreets/goconvey/convey" | 17 . "github.com/smartystreets/goconvey/convey" |
16 "golang.org/x/net/context" | 18 "golang.org/x/net/context" |
17 | 19 |
18 » "github.com/luci/luci-go/common/clock" | 20 » "appengine/taskqueue" |
19 » "github.com/luci/luci-go/common/clock/testclock" | |
20 ) | 21 ) |
21 | 22 |
22 func TestTaskQueue(t *testing.T) { | 23 func TestTaskQueue(t *testing.T) { |
23 t.Parallel() | 24 t.Parallel() |
24 | 25 |
25 Convey("TaskQueue", t, func() { | 26 Convey("TaskQueue", t, func() { |
26 now := time.Date(2000, time.January, 1, 1, 1, 1, 1, time.UTC) | 27 now := time.Date(2000, time.January, 1, 1, 1, 1, 1, time.UTC) |
27 c, tc := testclock.UseTime(context.Background(), now) | 28 c, tc := testclock.UseTime(context.Background(), now) |
28 » » c = gae.SetMathRand(c, rand.New(rand.NewSource(clock.Now(c).Unix
Nano()))) | 29 » » c = wrapper.SetMathRand(c, rand.New(rand.NewSource(clock.Now(c).
UnixNano()))) |
29 c = Use(c) | 30 c = Use(c) |
30 | 31 |
31 » » tq := gae.GetTQ(c).(interface { | 32 » » tq := wrapper.GetTQ(c).(interface { |
32 » » » gae.TQMultiReadWriter | 33 » » » wrapper.TQMultiReadWriter |
33 » » » gae.TQTestable | 34 » » » wrapper.TQTestable |
34 }) | 35 }) |
35 | 36 |
36 So(tq, ShouldNotBeNil) | 37 So(tq, ShouldNotBeNil) |
37 | 38 |
38 Convey("implements TQMultiReadWriter", func() { | 39 Convey("implements TQMultiReadWriter", func() { |
39 Convey("Add", func() { | 40 Convey("Add", func() { |
40 » » » » t := &gae.TQTask{Path: "/hello/world"} | 41 » » » » t := &taskqueue.Task{Path: "/hello/world"} |
41 | 42 |
42 Convey("works", func() { | 43 Convey("works", func() { |
43 t.Delay = 4 * time.Second | 44 t.Delay = 4 * time.Second |
44 t.Header = http.Header{} | 45 t.Header = http.Header{} |
45 t.Header.Add("Cat", "tabby") | 46 t.Header.Add("Cat", "tabby") |
46 t.Payload = []byte("watwatwat") | 47 t.Payload = []byte("watwatwat") |
47 » » » » » t.RetryOptions = &gae.TQRetryOptions{Age
Limit: 7 * time.Second} | 48 » » » » » t.RetryOptions = &taskqueue.RetryOptions
{AgeLimit: 7 * time.Second} |
48 _, err := tq.Add(t, "") | 49 _, err := tq.Add(t, "") |
49 So(err, ShouldBeNil) | 50 So(err, ShouldBeNil) |
50 name := "Z_UjshxM9ecyMQfGbZmUGOEcgxWU0_5
CGLl_-RntudwAw2DqQ5-58bzJiWQN4OKzeuUb9O4JrPkUw2rOvk2Ax46THojnQ6avBQgZdrKcJmrwQ6o
4qKfJdiyUbGXvy691yRfzLeQhs6cBhWrgf3wH-VPMcA4SC-zlbJ2U8An7I0zJQA5nBFnMNoMgT-2peGo
ay3rCSbj4z9VFFm9kS_i6JCaQH518ujLDSNCYdjTq6B6lcWrZAh0U_q3a1S2nXEwrKiw_t9MTNQFgAQZ
WyGBbvZQPmeRYtu8SPaWzTfd25v_YWgBuVL2rRSPSMvlDwE04nNdtvVzE8vNNiA1zRimmdzKeqATQF9_
ReUvj4D7U8dcS703DZWfKMBLgBffY9jqCassOOOw77V72Oq5EVauUw3Qw0L6bBsfM9FtahTKUdabzRZj
XUoze3EK4KXPt3-wdidau-8JrVf2XFocjjZbwHoxcGvbtT3b4nGLDlgwdC00bwaFBZWff" | 51 name := "Z_UjshxM9ecyMQfGbZmUGOEcgxWU0_5
CGLl_-RntudwAw2DqQ5-58bzJiWQN4OKzeuUb9O4JrPkUw2rOvk2Ax46THojnQ6avBQgZdrKcJmrwQ6o
4qKfJdiyUbGXvy691yRfzLeQhs6cBhWrgf3wH-VPMcA4SC-zlbJ2U8An7I0zJQA5nBFnMNoMgT-2peGo
ay3rCSbj4z9VFFm9kS_i6JCaQH518ujLDSNCYdjTq6B6lcWrZAh0U_q3a1S2nXEwrKiw_t9MTNQFgAQZ
WyGBbvZQPmeRYtu8SPaWzTfd25v_YWgBuVL2rRSPSMvlDwE04nNdtvVzE8vNNiA1zRimmdzKeqATQF9_
ReUvj4D7U8dcS703DZWfKMBLgBffY9jqCassOOOw77V72Oq5EVauUw3Qw0L6bBsfM9FtahTKUdabzRZj
XUoze3EK4KXPt3-wdidau-8JrVf2XFocjjZbwHoxcGvbtT3b4nGLDlgwdC00bwaFBZWff" |
51 » » » » » So(*tq.GetScheduledTasks()["default"][na
me], ShouldResemble, gae.TQTask{ | 52 » » » » » So(*tq.GetScheduledTasks()["default"][na
me], ShouldResemble, taskqueue.Task{ |
52 ETA: now.Add(4 * time.S
econd), | 53 ETA: now.Add(4 * time.S
econd), |
53 Header: http.Header{"Cat":
[]string{"tabby"}}, | 54 Header: http.Header{"Cat":
[]string{"tabby"}}, |
54 Method: "POST", | 55 Method: "POST", |
55 Name: name, | 56 Name: name, |
56 Path: "/hello/world", | 57 Path: "/hello/world", |
57 Payload: []byte("watwatwat"
), | 58 Payload: []byte("watwatwat"
), |
58 » » » » » » RetryOptions: &gae.TQRetryOption
s{AgeLimit: 7 * time.Second}, | 59 » » » » » » RetryOptions: &taskqueue.RetryOp
tions{AgeLimit: 7 * time.Second}, |
59 }) | 60 }) |
60 }) | 61 }) |
61 | 62 |
62 Convey("cannot add to bad queues", func() { | 63 Convey("cannot add to bad queues", func() { |
63 _, err := tq.Add(nil, "waaat") | 64 _, err := tq.Add(nil, "waaat") |
64 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") | 65 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") |
65 | 66 |
66 Convey("but you can add Queues when test
ing", func() { | 67 Convey("but you can add Queues when test
ing", func() { |
67 tq.CreateQueue("waaat") | 68 tq.CreateQueue("waaat") |
68 _, err := tq.Add(t, "waaat") | 69 _, err := tq.Add(t, "waaat") |
(...skipping 12 matching lines...) Expand all Loading... |
81 So(tr, ShouldBeNil) | 82 So(tr, ShouldBeNil) |
82 }) | 83 }) |
83 | 84 |
84 Convey("cannot add twice", func() { | 85 Convey("cannot add twice", func() { |
85 t.Name = "bob" | 86 t.Name = "bob" |
86 _, err := tq.Add(t, "") | 87 _, err := tq.Add(t, "") |
87 So(err, ShouldBeNil) | 88 So(err, ShouldBeNil) |
88 | 89 |
89 // can't add the same one twice! | 90 // can't add the same one twice! |
90 _, err = tq.Add(t, "") | 91 _, err = tq.Add(t, "") |
91 » » » » » So(err, ShouldEqual, gae.ErrTQTaskAlread
yAdded) | 92 » » » » » So(err, ShouldEqual, taskqueue.ErrTaskAl
readyAdded) |
92 }) | 93 }) |
93 | 94 |
94 Convey("cannot add deleted task", func() { | 95 Convey("cannot add deleted task", func() { |
95 t.Name = "bob" | 96 t.Name = "bob" |
96 _, err := tq.Add(t, "") | 97 _, err := tq.Add(t, "") |
97 So(err, ShouldBeNil) | 98 So(err, ShouldBeNil) |
98 | 99 |
99 err = tq.Delete(t, "") | 100 err = tq.Delete(t, "") |
100 So(err, ShouldBeNil) | 101 So(err, ShouldBeNil) |
101 | 102 |
102 // can't add a deleted task! | 103 // can't add a deleted task! |
103 _, err = tq.Add(t, "") | 104 _, err = tq.Add(t, "") |
104 » » » » » So(err, ShouldEqual, gae.ErrTQTaskAlread
yAdded) | 105 » » » » » So(err, ShouldEqual, taskqueue.ErrTaskAl
readyAdded) |
105 }) | 106 }) |
106 | 107 |
107 Convey("cannot set ETA+Delay", func() { | 108 Convey("cannot set ETA+Delay", func() { |
108 t.ETA = clock.Now(c).Add(time.Hour) | 109 t.ETA = clock.Now(c).Add(time.Hour) |
109 tc.Add(time.Second) | 110 tc.Add(time.Second) |
110 t.Delay = time.Hour | 111 t.Delay = time.Hour |
111 So(func() { tq.Add(t, "") }, ShouldPanic
) | 112 So(func() { tq.Add(t, "") }, ShouldPanic
) |
112 }) | 113 }) |
113 | 114 |
114 Convey("must use a reasonable method", func() { | 115 Convey("must use a reasonable method", func() { |
(...skipping 22 matching lines...) Expand all Loading... |
137 Convey("can be broken", func() { | 138 Convey("can be broken", func() { |
138 tq.BreakFeatures(nil, "Add") | 139 tq.BreakFeatures(nil, "Add") |
139 _, err := tq.Add(t, "") | 140 _, err := tq.Add(t, "") |
140 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") | 141 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") |
141 }) | 142 }) |
142 | 143 |
143 Convey("AddMulti also works", func() { | 144 Convey("AddMulti also works", func() { |
144 t2 := dupTask(t) | 145 t2 := dupTask(t) |
145 t2.Path = "/hi/city" | 146 t2.Path = "/hi/city" |
146 | 147 |
147 » » » » » expect := []*gae.TQTask{t, t2} | 148 » » » » » expect := []*taskqueue.Task{t, t2} |
148 | 149 |
149 tasks, err := tq.AddMulti(expect, "defau
lt") | 150 tasks, err := tq.AddMulti(expect, "defau
lt") |
150 So(err, ShouldBeNil) | 151 So(err, ShouldBeNil) |
151 So(len(tasks), ShouldEqual, 2) | 152 So(len(tasks), ShouldEqual, 2) |
152 So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 2) | 153 So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 2) |
153 | 154 |
154 for i := range expect { | 155 for i := range expect { |
155 Convey(fmt.Sprintf("task %d: %s"
, i, expect[i].Path), func() { | 156 Convey(fmt.Sprintf("task %d: %s"
, i, expect[i].Path), func() { |
156 expect[i].Method = "POST
" | 157 expect[i].Method = "POST
" |
157 expect[i].ETA = now | 158 expect[i].ETA = now |
158 So(expect[i].Name, Shoul
dEqual, "") | 159 So(expect[i].Name, Shoul
dEqual, "") |
159 So(len(tasks[i].Name), S
houldEqual, 500) | 160 So(len(tasks[i].Name), S
houldEqual, 500) |
160 tasks[i].Name = "" | 161 tasks[i].Name = "" |
161 So(tasks[i], ShouldResem
ble, expect[i]) | 162 So(tasks[i], ShouldResem
ble, expect[i]) |
162 }) | 163 }) |
163 } | 164 } |
164 | 165 |
165 Convey("can be broken", func() { | 166 Convey("can be broken", func() { |
166 tq.BreakFeatures(nil, "AddMulti"
) | 167 tq.BreakFeatures(nil, "AddMulti"
) |
167 » » » » » » _, err := tq.AddMulti([]*gae.TQT
ask{t}, "") | 168 » » » » » » _, err := tq.AddMulti([]*taskque
ue.Task{t}, "") |
168 So(err.Error(), ShouldContainSub
string, "TRANSIENT_ERROR") | 169 So(err.Error(), ShouldContainSub
string, "TRANSIENT_ERROR") |
169 }) | 170 }) |
170 | 171 |
171 Convey("is not broken by Add", func() { | 172 Convey("is not broken by Add", func() { |
172 tq.BreakFeatures(nil, "Add") | 173 tq.BreakFeatures(nil, "Add") |
173 » » » » » » _, err := tq.AddMulti([]*gae.TQT
ask{t}, "") | 174 » » » » » » _, err := tq.AddMulti([]*taskque
ue.Task{t}, "") |
174 So(err, ShouldBeNil) | 175 So(err, ShouldBeNil) |
175 }) | 176 }) |
176 }) | 177 }) |
177 }) | 178 }) |
178 | 179 |
179 Convey("Delete", func() { | 180 Convey("Delete", func() { |
180 » » » » t := &gae.TQTask{Path: "/hello/world"} | 181 » » » » t := &taskqueue.Task{Path: "/hello/world"} |
181 tEnQ, err := tq.Add(t, "") | 182 tEnQ, err := tq.Add(t, "") |
182 So(err, ShouldBeNil) | 183 So(err, ShouldBeNil) |
183 | 184 |
184 Convey("works", func() { | 185 Convey("works", func() { |
185 t.Name = tEnQ.Name | 186 t.Name = tEnQ.Name |
186 err := tq.Delete(t, "") | 187 err := tq.Delete(t, "") |
187 So(err, ShouldBeNil) | 188 So(err, ShouldBeNil) |
188 So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 0) | 189 So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 0) |
189 So(len(tq.GetTombstonedTasks()["default"
]), ShouldEqual, 1) | 190 So(len(tq.GetTombstonedTasks()["default"
]), ShouldEqual, 1) |
190 So(tq.GetTombstonedTasks()["default"][tE
nQ.Name], ShouldResemble, tEnQ) | 191 So(tq.GetTombstonedTasks()["default"][tE
nQ.Name], ShouldResemble, tEnQ) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") | 225 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") |
225 }) | 226 }) |
226 | 227 |
227 Convey("DeleteMulti also works", func() { | 228 Convey("DeleteMulti also works", func() { |
228 t2 := dupTask(t) | 229 t2 := dupTask(t) |
229 t2.Path = "/hi/city" | 230 t2.Path = "/hi/city" |
230 tEnQ2, err := tq.Add(t2, "") | 231 tEnQ2, err := tq.Add(t2, "") |
231 So(err, ShouldBeNil) | 232 So(err, ShouldBeNil) |
232 | 233 |
233 Convey("usually works", func() { | 234 Convey("usually works", func() { |
234 » » » » » » err = tq.DeleteMulti([]*gae.TQTa
sk{tEnQ, tEnQ2}, "") | 235 » » » » » » err = tq.DeleteMulti([]*taskqueu
e.Task{tEnQ, tEnQ2}, "") |
235 So(err, ShouldBeNil) | 236 So(err, ShouldBeNil) |
236 So(len(tq.GetScheduledTasks()["d
efault"]), ShouldEqual, 0) | 237 So(len(tq.GetScheduledTasks()["d
efault"]), ShouldEqual, 0) |
237 So(len(tq.GetTombstonedTasks()["
default"]), ShouldEqual, 2) | 238 So(len(tq.GetTombstonedTasks()["
default"]), ShouldEqual, 2) |
238 }) | 239 }) |
239 | 240 |
240 Convey("can be broken", func() { | 241 Convey("can be broken", func() { |
241 tq.BreakFeatures(nil, "DeleteMul
ti") | 242 tq.BreakFeatures(nil, "DeleteMul
ti") |
242 » » » » » » err = tq.DeleteMulti([]*gae.TQTa
sk{tEnQ, tEnQ2}, "") | 243 » » » » » » err = tq.DeleteMulti([]*taskqueu
e.Task{tEnQ, tEnQ2}, "") |
243 So(err.Error(), ShouldContainSub
string, "TRANSIENT_ERROR") | 244 So(err.Error(), ShouldContainSub
string, "TRANSIENT_ERROR") |
244 }) | 245 }) |
245 | 246 |
246 Convey("is not broken by Delete", func()
{ | 247 Convey("is not broken by Delete", func()
{ |
247 tq.BreakFeatures(nil, "Delete") | 248 tq.BreakFeatures(nil, "Delete") |
248 » » » » » » err = tq.DeleteMulti([]*gae.TQTa
sk{tEnQ, tEnQ2}, "") | 249 » » » » » » err = tq.DeleteMulti([]*taskqueu
e.Task{tEnQ, tEnQ2}, "") |
249 So(err, ShouldBeNil) | 250 So(err, ShouldBeNil) |
250 }) | 251 }) |
251 }) | 252 }) |
252 }) | 253 }) |
253 }) | 254 }) |
254 | 255 |
255 Convey("works with transactions", func() { | 256 Convey("works with transactions", func() { |
256 » » » t := &gae.TQTask{Path: "/hello/world"} | 257 » » » t := &taskqueue.Task{Path: "/hello/world"} |
257 tEnQ, err := tq.Add(t, "") | 258 tEnQ, err := tq.Add(t, "") |
258 So(err, ShouldBeNil) | 259 So(err, ShouldBeNil) |
259 | 260 |
260 » » » t2 := &gae.TQTask{Path: "/hi/city"} | 261 » » » t2 := &taskqueue.Task{Path: "/hi/city"} |
261 tEnQ2, err := tq.Add(t2, "") | 262 tEnQ2, err := tq.Add(t2, "") |
262 So(err, ShouldBeNil) | 263 So(err, ShouldBeNil) |
263 | 264 |
264 err = tq.Delete(tEnQ2, "") | 265 err = tq.Delete(tEnQ2, "") |
265 So(err, ShouldBeNil) | 266 So(err, ShouldBeNil) |
266 | 267 |
267 Convey("can view regular tasks", func() { | 268 Convey("can view regular tasks", func() { |
268 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 269 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
269 » » » » » tq := gae.GetTQ(c).(interface { | 270 » » » » » tq := wrapper.GetTQ(c).(interface { |
270 » » » » » » gae.TQTestable | 271 » » » » » » wrapper.TQTestable |
271 » » » » » » gae.TaskQueue | 272 » » » » » » wrapper.TaskQueue |
272 }) | 273 }) |
273 | 274 |
274 So(tq.GetScheduledTasks()["default"][tEn
Q.Name], ShouldResemble, tEnQ) | 275 So(tq.GetScheduledTasks()["default"][tEn
Q.Name], ShouldResemble, tEnQ) |
275 So(tq.GetTombstonedTasks()["default"][tE
nQ2.Name], ShouldResemble, tEnQ2) | 276 So(tq.GetTombstonedTasks()["default"][tE
nQ2.Name], ShouldResemble, tEnQ2) |
276 So(tq.GetTransactionTasks()["default"],
ShouldBeNil) | 277 So(tq.GetTransactionTasks()["default"],
ShouldBeNil) |
277 return nil | 278 return nil |
278 }, nil) | 279 }, nil) |
279 }) | 280 }) |
280 | 281 |
281 Convey("can add a new task", func() { | 282 Convey("can add a new task", func() { |
282 » » » » tEnQ3 := (*gae.TQTask)(nil) | 283 » » » » tEnQ3 := (*taskqueue.Task)(nil) |
283 | 284 |
284 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 285 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
285 » » » » » tq := gae.GetTQ(c).(interface { | 286 » » » » » tq := wrapper.GetTQ(c).(interface { |
286 » » » » » » gae.TQTestable | 287 » » » » » » wrapper.TQTestable |
287 » » » » » » gae.TaskQueue | 288 » » » » » » wrapper.TaskQueue |
288 }) | 289 }) |
289 | 290 |
290 » » » » » t3 := &gae.TQTask{Path: "/sandwitch/vict
ory"} | 291 » » » » » t3 := &taskqueue.Task{Path: "/sandwitch/
victory"} |
291 tEnQ3, err = tq.Add(t3, "") | 292 tEnQ3, err = tq.Add(t3, "") |
292 So(err, ShouldBeNil) | 293 So(err, ShouldBeNil) |
293 | 294 |
294 So(tq.GetScheduledTasks()["default"][tEn
Q.Name], ShouldResemble, tEnQ) | 295 So(tq.GetScheduledTasks()["default"][tEn
Q.Name], ShouldResemble, tEnQ) |
295 So(tq.GetTombstonedTasks()["default"][tE
nQ2.Name], ShouldResemble, tEnQ2) | 296 So(tq.GetTombstonedTasks()["default"][tE
nQ2.Name], ShouldResemble, tEnQ2) |
296 So(tq.GetTransactionTasks()["default"][0
], ShouldResemble, tEnQ3) | 297 So(tq.GetTransactionTasks()["default"][0
], ShouldResemble, tEnQ3) |
297 return nil | 298 return nil |
298 }, nil) | 299 }, nil) |
299 | 300 |
300 // name gets generated at transaction-commit-tim
e | 301 // name gets generated at transaction-commit-tim
e |
301 for name := range tq.GetScheduledTasks()["defaul
t"] { | 302 for name := range tq.GetScheduledTasks()["defaul
t"] { |
302 if name == tEnQ.Name { | 303 if name == tEnQ.Name { |
303 continue | 304 continue |
304 } | 305 } |
305 tEnQ3.Name = name | 306 tEnQ3.Name = name |
306 break | 307 break |
307 } | 308 } |
308 | 309 |
309 So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) | 310 So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) |
310 So(tq.GetScheduledTasks()["default"][tEnQ3.Name]
, ShouldResemble, tEnQ3) | 311 So(tq.GetScheduledTasks()["default"][tEnQ3.Name]
, ShouldResemble, tEnQ3) |
311 So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) | 312 So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) |
312 So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) | 313 So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) |
313 }) | 314 }) |
314 | 315 |
315 Convey("can a new task (but reset the state in a test)",
func() { | 316 Convey("can a new task (but reset the state in a test)",
func() { |
316 » » » » tEnQ3 := (*gae.TQTask)(nil) | 317 » » » » tEnQ3 := (*taskqueue.Task)(nil) |
317 | 318 |
318 ttq := interface { | 319 ttq := interface { |
319 » » » » » gae.TQTestable | 320 » » » » » wrapper.TQTestable |
320 » » » » » gae.TaskQueue | 321 » » » » » wrapper.TaskQueue |
321 }(nil) | 322 }(nil) |
322 | 323 |
323 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 324 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
324 » » » » » ttq = gae.GetTQ(c).(interface { | 325 » » » » » ttq = wrapper.GetTQ(c).(interface { |
325 » » » » » » gae.TQTestable | 326 » » » » » » wrapper.TQTestable |
326 » » » » » » gae.TaskQueue | 327 » » » » » » wrapper.TaskQueue |
327 }) | 328 }) |
328 | 329 |
329 » » » » » t3 := &gae.TQTask{Path: "/sandwitch/vict
ory"} | 330 » » » » » t3 := &taskqueue.Task{Path: "/sandwitch/
victory"} |
330 tEnQ3, err = ttq.Add(t3, "") | 331 tEnQ3, err = ttq.Add(t3, "") |
331 So(err, ShouldBeNil) | 332 So(err, ShouldBeNil) |
332 | 333 |
333 So(ttq.GetScheduledTasks()["default"][tE
nQ.Name], ShouldResemble, tEnQ) | 334 So(ttq.GetScheduledTasks()["default"][tE
nQ.Name], ShouldResemble, tEnQ) |
334 So(ttq.GetTombstonedTasks()["default"][t
EnQ2.Name], ShouldResemble, tEnQ2) | 335 So(ttq.GetTombstonedTasks()["default"][t
EnQ2.Name], ShouldResemble, tEnQ2) |
335 So(ttq.GetTransactionTasks()["default"][
0], ShouldResemble, tEnQ3) | 336 So(ttq.GetTransactionTasks()["default"][
0], ShouldResemble, tEnQ3) |
336 | 337 |
337 ttq.ResetTasks() | 338 ttq.ResetTasks() |
338 | 339 |
339 So(len(ttq.GetScheduledTasks()["default"
]), ShouldEqual, 0) | 340 So(len(ttq.GetScheduledTasks()["default"
]), ShouldEqual, 0) |
340 So(len(ttq.GetTombstonedTasks()["default
"]), ShouldEqual, 0) | 341 So(len(ttq.GetTombstonedTasks()["default
"]), ShouldEqual, 0) |
341 So(len(ttq.GetTransactionTasks()["defaul
t"]), ShouldEqual, 0) | 342 So(len(ttq.GetTransactionTasks()["defaul
t"]), ShouldEqual, 0) |
342 | 343 |
343 return nil | 344 return nil |
344 }, nil) | 345 }, nil) |
345 | 346 |
346 So(len(tq.GetScheduledTasks()["default"]), Shoul
dEqual, 0) | 347 So(len(tq.GetScheduledTasks()["default"]), Shoul
dEqual, 0) |
347 So(len(tq.GetTombstonedTasks()["default"]), Shou
ldEqual, 0) | 348 So(len(tq.GetTombstonedTasks()["default"]), Shou
ldEqual, 0) |
348 So(len(tq.GetTransactionTasks()["default"]), Sho
uldEqual, 0) | 349 So(len(tq.GetTransactionTasks()["default"]), Sho
uldEqual, 0) |
349 | 350 |
350 Convey("and reusing a closed context is bad time
s", func() { | 351 Convey("and reusing a closed context is bad time
s", func() { |
351 _, err := ttq.Add(nil, "") | 352 _, err := ttq.Add(nil, "") |
352 So(err.Error(), ShouldContainSubstring,
"expired") | 353 So(err.Error(), ShouldContainSubstring,
"expired") |
353 }) | 354 }) |
354 }) | 355 }) |
355 | 356 |
356 Convey("you can AddMulti as well", func() { | 357 Convey("you can AddMulti as well", func() { |
357 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 358 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
358 » » » » » tq := gae.GetTQ(c).(interface { | 359 » » » » » tq := wrapper.GetTQ(c).(interface { |
359 » » » » » » gae.TQTestable | 360 » » » » » » wrapper.TQTestable |
360 » » » » » » gae.TaskQueue | 361 » » » » » » wrapper.TaskQueue |
361 }) | 362 }) |
362 » » » » » _, err := tq.AddMulti([]*gae.TQTask{t, t
, t}, "") | 363 » » » » » _, err := tq.AddMulti([]*taskqueue.Task{
t, t, t}, "") |
363 So(err, ShouldBeNil) | 364 So(err, ShouldBeNil) |
364 So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 1) | 365 So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 1) |
365 So(len(tq.GetTransactionTasks()["default
"]), ShouldEqual, 3) | 366 So(len(tq.GetTransactionTasks()["default
"]), ShouldEqual, 3) |
366 return nil | 367 return nil |
367 }, nil) | 368 }, nil) |
368 So(len(tq.GetScheduledTasks()["default"]), Shoul
dEqual, 4) | 369 So(len(tq.GetScheduledTasks()["default"]), Shoul
dEqual, 4) |
369 So(len(tq.GetTransactionTasks()["default"]), Sho
uldEqual, 0) | 370 So(len(tq.GetTransactionTasks()["default"]), Sho
uldEqual, 0) |
370 }) | 371 }) |
371 | 372 |
372 Convey("unless you add too many things", func() { | 373 Convey("unless you add too many things", func() { |
373 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 374 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
374 for i := 0; i < 5; i++ { | 375 for i := 0; i < 5; i++ { |
375 » » » » » » _, err = gae.GetTQ(c).Add(t, "") | 376 » » » » » » _, err = wrapper.GetTQ(c).Add(t,
"") |
376 So(err, ShouldBeNil) | 377 So(err, ShouldBeNil) |
377 } | 378 } |
378 » » » » » _, err = gae.GetTQ(c).Add(t, "") | 379 » » » » » _, err = wrapper.GetTQ(c).Add(t, "") |
379 So(err.Error(), ShouldContainSubstring,
"BAD_REQUEST") | 380 So(err.Error(), ShouldContainSubstring,
"BAD_REQUEST") |
380 return nil | 381 return nil |
381 }, nil) | 382 }, nil) |
382 }) | 383 }) |
383 | 384 |
384 Convey("unless you Add to a bad queue", func() { | 385 Convey("unless you Add to a bad queue", func() { |
385 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 386 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
386 » » » » » _, err = gae.GetTQ(c).Add(t, "meat") | 387 » » » » » _, err = wrapper.GetTQ(c).Add(t, "meat") |
387 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") | 388 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") |
388 | 389 |
389 Convey("unless you add it!", func() { | 390 Convey("unless you add it!", func() { |
390 » » » » » » gae.GetTQ(c).(gae.TQTestable).Cr
eateQueue("meat") | 391 » » » » » » wrapper.GetTQ(c).(wrapper.TQTest
able).CreateQueue("meat") |
391 » » » » » » _, err = gae.GetTQ(c).Add(t, "me
at") | 392 » » » » » » _, err = wrapper.GetTQ(c).Add(t,
"meat") |
392 So(err, ShouldBeNil) | 393 So(err, ShouldBeNil) |
393 }) | 394 }) |
394 | 395 |
395 return nil | 396 return nil |
396 }, nil) | 397 }, nil) |
397 }) | 398 }) |
398 | 399 |
399 Convey("unless Add is broken", func() { | 400 Convey("unless Add is broken", func() { |
400 tq.BreakFeatures(nil, "Add") | 401 tq.BreakFeatures(nil, "Add") |
401 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 402 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
402 » » » » » _, err = gae.GetTQ(c).Add(t, "") | 403 » » » » » _, err = wrapper.GetTQ(c).Add(t, "") |
403 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") | 404 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") |
404 return nil | 405 return nil |
405 }, nil) | 406 }, nil) |
406 }) | 407 }) |
407 | 408 |
408 Convey("unless AddMulti is broken", func() { | 409 Convey("unless AddMulti is broken", func() { |
409 tq.BreakFeatures(nil, "AddMulti") | 410 tq.BreakFeatures(nil, "AddMulti") |
410 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 411 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
411 » » » » » _, err = gae.GetTQ(c).AddMulti(nil, "") | 412 » » » » » _, err = wrapper.GetTQ(c).AddMulti(nil,
"") |
412 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") | 413 So(err.Error(), ShouldContainSubstring,
"TRANSIENT_ERROR") |
413 return nil | 414 return nil |
414 }, nil) | 415 }, nil) |
415 }) | 416 }) |
416 | 417 |
417 Convey("No other features are available, however", func(
) { | 418 Convey("No other features are available, however", func(
) { |
418 err := error(nil) | 419 err := error(nil) |
419 func() { | 420 func() { |
420 defer func() { err = recover().(error) }
() | 421 defer func() { err = recover().(error) }
() |
421 » » » » » gae.GetRDS(c).RunInTransaction(func(c co
ntext.Context) error { | 422 » » » » » wrapper.GetDS(c).RunInTransaction(func(c
context.Context) error { |
422 » » » » » » gae.GetTQ(c).Delete(t, "") | 423 » » » » » » wrapper.GetTQ(c).Delete(t, "") |
423 return nil | 424 return nil |
424 }, nil) | 425 }, nil) |
425 }() | 426 }() |
426 So(err.Error(), ShouldContainSubstring, "TaskQue
ue.Delete") | 427 So(err.Error(), ShouldContainSubstring, "TaskQue
ue.Delete") |
427 }) | 428 }) |
428 | 429 |
429 Convey("adding a new task only happens if we don't errou
t", func() { | 430 Convey("adding a new task only happens if we don't errou
t", func() { |
430 » » » » gae.GetRDS(c).RunInTransaction(func(c context.Co
ntext) error { | 431 » » » » wrapper.GetDS(c).RunInTransaction(func(c context
.Context) error { |
431 » » » » » t3 := &gae.TQTask{Path: "/sandwitch/vict
ory"} | 432 » » » » » t3 := &taskqueue.Task{Path: "/sandwitch/
victory"} |
432 » » » » » _, err = gae.GetTQ(c).Add(t3, "") | 433 » » » » » _, err = wrapper.GetTQ(c).Add(t3, "") |
433 So(err, ShouldBeNil) | 434 So(err, ShouldBeNil) |
434 return fmt.Errorf("nooooo") | 435 return fmt.Errorf("nooooo") |
435 }, nil) | 436 }, nil) |
436 | 437 |
437 So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) | 438 So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) |
438 So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) | 439 So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) |
439 So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) | 440 So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) |
440 }) | 441 }) |
441 | 442 |
442 Convey("likewise, a panic doesn't schedule anything", fu
nc() { | 443 Convey("likewise, a panic doesn't schedule anything", fu
nc() { |
443 func() { | 444 func() { |
444 defer func() { recover() }() | 445 defer func() { recover() }() |
445 » » » » » gae.GetRDS(c).RunInTransaction(func(c co
ntext.Context) error { | 446 » » » » » wrapper.GetDS(c).RunInTransaction(func(c
context.Context) error { |
446 » » » » » » tq := gae.GetTQ(c).(interface { | 447 » » » » » » tq := wrapper.GetTQ(c).(interfac
e { |
447 » » » » » » » gae.TQTestable | 448 » » » » » » » wrapper.TQTestable |
448 » » » » » » » gae.TaskQueue | 449 » » » » » » » wrapper.TaskQueue |
449 }) | 450 }) |
450 | 451 |
451 » » » » » » t3 := &gae.TQTask{Path: "/sandwi
tch/victory"} | 452 » » » » » » t3 := &taskqueue.Task{Path: "/sa
ndwitch/victory"} |
452 _, err = tq.Add(t3, "") | 453 _, err = tq.Add(t3, "") |
453 So(err, ShouldBeNil) | 454 So(err, ShouldBeNil) |
454 | 455 |
455 panic(fmt.Errorf("nooooo")) | 456 panic(fmt.Errorf("nooooo")) |
456 }, nil) | 457 }, nil) |
457 }() | 458 }() |
458 | 459 |
459 So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) | 460 So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) |
460 So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) | 461 So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) |
461 So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) | 462 So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) |
462 }) | 463 }) |
463 | 464 |
464 }) | 465 }) |
465 }) | 466 }) |
466 } | 467 } |
OLD | NEW |