Files
grafana/pkg/services/ngalert/notifier/file_store_test.go
Tito LinsandYuri Tseretyan 9d1d0e72c2 Alerting: add sync timer support (#114602)
- add new feature flag to support enabling the dispatcher sync timer on the alertmanager
- this attempts to synchronize the flushes across HA nodes to decrease amount of duplicate notifications

---------

Co-authored-by: Yuri Tseretyan <yuriy.tseretyan@grafana.com>
2026-01-14 10:04:29 +01:00

154 lines
4.5 KiB
Go

package notifier
import (
"context"
"encoding/base64"
"strings"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
)
func TestFileStore_Silences(t *testing.T) {
store := fakes.NewFakeKVStore(t)
ctx := context.Background()
var orgId int64 = 1
// Initialize kvstore.
now := time.Now()
oneHour := now.Add(time.Hour)
initialState := silenceState{
"1": createSilence("1", now, oneHour),
"2": createSilence("2", now, oneHour),
}
decodedState, err := initialState.MarshalBinary()
require.NoError(t, err)
encodedState := base64.StdEncoding.EncodeToString(decodedState)
err = store.Set(ctx, orgId, KVNamespace, SilencesFilename, encodedState)
require.NoError(t, err)
fs := NewFileStore(orgId, store)
// Load initial.
silences, err := fs.GetSilences(ctx)
require.NoError(t, err)
decoded, err := decodeSilenceState(strings.NewReader(silences))
require.NoError(t, err)
if !cmp.Equal(initialState, decoded) {
t.Errorf("Unexpected Diff: %v", cmp.Diff(initialState, decoded))
}
// Save new.
newState := silenceState{
"a": createSilence("a", now, oneHour),
"b": createSilence("b", now, oneHour),
}
size, err := fs.SaveSilences(ctx, newState)
require.NoError(t, err)
require.EqualValues(t, len(decodedState), size)
// Load new.
silences, err = fs.GetSilences(ctx)
require.NoError(t, err)
decoded, err = decodeSilenceState(strings.NewReader(silences))
require.NoError(t, err)
if !cmp.Equal(newState, decoded) {
t.Errorf("Unexpected Diff: %v", cmp.Diff(newState, decoded))
}
}
func TestFileStore_NotificationLog(t *testing.T) {
store := fakes.NewFakeKVStore(t)
ctx := context.Background()
var orgId int64 = 1
// Initialize kvstore.
now := time.Now()
oneHour := now.Add(time.Hour)
k1, v1 := createNotificationLog("group1", "receiver1", now, oneHour)
k2, v2 := createNotificationLog("group2", "receiver2", now, oneHour)
initialState := nflogState{k1: v1, k2: v2}
decodedState, err := initialState.MarshalBinary()
require.NoError(t, err)
encodedState := base64.StdEncoding.EncodeToString(decodedState)
err = store.Set(ctx, orgId, KVNamespace, NotificationLogFilename, encodedState)
require.NoError(t, err)
fs := NewFileStore(orgId, store)
// Load initial.
nflog, err := fs.GetNotificationLog(ctx)
require.NoError(t, err)
decoded, err := decodeNflogState(strings.NewReader(nflog))
require.NoError(t, err)
if !cmp.Equal(initialState, decoded) {
t.Errorf("Unexpected Diff: %v", cmp.Diff(initialState, decoded))
}
// Save new.
k1, v1 = createNotificationLog("groupA", "receiverA", now, oneHour)
k2, v2 = createNotificationLog("groupB", "receiverB", now, oneHour)
newState := nflogState{k1: v1, k2: v2}
size, err := fs.SaveNotificationLog(ctx, newState)
require.NoError(t, err)
require.EqualValues(t, len(decodedState), size)
// Load new.
nflog, err = fs.GetNotificationLog(ctx)
require.NoError(t, err)
decoded, err = decodeNflogState(strings.NewReader(nflog))
require.NoError(t, err)
if !cmp.Equal(newState, decoded) {
t.Errorf("Unexpected Diff: %v", cmp.Diff(newState, decoded))
}
}
func TestFileStore_FlushLog(t *testing.T) {
store := fakes.NewFakeKVStore(t)
ctx := context.Background()
var orgId int64 = 1
// Initialize kvstore with empty flush log state.
initialState := flushLogState{} // FlushLog uses the same structure as nflog
decodedState, err := initialState.MarshalBinary()
require.NoError(t, err)
encodedState := base64.StdEncoding.EncodeToString(decodedState)
err = store.Set(ctx, orgId, KVNamespace, FlushLogFilename, encodedState)
require.NoError(t, err)
fs := NewFileStore(orgId, store)
// Load initial (empty).
flushLog, err := fs.GetFlushLog(ctx)
require.NoError(t, err)
decoded, err := decodeFlushLogState(strings.NewReader(flushLog))
require.NoError(t, err)
if !cmp.Equal(initialState, decoded) {
t.Errorf("Unexpected Diff: %v", cmp.Diff(initialState, decoded))
}
// Save new flush log state.
now := time.Now()
oneHour := now.Add(time.Hour)
v1 := createFlushLog(1, now, oneHour)
v2 := createFlushLog(2, now, oneHour)
newState := flushLogState{1: v1, 2: v2}
size, err := fs.SaveFlushLog(ctx, newState)
require.NoError(t, err)
require.Greater(t, size, int64(0))
// Load new.
flushLog, err = fs.GetFlushLog(ctx)
require.NoError(t, err)
decoded, err = decodeFlushLogState(strings.NewReader(flushLog))
require.NoError(t, err)
if !cmp.Equal(newState, decoded) {
t.Errorf("Unexpected Diff: %v", cmp.Diff(newState, decoded))
}
}