diff --git a/docs/content/docs.md b/docs/content/docs.md index 7c2eeceaf..d5987325e 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -279,19 +279,40 @@ For example, to limit bandwidth usage to 10 MBytes/s use `--bwlimit 10M` It is also possible to specify a "timetable" of limits, which will cause certain limits to be applied at certain times. To specify a timetable, format your -entries as "HH:MM,BANDWIDTH HH:MM,BANDWIDTH...". +entries as "WEEKDAY-HH:MM,BANDWIDTH WEEKDAY-HH:MM,BANDWIDTH..." where: +WEEKDAY is optional element. +It could be writen as whole world or only using 3 first characters. +HH:MM is an hour from 00:00 to 23:59. An example of a typical timetable to avoid link saturation during daytime working hours could be: `--bwlimit "08:00,512 12:00,10M 13:00,512 18:00,30M 23:00,off"` -In this example, the transfer bandwidth will be set to 512kBytes/sec at 8am. +In this example, the transfer bandwidth will be every day set to 512kBytes/sec at 8am. At noon, it will raise to 10Mbytes/s, and drop back to 512kBytes/sec at 1pm. At 6pm, the bandwidth limit will be set to 30MBytes/s, and at 11pm it will be completely disabled (full speed). Anything between 11pm and 8am will remain unlimited. +An example of timetable with WEEKDAY could be: + +`--bwlimit "Mon-00:00,512 Fri-23:59,10M Sat-10:00,1M Sun-20:00,off"` + +It mean that, the transfer bandwidh will be set to 512kBytes/sec on Monday. +It will raise to 10Mbytes/s before the end of Friday. +At 10:00 on Sunday it will be set to 1Mbyte/s. +From 20:00 at Sunday will be unlimited. + +Timeslots without weekday are extended to whole week. +So this one example: + +`--bwlimit "Mon-00:00,512 12:00,1M Sun-20:00,off"` + +Is equal to this: + +`--bwlimit "Mon-00:00,512Mon-12:00,1M Tue-12:00,1M Wed-12:00,1M Thu-12:00,1M Fri-12:00,1M Sat-12:00,1M Sun-12:00,1M Sun-20:00,off"` + Bandwidth limits only apply to the data transfer. They don't apply to the bandwidth of the directory listings etc. diff --git a/fs/bwtimetable.go b/fs/bwtimetable.go index 558bc9da1..f4f2c0686 100644 --- a/fs/bwtimetable.go +++ b/fs/bwtimetable.go @@ -11,8 +11,9 @@ import ( // BwTimeSlot represents a bandwidth configuration at a point in time. type BwTimeSlot struct { - HHMM int - Bandwidth SizeSuffix + DayOfTheWeek int + HHMM int + Bandwidth SizeSuffix } // BwTimetable contains all configured time slots. @@ -22,15 +23,64 @@ type BwTimetable []BwTimeSlot func (x BwTimetable) String() string { ret := []string{} for _, ts := range x { - ret = append(ret, fmt.Sprintf("%04.4d,%s", ts.HHMM, ts.Bandwidth.String())) + ret = append(ret, fmt.Sprintf("%s-%04.4d,%s", time.Weekday(ts.DayOfTheWeek), ts.HHMM, ts.Bandwidth.String())) } return strings.Join(ret, " ") } +// Basic hour format checking +func validateHour(HHMM string) error { + if len(HHMM) != 5 { + return errors.Errorf("invalid time specification (hh:mm): %q", HHMM) + } + hh, err := strconv.Atoi(HHMM[0:2]) + if err != nil { + return errors.Errorf("invalid hour in time specification %q: %v", HHMM, err) + } + if hh < 0 || hh > 23 { + return errors.Errorf("invalid hour (must be between 00 and 23): %q", hh) + } + mm, err := strconv.Atoi(HHMM[3:]) + if err != nil { + return errors.Errorf("invalid minute in time specification: %q: %v", HHMM, err) + } + if mm < 0 || mm > 59 { + return errors.Errorf("invalid minute (must be between 00 and 59): %q", hh) + } + return nil +} + +// Basic weekday format checking +func parseWeekday(dayOfWeek string) (int, error) { + dayOfWeek = strings.ToLower(dayOfWeek) + if dayOfWeek == "sun" || dayOfWeek == "sunday" { + return 0, nil + } + if dayOfWeek == "mon" || dayOfWeek == "monday" { + return 1, nil + } + if dayOfWeek == "tue" || dayOfWeek == "tuesday" { + return 2, nil + } + if dayOfWeek == "wed" || dayOfWeek == "wednesday" { + return 3, nil + } + if dayOfWeek == "thu" || dayOfWeek == "thursday" { + return 4, nil + } + if dayOfWeek == "fri" || dayOfWeek == "friday" { + return 5, nil + } + if dayOfWeek == "sat" || dayOfWeek == "saturday" { + return 6, nil + } + return 0, errors.Errorf("invalid weekday: %q", dayOfWeek) +} + // Set the bandwidth timetable. func (x *BwTimetable) Set(s string) error { // The timetable is formatted as: - // "hh:mm,bandwidth hh:mm,banwidth..." ex: "10:00,10G 11:30,1G 18:00,off" + // "dayOfWeek-hh:mm,bandwidth dayOfWeek-hh:mm,banwidth..." ex: "Mon-10:00,10G Mon-11:30,1G Tue-18:00,off" // If only a single bandwidth identifier is provided, we assume constant bandwidth. if len(s) == 0 { @@ -42,6 +92,7 @@ func (x *BwTimetable) Set(s string) error { if err := ts.Bandwidth.Set(s); err != nil { return err } + ts.DayOfTheWeek = 0 ts.HHMM = 0 *x = BwTimetable{ts} return nil @@ -50,69 +101,100 @@ func (x *BwTimetable) Set(s string) error { for _, tok := range strings.Split(s, " ") { tv := strings.Split(tok, ",") - // Format must be HH:MM,BW + // Format must be dayOfWeek-HH:MM,BW if len(tv) != 2 { return errors.Errorf("invalid time/bandwidth specification: %q", tok) } - // Basic timespec sanity checking - HHMM := tv[0] - if len(HHMM) != 5 { - return errors.Errorf("invalid time specification (hh:mm): %q", HHMM) - } - hh, err := strconv.Atoi(HHMM[0:2]) - if err != nil { - return errors.Errorf("invalid hour in time specification %q: %v", HHMM, err) - } - if hh < 0 || hh > 23 { - return errors.Errorf("invalid hour (must be between 00 and 23): %q", hh) - } - mm, err := strconv.Atoi(HHMM[3:]) - if err != nil { - return errors.Errorf("invalid minute in time specification: %q: %v", HHMM, err) - } - if mm < 0 || mm > 59 { - return errors.Errorf("invalid minute (must be between 00 and 59): %q", hh) - } + weekday := 0 + HHMM := "" + if !strings.Contains(tv[0], "-") { + HHMM = tv[0] + if err := validateHour(HHMM); err != nil { + return err + } + for i := 0; i < 7; i++ { + hh, _ := strconv.Atoi(HHMM[0:2]) + mm, _ := strconv.Atoi(HHMM[3:]) + ts := BwTimeSlot{ + DayOfTheWeek: i, + HHMM: (hh * 100) + mm, + } + if err := ts.Bandwidth.Set(tv[1]); err != nil { + return err + } + *x = append(*x, ts) + } + } else { + timespec := strings.Split(tv[0], "-") + if len(timespec) != 2 { + return errors.Errorf("invalid time specification: %q", tv[0]) + } + var err error + weekday, err = parseWeekday(timespec[0]) + if err != nil { + return err + } + HHMM = timespec[1] + if err := validateHour(HHMM); err != nil { + return err + } - ts := BwTimeSlot{ - HHMM: (hh * 100) + mm, + hh, _ := strconv.Atoi(HHMM[0:2]) + mm, _ := strconv.Atoi(HHMM[3:]) + ts := BwTimeSlot{ + DayOfTheWeek: weekday, + HHMM: (hh * 100) + mm, + } + // Bandwidth limit for this time slot. + if err := ts.Bandwidth.Set(tv[1]); err != nil { + return err + } + *x = append(*x, ts) } - // Bandwidth limit for this time slot. - if err := ts.Bandwidth.Set(tv[1]); err != nil { - return err - } - *x = append(*x, ts) } return nil } +// Difference in minutes between lateDayOfWeekHHMM and earlyDayOfWeekHHMM +func timeDiff(lateDayOfWeekHHMM int, earlyDayOfWeekHHMM int) int { + + lateTimeMinutes := (lateDayOfWeekHHMM / 10000) * 24 * 60 + lateTimeMinutes += ((lateDayOfWeekHHMM / 100) % 100) * 60 + lateTimeMinutes += lateDayOfWeekHHMM % 100 + + earlyTimeMinutes := (earlyDayOfWeekHHMM / 10000) * 24 * 60 + earlyTimeMinutes += ((earlyDayOfWeekHHMM / 100) % 100) * 60 + earlyTimeMinutes += earlyDayOfWeekHHMM % 100 + + return lateTimeMinutes - earlyTimeMinutes +} + // LimitAt returns a BwTimeSlot for the time requested. func (x BwTimetable) LimitAt(tt time.Time) BwTimeSlot { - // If the timetable is empty, we return an unlimited BwTimeSlot starting at midnight. + // If the timetable is empty, we return an unlimited BwTimeSlot starting at Sunday midnight. if len(x) == 0 { - return BwTimeSlot{HHMM: 0, Bandwidth: -1} + return BwTimeSlot{DayOfTheWeek: 0, HHMM: 0, Bandwidth: -1} } - HHMM := tt.Hour()*100 + tt.Minute() + dayOfWeekHHMM := int(tt.Weekday())*10000 + tt.Hour()*100 + tt.Minute() // By default, we return the last element in the timetable. This // satisfies two conditions: 1) If there's only one element it // will always be selected, and 2) The last element of the table - // will "wrap around" until overriden by an earlier time slot. + // will "wrap around" until overridden by an earlier time slot. // there's only one time slot in the timetable. ret := x[len(x)-1] - mindif := 0 first := true // Look for most recent time slot. for _, ts := range x { // Ignore the past - if HHMM < ts.HHMM { + if dayOfWeekHHMM < (ts.DayOfTheWeek*10000)+ts.HHMM { continue } - dif := ((HHMM / 100 * 60) + (HHMM % 100)) - ((ts.HHMM / 100 * 60) + (ts.HHMM % 100)) + dif := timeDiff(dayOfWeekHHMM, (ts.DayOfTheWeek*10000)+ts.HHMM) if first { mindif = dif first = false diff --git a/fs/bwtimetable_test.go b/fs/bwtimetable_test.go index 6c1fd3bd5..af57237fc 100644 --- a/fs/bwtimetable_test.go +++ b/fs/bwtimetable_test.go @@ -19,25 +19,104 @@ func TestBwTimetableSet(t *testing.T) { err bool }{ {"", BwTimetable{}, true}, - {"0", BwTimetable{BwTimeSlot{HHMM: 0, Bandwidth: 0}}, false}, - {"666", BwTimetable{BwTimeSlot{HHMM: 0, Bandwidth: 666 * 1024}}, false}, - {"10:20,666", BwTimetable{BwTimeSlot{HHMM: 1020, Bandwidth: 666 * 1024}}, false}, - { - "11:00,333 13:40,666 23:50,10M 23:59,off", - BwTimetable{ - BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}, - BwTimeSlot{HHMM: 1340, Bandwidth: 666 * 1024}, - BwTimeSlot{HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, - BwTimeSlot{HHMM: 2359, Bandwidth: -1}, - }, - false, - }, {"bad,bad", BwTimetable{}, true}, {"bad bad", BwTimetable{}, true}, {"bad", BwTimetable{}, true}, {"1000X", BwTimetable{}, true}, {"2401,666", BwTimetable{}, true}, {"1061,666", BwTimetable{}, true}, + {"bad-10:20,666", BwTimetable{}, true}, + {"Mon-bad,666", BwTimetable{}, true}, + {"Mon-10:20,bad", BwTimetable{}, true}, + { + "0", + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 0, HHMM: 0, Bandwidth: 0}, + }, + false, + }, + { + "666", + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 0, HHMM: 0, Bandwidth: 666 * 1024}, + }, + false, + }, + { + "10:20,666", + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1020, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1020, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1020, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1020, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1020, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1020, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1020, Bandwidth: 666 * 1024}, + }, + false, + }, + { + "11:00,333 13:40,666 23:50,10M 23:59,off", + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2350, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2359, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2359, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2359, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2359, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2359, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2359, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2359, Bandwidth: -1}, + }, + false, + }, + { + "Mon-11:00,333 Tue-13:40,666 Fri-00:00,10M Sat-10:00,off Sun-23:00,666", + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 0000, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1000, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2300, Bandwidth: 666 * 1024}, + }, + false, + }, + { + "Mon-11:00,333 Tue-13:40,666 Fri-00:00,10M 00:01,off Sun-23:00,666", + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 0000, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2300, Bandwidth: 666 * 1024}, + }, + false, + }, } { tt := BwTimetable{} err := tt.Set(test.in) @@ -59,52 +138,189 @@ func TestBwTimetableLimitAt(t *testing.T) { { BwTimetable{}, time.Date(2017, time.April, 20, 15, 0, 0, 0, time.UTC), - BwTimeSlot{HHMM: 0, Bandwidth: -1}, - }, - { - BwTimetable{BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}}, - time.Date(2017, time.April, 20, 15, 0, 0, 0, time.UTC), - BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 0, Bandwidth: -1}, }, { BwTimetable{ - BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}, - BwTimeSlot{HHMM: 1300, Bandwidth: 666 * 1024}, - BwTimeSlot{HHMM: 2301, Bandwidth: 1024 * 1024}, - BwTimeSlot{HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1100, Bandwidth: 333 * 1024}, + }, + time.Date(2017, time.April, 20, 15, 0, 0, 0, time.UTC), + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, + }, + { + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2350, Bandwidth: -1}, }, time.Date(2017, time.April, 20, 10, 15, 0, 0, time.UTC), - BwTimeSlot{HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2350, Bandwidth: -1}, }, { BwTimetable{ - BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}, - BwTimeSlot{HHMM: 1300, Bandwidth: 666 * 1024}, - BwTimeSlot{HHMM: 2301, Bandwidth: 1024 * 1024}, - BwTimeSlot{HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2350, Bandwidth: -1}, }, time.Date(2017, time.April, 20, 11, 0, 0, 0, time.UTC), - BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, }, { BwTimetable{ - BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}, - BwTimeSlot{HHMM: 1300, Bandwidth: 666 * 1024}, - BwTimeSlot{HHMM: 2301, Bandwidth: 1024 * 1024}, - BwTimeSlot{HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2350, Bandwidth: -1}, }, time.Date(2017, time.April, 20, 13, 1, 0, 0, time.UTC), - BwTimeSlot{HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1300, Bandwidth: 666 * 1024}, }, { BwTimetable{ - BwTimeSlot{HHMM: 1100, Bandwidth: 333 * 1024}, - BwTimeSlot{HHMM: 1300, Bandwidth: 666 * 1024}, - BwTimeSlot{HHMM: 2301, Bandwidth: 1024 * 1024}, - BwTimeSlot{HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1300, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2301, Bandwidth: 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 1, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 3, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 2350, Bandwidth: -1}, }, time.Date(2017, time.April, 20, 23, 59, 0, 0, time.UTC), - BwTimeSlot{HHMM: 2350, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 4, HHMM: 2350, Bandwidth: -1}, + }, + { + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 0000, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1000, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2300, Bandwidth: 666 * 1024}, + }, + time.Date(2017, time.April, 20, 23, 59, 0, 0, time.UTC), + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1340, Bandwidth: 666 * 1024}, + }, + { + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 0000, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1000, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2300, Bandwidth: 666 * 1024}, + }, + time.Date(2017, time.April, 21, 23, 59, 0, 0, time.UTC), + BwTimeSlot{DayOfTheWeek: 5, HHMM: 0000, Bandwidth: 10 * 1024 * 1024}, + }, + { + BwTimetable{ + BwTimeSlot{DayOfTheWeek: 1, HHMM: 1100, Bandwidth: 333 * 1024}, + BwTimeSlot{DayOfTheWeek: 2, HHMM: 1340, Bandwidth: 666 * 1024}, + BwTimeSlot{DayOfTheWeek: 5, HHMM: 0000, Bandwidth: 10 * 1024 * 1024}, + BwTimeSlot{DayOfTheWeek: 6, HHMM: 1000, Bandwidth: -1}, + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2300, Bandwidth: 666 * 1024}, + }, + time.Date(2017, time.April, 17, 10, 59, 0, 0, time.UTC), + BwTimeSlot{DayOfTheWeek: 0, HHMM: 2300, Bandwidth: 666 * 1024}, }, } { slot := test.tt.LimitAt(test.now)