go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/gce/api/config/v1/amount_test.go (about) 1 // Copyright 2019 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package config 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "google.golang.org/genproto/googleapis/type/dayofweek" 23 24 "go.chromium.org/luci/config/validation" 25 26 . "github.com/smartystreets/goconvey/convey" 27 . "go.chromium.org/luci/common/testing/assertions" 28 ) 29 30 func TestAmount(t *testing.T) { 31 t.Parallel() 32 33 Convey("getAmount", t, func() { 34 now := time.Time{} 35 So(now.Weekday(), ShouldEqual, time.Monday) 36 So(now.Hour(), ShouldEqual, 0) 37 38 Convey("min", func() { 39 a := &Amount{ 40 Min: 1, 41 Max: 3, 42 } 43 n, err := a.getAmount(0, now) 44 So(err, ShouldBeNil) 45 So(n, ShouldEqual, 1) 46 }) 47 48 Convey("max", func() { 49 a := &Amount{ 50 Min: 1, 51 Max: 3, 52 } 53 n, err := a.getAmount(4, now) 54 So(err, ShouldBeNil) 55 So(n, ShouldEqual, 3) 56 }) 57 58 Convey("proposed", func() { 59 a := &Amount{ 60 Min: 1, 61 Max: 3, 62 } 63 n, err := a.getAmount(2, now) 64 So(err, ShouldBeNil) 65 So(n, ShouldEqual, 2) 66 }) 67 68 Convey("equal", func() { 69 a := &Amount{ 70 Min: 2, 71 Max: 2, 72 } 73 n, err := a.getAmount(2, now) 74 So(err, ShouldBeNil) 75 So(n, ShouldEqual, 2) 76 }) 77 78 Convey("schedule", func() { 79 a := &Amount{ 80 Min: 1, 81 Max: 1, 82 Change: []*Schedule{ 83 { 84 Min: 2, 85 Max: 2, 86 Length: &TimePeriod{ 87 Time: &TimePeriod_Duration{ 88 Duration: "2h", 89 }, 90 }, 91 Start: &TimeOfDay{ 92 Day: dayofweek.DayOfWeek_SUNDAY, 93 Time: "23:00", 94 }, 95 }, 96 }, 97 } 98 n, err := a.getAmount(5, now) 99 So(err, ShouldBeNil) 100 So(n, ShouldEqual, 2) 101 102 n, err = a.getAmount(5, now.Add(time.Minute*59)) 103 So(err, ShouldBeNil) 104 So(n, ShouldEqual, 2) 105 106 n, err = a.getAmount(5, now.Add(time.Hour)) 107 So(err, ShouldBeNil) 108 So(n, ShouldEqual, 1) 109 110 n, err = a.getAmount(5, now.Add(time.Hour*-1)) 111 So(err, ShouldBeNil) 112 So(n, ShouldEqual, 2) 113 114 n, err = a.getAmount(5, now.Add(time.Minute*-61)) 115 So(err, ShouldBeNil) 116 So(n, ShouldEqual, 1) 117 }) 118 119 Convey("schedules", func() { 120 a := &Amount{ 121 Min: 1, 122 Max: 1, 123 Change: []*Schedule{ 124 { 125 Min: 2, 126 Max: 2, 127 Length: &TimePeriod{ 128 Time: &TimePeriod_Duration{ 129 Duration: "2h", 130 }, 131 }, 132 Start: &TimeOfDay{ 133 Day: dayofweek.DayOfWeek_SUNDAY, 134 Time: "23:00", 135 }, 136 }, 137 { 138 Min: 3, 139 Max: 3, 140 Length: &TimePeriod{ 141 Time: &TimePeriod_Duration{ 142 Duration: "1m", 143 }, 144 }, 145 Start: &TimeOfDay{ 146 Day: dayofweek.DayOfWeek_MONDAY, 147 Time: "1:00", 148 }, 149 }, 150 }, 151 } 152 n, err := a.getAmount(5, now) 153 So(err, ShouldBeNil) 154 So(n, ShouldEqual, 2) 155 156 n, err = a.getAmount(5, now.Add(time.Minute*59)) 157 So(err, ShouldBeNil) 158 So(n, ShouldEqual, 2) 159 160 n, err = a.getAmount(5, now.Add(time.Hour)) 161 So(err, ShouldBeNil) 162 So(n, ShouldEqual, 3) 163 164 n, err = a.getAmount(5, now.Add(time.Minute*61)) 165 So(err, ShouldBeNil) 166 So(n, ShouldEqual, 1) 167 }) 168 }) 169 170 Convey("Validate", t, func() { 171 c := &validation.Context{Context: context.Background()} 172 173 Convey("invalid", func() { 174 Convey("min", func() { 175 a := &Amount{ 176 Min: -1, 177 } 178 a.Validate(c) 179 errs := c.Finalize().(*validation.Error).Errors 180 So(errs, ShouldContainErr, "minimum amount must be non-negative") 181 }) 182 183 Convey("max", func() { 184 a := &Amount{ 185 Max: -1, 186 } 187 a.Validate(c) 188 errs := c.Finalize().(*validation.Error).Errors 189 So(errs, ShouldContainErr, "maximum amount must be non-negative") 190 }) 191 192 Convey("min > max", func() { 193 a := &Amount{ 194 Min: 2, 195 Max: 1, 196 } 197 a.Validate(c) 198 errs := c.Finalize().(*validation.Error).Errors 199 So(errs, ShouldContainErr, "minimum amount must not exceed maximum amount") 200 }) 201 202 Convey("schedule", func() { 203 Convey("empty", func() { 204 a := &Amount{ 205 Change: []*Schedule{ 206 {}, 207 }, 208 } 209 a.Validate(c) 210 errs := c.Finalize().(*validation.Error).Errors 211 So(errs, ShouldContainErr, "duration or seconds is required") 212 So(errs, ShouldContainErr, "time must match regex") 213 }) 214 215 Convey("conflict", func() { 216 Convey("same day", func() { 217 a := &Amount{ 218 Change: []*Schedule{ 219 { 220 Length: &TimePeriod{ 221 Time: &TimePeriod_Duration{ 222 Duration: "2h", 223 }, 224 }, 225 Start: &TimeOfDay{ 226 Day: dayofweek.DayOfWeek_WEDNESDAY, 227 Time: "1:00", 228 }, 229 }, 230 { 231 Start: &TimeOfDay{ 232 Day: dayofweek.DayOfWeek_WEDNESDAY, 233 Time: "2:59", 234 }, 235 }, 236 }, 237 } 238 a.Validate(c) 239 errs := c.Finalize().(*validation.Error).Errors 240 So(errs, ShouldContainErr, "start time is before") 241 }) 242 243 Convey("different day", func() { 244 a := &Amount{ 245 Change: []*Schedule{ 246 { 247 Length: &TimePeriod{ 248 Time: &TimePeriod_Duration{ 249 Duration: "48h", 250 }, 251 }, 252 Start: &TimeOfDay{ 253 Day: dayofweek.DayOfWeek_WEDNESDAY, 254 Time: "1:00", 255 }, 256 }, 257 { 258 Start: &TimeOfDay{ 259 Day: dayofweek.DayOfWeek_THURSDAY, 260 Time: "1:00", 261 }, 262 }, 263 }, 264 } 265 a.Validate(c) 266 errs := c.Finalize().(*validation.Error).Errors 267 So(errs, ShouldContainErr, "start time is before") 268 }) 269 270 Convey("different week", func() { 271 a := &Amount{ 272 Change: []*Schedule{ 273 { 274 Length: &TimePeriod{ 275 Time: &TimePeriod_Duration{ 276 Duration: "6d", 277 }, 278 }, 279 Start: &TimeOfDay{ 280 Day: dayofweek.DayOfWeek_TUESDAY, 281 Time: "1:00", 282 }, 283 }, 284 { 285 Start: &TimeOfDay{ 286 Day: dayofweek.DayOfWeek_MONDAY, 287 Time: "0:59", 288 }, 289 }, 290 }, 291 } 292 a.Validate(c) 293 errs := c.Finalize().(*validation.Error).Errors 294 So(errs, ShouldContainErr, "start time is before") 295 }) 296 }) 297 }) 298 }) 299 300 Convey("valid", func() { 301 Convey("empty", func() { 302 a := &Amount{} 303 a.Validate(c) 304 So(c.Finalize(), ShouldBeNil) 305 }) 306 307 Convey("non-empty", func() { 308 a := &Amount{ 309 Min: 1, 310 Max: 1, 311 } 312 a.Validate(c) 313 So(c.Finalize(), ShouldBeNil) 314 }) 315 316 Convey("schedule", func() { 317 Convey("empty", func() { 318 a := &Amount{ 319 Change: []*Schedule{}, 320 } 321 a.Validate(c) 322 So(c.Finalize(), ShouldBeNil) 323 }) 324 325 Convey("same day", func() { 326 a := &Amount{ 327 Change: []*Schedule{ 328 { 329 Length: &TimePeriod{ 330 Time: &TimePeriod_Duration{ 331 Duration: "2h", 332 }, 333 }, 334 Start: &TimeOfDay{ 335 Day: dayofweek.DayOfWeek_WEDNESDAY, 336 Time: "1:00", 337 }, 338 }, 339 { 340 Length: &TimePeriod{ 341 Time: &TimePeriod_Duration{ 342 Duration: "2h", 343 }, 344 }, 345 Start: &TimeOfDay{ 346 Day: dayofweek.DayOfWeek_WEDNESDAY, 347 Time: "3:00", 348 }, 349 }, 350 }, 351 } 352 a.Validate(c) 353 So(c.Finalize(), ShouldBeNil) 354 }) 355 356 Convey("different day", func() { 357 a := &Amount{ 358 Change: []*Schedule{ 359 { 360 Length: &TimePeriod{ 361 Time: &TimePeriod_Duration{ 362 Duration: "48h", 363 }, 364 }, 365 Start: &TimeOfDay{ 366 Day: dayofweek.DayOfWeek_WEDNESDAY, 367 Time: "1:00", 368 }, 369 }, 370 { 371 Length: &TimePeriod{ 372 Time: &TimePeriod_Duration{ 373 Duration: "48h", 374 }, 375 }, 376 Start: &TimeOfDay{ 377 Day: dayofweek.DayOfWeek_FRIDAY, 378 Time: "1:00", 379 }, 380 }, 381 }, 382 } 383 a.Validate(c) 384 So(c.Finalize(), ShouldBeNil) 385 }) 386 387 Convey("different week", func() { 388 a := &Amount{ 389 Change: []*Schedule{ 390 { 391 Length: &TimePeriod{ 392 Time: &TimePeriod_Duration{ 393 Duration: "6d", 394 }, 395 }, 396 Start: &TimeOfDay{ 397 Day: dayofweek.DayOfWeek_TUESDAY, 398 Location: "America/Los_Angeles", 399 Time: "1:00", 400 }, 401 }, 402 { 403 Length: &TimePeriod{ 404 Time: &TimePeriod_Duration{ 405 Duration: "2h", 406 }, 407 }, 408 Start: &TimeOfDay{ 409 Day: dayofweek.DayOfWeek_MONDAY, 410 Location: "America/Los_Angeles", 411 Time: "1:00", 412 }, 413 }, 414 }, 415 } 416 a.Validate(c) 417 So(c.Finalize(), ShouldBeNil) 418 }) 419 420 Convey("different location", func() { 421 a := &Amount{ 422 Change: []*Schedule{ 423 { 424 Length: &TimePeriod{ 425 Time: &TimePeriod_Duration{ 426 Duration: "1h", 427 }, 428 }, 429 Start: &TimeOfDay{ 430 Day: dayofweek.DayOfWeek_MONDAY, 431 Location: "America/Los_Angeles", 432 Time: "23:00", 433 }, 434 }, 435 { 436 Length: &TimePeriod{ 437 Time: &TimePeriod_Duration{ 438 Duration: "6h", 439 }, 440 }, 441 Start: &TimeOfDay{ 442 Day: dayofweek.DayOfWeek_TUESDAY, 443 Time: "1:00", 444 }, 445 }, 446 }, 447 } 448 a.Validate(c) 449 So(c.Finalize(), ShouldBeNil) 450 }) 451 }) 452 }) 453 }) 454 }