Skip to content

Commit 190d201

Browse files
Return the names of all time intervals
Signed-off-by: George Robinson <george.robinson@grafana.com>
1 parent 36db0f4 commit 190d201

File tree

2 files changed

+79
-88
lines changed

2 files changed

+79
-88
lines changed

timeinterval/timeinterval.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Intervener struct {
3434
}
3535

3636
func (i *Intervener) Mutes(names []string, now time.Time) (bool, []string, error) {
37+
var in []string
3738
for _, name := range names {
3839
interval, ok := i.intervals[name]
3940
if !ok {
@@ -42,12 +43,12 @@ func (i *Intervener) Mutes(names []string, now time.Time) (bool, []string, error
4243

4344
for _, ti := range interval {
4445
if ti.ContainsTime(now.UTC()) {
45-
return true, []string{name}, nil
46+
in = append(in, name)
4647
}
4748
}
4849
}
4950

50-
return false, nil, nil
51+
return len(in) > 0, in, nil
5152
}
5253

5354
func NewIntervener(ti map[string][]TimeInterval) *Intervener {

timeinterval/timeinterval_test.go

Lines changed: 76 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package timeinterval
1616
import (
1717
"encoding/json"
1818
"reflect"
19+
"sort"
1920
"testing"
2021
"time"
2122

@@ -662,100 +663,89 @@ func mustLoadLocation(name string) *time.Location {
662663
}
663664

664665
func TestIntervener_Mutes(t *testing.T) {
665-
// muteIn mutes alerts outside business hours in November, using the +1100 timezone.
666-
muteIn := `
667-
---
668-
- weekdays:
669-
- monday:friday
670-
location: Australia/Sydney
671-
months:
672-
- November
673-
times:
674-
- start_time: 00:00
675-
end_time: 09:00
676-
- start_time: 17:00
677-
end_time: 24:00
678-
- weekdays:
679-
- saturday
680-
- sunday
681-
months:
682-
- November
683-
location: 'Australia/Sydney'
684-
`
685-
intervalName := "test"
686-
var intervals []TimeInterval
687-
err := yaml.Unmarshal([]byte(muteIn), &intervals)
688-
require.NoError(t, err)
689-
m := map[string][]TimeInterval{intervalName: intervals}
690-
691-
tc := []struct {
692-
name string
693-
firedAt string
694-
expected bool
695-
err error
696-
}{
697-
{
698-
name: "Should not mute on Friday during business hours",
699-
firedAt: "19 Nov 21 13:00 +1100",
700-
expected: false,
701-
},
702-
{
703-
name: "Should not mute on a Tuesday before 5pm",
704-
firedAt: "16 Nov 21 16:59 +1100",
705-
expected: false,
706-
},
707-
{
708-
name: "Should mute on a Saturday",
709-
firedAt: "20 Nov 21 10:00 +1100",
710-
expected: true,
711-
},
712-
{
713-
name: "Should mute before 9am on a Wednesday",
714-
firedAt: "17 Nov 21 05:00 +1100",
715-
expected: true,
716-
},
717-
{
718-
name: "Should mute even if we are in a different timezone (KST)",
719-
firedAt: "14 Nov 21 20:00 +0900",
720-
expected: true,
721-
},
722-
{
723-
name: "Should mute even if the timezone is UTC",
724-
firedAt: "14 Nov 21 21:30 +0000",
725-
expected: true,
726-
},
727-
{
728-
name: "Should not mute different timezone (KST)",
729-
firedAt: "15 Nov 22 14:30 +0900",
730-
expected: false,
731-
},
732-
{
733-
name: "Should mute in a different timezone (PET)",
734-
firedAt: "15 Nov 21 02:00 -0500",
735-
expected: true,
736-
},
666+
sydney, err := time.LoadLocation("Australia/Sydney")
667+
if err != nil {
668+
t.Fatalf("Failed to load location Australia/Sydney: %s", err)
669+
}
670+
eveningsAndWeekends := map[string][]TimeInterval{
671+
"evenings": {{
672+
Times: []TimeRange{{
673+
StartMinute: 0, // 00:00
674+
EndMinute: 540, // 09:00
675+
}, {
676+
StartMinute: 1020, // 17:00
677+
EndMinute: 1440, // 24:00
678+
}},
679+
Location: &Location{Location: sydney},
680+
}},
681+
"weekends": {{
682+
Weekdays: []WeekdayRange{{
683+
InclusiveRange: InclusiveRange{Begin: 6, End: 6}, // Saturday
684+
}, {
685+
InclusiveRange: InclusiveRange{Begin: 0, End: 0}, // Sunday
686+
}},
687+
Location: &Location{Location: sydney},
688+
}},
737689
}
738690

739-
for _, tt := range tc {
740-
t.Run(tt.name, func(t *testing.T) {
741-
now, err := time.Parse(time.RFC822Z, tt.firedAt)
742-
require.NoError(t, err)
691+
tests := []struct {
692+
name string
693+
intervals map[string][]TimeInterval
694+
now time.Time
695+
mutedBy []string
696+
}{{
697+
name: "Should be muted outside working hours",
698+
intervals: eveningsAndWeekends,
699+
now: time.Date(2024, 1, 1, 0, 0, 0, 0, sydney),
700+
mutedBy: []string{"evenings"},
701+
}, {
702+
name: "Should not be muted during working hours",
703+
intervals: eveningsAndWeekends,
704+
now: time.Date(2024, 1, 1, 9, 0, 0, 0, sydney),
705+
mutedBy: nil,
706+
}, {
707+
name: "Should be muted during weekends",
708+
intervals: eveningsAndWeekends,
709+
now: time.Date(2024, 1, 6, 10, 0, 0, 0, sydney),
710+
mutedBy: []string{"weekends"},
711+
}, {
712+
name: "Should be muted during weekend evenings",
713+
intervals: eveningsAndWeekends,
714+
now: time.Date(2024, 1, 6, 17, 0, 0, 0, sydney),
715+
mutedBy: []string{"evenings", "weekends"},
716+
}, {
717+
name: "Should be muted at 12pm UTC on a weekday",
718+
intervals: eveningsAndWeekends,
719+
now: time.Date(2024, 1, 1, 10, 0, 0, 0, time.UTC),
720+
mutedBy: []string{"evenings"},
721+
}, {
722+
name: "Should be muted at 12pm UTC on a weekend",
723+
intervals: eveningsAndWeekends,
724+
now: time.Date(2024, 1, 6, 10, 0, 0, 0, time.UTC),
725+
mutedBy: []string{"evenings", "weekends"},
726+
}}
743727

744-
intervener := NewIntervener(m)
728+
for _, test := range tests {
729+
t.Run(test.name, func(t *testing.T) {
730+
intervener := NewIntervener(test.intervals)
745731

746-
expected, timeIntervalNames, err := intervener.Mutes([]string{intervalName}, now)
747-
if err != nil {
748-
require.Error(t, tt.err)
749-
require.False(t, tt.expected)
732+
// Get the names of all time intervals for the context.
733+
timeIntervalNames := make([]string, 0, len(test.intervals))
734+
for name := range test.intervals {
735+
timeIntervalNames = append(timeIntervalNames, name)
750736
}
737+
// Sort the names so we can compare mutedBy with test.mutedBy.
738+
sort.Strings(timeIntervalNames)
751739

740+
isMuted, mutedBy, err := intervener.Mutes(timeIntervalNames, test.now)
752741
require.NoError(t, err)
753-
require.Equal(t, expected, tt.expected)
754-
if tt.expected {
755-
require.Len(t, timeIntervalNames, 1)
756-
require.Equal(t, timeIntervalNames[0], intervalName)
742+
743+
if len(test.mutedBy) == 0 {
744+
require.False(t, isMuted)
745+
require.Empty(t, mutedBy)
757746
} else {
758-
require.Empty(t, timeIntervalNames)
747+
require.True(t, isMuted)
748+
require.Equal(t, test.mutedBy, mutedBy)
759749
}
760750
})
761751
}

0 commit comments

Comments
 (0)