go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/gce/api/config/v1/schedule.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 "time" 19 20 "google.golang.org/genproto/googleapis/type/dayofweek" 21 22 "go.chromium.org/luci/common/errors" 23 "go.chromium.org/luci/config/validation" 24 ) 25 26 // isSameDay returns whether the given time.Weekday and dayofweek.DayOfWeek 27 // represent the same day of the week. 28 func isSameDay(wkd time.Weekday, dow dayofweek.DayOfWeek) bool { 29 switch dow { 30 case dayofweek.DayOfWeek_DAY_OF_WEEK_UNSPECIFIED: 31 return false 32 case dayofweek.DayOfWeek_SUNDAY: 33 // time.Weekday has Sunday == 0, dayofweek.DayOfWeek has Sunday == 7. 34 return wkd == time.Sunday 35 default: 36 // For all other values, time.Weekday == dayofweek.DayOfWeek. 37 return int(wkd) == int(dow) 38 } 39 } 40 41 // mostRecentStart returns the most recent start time for this schedule relative 42 // to the given time. The date in the returned time.Time will be the most recent 43 // date falling on the day of the week specified in this schedule which results 44 // in the returned time being equal to or before the given time. 45 func (s *Schedule) mostRecentStart(now time.Time) (time.Time, error) { 46 t, err := s.GetStart().toTime() 47 if err != nil { 48 return time.Time{}, err 49 } 50 now = now.In(t.Location()) 51 // toTime returns a time relative to the current date. Change it to be relative to the given date. 52 t = time.Date(now.Year(), now.Month(), now.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location()) 53 if s.GetStart().Day == dayofweek.DayOfWeek_DAY_OF_WEEK_UNSPECIFIED { 54 return time.Time{}, errors.Reason("day must be specified").Err() 55 } 56 for !isSameDay(t.Weekday(), s.GetStart().Day) { 57 t = t.Add(time.Hour * -24) 58 } 59 if t.After(now) { 60 t = t.Add(time.Hour * -24 * 7) 61 } 62 return t, nil 63 } 64 65 // Validate validates this schedule. 66 func (s *Schedule) Validate(c *validation.Context) { 67 if s.GetMin() < 0 { 68 c.Errorf("minimum amount must be non-negative") 69 } 70 if s.GetMax() < 0 { 71 c.Errorf("maximum amount must be non-negative") 72 } 73 if s.GetMin() > s.GetMax() { 74 c.Errorf("minimum amount must not exceed maximum amount") 75 } 76 c.Enter("length") 77 s.GetLength().Validate(c) 78 switch n, err := s.Length.ToSeconds(); { 79 case err != nil: 80 c.Errorf("%s", err) 81 case n == 0: 82 c.Errorf("duration or seconds is required") 83 } 84 c.Exit() 85 c.Enter("start") 86 s.GetStart().Validate(c) 87 c.Exit() 88 }