1// Copyright 2018 Prometheus Team
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package test
15
16import (
17	"fmt"
18	"sync"
19	"testing"
20	"time"
21
22	a "github.com/prometheus/alertmanager/test/with_api_v2"
23)
24
25// TestClusterDeduplication tests, that in an Alertmanager cluster of 3
26// instances, only one should send a notification for a given alert.
27func TestClusterDeduplication(t *testing.T) {
28	t.Parallel()
29
30	conf := `
31route:
32  receiver: "default"
33  group_by: []
34  group_wait:      1s
35  group_interval:  1s
36  repeat_interval: 1h
37
38receivers:
39- name: "default"
40  webhook_configs:
41  - url: 'http://%s'
42`
43
44	at := a.NewAcceptanceTest(t, &a.AcceptanceOpts{
45		Tolerance: 1 * time.Second,
46	})
47	co := at.Collector("webhook")
48	wh := a.NewWebhook(co)
49
50	amc := at.AlertmanagerCluster(fmt.Sprintf(conf, wh.Address()), 3)
51
52	amc.Push(a.At(1), a.Alert("alertname", "test1"))
53
54	co.Want(a.Between(2, 3), a.Alert("alertname", "test1").Active(1))
55
56	at.Run()
57
58	t.Log(co.Check())
59}
60
61// TestClusterVSInstance compares notifications sent by Alertmanager cluster to
62// notifications sent by single instance.
63func TestClusterVSInstance(t *testing.T) {
64	t.Parallel()
65
66	conf := `
67route:
68  receiver: "default"
69  group_by: [ "alertname" ]
70  group_wait:      1s
71  group_interval:  1s
72  repeat_interval: 1h
73
74receivers:
75- name: "default"
76  webhook_configs:
77  - url: 'http://%s'
78`
79
80	acceptanceOpts := &a.AcceptanceOpts{
81		Tolerance: 2 * time.Second,
82	}
83
84	clusterSizes := []int{1, 3}
85
86	tests := []*a.AcceptanceTest{
87		a.NewAcceptanceTest(t, acceptanceOpts),
88		a.NewAcceptanceTest(t, acceptanceOpts),
89	}
90
91	collectors := []*a.Collector{}
92	amClusters := []*a.AlertmanagerCluster{}
93	wg := sync.WaitGroup{}
94
95	for i, t := range tests {
96		collectors = append(collectors, t.Collector("webhook"))
97		webhook := a.NewWebhook(collectors[i])
98
99		amClusters = append(amClusters, t.AlertmanagerCluster(fmt.Sprintf(conf, webhook.Address()), clusterSizes[i]))
100
101		wg.Add(1)
102	}
103
104	for _, time := range []float64{0, 2, 4, 6, 8} {
105		for i, amc := range amClusters {
106			alert := a.Alert("alertname", fmt.Sprintf("test1-%v", time))
107			amc.Push(a.At(time), alert)
108			collectors[i].Want(a.Between(time, time+5), alert.Active(time))
109		}
110	}
111
112	for _, t := range tests {
113		go func(t *a.AcceptanceTest) {
114			t.Run()
115			wg.Done()
116		}(t)
117	}
118
119	wg.Wait()
120
121	_, err := a.CompareCollectors(collectors[0], collectors[1], acceptanceOpts)
122	if err != nil {
123		t.Fatal(err)
124	}
125}
126