| 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 |