예제 #1
0
func TestDedupingNotifier(t *testing.T) {
	var (
		record   = &recordNotifier{}
		notifies = provider.NewMemNotifies(provider.NewMemData())
		deduper  = Dedup(notifies, record)
		ctx      = context.Background()
	)
	now := time.Now()

	ctx = WithReceiver(ctx, "name")
	ctx = WithRepeatInterval(ctx, time.Duration(100*time.Minute))
	ctx = WithNow(ctx, now)

	alerts := []*types.Alert{
		{
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "0"},
			},
		}, {
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "1"},
				EndsAt: now.Add(-5 * time.Minute),
			},
		},
	}

	// Set an initial NotifyInfo to ensure that on notification failure
	// nothing changes.
	nsBefore := []*types.NotifyInfo{
		nil,
		{
			Alert:     alerts[1].Fingerprint(),
			Receiver:  "name",
			Resolved:  false,
			Timestamp: now.Add(-10 * time.Minute),
		},
	}

	if err := notifies.Set(nsBefore...); err != nil {
		t.Fatalf("Setting notifies failed: %s", err)
	}

	deduper.notifier = &failNotifier{}
	if err := deduper.Notify(ctx, alerts...); err == nil {
		t.Fatalf("Fail notifier did not fail")
	}
	// After a failing notify the notifies data must be unchanged.
	nsCur, err := notifies.Get("name", alerts[0].Fingerprint(), alerts[1].Fingerprint())
	if err != nil {
		t.Fatalf("Error getting notify info: %s", err)
	}
	if !reflect.DeepEqual(nsBefore, nsCur) {
		t.Fatalf("Notify info data has changed unexpectedly")
	}

	deduper.notifier = record
	if err := deduper.Notify(ctx, alerts...); err != nil {
		t.Fatalf("Notify failed: %s", err)
	}

	if !reflect.DeepEqual(record.alerts, alerts) {
		t.Fatalf("Expected alerts %v, got %v", alerts, record.alerts)
	}
	nsCur, err = notifies.Get("name", alerts[0].Fingerprint(), alerts[1].Fingerprint())
	if err != nil {
		t.Fatalf("Error getting notifies: %s", err)
	}

	nsAfter := []*types.NotifyInfo{
		{
			Alert:     alerts[0].Fingerprint(),
			Receiver:  "name",
			Resolved:  false,
			Timestamp: now,
		},
		{
			Alert:     alerts[1].Fingerprint(),
			Receiver:  "name",
			Resolved:  true,
			Timestamp: now,
		},
	}

	for i, after := range nsAfter {
		cur := nsCur[i]

		// Hack correct timestamps back in if they are sane.
		if cur != nil && after.Timestamp.IsZero() {
			if cur.Timestamp.Before(now) {
				t.Fatalf("Wrong timestamp for notify %v", cur)
			}
			after.Timestamp = cur.Timestamp
		}

		if !reflect.DeepEqual(after, cur) {
			t.Errorf("Unexpected notifies, expected: %v, got: %v", after, cur)
		}
	}
}
예제 #2
0
func TestDedupingNotifier(t *testing.T) {
	var (
		record   = &recordNotifier{}
		notifies = provider.NewMemNotifies(provider.NewMemData())
		deduper  = Dedup(notifies, record)
		ctx      = context.Background()
	)
	now := time.Now()

	ctx = WithReceiver(ctx, "name")
	ctx = WithRepeatInterval(ctx, time.Duration(100*time.Minute))
	ctx = WithNow(ctx, now)

	alerts := []*types.Alert{
		{
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "0"},
			},
		}, {
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "1"},
				EndsAt: now.Add(-5 * time.Minute),
			},
		}, {
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "2"},
				EndsAt: now.Add(-9 * time.Minute),
			},
		}, {
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "3"},
				EndsAt: now.Add(-10 * time.Minute),
			},
		}, {
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "4"},
			},
		}, {
			Alert: model.Alert{
				Labels: model.LabelSet{"alertname": "5"},
			},
		},
	}

	var fps []model.Fingerprint
	for _, a := range alerts {
		fps = append(fps, a.Fingerprint())
	}

	nsBefore := []*types.NotifyInfo{
		// The first a new alert starting now.
		nil,
		// The second alert was not previously notified about and
		// is already resolved.
		nil,
		// The third alert is an attempt to resolve a previously
		// firing alert.
		{
			Alert:     fps[2],
			Receiver:  "name",
			Resolved:  false,
			Timestamp: now.Add(-10 * time.Minute),
		},
		// The fourth alert is an attempt to resolve an alert again
		// even though the previous notification succeeded.
		{
			Alert:     fps[3],
			Receiver:  "name",
			Resolved:  true,
			Timestamp: now.Add(-10 * time.Minute),
		},
		// The fifth alert resends a previously successful notification
		// that was longer than ago than the repeat interval.
		{
			Alert:     fps[4],
			Receiver:  "name",
			Resolved:  false,
			Timestamp: now.Add(-110 * time.Minute),
		},
		// The sixth alert is a firing again after being resolved before.
		{
			Alert:     fps[5],
			Receiver:  "name",
			Resolved:  true,
			Timestamp: now.Add(3 * time.Minute),
		},
	}

	if err := notifies.Set(nsBefore...); err != nil {
		t.Fatalf("Setting notifies failed: %s", err)
	}

	deduper.notifier = &failNotifier{}
	if err := deduper.Notify(ctx, alerts...); err == nil {
		t.Fatalf("Fail notifier did not fail")
	}
	// After a failing notify the notifies data must be unchanged.
	nsCur, err := notifies.Get("name", fps...)
	if err != nil {
		t.Fatalf("Error getting notify info: %s", err)
	}
	if !reflect.DeepEqual(nsBefore, nsCur) {
		t.Fatalf("Notify info data has changed unexpectedly")
	}

	deduper.notifier = record
	if err := deduper.Notify(ctx, alerts...); err != nil {
		t.Fatalf("Notify failed: %s", err)
	}

	alertsExp := []*types.Alert{
		alerts[0],
		alerts[2],
		alerts[4],
		alerts[5],
	}

	nsAfter := []*types.NotifyInfo{
		{
			Alert:    fps[0],
			Receiver: "name",
			Resolved: false,
		},
		nil,
		{
			Alert:    fps[2],
			Receiver: "name",
			Resolved: true,
		},
		nsBefore[3],
		{
			Alert:    fps[4],
			Receiver: "name",
			Resolved: false,
		},
		{
			Alert:    fps[5],
			Receiver: "name",
			Resolved: false,
		},
	}

	if !reflect.DeepEqual(record.alerts, alertsExp) {
		t.Fatalf("Expected alerts %v, got %v", alertsExp, record.alerts)
	}
	nsCur, err = notifies.Get("name", fps...)
	if err != nil {
		t.Fatalf("Error getting notifies: %s", err)
	}

	for i, after := range nsAfter {
		cur := nsCur[i]

		// Hack correct timestamps back in if they are sane.
		if cur != nil && after.Timestamp.IsZero() {
			if cur.Timestamp.Before(now) {
				t.Fatalf("Wrong timestamp for notify %v", cur)
			}
			after.Timestamp = cur.Timestamp
		}

		if !reflect.DeepEqual(after, cur) {
			t.Errorf("Unexpected notifies, expected: %v, got: %v", after, cur)
		}
	}
}