Skip to content

Commit

Permalink
Merge pull request #618 from grobinson-grafana/grobinson/add-status-at
Browse files Browse the repository at this point in the history
Add StatusAt method for Alert struct
  • Loading branch information
roidelapluie committed Apr 15, 2024
2 parents 0234594 + 506a12c commit ea817bb
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 7 deletions.
27 changes: 26 additions & 1 deletion model/alert.go
Expand Up @@ -75,7 +75,12 @@ func (a *Alert) ResolvedAt(ts time.Time) bool {

// Status returns the status of the alert.
func (a *Alert) Status() AlertStatus {
if a.Resolved() {
return a.StatusAt(time.Now())
}

// StatusAt returns the status of the alert at the given timestamp.
func (a *Alert) StatusAt(ts time.Time) AlertStatus {
if a.ResolvedAt(ts) {
return AlertResolved
}
return AlertFiring
Expand Down Expand Up @@ -127,10 +132,30 @@ func (as Alerts) HasFiring() bool {
return false
}

// HasFiringAt returns true iff one of the alerts is not resolved
// at the time ts.
func (as Alerts) HasFiringAt(ts time.Time) bool {
for _, a := range as {
if !a.ResolvedAt(ts) {
return true
}
}
return false
}

// Status returns StatusFiring iff at least one of the alerts is firing.
func (as Alerts) Status() AlertStatus {
if as.HasFiring() {
return AlertFiring
}
return AlertResolved
}

// StatusAt returns StatusFiring iff at least one of the alerts is firing
// at the time ts.
func (as Alerts) StatusAt(ts time.Time) AlertStatus {
if as.HasFiringAt(ts) {
return AlertFiring
}
return AlertResolved
}
95 changes: 89 additions & 6 deletions model/alert_test.go
Expand Up @@ -133,8 +133,8 @@ func TestAlert(t *testing.T) {
t.Errorf("expected %s, but got %s", expected, actual)
}

actualStatus := string(alert.Status())
expectedStatus := "firing"
actualStatus := alert.Status()
expectedStatus := AlertStatus("firing")

if actualStatus != expectedStatus {
t.Errorf("expected alertStatus %s, but got %s", expectedStatus, actualStatus)
Expand All @@ -150,19 +150,55 @@ func TestAlert(t *testing.T) {
EndsAt: ts2,
}

if !alert.Resolved() {
t.Error("expected alert to be resolved, but it was not")
}

actual = fmt.Sprint(alert)
expected = "[d181d0f][resolved]"

if actual != expected {
t.Errorf("expected %s, but got %s", expected, actual)
}

actualStatus = string(alert.Status())
actualStatus = alert.Status()
expectedStatus = "resolved"

if actualStatus != expectedStatus {
t.Errorf("expected alertStatus %s, but got %s", expectedStatus, actualStatus)
}

// Verifying that ResolvedAt works for different times
if alert.ResolvedAt(ts1) {
t.Error("unexpected alert was resolved at start time")
}
if alert.ResolvedAt(ts2.Add(-time.Millisecond)) {
t.Error("unexpected alert was resolved before it ended")
}
if !alert.ResolvedAt(ts2) {
t.Error("expected alert to be resolved at end time")
}
if !alert.ResolvedAt(ts2.Add(time.Millisecond)) {
t.Error("expected alert to be resolved after it ended")
}

// Verifying that StatusAt works for different times
actualStatus = alert.StatusAt(ts1)
if actualStatus != "firing" {
t.Errorf("expected alert to be firing at start time, but got %s", actualStatus)
}
actualStatus = alert.StatusAt(ts1.Add(-time.Millisecond))
if actualStatus != "firing" {
t.Errorf("expected alert to be firing before it ended, but got %s", actualStatus)
}
actualStatus = alert.StatusAt(ts2)
if actualStatus != "resolved" {
t.Errorf("expected alert to be resolved at end time, but got %s", actualStatus)
}
actualStatus = alert.StatusAt(ts2.Add(time.Millisecond))
if actualStatus != "resolved" {
t.Errorf("expected alert to be resolved after it ended, but got %s", actualStatus)
}
}

func TestSortAlerts(t *testing.T) {
Expand Down Expand Up @@ -228,18 +264,19 @@ func TestSortAlerts(t *testing.T) {
}

func TestAlertsStatus(t *testing.T) {
ts := time.Now()
firingAlerts := Alerts{
{
Labels: LabelSet{
"foo": "bar",
},
StartsAt: time.Now(),
StartsAt: ts,
},
{
Labels: LabelSet{
"bar": "baz",
},
StartsAt: time.Now(),
StartsAt: ts,
},
}

Expand All @@ -250,7 +287,12 @@ func TestAlertsStatus(t *testing.T) {
t.Errorf("expected status %s, but got %s", expectedStatus, actualStatus)
}

ts := time.Now()
actualStatus = firingAlerts.StatusAt(ts)
if actualStatus != expectedStatus {
t.Errorf("expected status %s, but got %s", expectedStatus, actualStatus)
}

ts = time.Now()
resolvedAlerts := Alerts{
{
Labels: LabelSet{
Expand All @@ -270,7 +312,48 @@ func TestAlertsStatus(t *testing.T) {

actualStatus = resolvedAlerts.Status()
expectedStatus = AlertResolved
if actualStatus != expectedStatus {
t.Errorf("expected status %s, but got %s", expectedStatus, actualStatus)
}

actualStatus = resolvedAlerts.StatusAt(ts)
expectedStatus = AlertResolved
if actualStatus != expectedStatus {
t.Errorf("expected status %s, but got %s", expectedStatus, actualStatus)
}

ts = time.Now()
mixedAlerts := Alerts{
{
Labels: LabelSet{
"foo": "bar",
},
StartsAt: ts.Add(-1 * time.Minute),
EndsAt: ts.Add(5 * time.Minute),
},
{
Labels: LabelSet{
"bar": "baz",
},
StartsAt: ts.Add(-1 * time.Minute),
EndsAt: ts,
},
}

actualStatus = mixedAlerts.Status()
expectedStatus = AlertFiring
if actualStatus != expectedStatus {
t.Errorf("expected status %s, but got %s", expectedStatus, actualStatus)
}

actualStatus = mixedAlerts.StatusAt(ts)
expectedStatus = AlertFiring
if actualStatus != expectedStatus {
t.Errorf("expected status %s, but got %s", expectedStatus, actualStatus)
}

actualStatus = mixedAlerts.StatusAt(ts.Add(5 * time.Minute))
expectedStatus = AlertResolved
if actualStatus != expectedStatus {
t.Errorf("expected status %s, but got %s", expectedStatus, actualStatus)
}
Expand Down

0 comments on commit ea817bb

Please sign in to comment.