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 model | 5 package model |
6 | 6 |
7 import ( | 7 import ( |
8 "testing" | 8 "testing" |
9 | 9 |
10 "golang.org/x/net/context" | 10 "golang.org/x/net/context" |
(...skipping 17 matching lines...) Expand all Loading... |
28 | 28 |
29 Convey("Execution", t, func() { | 29 Convey("Execution", t, func() { |
30 c := memory.Use(context.Background()) | 30 c := memory.Use(context.Background()) |
31 c = memlogger.Use(c) | 31 c = memlogger.Use(c) |
32 ds := datastore.Get(c) | 32 ds := datastore.Get(c) |
33 | 33 |
34 a := &Attempt{ID: *dm.NewAttemptID("q", 1)} | 34 a := &Attempt{ID: *dm.NewAttemptID("q", 1)} |
35 ak := ds.KeyForObj(a) | 35 ak := ds.KeyForObj(a) |
36 | 36 |
37 Convey("Revoke", func() { | 37 Convey("Revoke", func() { |
38 » » » e1 := &Execution{ID: 1, Attempt: ak, Token: []byte("good
tok")} | 38 » » » e1 := &Execution{ID: 1, Attempt: ak, Token: []byte("good
tok"), State: dm.Execution_RUNNING} |
39 So(ds.Put(e1), ShouldBeNil) | 39 So(ds.Put(e1), ShouldBeNil) |
40 | 40 |
41 e2 := *e1 | 41 e2 := *e1 |
42 So(e2.Revoke(c), ShouldBeNil) | 42 So(e2.Revoke(c), ShouldBeNil) |
43 | 43 |
44 So(e1.Token, ShouldResemble, []byte("good tok")) | 44 So(e1.Token, ShouldResemble, []byte("good tok")) |
45 So(ds.Get(e1), ShouldBeNil) | 45 So(ds.Get(e1), ShouldBeNil) |
46 So(e1.Token, ShouldBeNil) | 46 So(e1.Token, ShouldBeNil) |
47 }) | 47 }) |
48 | 48 |
49 Convey("Verify", func() { | 49 Convey("Verify", func() { |
50 e1 := &Execution{ID: 1, Attempt: ak, Token: []byte("good
tok")} | 50 e1 := &Execution{ID: 1, Attempt: ak, Token: []byte("good
tok")} |
51 So(ds.Put(e1), ShouldBeNil) | 51 So(ds.Put(e1), ShouldBeNil) |
52 | 52 |
53 auth := &dm.Execution_Auth{ | 53 auth := &dm.Execution_Auth{ |
54 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), | 54 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), |
55 Token: []byte("bad tok"), | 55 Token: []byte("bad tok"), |
56 } | 56 } |
57 | 57 |
58 _, _, err := AuthenticateExecution(c, auth) | 58 _, _, err := AuthenticateExecution(c, auth) |
59 » » » So(err, ShouldBeRPCUnauthenticated, "execution Auth") | 59 » » » So(err, ShouldBeRPCInternal, "execution Auth") |
60 | 60 |
61 So(ds.Put(a), ShouldBeNil) | 61 So(ds.Put(a), ShouldBeNil) |
62 _, _, err = AuthenticateExecution(c, auth) | 62 _, _, err = AuthenticateExecution(c, auth) |
63 » » » So(err, ShouldBeRPCUnauthenticated, "execution Auth") | 63 » » » So(err, ShouldBeRPCPermissionDenied, "execution Auth") |
64 | 64 |
65 a.CurExecution = 1 | 65 a.CurExecution = 1 |
66 So(ds.Put(a), ShouldBeNil) | 66 So(ds.Put(a), ShouldBeNil) |
67 _, _, err = AuthenticateExecution(c, auth) | 67 _, _, err = AuthenticateExecution(c, auth) |
68 » » » So(err, ShouldBeRPCUnauthenticated, "execution Auth") | 68 » » » So(err, ShouldBeRPCPermissionDenied, "execution Auth") |
69 | 69 |
70 a.State = dm.Attempt_EXECUTING | 70 a.State = dm.Attempt_EXECUTING |
71 So(ds.Put(a), ShouldBeNil) | 71 So(ds.Put(a), ShouldBeNil) |
72 _, _, err = AuthenticateExecution(c, auth) | 72 _, _, err = AuthenticateExecution(c, auth) |
73 » » » So(err, ShouldBeRPCUnauthenticated, "execution Auth") | 73 » » » So(err, ShouldBeRPCPermissionDenied, "execution Auth") |
74 | 74 |
75 e1.State = dm.Execution_RUNNING | 75 e1.State = dm.Execution_RUNNING |
76 So(ds.Put(e1), ShouldBeNil) | 76 So(ds.Put(e1), ShouldBeNil) |
77 _, _, err = AuthenticateExecution(c, auth) | 77 _, _, err = AuthenticateExecution(c, auth) |
78 » » » So(err, ShouldBeRPCUnauthenticated, "execution Auth") | 78 » » » So(err, ShouldBeRPCPermissionDenied, "execution Auth") |
79 | 79 |
80 auth.Token = []byte("good tok") | 80 auth.Token = []byte("good tok") |
81 atmpt, exe, err := AuthenticateExecution(c, auth) | 81 atmpt, exe, err := AuthenticateExecution(c, auth) |
82 So(err, ShouldBeNil) | 82 So(err, ShouldBeNil) |
83 | 83 |
84 So(atmpt, ShouldResemble, a) | 84 So(atmpt, ShouldResemble, a) |
85 So(exe, ShouldResemble, e1) | 85 So(exe, ShouldResemble, e1) |
86 }) | 86 }) |
87 | 87 |
88 Convey("Activate", func() { | 88 Convey("Activate", func() { |
89 e1 := &Execution{ | 89 e1 := &Execution{ |
90 ID: 1, | 90 ID: 1, |
91 Attempt: ak, | 91 Attempt: ak, |
92 Token: []byte("good tok"), | 92 Token: []byte("good tok"), |
93 } | 93 } |
94 a.CurExecution = 1 | 94 a.CurExecution = 1 |
95 So(ds.Put(a, e1), ShouldBeNil) | 95 So(ds.Put(a, e1), ShouldBeNil) |
96 | 96 |
97 auth := &dm.Execution_Auth{ | 97 auth := &dm.Execution_Auth{ |
98 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), | 98 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), |
99 Token: []byte("wrong tok"), | 99 Token: []byte("wrong tok"), |
100 } | 100 } |
101 | 101 |
102 Convey("wrong execution id", func() { | 102 Convey("wrong execution id", func() { |
103 auth.Id.Id++ | 103 auth.Id.Id++ |
104 _, _, err := ActivateExecution(c, auth, []byte("
wrong tok")) | 104 _, _, err := ActivateExecution(c, auth, []byte("
wrong tok")) |
105 » » » » So(err, ShouldBeRPCUnauthenticated, "execution A
uth") | 105 » » » » So(err, ShouldBeRPCInternal, "execution Auth") |
106 }) | 106 }) |
107 | 107 |
108 Convey("attempt bad state", func() { | 108 Convey("attempt bad state", func() { |
109 _, _, err := ActivateExecution(c, auth, []byte("
wrong tok")) | 109 _, _, err := ActivateExecution(c, auth, []byte("
wrong tok")) |
110 » » » » So(err, ShouldBeRPCUnauthenticated, "execution A
uth") | 110 » » » » So(err, ShouldBeRPCPermissionDenied, "execution
Auth") |
111 }) | 111 }) |
112 | 112 |
113 Convey("attempt executing", func() { | 113 Convey("attempt executing", func() { |
114 a.State = dm.Attempt_EXECUTING | 114 a.State = dm.Attempt_EXECUTING |
115 So(ds.Put(a), ShouldBeNil) | 115 So(ds.Put(a), ShouldBeNil) |
116 | 116 |
117 Convey("wrong execution state", func() { | 117 Convey("wrong execution state", func() { |
118 » » » » » e1.State = dm.Execution_CANCELLED | 118 » » » » » e1.State = dm.Execution_STOPPING |
119 So(ds.Put(e1), ShouldBeNil) | 119 So(ds.Put(e1), ShouldBeNil) |
120 _, _, err := ActivateExecution(c, auth,
[]byte("wrong token")) | 120 _, _, err := ActivateExecution(c, auth,
[]byte("wrong token")) |
121 » » » » » So(err, ShouldBeRPCUnauthenticated, "exe
cution Auth") | 121 » » » » » So(err, ShouldBeRPCPermissionDenied, "ex
ecution Auth") |
122 }) | 122 }) |
123 | 123 |
124 Convey("wrong token", func() { | 124 Convey("wrong token", func() { |
125 _, _, err := ActivateExecution(c, auth,
[]byte("wrong tok")) | 125 _, _, err := ActivateExecution(c, auth,
[]byte("wrong tok")) |
126 » » » » » So(err, ShouldBeRPCUnauthenticated, "exe
cution Auth") | 126 » » » » » So(err, ShouldBeRPCPermissionDenied, "ex
ecution Auth") |
127 }) | 127 }) |
128 | 128 |
129 Convey("correct token", func() { | 129 Convey("correct token", func() { |
130 auth.Token = []byte("good tok") | 130 auth.Token = []byte("good tok") |
131 memlogger.Reset(c) | |
132 newA, e, err := ActivateExecution(c, aut
h, []byte("new token")) | 131 newA, e, err := ActivateExecution(c, aut
h, []byte("new token")) |
133 memlogger.MustDumpStdout(c) | |
134 So(err, ShouldBeNil) | 132 So(err, ShouldBeNil) |
135 So(newA, ShouldResemble, a) | 133 So(newA, ShouldResemble, a) |
136 So(e.State, ShouldEqual, dm.Execution_RU
NNING) | 134 So(e.State, ShouldEqual, dm.Execution_RU
NNING) |
137 | 135 |
138 Convey("retry with different token fails
", func() { | 136 Convey("retry with different token fails
", func() { |
139 _, _, err = ActivateExecution(c,
auth, []byte("other token")) | 137 _, _, err = ActivateExecution(c,
auth, []byte("other token")) |
140 » » » » » » So(err, ShouldBeRPCUnauthenticat
ed, "execution Auth") | 138 » » » » » » So(err, ShouldBeRPCPermissionDen
ied, "execution Auth") |
141 }) | 139 }) |
142 | 140 |
143 Convey("retry with same token OK", func(
) { | 141 Convey("retry with same token OK", func(
) { |
144 auth.Token = []byte("new token") | 142 auth.Token = []byte("new token") |
145 _, _, err = ActivateExecution(c,
auth, []byte("new token")) | 143 _, _, err = ActivateExecution(c,
auth, []byte("new token")) |
146 So(err, ShouldBeNil) | 144 So(err, ShouldBeNil) |
147 }) | 145 }) |
148 }) | 146 }) |
149 }) | 147 }) |
150 | 148 |
(...skipping 11 matching lines...) Expand all Loading... |
162 a.CurExecution = 1 | 160 a.CurExecution = 1 |
163 a.State = dm.Attempt_EXECUTING | 161 a.State = dm.Attempt_EXECUTING |
164 So(ds.Put(a), ShouldBeNil) | 162 So(ds.Put(a), ShouldBeNil) |
165 | 163 |
166 auth := &dm.Execution_Auth{ | 164 auth := &dm.Execution_Auth{ |
167 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), | 165 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), |
168 Token: []byte("bad token"), | 166 Token: []byte("bad token"), |
169 } | 167 } |
170 | 168 |
171 _, _, err := InvalidateExecution(c, auth) | 169 _, _, err := InvalidateExecution(c, auth) |
172 » » » So(err, ShouldBeRPCUnauthenticated, "execution Auth") | 170 » » » So(err, ShouldBeRPCPermissionDenied, "execution Auth") |
173 | 171 |
174 auth.Token = []byte("good tok") | 172 auth.Token = []byte("good tok") |
175 _, _, err = InvalidateExecution(c, auth) | 173 _, _, err = InvalidateExecution(c, auth) |
176 So(err, ShouldBeNil) | 174 So(err, ShouldBeNil) |
177 | 175 |
178 So(ds.Get(e1), ShouldBeNil) | 176 So(ds.Get(e1), ShouldBeNil) |
179 So(e1.Token, ShouldBeNil) | 177 So(e1.Token, ShouldBeNil) |
180 | 178 |
181 _, _, err = InvalidateExecution(c, auth) | 179 _, _, err = InvalidateExecution(c, auth) |
182 » » » So(err, ShouldBeRPCUnauthenticated, "requires execution
Auth") | 180 » » » So(err, ShouldBeRPCPermissionDenied, "requires execution
Auth") |
183 }) | 181 }) |
184 | 182 |
185 Convey("failed invalidation", func() { | 183 Convey("failed invalidation", func() { |
186 e1 := &Execution{ | 184 e1 := &Execution{ |
187 ID: 1, | 185 ID: 1, |
188 Attempt: ak, | 186 Attempt: ak, |
189 Token: []byte("good tok"), | 187 Token: []byte("good tok"), |
190 State: dm.Execution_RUNNING, | 188 State: dm.Execution_RUNNING, |
191 } | 189 } |
192 So(ds.Put(e1), ShouldBeNil) | 190 So(ds.Put(e1), ShouldBeNil) |
193 a.CurExecution = 1 | 191 a.CurExecution = 1 |
194 a.State = dm.Attempt_EXECUTING | 192 a.State = dm.Attempt_EXECUTING |
195 So(ds.Put(a), ShouldBeNil) | 193 So(ds.Put(a), ShouldBeNil) |
196 | 194 |
197 auth := &dm.Execution_Auth{ | 195 auth := &dm.Execution_Auth{ |
198 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), | 196 Id: dm.NewExecutionID("q", a.ID.Id, uint32(e1
.ID)), |
199 Token: []byte("good tok"), | 197 Token: []byte("good tok"), |
200 } | 198 } |
201 | 199 |
202 c, fb := featureBreaker.FilterRDS(c, nil) | 200 c, fb := featureBreaker.FilterRDS(c, nil) |
203 fb.BreakFeatures(nil, "PutMulti") | 201 fb.BreakFeatures(nil, "PutMulti") |
204 | 202 |
205 _, _, err := InvalidateExecution(c, auth) | 203 _, _, err := InvalidateExecution(c, auth) |
206 » » » So(err, ShouldBeRPCInternal, "unable to invalidate Auth"
) | 204 » » » So(err, ShouldBeRPCPermissionDenied, "unable to invalida
te Auth") |
207 | 205 |
208 fb.UnbreakFeatures("PutMulti") | 206 fb.UnbreakFeatures("PutMulti") |
209 | 207 |
210 _, _, err = InvalidateExecution(c, auth) | 208 _, _, err = InvalidateExecution(c, auth) |
211 So(err, ShouldBeNil) | 209 So(err, ShouldBeNil) |
212 | 210 |
213 So(ds.Get(e1), ShouldBeNil) | 211 So(ds.Get(e1), ShouldBeNil) |
214 So(e1.Token, ShouldBeNil) | 212 So(e1.Token, ShouldBeNil) |
215 }) | 213 }) |
216 }) | 214 }) |
217 | 215 |
218 } | 216 } |
219 | 217 |
220 func TestExecutionToProto(t *testing.T) { | 218 func TestExecutionToProto(t *testing.T) { |
221 t.Parallel() | 219 t.Parallel() |
222 | 220 |
223 Convey("Test Execution.ToProto", t, func() { | 221 Convey("Test Execution.ToProto", t, func() { |
224 c := memory.Use(context.Background()) | 222 c := memory.Use(context.Background()) |
225 c = memlogger.Use(c) | 223 c = memlogger.Use(c) |
226 ds := datastore.Get(c) | 224 ds := datastore.Get(c) |
227 | 225 |
228 e := &Execution{ | 226 e := &Execution{ |
229 ID: 1, | 227 ID: 1, |
230 Attempt: ds.MakeKey("Attempt", "qst|fffffffe"), | 228 Attempt: ds.MakeKey("Attempt", "qst|fffffffe"), |
231 | 229 |
232 StateReason: "scheduled by DM", | |
233 | |
234 Created: testclock.TestTimeUTC, | 230 Created: testclock.TestTimeUTC, |
| 231 Modified: testclock.TestTimeUTC, |
235 DistributorToken: "id", | 232 DistributorToken: "id", |
236 DistributorURL: "https://thing.place.example.com/task/
id", | |
237 | 233 |
238 Token: []byte("secret"), | 234 Token: []byte("secret"), |
239 } | 235 } |
240 | 236 |
241 Convey("no id", func() { | 237 Convey("no id", func() { |
242 » » » So(e.ToProto(false), ShouldResemble, &dm.Execution{Data:
&dm.Execution_Data{ | 238 » » » exp := dm.NewExecutionScheduling() |
243 » » » » State: dm.Execution_SCHEDULED, | 239 » » » exp.Data.Created = google.NewTimestamp(testclock.TestTim
eUTC) |
244 » » » » StateReason: "scheduled by DM", | 240 » » » exp.Data.Modified = google.NewTimestamp(testclock.TestTi
meUTC) |
245 » » » » Created: google.NewTimestamp(testcloc
k.TestTimeUTC), | 241 » » » exp.Data.DistributorInfo = &dm.Execution_Data_Distributo
rInfo{Token: "id"} |
246 » » » » DistributorToken: "id", | 242 |
247 » » » » DistributorInfoUrl: "https://thing.place.example
.com/task/id", | 243 » » » So(e.ToProto(false), ShouldResemble, exp) |
248 » » » }}) | |
249 }) | 244 }) |
250 | 245 |
251 Convey("with id", func() { | 246 Convey("with id", func() { |
252 » » » So(e.ToProto(true), ShouldResemble, &dm.Execution{ | 247 » » » exp := dm.NewExecutionScheduling() |
253 » » » » Id: dm.NewExecutionID("qst", 1, 1), | 248 » » » exp.Id = dm.NewExecutionID("qst", 1, 1) |
254 » » » » Data: &dm.Execution_Data{ | 249 » » » exp.Data.Created = google.NewTimestamp(testclock.TestTim
eUTC) |
255 » » » » » State: dm.Execution_SCHEDUL
ED, | 250 » » » exp.Data.Modified = google.NewTimestamp(testclock.TestTi
meUTC) |
256 » » » » » StateReason: "scheduled by DM", | 251 » » » exp.Data.DistributorInfo = &dm.Execution_Data_Distributo
rInfo{Token: "id"} |
257 » » » » » Created: google.NewTimestamp(
testclock.TestTimeUTC), | 252 |
258 » » » » » DistributorToken: "id", | 253 » » » So(e.ToProto(true), ShouldResemble, exp) |
259 » » » » » DistributorInfoUrl: "https://thing.place
.example.com/task/id", | |
260 » » » » }, | |
261 » » » }) | |
262 }) | 254 }) |
263 }) | 255 }) |
264 } | 256 } |
OLD | NEW |