github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/alertmanager/merger/v2_alert_groups_test.go (about)

     1  package merger
     2  
     3  import (
     4  	"testing"
     5  
     6  	v2_models "github.com/prometheus/alertmanager/api/v2/models"
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestV2AlertGroups(t *testing.T) {
    11  
    12  	// This test is to check the parsing round-trip is working as expected, the merging logic is
    13  	// tested in TestMergeV2AlertGroups. The test data is based on captures from an actual Alertmanager.
    14  
    15  	in := [][]byte{
    16  
    17  		[]byte(`[` +
    18  			`{"alerts":[{"annotations":{},"endsAt":"2021-04-21T10:47:32.161+02:00","fingerprint":"c4b6b79a607b6ba0",` +
    19  			`"receivers":[{"name":"dummy"}],"startsAt":"2021-04-21T09:47:32.161+02:00",` +
    20  			`"status":{"inhibitedBy":[],"silencedBy":[],"state":"unprocessed"},` +
    21  			`"updatedAt":"2021-04-21T07:47:32.163Z","labels":{"group":"group_1","name":"alert_1"}}],` +
    22  			`"labels":{"group":"group_1"},"receiver":{"name":"dummy"}},` +
    23  			`{"alerts":[{"annotations":{},"endsAt":"2021-04-21T10:47:32.165+02:00","fingerprint":"465de60f606461c3",` +
    24  			`"receivers":[{"name":"dummy"}],"startsAt":"2021-04-21T09:47:32.165+02:00",` +
    25  			`"status":{"inhibitedBy":[],"silencedBy":[],"state":"unprocessed"},` +
    26  			`"updatedAt":"2021-04-21T07:47:32.167Z","labels":{"group":"group_2","name":"alert_3"}}],` +
    27  			`"labels":{"group":"group_2"},"receiver":{"name":"dummy"}}` +
    28  			`]`),
    29  		[]byte(`[` +
    30  			`{"alerts":[{"annotations":{},"endsAt":"2021-04-21T10:47:32.163+02:00","fingerprint":"c4b8b79a607bee77",` +
    31  			`"receivers":[{"name":"dummy"}],"startsAt":"2021-04-21T09:47:32.163+02:00",` +
    32  			`"status":{"inhibitedBy":[],"silencedBy":[],"state":"unprocessed"},` +
    33  			`"updatedAt":"2021-04-21T07:47:32.165Z","labels":{"group":"group_1","name":"alert_2"}}],` +
    34  			`"labels":{"group":"group_1"},"receiver":{"name":"dummy"}}` +
    35  			`]`),
    36  		[]byte(`[]`),
    37  	}
    38  
    39  	expected := []byte(`[` +
    40  		`{"alerts":[{"annotations":{},"endsAt":"2021-04-21T10:47:32.161+02:00","fingerprint":"c4b6b79a607b6ba0",` +
    41  		`"receivers":[{"name":"dummy"}],"startsAt":"2021-04-21T09:47:32.161+02:00",` +
    42  		`"status":{"inhibitedBy":[],"silencedBy":[],"state":"unprocessed"},` +
    43  		`"updatedAt":"2021-04-21T07:47:32.163Z","labels":{"group":"group_1","name":"alert_1"}},` +
    44  		`{"annotations":{},"endsAt":"2021-04-21T10:47:32.163+02:00","fingerprint":"c4b8b79a607bee77",` +
    45  		`"receivers":[{"name":"dummy"}],"startsAt":"2021-04-21T09:47:32.163+02:00",` +
    46  		`"status":{"inhibitedBy":[],"silencedBy":[],"state":"unprocessed"},` +
    47  		`"updatedAt":"2021-04-21T07:47:32.165Z","labels":{"group":"group_1","name":"alert_2"}}],` +
    48  		`"labels":{"group":"group_1"},"receiver":{"name":"dummy"}},` +
    49  		`{"alerts":[{"annotations":{},"endsAt":"2021-04-21T10:47:32.165+02:00","fingerprint":"465de60f606461c3",` +
    50  		`"receivers":[{"name":"dummy"}],"startsAt":"2021-04-21T09:47:32.165+02:00",` +
    51  		`"status":{"inhibitedBy":[],"silencedBy":[],"state":"unprocessed"},` +
    52  		`"updatedAt":"2021-04-21T07:47:32.167Z","labels":{"group":"group_2","name":"alert_3"}}],` +
    53  		`"labels":{"group":"group_2"},"receiver":{"name":"dummy"}}]`)
    54  
    55  	out, err := V2AlertGroups{}.MergeResponses(in)
    56  	require.NoError(t, err)
    57  	require.Equal(t, expected, out)
    58  }
    59  
    60  func v2group(label, receiver string, alerts ...*v2_models.GettableAlert) *v2_models.AlertGroup {
    61  	return &v2_models.AlertGroup{
    62  		Alerts:   alerts,
    63  		Labels:   v2_models.LabelSet{"some-label": label},
    64  		Receiver: &v2_models.Receiver{Name: &receiver},
    65  	}
    66  }
    67  
    68  func v2groups(groups ...*v2_models.AlertGroup) v2_models.AlertGroups {
    69  	return groups
    70  }
    71  
    72  func TestMergeV2AlertGroups(t *testing.T) {
    73  	var (
    74  		alert1      = v2alert("1111111111111111", "a1-", "2020-01-01T12:00:00.000Z")
    75  		newerAlert1 = v2alert("1111111111111111", "a1+", "2020-01-01T12:00:00.001Z")
    76  		alert2      = v2alert("2222222222222222", "a2-", "2020-01-01T12:00:00.000Z")
    77  		alert3      = v2alert("3333333333333333", "a2-", "2020-01-01T12:00:00.000Z")
    78  	)
    79  	cases := []struct {
    80  		name string
    81  		in   v2_models.AlertGroups
    82  		err  error
    83  		out  v2_models.AlertGroups
    84  	}{
    85  		{
    86  			name: "no groups, should return no groups",
    87  			in:   v2groups(),
    88  			out:  v2_models.AlertGroups{},
    89  		},
    90  		{
    91  			name: "one group with one alert, should return one group",
    92  			in:   v2groups(v2group("g1", "r1", alert1)),
    93  			out:  v2groups(v2group("g1", "r1", alert1)),
    94  		},
    95  		{
    96  			name: "two groups with different labels, should return two groups",
    97  			in:   v2groups(v2group("g1", "r1", alert1), v2group("g2", "r1", alert2)),
    98  			out:  v2groups(v2group("g1", "r1", alert1), v2group("g2", "r1", alert2)),
    99  		},
   100  		{
   101  			name: "two groups with different receiver, should return two groups",
   102  			in:   v2groups(v2group("g1", "r1", alert1), v2group("g1", "r2", alert2)),
   103  			out:  v2groups(v2group("g1", "r1", alert1), v2group("g1", "r2", alert2)),
   104  		},
   105  		{
   106  			name: "two identical groups with different alerts, should return one group with two alerts",
   107  			in:   v2groups(v2group("g1", "r1", alert1), v2group("g1", "r1", alert2)),
   108  			out:  v2groups(v2group("g1", "r1", alert1, alert2)),
   109  		},
   110  		{
   111  			name: "two identical groups with identical alerts, should return one group with one alert",
   112  			in:   v2groups(v2group("g1", "r1", alert1), v2group("g1", "r1", alert1)),
   113  			out:  v2groups(v2group("g1", "r1", alert1)),
   114  		},
   115  		{
   116  			name: "two identical groups with diverged alerts, should return one group with the newer alert",
   117  			in:   v2groups(v2group("g1", "r1", alert1), v2group("g1", "r1", newerAlert1)),
   118  			out:  v2groups(v2group("g1", "r1", newerAlert1)),
   119  		},
   120  		{
   121  			name: "two sets of identical groups with single alerts, should merge all into two groups ",
   122  			in: v2groups(
   123  				v2group("g1", "r1", alert1), v2group("g1", "r1", alert2),
   124  				v2group("g2", "r1", alert1), v2group("g2", "r1", alert3)),
   125  			out: v2groups(
   126  				v2group("g1", "r1", alert1, alert2),
   127  				v2group("g2", "r1", alert1, alert3)),
   128  		},
   129  		{
   130  			name: "many unordered groups, should return groups ordered by labels then receiver",
   131  			in: v2groups(
   132  				v2group("g3", "r2", alert3), v2group("g2", "r1", alert2),
   133  				v2group("g1", "r2", alert1), v2group("g1", "r1", alert1),
   134  				v2group("g2", "r2", alert2), v2group("g3", "r1", alert3)),
   135  			out: v2groups(
   136  				v2group("g1", "r1", alert1), v2group("g1", "r2", alert1),
   137  				v2group("g2", "r1", alert2), v2group("g2", "r2", alert2),
   138  				v2group("g3", "r1", alert3), v2group("g3", "r2", alert3)),
   139  		},
   140  	}
   141  
   142  	for _, c := range cases {
   143  		t.Run(c.name, func(t *testing.T) {
   144  			out, err := mergeV2AlertGroups(c.in)
   145  			require.Equal(t, c.err, err)
   146  			require.Equal(t, c.out, out)
   147  		})
   148  	}
   149  }