| 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 "math/rand" | 9 "math/rand" |
| 10 "net/http" | 10 "net/http" |
| 11 "testing" | 11 "testing" |
| 12 "time" | 12 "time" |
| 13 | 13 |
| 14 dsS "github.com/luci/gae/service/datastore" | 14 dsS "github.com/luci/gae/service/datastore" |
| 15 "github.com/luci/gae/service/info" |
| 15 tqS "github.com/luci/gae/service/taskqueue" | 16 tqS "github.com/luci/gae/service/taskqueue" |
| 16 "github.com/luci/luci-go/common/clock" | 17 "github.com/luci/luci-go/common/clock" |
| 17 "github.com/luci/luci-go/common/clock/testclock" | 18 "github.com/luci/luci-go/common/clock/testclock" |
| 18 "github.com/luci/luci-go/common/mathrand" | 19 "github.com/luci/luci-go/common/mathrand" |
| 19 . "github.com/smartystreets/goconvey/convey" | 20 . "github.com/smartystreets/goconvey/convey" |
| 20 "golang.org/x/net/context" | 21 "golang.org/x/net/context" |
| 21 ) | 22 ) |
| 22 | 23 |
| 23 func TestTaskQueue(t *testing.T) { | 24 func TestTaskQueue(t *testing.T) { |
| 24 t.Parallel() | 25 t.Parallel() |
| 25 | 26 |
| 26 Convey("TaskQueue", t, func() { | 27 Convey("TaskQueue", t, func() { |
| 27 now := time.Date(2000, time.January, 1, 1, 1, 1, 1, time.UTC) | 28 now := time.Date(2000, time.January, 1, 1, 1, 1, 1, time.UTC) |
| 28 c, tc := testclock.UseTime(context.Background(), now) | 29 c, tc := testclock.UseTime(context.Background(), now) |
| 29 c = mathrand.Set(c, rand.New(rand.NewSource(clock.Now(c).UnixNan
o()))) | 30 c = mathrand.Set(c, rand.New(rand.NewSource(clock.Now(c).UnixNan
o()))) |
| 30 c = Use(c) | 31 c = Use(c) |
| 31 | 32 |
| 32 » » tq := tqS.Get(c).(interface { | 33 » » tq := tqS.Get(c) |
| 33 » » » tqS.Interface | 34 » » tqt := tq.Raw().(tqS.Testable) |
| 34 » » » tqS.Testable | |
| 35 » » }) | |
| 36 | 35 |
| 37 So(tq, ShouldNotBeNil) | 36 So(tq, ShouldNotBeNil) |
| 38 | 37 |
| 39 Convey("implements TQMultiReadWriter", func() { | 38 Convey("implements TQMultiReadWriter", func() { |
| 40 Convey("Add", func() { | 39 Convey("Add", func() { |
| 41 » » » » t := &tqS.Task{Path: "/hello/world"} | 40 » » » » t := tq.NewTask("/hello/world") |
| 42 | 41 |
| 43 Convey("works", func() { | 42 Convey("works", func() { |
| 44 t.Delay = 4 * time.Second | 43 t.Delay = 4 * time.Second |
| 45 t.Header = http.Header{} | 44 t.Header = http.Header{} |
| 46 t.Header.Add("Cat", "tabby") | 45 t.Header.Add("Cat", "tabby") |
| 47 t.Payload = []byte("watwatwat") | 46 t.Payload = []byte("watwatwat") |
| 48 t.RetryOptions = &tqS.RetryOptions{AgeLi
mit: 7 * time.Second} | 47 t.RetryOptions = &tqS.RetryOptions{AgeLi
mit: 7 * time.Second} |
| 49 » » » » » _, err := tq.Add(t, "") | 48 » » » » » So(tq.Add(t, ""), ShouldBeNil) |
| 50 » » » » » So(err, ShouldBeNil) | 49 |
| 51 name := "Z_UjshxM9ecyMQfGbZmUGOEcgxWU0_5
CGLl_-RntudwAw2DqQ5-58bzJiWQN4OKzeuUb9O4JrPkUw2rOvk2Ax46THojnQ6avBQgZdrKcJmrwQ6o
4qKfJdiyUbGXvy691yRfzLeQhs6cBhWrgf3wH-VPMcA4SC-zlbJ2U8An7I0zJQA5nBFnMNoMgT-2peGo
ay3rCSbj4z9VFFm9kS_i6JCaQH518ujLDSNCYdjTq6B6lcWrZAh0U_q3a1S2nXEwrKiw_t9MTNQFgAQZ
WyGBbvZQPmeRYtu8SPaWzTfd25v_YWgBuVL2rRSPSMvlDwE04nNdtvVzE8vNNiA1zRimmdzKeqATQF9_
ReUvj4D7U8dcS703DZWfKMBLgBffY9jqCassOOOw77V72Oq5EVauUw3Qw0L6bBsfM9FtahTKUdabzRZj
XUoze3EK4KXPt3-wdidau-8JrVf2XFocjjZbwHoxcGvbtT3b4nGLDlgwdC00bwaFBZWff" | 50 name := "Z_UjshxM9ecyMQfGbZmUGOEcgxWU0_5
CGLl_-RntudwAw2DqQ5-58bzJiWQN4OKzeuUb9O4JrPkUw2rOvk2Ax46THojnQ6avBQgZdrKcJmrwQ6o
4qKfJdiyUbGXvy691yRfzLeQhs6cBhWrgf3wH-VPMcA4SC-zlbJ2U8An7I0zJQA5nBFnMNoMgT-2peGo
ay3rCSbj4z9VFFm9kS_i6JCaQH518ujLDSNCYdjTq6B6lcWrZAh0U_q3a1S2nXEwrKiw_t9MTNQFgAQZ
WyGBbvZQPmeRYtu8SPaWzTfd25v_YWgBuVL2rRSPSMvlDwE04nNdtvVzE8vNNiA1zRimmdzKeqATQF9_
ReUvj4D7U8dcS703DZWfKMBLgBffY9jqCassOOOw77V72Oq5EVauUw3Qw0L6bBsfM9FtahTKUdabzRZj
XUoze3EK4KXPt3-wdidau-8JrVf2XFocjjZbwHoxcGvbtT3b4nGLDlgwdC00bwaFBZWff" |
| 52 » » » » » So(*tq.GetScheduledTasks()["default"][na
me], ShouldResemble, tqS.Task{ | 51 » » » » » So(tqt.GetScheduledTasks()["default"][na
me], ShouldResemble, &tqS.Task{ |
| 53 ETA: now.Add(4 * time.S
econd), | 52 ETA: now.Add(4 * time.S
econd), |
| 54 Header: http.Header{"Cat":
[]string{"tabby"}}, | 53 Header: http.Header{"Cat":
[]string{"tabby"}}, |
| 55 Method: "POST", | 54 Method: "POST", |
| 56 Name: name, | 55 Name: name, |
| 57 Path: "/hello/world", | 56 Path: "/hello/world", |
| 58 Payload: []byte("watwatwat"
), | 57 Payload: []byte("watwatwat"
), |
| 59 RetryOptions: &tqS.RetryOptions{
AgeLimit: 7 * time.Second}, | 58 RetryOptions: &tqS.RetryOptions{
AgeLimit: 7 * time.Second}, |
| 60 }) | 59 }) |
| 61 }) | 60 }) |
| 62 | 61 |
| 62 Convey("picks up namespace", func() { |
| 63 c, err := info.Get(c).Namespace("coolNam
espace") |
| 64 So(err, ShouldBeNil) |
| 65 tq = tqS.Get(c) |
| 66 |
| 67 t := tq.NewTask("") |
| 68 So(tq.Add(t, ""), ShouldBeNil) |
| 69 So(t.Header, ShouldResemble, http.Header
{ |
| 70 "X-Appengine-Current-Namespace":
{"coolNamespace"}, |
| 71 }) |
| 72 |
| 73 }) |
| 74 |
| 63 Convey("cannot add to bad queues", func() { | 75 Convey("cannot add to bad queues", func() { |
| 64 » » » » » _, err := tq.Add(nil, "waaat") | 76 » » » » » So(tq.Add(nil, "waaat").Error(), ShouldC
ontainSubstring, "UNKNOWN_QUEUE") |
| 65 » » » » » So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") | |
| 66 | 77 |
| 67 Convey("but you can add Queues when test
ing", func() { | 78 Convey("but you can add Queues when test
ing", func() { |
| 68 » » » » » » tq.CreateQueue("waaat") | 79 » » » » » » tqt.CreateQueue("waaat") |
| 69 » » » » » » _, err := tq.Add(t, "waaat") | 80 » » » » » » So(tq.Add(t, "waaat"), ShouldBeN
il) |
| 70 » » » » » » So(err, ShouldBeNil) | |
| 71 | 81 |
| 72 Convey("you just can't add them
twice", func() { | 82 Convey("you just can't add them
twice", func() { |
| 73 » » » » » » » So(func() { tq.CreateQue
ue("waaat") }, ShouldPanic) | 83 » » » » » » » So(func() { tqt.CreateQu
eue("waaat") }, ShouldPanic) |
| 74 }) | 84 }) |
| 75 }) | 85 }) |
| 76 }) | 86 }) |
| 77 | 87 |
| 78 Convey("supplies a URL if it's missing", func()
{ | 88 Convey("supplies a URL if it's missing", func()
{ |
| 79 t.Path = "" | 89 t.Path = "" |
| 80 » » » » » tr, err := tq.Add(t, "") | 90 » » » » » So(tq.Add(t, ""), ShouldBeNil) |
| 81 » » » » » So(err, ShouldBeNil) | 91 » » » » » So(t.Path, ShouldEqual, "/_ah/queue/defa
ult") |
| 82 » » » » » So(tr.Path, ShouldEqual, "/_ah/queue/def
ault") | |
| 83 }) | 92 }) |
| 84 | 93 |
| 85 Convey("cannot add twice", func() { | 94 Convey("cannot add twice", func() { |
| 86 t.Name = "bob" | 95 t.Name = "bob" |
| 87 » » » » » _, err := tq.Add(t, "") | 96 » » » » » So(tq.Add(t, ""), ShouldBeNil) |
| 88 » » » » » So(err, ShouldBeNil) | |
| 89 | 97 |
| 90 // can't add the same one twice! | 98 // can't add the same one twice! |
| 91 » » » » » _, err = tq.Add(t, "") | 99 » » » » » So(tq.Add(t, ""), ShouldEqual, tqS.ErrTa
skAlreadyAdded) |
| 92 » » » » » So(err, ShouldEqual, tqS.ErrTaskAlreadyA
dded) | |
| 93 }) | 100 }) |
| 94 | 101 |
| 95 Convey("cannot add deleted task", func() { | 102 Convey("cannot add deleted task", func() { |
| 96 t.Name = "bob" | 103 t.Name = "bob" |
| 97 » » » » » _, err := tq.Add(t, "") | 104 » » » » » So(tq.Add(t, ""), ShouldBeNil) |
| 98 » » » » » So(err, ShouldBeNil) | |
| 99 | 105 |
| 100 » » » » » err = tq.Delete(t, "") | 106 » » » » » So(tq.Delete(t, ""), ShouldBeNil) |
| 101 » » » » » So(err, ShouldBeNil) | |
| 102 | 107 |
| 103 // can't add a deleted task! | 108 // can't add a deleted task! |
| 104 » » » » » _, err = tq.Add(t, "") | 109 » » » » » So(tq.Add(t, ""), ShouldEqual, tqS.ErrTa
skAlreadyAdded) |
| 105 » » » » » So(err, ShouldEqual, tqS.ErrTaskAlreadyA
dded) | |
| 106 }) | 110 }) |
| 107 | 111 |
| 108 Convey("cannot set ETA+Delay", func() { | 112 Convey("cannot set ETA+Delay", func() { |
| 109 t.ETA = clock.Now(c).Add(time.Hour) | 113 t.ETA = clock.Now(c).Add(time.Hour) |
| 110 tc.Add(time.Second) | 114 tc.Add(time.Second) |
| 111 t.Delay = time.Hour | 115 t.Delay = time.Hour |
| 112 So(func() { tq.Add(t, "") }, ShouldPanic
) | 116 So(func() { tq.Add(t, "") }, ShouldPanic
) |
| 113 }) | 117 }) |
| 114 | 118 |
| 115 Convey("must use a reasonable method", func() { | 119 Convey("must use a reasonable method", func() { |
| 116 t.Method = "Crystal" | 120 t.Method = "Crystal" |
| 117 » » » » » _, err := tq.Add(t, "") | 121 » » » » » So(tq.Add(t, "").Error(), ShouldContainS
ubstring, "bad method") |
| 118 » » » » » So(err.Error(), ShouldContainSubstring,
"bad method") | |
| 119 }) | 122 }) |
| 120 | 123 |
| 121 Convey("payload gets dumped for non POST/PUT met
hods", func() { | 124 Convey("payload gets dumped for non POST/PUT met
hods", func() { |
| 122 t.Method = "HEAD" | 125 t.Method = "HEAD" |
| 123 t.Payload = []byte("coool") | 126 t.Payload = []byte("coool") |
| 124 » » » » » tq, err := tq.Add(t, "") | 127 » » » » » So(tq.Add(t, ""), ShouldBeNil) |
| 125 » » » » » So(err, ShouldBeNil) | 128 » » » » » So(t.Payload, ShouldBeNil) |
| 126 » » » » » So(tq.Payload, ShouldBeNil) | |
| 127 | |
| 128 » » » » » // check that it didn't modify our origi
nal | |
| 129 » » » » » So(t.Payload, ShouldResemble, []byte("co
ool")) | |
| 130 }) | 129 }) |
| 131 | 130 |
| 132 Convey("invalid names are rejected", func() { | 131 Convey("invalid names are rejected", func() { |
| 133 t.Name = "happy times" | 132 t.Name = "happy times" |
| 134 » » » » » _, err := tq.Add(t, "") | 133 » » » » » So(tq.Add(t, "").Error(), ShouldContainS
ubstring, "INVALID_TASK_NAME") |
| 135 » » » » » So(err.Error(), ShouldContainSubstring,
"INVALID_TASK_NAME") | |
| 136 }) | 134 }) |
| 137 | 135 |
| 138 Convey("AddMulti also works", func() { | 136 Convey("AddMulti also works", func() { |
| 139 » » » » » t2 := dupTask(t) | 137 » » » » » t2 := t.Duplicate() |
| 140 t2.Path = "/hi/city" | 138 t2.Path = "/hi/city" |
| 141 | 139 |
| 142 expect := []*tqS.Task{t, t2} | 140 expect := []*tqS.Task{t, t2} |
| 143 | 141 |
| 144 » » » » » tasks, err := tq.AddMulti(expect, "defau
lt") | 142 » » » » » So(tq.AddMulti(expect, "default"), Shoul
dBeNil) |
| 145 » » » » » So(err, ShouldBeNil) | 143 » » » » » So(len(expect), ShouldEqual, 2) |
| 146 » » » » » So(len(tasks), ShouldEqual, 2) | 144 » » » » » So(len(tqt.GetScheduledTasks()["default"
]), ShouldEqual, 2) |
| 147 » » » » » So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 2) | |
| 148 | 145 |
| 149 for i := range expect { | 146 for i := range expect { |
| 150 Convey(fmt.Sprintf("task %d: %s"
, i, expect[i].Path), func() { | 147 Convey(fmt.Sprintf("task %d: %s"
, i, expect[i].Path), func() { |
| 151 » » » » » » » expect[i].Method = "POST
" | 148 » » » » » » » So(expect[i].Method, Sho
uldEqual, "POST") |
| 152 » » » » » » » expect[i].ETA = now | 149 » » » » » » » So(expect[i].ETA, Should
HappenOnOrBefore, now) |
| 153 » » » » » » » So(expect[i].Name, Shoul
dEqual, "") | 150 » » » » » » » So(len(expect[i].Name),
ShouldEqual, 500) |
| 154 » » » » » » » So(len(tasks[i].Name), S
houldEqual, 500) | |
| 155 » » » » » » » tasks[i].Name = "" | |
| 156 » » » » » » » So(tasks[i], ShouldResem
ble, expect[i]) | |
| 157 }) | 151 }) |
| 158 } | 152 } |
| 153 |
| 154 Convey("stats work too", func() { |
| 155 delay := -time.Second * 400 |
| 156 |
| 157 t := tq.NewTask("/somewhere") |
| 158 t.Delay = delay |
| 159 So(tq.Add(t, ""), ShouldBeNil) |
| 160 |
| 161 stats, err := tq.Stats("") |
| 162 So(err, ShouldBeNil) |
| 163 So(stats[0].Tasks, ShouldEqual,
3) |
| 164 So(stats[0].OldestETA, ShouldHap
penOnOrBefore, clock.Now(c).Add(delay)) |
| 165 |
| 166 _, err = tq.Stats("noexist") |
| 167 So(err.Error(), ShouldContainSub
string, "UNKNOWN_QUEUE") |
| 168 }) |
| 169 |
| 170 Convey("can purge all tasks", func() { |
| 171 So(tq.Add(&tqS.Task{Path: "/wut/
nerbs"}, ""), ShouldBeNil) |
| 172 So(tq.Purge(""), ShouldBeNil) |
| 173 |
| 174 So(len(tqt.GetScheduledTasks()["
default"]), ShouldEqual, 0) |
| 175 So(len(tqt.GetTombstonedTasks()[
"default"]), ShouldEqual, 0) |
| 176 So(len(tqt.GetTransactionTasks()
["default"]), ShouldEqual, 0) |
| 177 |
| 178 Convey("purging a queue which DN
E fails", func() { |
| 179 So(tq.Purge("noexist").E
rror(), ShouldContainSubstring, "UNKNOWN_QUEUE") |
| 180 }) |
| 181 }) |
| 182 |
| 159 }) | 183 }) |
| 160 }) | 184 }) |
| 161 | 185 |
| 162 Convey("Delete", func() { | 186 Convey("Delete", func() { |
| 163 t := &tqS.Task{Path: "/hello/world"} | 187 t := &tqS.Task{Path: "/hello/world"} |
| 164 » » » » tEnQ, err := tq.Add(t, "") | 188 » » » » So(tq.Add(t, ""), ShouldBeNil) |
| 165 » » » » So(err, ShouldBeNil) | |
| 166 | 189 |
| 167 Convey("works", func() { | 190 Convey("works", func() { |
| 168 t.Name = tEnQ.Name | |
| 169 err := tq.Delete(t, "") | 191 err := tq.Delete(t, "") |
| 170 So(err, ShouldBeNil) | 192 So(err, ShouldBeNil) |
| 171 » » » » » So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 0) | 193 » » » » » So(len(tqt.GetScheduledTasks()["default"
]), ShouldEqual, 0) |
| 172 » » » » » So(len(tq.GetTombstonedTasks()["default"
]), ShouldEqual, 1) | 194 » » » » » So(len(tqt.GetTombstonedTasks()["default
"]), ShouldEqual, 1) |
| 173 » » » » » So(tq.GetTombstonedTasks()["default"][tE
nQ.Name], ShouldResemble, tEnQ) | 195 » » » » » So(tqt.GetTombstonedTasks()["default"][t
.Name], ShouldResemble, t) |
| 174 }) | 196 }) |
| 175 | 197 |
| 176 Convey("cannot delete a task twice", func() { | 198 Convey("cannot delete a task twice", func() { |
| 177 » » » » » err := tq.Delete(tEnQ, "") | 199 » » » » » So(tq.Delete(t, ""), ShouldBeNil) |
| 178 » » » » » So(err, ShouldBeNil) | |
| 179 | 200 |
| 180 » » » » » err = tq.Delete(tEnQ, "") | 201 » » » » » So(tq.Delete(t, "").Error(), ShouldConta
inSubstring, "TOMBSTONED_TASK") |
| 181 » » » » » So(err.Error(), ShouldContainSubstring,
"TOMBSTONED_TASK") | |
| 182 | 202 |
| 183 Convey("but you can if you do a reset",
func() { | 203 Convey("but you can if you do a reset",
func() { |
| 184 » » » » » » tq.ResetTasks() | 204 » » » » » » tqt.ResetTasks() |
| 185 | 205 |
| 186 » » » » » » tEnQ, err := tq.Add(t, "") | 206 » » » » » » So(tq.Add(t, ""), ShouldBeNil) |
| 187 » » » » » » So(err, ShouldBeNil) | 207 » » » » » » So(tq.Delete(t, ""), ShouldBeNil
) |
| 188 » » » » » » err = tq.Delete(tEnQ, "") | |
| 189 » » » » » » So(err, ShouldBeNil) | |
| 190 }) | 208 }) |
| 191 }) | 209 }) |
| 192 | 210 |
| 193 Convey("cannot delete from bogus queues", func()
{ | 211 Convey("cannot delete from bogus queues", func()
{ |
| 194 err := tq.Delete(t, "wat") | 212 err := tq.Delete(t, "wat") |
| 195 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") | 213 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") |
| 196 }) | 214 }) |
| 197 | 215 |
| 198 Convey("cannot delete a missing task", func() { | 216 Convey("cannot delete a missing task", func() { |
| 199 t.Name = "tarntioarenstyw" | 217 t.Name = "tarntioarenstyw" |
| 200 err := tq.Delete(t, "") | 218 err := tq.Delete(t, "") |
| 201 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_TASK") | 219 So(err.Error(), ShouldContainSubstring,
"UNKNOWN_TASK") |
| 202 }) | 220 }) |
| 203 | 221 |
| 204 Convey("DeleteMulti also works", func() { | 222 Convey("DeleteMulti also works", func() { |
| 205 » » » » » t2 := dupTask(t) | 223 » » » » » t2 := t.Duplicate() |
| 224 » » » » » t2.Name = "" |
| 206 t2.Path = "/hi/city" | 225 t2.Path = "/hi/city" |
| 207 » » » » » tEnQ2, err := tq.Add(t2, "") | 226 » » » » » So(tq.Add(t2, ""), ShouldBeNil) |
| 208 » » » » » So(err, ShouldBeNil) | |
| 209 | 227 |
| 210 Convey("usually works", func() { | 228 Convey("usually works", func() { |
| 211 » » » » » » err = tq.DeleteMulti([]*tqS.Task
{tEnQ, tEnQ2}, "") | 229 » » » » » » So(tq.DeleteMulti([]*tqS.Task{t,
t2}, ""), ShouldBeNil) |
| 212 » » » » » » So(err, ShouldBeNil) | 230 » » » » » » So(len(tqt.GetScheduledTasks()["
default"]), ShouldEqual, 0) |
| 213 » » » » » » So(len(tq.GetScheduledTasks()["d
efault"]), ShouldEqual, 0) | 231 » » » » » » So(len(tqt.GetTombstonedTasks()[
"default"]), ShouldEqual, 2) |
| 214 » » » » » » So(len(tq.GetTombstonedTasks()["
default"]), ShouldEqual, 2) | |
| 215 }) | 232 }) |
| 216 }) | 233 }) |
| 217 }) | 234 }) |
| 218 }) | 235 }) |
| 219 | 236 |
| 220 Convey("works with transactions", func() { | 237 Convey("works with transactions", func() { |
| 221 t := &tqS.Task{Path: "/hello/world"} | 238 t := &tqS.Task{Path: "/hello/world"} |
| 222 » » » tEnQ, err := tq.Add(t, "") | 239 » » » So(tq.Add(t, ""), ShouldBeNil) |
| 223 » » » So(err, ShouldBeNil) | |
| 224 | 240 |
| 225 t2 := &tqS.Task{Path: "/hi/city"} | 241 t2 := &tqS.Task{Path: "/hi/city"} |
| 226 » » » tEnQ2, err := tq.Add(t2, "") | 242 » » » So(tq.Add(t2, ""), ShouldBeNil) |
| 227 » » » So(err, ShouldBeNil) | |
| 228 | 243 |
| 229 » » » err = tq.Delete(tEnQ2, "") | 244 » » » So(tq.Delete(t2, ""), ShouldBeNil) |
| 230 » » » So(err, ShouldBeNil) | |
| 231 | 245 |
| 232 Convey("can view regular tasks", func() { | 246 Convey("can view regular tasks", func() { |
| 233 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { | 247 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { |
| 234 » » » » » tq := tqS.Get(c).(interface { | 248 » » » » » tqt := tqS.Get(c).Raw().(tqS.Testable) |
| 235 » » » » » » tqS.Testable | |
| 236 » » » » » » tqS.Interface | |
| 237 » » » » » }) | |
| 238 | 249 |
| 239 » » » » » So(tq.GetScheduledTasks()["default"][tEn
Q.Name], ShouldResemble, tEnQ) | 250 » » » » » So(tqt.GetScheduledTasks()["default"][t.
Name], ShouldResemble, t) |
| 240 » » » » » So(tq.GetTombstonedTasks()["default"][tE
nQ2.Name], ShouldResemble, tEnQ2) | 251 » » » » » So(tqt.GetTombstonedTasks()["default"][t
2.Name], ShouldResemble, t2) |
| 241 » » » » » So(tq.GetTransactionTasks()["default"],
ShouldBeNil) | 252 » » » » » So(tqt.GetTransactionTasks()["default"],
ShouldBeNil) |
| 242 return nil | 253 return nil |
| 243 }, nil) | 254 }, nil) |
| 244 }) | 255 }) |
| 245 | 256 |
| 246 Convey("can add a new task", func() { | 257 Convey("can add a new task", func() { |
| 247 » » » » tEnQ3 := (*tqS.Task)(nil) | 258 » » » » t3 := &tqS.Task{Path: "/sandwitch/victory"} |
| 259 |
| 260 » » » » err := dsS.Get(c).RunInTransaction(func(c contex
t.Context) error { |
| 261 » » » » » tq := tqS.Get(c) |
| 262 » » » » » tqt := tq.Raw().(tqS.Testable) |
| 263 |
| 264 » » » » » So(tq.Add(t3, ""), ShouldBeNil) |
| 265 » » » » » So(t3.Name, ShouldEqual, "") |
| 266 |
| 267 » » » » » So(tqt.GetScheduledTasks()["default"][t.
Name], ShouldResemble, t) |
| 268 » » » » » So(tqt.GetTombstonedTasks()["default"][t
2.Name], ShouldResemble, t2) |
| 269 » » » » » So(tqt.GetTransactionTasks()["default"][
0], ShouldResemble, t3) |
| 270 » » » » » return nil |
| 271 » » » » }, nil) |
| 272 » » » » So(err, ShouldBeNil) |
| 273 |
| 274 » » » » for _, tsk := range tqt.GetScheduledTasks()["def
ault"] { |
| 275 » » » » » if tsk.Name == t.Name { |
| 276 » » » » » » So(tsk, ShouldResemble, t) |
| 277 » » » » » } else { |
| 278 » » » » » » tsk.Name = "" |
| 279 » » » » » » So(tsk, ShouldResemble, t3) |
| 280 » » » » » } |
| 281 » » » » } |
| 282 |
| 283 » » » » So(tqt.GetTombstonedTasks()["default"][t2.Name],
ShouldResemble, t2) |
| 284 » » » » So(tqt.GetTransactionTasks()["default"], ShouldB
eNil) |
| 285 » » » }) |
| 286 |
| 287 » » » Convey("can add a new task (but reset the state in a tes
t)", func() { |
| 288 » » » » t3 := &tqS.Task{Path: "/sandwitch/victory"} |
| 289 |
| 290 » » » » ttq := tqS.Interface(nil) |
| 248 | 291 |
| 249 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { | 292 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { |
| 250 » » » » » tq := tqS.Get(c).(interface { | 293 » » » » » ttq = tqS.Get(c) |
| 251 » » » » » » tqS.Testable | 294 » » » » » tqt := ttq.Raw().(tqS.Testable) |
| 252 » » » » » » tqS.Interface | |
| 253 » » » » » }) | |
| 254 | 295 |
| 255 » » » » » t3 := &tqS.Task{Path: "/sandwitch/victor
y"} | 296 » » » » » So(ttq.Add(t3, ""), ShouldBeNil) |
| 256 » » » » » tEnQ3, err = tq.Add(t3, "") | |
| 257 » » » » » So(err, ShouldBeNil) | |
| 258 | 297 |
| 259 » » » » » So(tq.GetScheduledTasks()["default"][tEn
Q.Name], ShouldResemble, tEnQ) | 298 » » » » » So(tqt.GetScheduledTasks()["default"][t.
Name], ShouldResemble, t) |
| 260 » » » » » So(tq.GetTombstonedTasks()["default"][tE
nQ2.Name], ShouldResemble, tEnQ2) | 299 » » » » » So(tqt.GetTombstonedTasks()["default"][t
2.Name], ShouldResemble, t2) |
| 261 » » » » » So(tq.GetTransactionTasks()["default"][0
], ShouldResemble, tEnQ3) | 300 » » » » » So(tqt.GetTransactionTasks()["default"][
0], ShouldResemble, t3) |
| 262 » » » » » return nil | |
| 263 » » » » }, nil) | |
| 264 | 301 |
| 265 » » » » // name gets generated at transaction-commit-tim
e | 302 » » » » » tqt.ResetTasks() |
| 266 » » » » for name := range tq.GetScheduledTasks()["defaul
t"] { | |
| 267 » » » » » if name == tEnQ.Name { | |
| 268 » » » » » » continue | |
| 269 » » » » » } | |
| 270 » » » » » tEnQ3.Name = name | |
| 271 » » » » » break | |
| 272 » » » » } | |
| 273 | 303 |
| 274 » » » » So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) | 304 » » » » » So(len(tqt.GetScheduledTasks()["default"
]), ShouldEqual, 0) |
| 275 » » » » So(tq.GetScheduledTasks()["default"][tEnQ3.Name]
, ShouldResemble, tEnQ3) | 305 » » » » » So(len(tqt.GetTombstonedTasks()["default
"]), ShouldEqual, 0) |
| 276 » » » » So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) | 306 » » » » » So(len(tqt.GetTransactionTasks()["defaul
t"]), ShouldEqual, 0) |
| 277 » » » » So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) | |
| 278 » » » }) | |
| 279 | |
| 280 » » » Convey("can a new task (but reset the state in a test)",
func() { | |
| 281 » » » » tEnQ3 := (*tqS.Task)(nil) | |
| 282 | |
| 283 » » » » ttq := interface { | |
| 284 » » » » » tqS.Testable | |
| 285 » » » » » tqS.Interface | |
| 286 » » » » }(nil) | |
| 287 | |
| 288 » » » » dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { | |
| 289 » » » » » ttq = tqS.Get(c).(interface { | |
| 290 » » » » » » tqS.Testable | |
| 291 » » » » » » tqS.Interface | |
| 292 » » » » » }) | |
| 293 | |
| 294 » » » » » t3 := &tqS.Task{Path: "/sandwitch/victor
y"} | |
| 295 » » » » » tEnQ3, err = ttq.Add(t3, "") | |
| 296 » » » » » So(err, ShouldBeNil) | |
| 297 | |
| 298 » » » » » So(ttq.GetScheduledTasks()["default"][tE
nQ.Name], ShouldResemble, tEnQ) | |
| 299 » » » » » So(ttq.GetTombstonedTasks()["default"][t
EnQ2.Name], ShouldResemble, tEnQ2) | |
| 300 » » » » » So(ttq.GetTransactionTasks()["default"][
0], ShouldResemble, tEnQ3) | |
| 301 | |
| 302 » » » » » ttq.ResetTasks() | |
| 303 | |
| 304 » » » » » So(len(ttq.GetScheduledTasks()["default"
]), ShouldEqual, 0) | |
| 305 » » » » » So(len(ttq.GetTombstonedTasks()["default
"]), ShouldEqual, 0) | |
| 306 » » » » » So(len(ttq.GetTransactionTasks()["defaul
t"]), ShouldEqual, 0) | |
| 307 | 307 |
| 308 return nil | 308 return nil |
| 309 }, nil) | 309 }, nil) |
| 310 | 310 |
| 311 » » » » So(len(tq.GetScheduledTasks()["default"]), Shoul
dEqual, 0) | 311 » » » » So(len(tqt.GetScheduledTasks()["default"]), Shou
ldEqual, 0) |
| 312 » » » » So(len(tq.GetTombstonedTasks()["default"]), Shou
ldEqual, 0) | 312 » » » » So(len(tqt.GetTombstonedTasks()["default"]), Sho
uldEqual, 0) |
| 313 » » » » So(len(tq.GetTransactionTasks()["default"]), Sho
uldEqual, 0) | 313 » » » » So(len(tqt.GetTransactionTasks()["default"]), Sh
ouldEqual, 0) |
| 314 | 314 |
| 315 Convey("and reusing a closed context is bad time
s", func() { | 315 Convey("and reusing a closed context is bad time
s", func() { |
| 316 » » » » » _, err := ttq.Add(nil, "") | 316 » » » » » So(ttq.Add(nil, "").Error(), ShouldConta
inSubstring, "expired") |
| 317 » » » » » So(err.Error(), ShouldContainSubstring,
"expired") | |
| 318 }) | 317 }) |
| 319 }) | 318 }) |
| 320 | 319 |
| 321 Convey("you can AddMulti as well", func() { | 320 Convey("you can AddMulti as well", func() { |
| 322 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { | 321 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { |
| 323 » » » » » tq := tqS.Get(c).(interface { | 322 » » » » » tq := tqS.Get(c) |
| 324 » » » » » » tqS.Testable | 323 » » » » » tqt := tq.Raw().(tqS.Testable) |
| 325 » » » » » » tqS.Interface | 324 |
| 326 » » » » » }) | 325 » » » » » t.Name = "" |
| 327 » » » » » _, err := tq.AddMulti([]*tqS.Task{t, t,
t}, "") | 326 » » » » » tasks := []*tqS.Task{t.Duplicate(), t.Du
plicate(), t.Duplicate()} |
| 328 » » » » » So(err, ShouldBeNil) | 327 » » » » » So(tq.AddMulti(tasks, ""), ShouldBeNil) |
| 329 » » » » » So(len(tq.GetScheduledTasks()["default"]
), ShouldEqual, 1) | 328 » » » » » So(len(tqt.GetScheduledTasks()["default"
]), ShouldEqual, 1) |
| 330 » » » » » So(len(tq.GetTransactionTasks()["default
"]), ShouldEqual, 3) | 329 » » » » » So(len(tqt.GetTransactionTasks()["defaul
t"]), ShouldEqual, 3) |
| 331 return nil | 330 return nil |
| 332 }, nil) | 331 }, nil) |
| 333 » » » » So(len(tq.GetScheduledTasks()["default"]), Shoul
dEqual, 4) | 332 » » » » So(len(tqt.GetScheduledTasks()["default"]), Shou
ldEqual, 4) |
| 334 » » » » So(len(tq.GetTransactionTasks()["default"]), Sho
uldEqual, 0) | 333 » » » » So(len(tqt.GetTransactionTasks()["default"]), Sh
ouldEqual, 0) |
| 335 }) | 334 }) |
| 336 | 335 |
| 337 Convey("unless you add too many things", func() { | 336 Convey("unless you add too many things", func() { |
| 338 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { | 337 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { |
| 339 for i := 0; i < 5; i++ { | 338 for i := 0; i < 5; i++ { |
| 340 » » » » » » _, err = tqS.Get(c).Add(t, "") | 339 » » » » » » So(tqS.Get(c).Add(t.Duplicate(),
""), ShouldBeNil) |
| 341 » » » » » » So(err, ShouldBeNil) | |
| 342 } | 340 } |
| 343 » » » » » _, err = tqS.Get(c).Add(t, "") | 341 » » » » » So(tqS.Get(c).Add(t, "").Error(), Should
ContainSubstring, "BAD_REQUEST") |
| 344 » » » » » So(err.Error(), ShouldContainSubstring,
"BAD_REQUEST") | |
| 345 return nil | 342 return nil |
| 346 }, nil) | 343 }, nil) |
| 347 }) | 344 }) |
| 348 | 345 |
| 349 Convey("unless you Add to a bad queue", func() { | 346 Convey("unless you Add to a bad queue", func() { |
| 350 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { | 347 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { |
| 351 » » » » » _, err = tqS.Get(c).Add(t, "meat") | 348 » » » » » So(tqS.Get(c).Add(t, "meat").Error(), Sh
ouldContainSubstring, "UNKNOWN_QUEUE") |
| 352 » » » » » So(err.Error(), ShouldContainSubstring,
"UNKNOWN_QUEUE") | |
| 353 | 349 |
| 354 Convey("unless you add it!", func() { | 350 Convey("unless you add it!", func() { |
| 355 » » » » » » tqS.Get(c).(tqS.Testable).Create
Queue("meat") | 351 » » » » » » tqS.Get(c).Raw().(tqS.Testable).
CreateQueue("meat") |
| 356 » » » » » » _, err = tqS.Get(c).Add(t, "meat
") | 352 » » » » » » So(tqS.Get(c).Add(t, "meat"), Sh
ouldBeNil) |
| 357 » » » » » » So(err, ShouldBeNil) | |
| 358 }) | 353 }) |
| 359 | 354 |
| 360 return nil | 355 return nil |
| 361 }, nil) | 356 }, nil) |
| 362 }) | 357 }) |
| 363 | 358 |
| 364 Convey("No other features are available, however", func(
) { | 359 Convey("No other features are available, however", func(
) { |
| 365 » » » » err := error(nil) | 360 » » » » dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { |
| 366 » » » » func() { | 361 » » » » » So(tqS.Get(c).Delete(t, "").Error(), Sho
uldContainSubstring, "cannot DeleteMulti from a transaction") |
| 367 » » » » » defer func() { err = recover().(error) }
() | 362 » » » » » So(tqS.Get(c).Purge("").Error(), ShouldC
ontainSubstring, "cannot Purge from a transaction") |
| 368 » » » » » dsS.Get(c).RunInTransaction(func(c conte
xt.Context) error { | 363 » » » » » _, err := tqS.Get(c).Stats("") |
| 369 » » » » » » tqS.Get(c).Delete(t, "") | 364 » » » » » So(err.Error(), ShouldContainSubstring,
"cannot Stats from a transaction") |
| 370 » » » » » » return nil | 365 » » » » » return nil |
| 371 » » » » » }, nil) | 366 » » » » }, nil) |
| 372 » » » » }() | |
| 373 » » » » So(err.Error(), ShouldContainSubstring, "TaskQue
ue.Delete") | |
| 374 }) | 367 }) |
| 375 | 368 |
| 376 Convey("adding a new task only happens if we don't errou
t", func() { | 369 Convey("adding a new task only happens if we don't errou
t", func() { |
| 377 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { | 370 dsS.Get(c).RunInTransaction(func(c context.Conte
xt) error { |
| 378 » » » » » t3 := &tqS.Task{Path: "/sandwitch/victor
y"} | 371 » » » » » t3 := tq.NewTask("/sandwitch/victory") |
| 379 » » » » » _, err = tqS.Get(c).Add(t3, "") | 372 » » » » » So(tqS.Get(c).Add(t3, ""), ShouldBeNil) |
| 380 » » » » » So(err, ShouldBeNil) | |
| 381 return fmt.Errorf("nooooo") | 373 return fmt.Errorf("nooooo") |
| 382 }, nil) | 374 }, nil) |
| 383 | 375 |
| 384 » » » » So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) | 376 » » » » So(tqt.GetScheduledTasks()["default"][t.Name], S
houldResemble, t) |
| 385 » » » » So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) | 377 » » » » So(tqt.GetTombstonedTasks()["default"][t2.Name],
ShouldResemble, t2) |
| 386 » » » » So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) | 378 » » » » So(tqt.GetTransactionTasks()["default"], ShouldB
eNil) |
| 387 }) | 379 }) |
| 388 | 380 |
| 389 Convey("likewise, a panic doesn't schedule anything", fu
nc() { | 381 Convey("likewise, a panic doesn't schedule anything", fu
nc() { |
| 390 func() { | 382 func() { |
| 391 defer func() { recover() }() | 383 defer func() { recover() }() |
| 392 dsS.Get(c).RunInTransaction(func(c conte
xt.Context) error { | 384 dsS.Get(c).RunInTransaction(func(c conte
xt.Context) error { |
| 393 tq := tqS.Get(c).(interface { | 385 tq := tqS.Get(c).(interface { |
| 394 tqS.Testable | 386 tqS.Testable |
| 395 tqS.Interface | 387 tqS.Interface |
| 396 }) | 388 }) |
| 397 | 389 |
| 398 » » » » » » t3 := &tqS.Task{Path: "/sandwitc
h/victory"} | 390 » » » » » » So(tq.Add(tq.NewTask("/sandwitch
/victory"), ""), ShouldBeNil) |
| 399 » » » » » » _, err = tq.Add(t3, "") | |
| 400 » » » » » » So(err, ShouldBeNil) | |
| 401 | 391 |
| 402 panic(fmt.Errorf("nooooo")) | 392 panic(fmt.Errorf("nooooo")) |
| 403 }, nil) | 393 }, nil) |
| 404 }() | 394 }() |
| 405 | 395 |
| 406 » » » » So(tq.GetScheduledTasks()["default"][tEnQ.Name],
ShouldResemble, tEnQ) | 396 » » » » So(tqt.GetScheduledTasks()["default"][t.Name], S
houldResemble, t) |
| 407 » » » » So(tq.GetTombstonedTasks()["default"][tEnQ2.Name
], ShouldResemble, tEnQ2) | 397 » » » » So(tqt.GetTombstonedTasks()["default"][t2.Name],
ShouldResemble, t2) |
| 408 » » » » So(tq.GetTransactionTasks()["default"], ShouldBe
Nil) | 398 » » » » So(tqt.GetTransactionTasks()["default"], ShouldB
eNil) |
| 409 }) | 399 }) |
| 410 | 400 |
| 411 }) | 401 }) |
| 412 }) | 402 }) |
| 413 } | 403 } |
| OLD | NEW |