mirror of
https://github.com/prometheus/alertmanager.git
synced 2026-02-05 06:45:45 +01:00
Enable modernize linter (#4750)
Enable the golangci-lint modernize linter. * Add exception for the omitempty struct issue. * Apply modernize fixes. Signed-off-by: SuperQ <superq@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ linters:
|
||||
- errorlint
|
||||
- godot
|
||||
- misspell
|
||||
- modernize
|
||||
- revive
|
||||
- sloglint
|
||||
- testifylint
|
||||
@@ -77,6 +78,9 @@ linters:
|
||||
- linters:
|
||||
- errcheck
|
||||
path: _test.go
|
||||
- linters:
|
||||
- modernize
|
||||
text: "omitzero: Omitempty has no effect on nested struct fields"
|
||||
warn-unused: true
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
|
||||
@@ -118,10 +118,7 @@ func New(opts Options) (*API, error) {
|
||||
}
|
||||
concurrency := opts.Concurrency
|
||||
if concurrency < 1 {
|
||||
concurrency = runtime.GOMAXPROCS(0)
|
||||
if concurrency < 8 {
|
||||
concurrency = 8
|
||||
}
|
||||
concurrency = max(runtime.GOMAXPROCS(0), 8)
|
||||
}
|
||||
|
||||
v2, err := apiv2.NewAPI(
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -286,7 +287,7 @@ func (api *API) getAlertsHandler(params alert_ops.GetAlertsParams) middleware.Re
|
||||
receivers = append(receivers, r.RouteOpts.Receiver)
|
||||
}
|
||||
|
||||
if receiverFilter != nil && !receiversMatchFilter(receivers, receiverFilter) {
|
||||
if receiverFilter != nil && !slices.ContainsFunc(receivers, receiverFilter.MatchString) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -474,16 +475,6 @@ func removeEmptyLabels(ls prometheus_model.LabelSet) {
|
||||
}
|
||||
}
|
||||
|
||||
func receiversMatchFilter(receivers []string, filter *regexp.Regexp) bool {
|
||||
for _, r := range receivers {
|
||||
if filter.MatchString(r) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func alertMatchesFilterLabels(a *prometheus_model.Alert, matchers []*labels.Matcher) bool {
|
||||
sms := make(map[string]string)
|
||||
for name, value := range a.Labels {
|
||||
|
||||
@@ -216,10 +216,7 @@ func Create(
|
||||
|
||||
p.register(reg, name)
|
||||
|
||||
retransmit := len(knownPeers) / 2
|
||||
if retransmit < 3 {
|
||||
retransmit = 3
|
||||
}
|
||||
retransmit := max(len(knownPeers)/2, 3)
|
||||
p.delegate = newDelegate(l, reg, p, retransmit)
|
||||
|
||||
cfg := memberlist.DefaultLANConfig()
|
||||
|
||||
@@ -79,7 +79,6 @@ func TestExternalURL(t *testing.T) {
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
if tc.hostnameResolver == nil {
|
||||
tc.hostnameResolver = func() (string, error) {
|
||||
return hostname, nil
|
||||
|
||||
@@ -1398,7 +1398,6 @@ func TestUnmarshalHostPort(t *testing.T) {
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.in, func(t *testing.T) {
|
||||
hp := HostPort{}
|
||||
err := yaml.Unmarshal([]byte(tc.in), &hp)
|
||||
|
||||
@@ -569,7 +569,7 @@ type IncidentioConfig struct {
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
func (c *IncidentioConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
func (c *IncidentioConfig) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
*c = DefaultIncidentioConfig
|
||||
type plain IncidentioConfig
|
||||
if err := unmarshal((*plain)(c)); err != nil {
|
||||
@@ -1102,7 +1102,7 @@ type MattermostField struct {
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface for MattermostField.
|
||||
func (c *MattermostField) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
func (c *MattermostField) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
type plain MattermostField
|
||||
if err := unmarshal((*plain)(c)); err != nil {
|
||||
return err
|
||||
@@ -1157,7 +1157,7 @@ type MattermostConfig struct {
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
func (c *MattermostConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
func (c *MattermostConfig) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
*c = DefaultMattermostConfig
|
||||
type plain MattermostConfig
|
||||
if err := unmarshal((*plain)(c)); err != nil {
|
||||
|
||||
@@ -69,7 +69,6 @@ func TestBuildReceiverIntegrations(t *testing.T) {
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run("", func(t *testing.T) {
|
||||
integrations, err := BuildReceiverIntegrations(tc.receiver, nil, nil)
|
||||
if tc.err {
|
||||
|
||||
@@ -700,7 +700,7 @@ func TestDispatcherRaceOnFirstAlertNotDeliveredWhenGroupWaitIsZero(t *testing.T)
|
||||
defer dispatcher.Stop()
|
||||
|
||||
// Push all alerts.
|
||||
for i := 0; i < numAlerts; i++ {
|
||||
for i := range numAlerts {
|
||||
alert := newAlert(model.LabelSet{"alertname": model.LabelValue(fmt.Sprintf("Alert_%d", i))})
|
||||
require.NoError(t, alerts.Put(alert))
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ func NewFlags(logger *slog.Logger, features string) (Flagger, error) {
|
||||
return NoopFlags{}, nil
|
||||
}
|
||||
|
||||
for _, feature := range strings.Split(features, ",") {
|
||||
for feature := range strings.SplitSeq(features, ",") {
|
||||
switch feature {
|
||||
case FeatureReceiverNameInMetrics:
|
||||
opts = append(opts, enableReceiverNameInMetrics())
|
||||
|
||||
@@ -759,7 +759,7 @@ func TestLexer_Peek(t *testing.T) {
|
||||
// error has occurred.
|
||||
func TestLexer_PeekError(t *testing.T) {
|
||||
l := lexer{input: "\"hello"}
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
tok, err := l.peek()
|
||||
require.Equal(t, token{}, tok)
|
||||
require.EqualError(t, err, "0:6: \"hello: missing end \"")
|
||||
|
||||
@@ -16,6 +16,7 @@ package parse
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
)
|
||||
@@ -73,12 +74,7 @@ func (t token) isEOF() bool {
|
||||
|
||||
// isOneOf returns true if the token is one of the specified kinds.
|
||||
func (t token) isOneOf(kinds ...tokenKind) bool {
|
||||
for _, k := range kinds {
|
||||
if k == t.kind {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return slices.Contains(kinds, t.kind)
|
||||
}
|
||||
|
||||
// unquote the value in token. If unquoted returns it unmodified.
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sync"
|
||||
@@ -159,9 +160,7 @@ type state map[string]*pb.MeshEntry
|
||||
|
||||
func (s state) clone() state {
|
||||
c := make(state, len(s))
|
||||
for k, v := range s {
|
||||
c[k] = v
|
||||
}
|
||||
maps.Copy(c, s)
|
||||
return c
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ func (n *Email) auth(mechs string) (smtp.Auth, error) {
|
||||
}
|
||||
|
||||
err := &types.MultiError{}
|
||||
for _, mech := range strings.Split(mechs, " ") {
|
||||
for mech := range strings.SplitSeq(mechs, " ") {
|
||||
switch mech {
|
||||
case "CRAM-MD5":
|
||||
secret := string(n.conf.AuthSecret)
|
||||
|
||||
@@ -300,7 +300,6 @@ func TestEmailNotifyWithErrors(t *testing.T) {
|
||||
hasEmail: true,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
if len(tc.errMsg) == 0 {
|
||||
t.Fatal("please define the expected error message")
|
||||
@@ -579,7 +578,6 @@ func TestEmailNotifyWithAuthentication(t *testing.T) {
|
||||
retry: true,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
emailCfg := &config.EmailConfig{
|
||||
Smarthost: c.Smarthost,
|
||||
|
||||
@@ -142,7 +142,6 @@ func TestSearchExistingIssue(t *testing.T) {
|
||||
expectedJQL: `statusCategory != Done and project="PROJ" and labels="ALERT{1}" order by status ASC,resolutiondate DESC`,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
expectedJQL = tc.expectedJQL
|
||||
tc.cfg.APIURL = &config.URL{URL: u}
|
||||
@@ -300,7 +299,6 @@ func TestPrepareSearchRequest(t *testing.T) {
|
||||
expectedURLPath: "/rest/api/2",
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
tc.cfg.HTTPConfig = &commoncfg.HTTPClientConfig{}
|
||||
|
||||
@@ -402,8 +400,6 @@ func TestJiraTemplating(t *testing.T) {
|
||||
errMsg: "template: :1: unclosed action",
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
capturedBody = nil
|
||||
|
||||
@@ -778,8 +774,6 @@ func TestJiraNotify(t *testing.T) {
|
||||
errMsg: "can't find transition REOPEN for issue OPS-3",
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
@@ -1118,8 +1112,6 @@ func TestJiraPriority(t *testing.T) {
|
||||
"Medium",
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
u, err := url.Parse("http://example.com/")
|
||||
|
||||
@@ -15,6 +15,7 @@ package jira
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"maps"
|
||||
)
|
||||
|
||||
type issue struct {
|
||||
@@ -97,9 +98,7 @@ func (i issueFields) MarshalJSON() ([]byte, error) {
|
||||
jsonFields["status"] = i.Status
|
||||
}
|
||||
|
||||
for key, field := range i.Fields {
|
||||
jsonFields[key] = field
|
||||
}
|
||||
maps.Copy(jsonFields, i.Fields)
|
||||
|
||||
return json.Marshal(jsonFields)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func TestMattermostTemplating(t *testing.T) {
|
||||
// Create a fake HTTP server to simulate the Mattermost webhook
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
dec := json.NewDecoder(r.Body)
|
||||
out := make(map[string]interface{})
|
||||
out := make(map[string]any)
|
||||
err := dec.Decode(&out)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -141,9 +142,7 @@ func (n *Notifier) createRequests(ctx context.Context, as ...*types.Alert) ([]*h
|
||||
|
||||
details := make(map[string]string)
|
||||
|
||||
for k, v := range data.CommonLabels {
|
||||
details[k] = v
|
||||
}
|
||||
maps.Copy(details, data.CommonLabels)
|
||||
|
||||
for k, v := range n.conf.Details {
|
||||
details[k] = tmpl(v)
|
||||
|
||||
@@ -313,7 +313,6 @@ func TestErrDetails(t *testing.T) {
|
||||
exp: "",
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run("", func(t *testing.T) {
|
||||
err := errDetails(tc.status, tc.body)
|
||||
require.Contains(t, err, tc.exp)
|
||||
|
||||
@@ -113,7 +113,6 @@ func TestNotifyWithInvalidTemplate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
snsCfg := &config.SNSConfig{
|
||||
HTTPConfig: &commoncfg.HTTPClientConfig{},
|
||||
|
||||
@@ -127,8 +127,8 @@ func ParseMatcher(s string) (_ *Matcher, err error) {
|
||||
expectTrailingQuote bool
|
||||
)
|
||||
|
||||
if strings.HasPrefix(rawValue, "\"") {
|
||||
rawValue = strings.TrimPrefix(rawValue, "\"")
|
||||
if after, ok := strings.CutPrefix(rawValue, "\""); ok {
|
||||
rawValue = after
|
||||
expectTrailingQuote = true
|
||||
}
|
||||
|
||||
|
||||
@@ -166,13 +166,6 @@ func (a *Alerts) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Subscribe returns an iterator over active alerts that have not been
|
||||
// resolved and successfully notified about.
|
||||
// They are not guaranteed to be in chronological order.
|
||||
|
||||
@@ -221,8 +221,7 @@ func TestAlertsPut(t *testing.T) {
|
||||
func TestAlertsSubscribe(t *testing.T) {
|
||||
marker := types.NewMarker(prometheus.NewRegistry())
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx := t.Context()
|
||||
alerts, err := NewAlerts(ctx, marker, 30*time.Minute, noopCallback{}, promslog.NewNopLogger(), prometheus.NewRegistry())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -246,7 +245,7 @@ func TestAlertsSubscribe(t *testing.T) {
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
wg.Add(nb)
|
||||
for i := 0; i < nb; i++ {
|
||||
for i := range nb {
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
|
||||
@@ -576,7 +575,7 @@ func TestAlertsConcurrently(t *testing.T) {
|
||||
}()
|
||||
expire := 10 * time.Millisecond
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 100; i++ {
|
||||
for range 100 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -932,10 +933,8 @@ func QState(states ...types.SilenceState) QueryParam {
|
||||
f := func(sil *pb.Silence, _ *Silences, now time.Time) (bool, error) {
|
||||
s := getState(sil, now)
|
||||
|
||||
for _, ps := range states {
|
||||
if s == ps {
|
||||
return true, nil
|
||||
}
|
||||
if slices.Contains(states, s) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ func benchmarkQueryWithConcurrentAdds(b *testing.B, initialSilences int, addRati
|
||||
lset := model.LabelSet{"aaaa": "AAAA", "bbbb": "BBBB", "cccc": "CCCC"}
|
||||
|
||||
// Create initial silences
|
||||
for i := 0; i < initialSilences; i++ {
|
||||
for i := range initialSilences {
|
||||
id := strconv.Itoa(i)
|
||||
patA := "A{4}|" + id
|
||||
patB := id
|
||||
|
||||
@@ -435,7 +435,7 @@ type TemplateFunc func(string) (string, error)
|
||||
// deepCopyWithTemplate returns a deep copy of a map/slice/array/string/int/bool or combination thereof, executing the
|
||||
// provided template (with the provided data) on all string keys or values. All maps are connverted to
|
||||
// map[string]interface{}, with all non-string keys discarded.
|
||||
func DeepCopyWithTemplate(value interface{}, tmplTextFunc TemplateFunc) (interface{}, error) {
|
||||
func DeepCopyWithTemplate(value any, tmplTextFunc TemplateFunc) (any, error) {
|
||||
if value == nil {
|
||||
return value, nil
|
||||
}
|
||||
@@ -446,7 +446,7 @@ func DeepCopyWithTemplate(value interface{}, tmplTextFunc TemplateFunc) (interfa
|
||||
case reflect.String:
|
||||
parsed, ok := tmplTextFunc(value.(string))
|
||||
if ok == nil {
|
||||
var inlineType interface{}
|
||||
var inlineType any
|
||||
err := yaml.Unmarshal([]byte(parsed), &inlineType)
|
||||
if err != nil || (inlineType != nil && reflect.TypeOf(inlineType).Kind() == reflect.String) {
|
||||
// ignore error, thus the string is not an interface
|
||||
@@ -458,8 +458,8 @@ func DeepCopyWithTemplate(value interface{}, tmplTextFunc TemplateFunc) (interfa
|
||||
|
||||
case reflect.Array, reflect.Slice:
|
||||
arrayLen := valueMeta.Len()
|
||||
converted := make([]interface{}, arrayLen)
|
||||
for i := 0; i < arrayLen; i++ {
|
||||
converted := make([]any, arrayLen)
|
||||
for i := range arrayLen {
|
||||
var err error
|
||||
converted[i], err = DeepCopyWithTemplate(valueMeta.Index(i).Interface(), tmplTextFunc)
|
||||
if err != nil {
|
||||
@@ -470,7 +470,7 @@ func DeepCopyWithTemplate(value interface{}, tmplTextFunc TemplateFunc) (interfa
|
||||
|
||||
case reflect.Map:
|
||||
keys := valueMeta.MapKeys()
|
||||
converted := make(map[string]interface{}, len(keys))
|
||||
converted := make(map[string]any, len(keys))
|
||||
|
||||
for _, keyMeta := range keys {
|
||||
var err error
|
||||
|
||||
@@ -278,7 +278,6 @@ func TestData(t *testing.T) {
|
||||
},
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run("", func(t *testing.T) {
|
||||
got := tmpl.Data(tc.receiver, tc.groupLabels, tc.alerts...)
|
||||
require.Equal(t, tc.exp, got)
|
||||
@@ -403,7 +402,6 @@ func TestTemplateExpansion(t *testing.T) {
|
||||
exp: "[key2 key4]",
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
f := tmpl.ExecuteTextString
|
||||
if tc.html {
|
||||
@@ -465,7 +463,6 @@ func TestTemplateExpansionWithOptions(t *testing.T) {
|
||||
exp: "bar",
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
tmpl, err := FromGlobs([]string{}, tc.options...)
|
||||
require.NoError(t, err)
|
||||
@@ -579,10 +576,9 @@ func TestTemplateFuncs(t *testing.T) {
|
||||
data: time.Now().Add(-1 * time.Hour),
|
||||
exp: "1h 0m 0s",
|
||||
}} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 10; i++ {
|
||||
for range 10 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
@@ -656,7 +652,6 @@ func TestDeepCopyWithTemplate(t *testing.T) {
|
||||
want: nil,
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
got, err := DeepCopyWithTemplate(tc.input, tc.fn)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -485,9 +486,7 @@ func (am *Alertmanager) addAlertCommand(omitEquals bool, alert *TestAlert) ([]by
|
||||
args := []string{amURLFlag, "alert", "add"}
|
||||
// Make a copy of the labels
|
||||
labels := make(models.LabelSet, len(alert.labels))
|
||||
for k, v := range alert.labels {
|
||||
labels[k] = v
|
||||
}
|
||||
maps.Copy(labels, alert.labels)
|
||||
if omitEquals {
|
||||
// If alertname is present and omitEquals is true then the command should
|
||||
// be `amtool alert add foo ...` and not `amtool alert add alertname=foo ...`.
|
||||
|
||||
@@ -16,6 +16,7 @@ package test
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -105,12 +106,13 @@ func (c *Collector) add(alerts ...*models.GettableAlert) {
|
||||
}
|
||||
|
||||
func (c *Collector) Check() string {
|
||||
report := fmt.Sprintf("\ncollector %q:\n\n", c)
|
||||
var report strings.Builder
|
||||
report.WriteString(fmt.Sprintf("\ncollector %q:\n\n", c))
|
||||
|
||||
c.mtx.RLock()
|
||||
defer c.mtx.RUnlock()
|
||||
for iv, expected := range c.expected {
|
||||
report += fmt.Sprintf("interval %v\n", iv)
|
||||
report.WriteString(fmt.Sprintf("interval %v\n", iv))
|
||||
|
||||
var alerts []models.GettableAlerts
|
||||
for at, got := range c.collected {
|
||||
@@ -122,10 +124,10 @@ func (c *Collector) Check() string {
|
||||
for _, exp := range expected {
|
||||
found := len(exp) == 0 && len(alerts) == 0
|
||||
|
||||
report += "---\n"
|
||||
report.WriteString("---\n")
|
||||
|
||||
for _, e := range exp {
|
||||
report += fmt.Sprintf("- %v\n", c.opts.alertString(e))
|
||||
report.WriteString(fmt.Sprintf("- %v\n", c.opts.alertString(e)))
|
||||
}
|
||||
|
||||
for _, a := range alerts {
|
||||
@@ -136,10 +138,10 @@ func (c *Collector) Check() string {
|
||||
}
|
||||
|
||||
if found {
|
||||
report += " [ ✓ ]\n"
|
||||
report.WriteString(" [ ✓ ]\n")
|
||||
} else {
|
||||
c.t.Fail()
|
||||
report += " [ ✗ ]\n"
|
||||
report.WriteString(" [ ✗ ]\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,23 +163,23 @@ func (c *Collector) Check() string {
|
||||
}
|
||||
if totalExp != totalAct {
|
||||
c.t.Fail()
|
||||
report += fmt.Sprintf("\nExpected total of %d alerts, got %d", totalExp, totalAct)
|
||||
report.WriteString(fmt.Sprintf("\nExpected total of %d alerts, got %d", totalExp, totalAct))
|
||||
}
|
||||
|
||||
if c.t.Failed() {
|
||||
report += "\nreceived:\n"
|
||||
report.WriteString("\nreceived:\n")
|
||||
|
||||
for at, col := range c.collected {
|
||||
for _, alerts := range col {
|
||||
report += fmt.Sprintf("@ %v\n", at)
|
||||
report.WriteString(fmt.Sprintf("@ %v\n", at))
|
||||
for _, a := range alerts {
|
||||
report += fmt.Sprintf("- %v\n", c.opts.alertString(a))
|
||||
report.WriteString(fmt.Sprintf("- %v\n", c.opts.alertString(a)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return report
|
||||
return report.String()
|
||||
}
|
||||
|
||||
// alertsToString returns a string representation of the given Alerts. Use for
|
||||
|
||||
@@ -16,6 +16,7 @@ package test
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
@@ -293,12 +294,8 @@ func (ws *MockWebhook) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
labels = models.LabelSet{}
|
||||
annotations = models.LabelSet{}
|
||||
)
|
||||
for k, v := range a.Labels {
|
||||
labels[k] = v
|
||||
}
|
||||
for k, v := range a.Annotations {
|
||||
annotations[k] = v
|
||||
}
|
||||
maps.Copy(labels, a.Labels)
|
||||
maps.Copy(annotations, a.Annotations)
|
||||
|
||||
start := strfmt.DateTime(a.StartsAt)
|
||||
end := strfmt.DateTime(a.EndsAt)
|
||||
|
||||
@@ -16,6 +16,7 @@ package test
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -105,12 +106,13 @@ func (c *Collector) add(alerts ...*models.GettableAlert) {
|
||||
}
|
||||
|
||||
func (c *Collector) Check() string {
|
||||
report := fmt.Sprintf("\ncollector %q:\n\n", c)
|
||||
var report strings.Builder
|
||||
report.WriteString(fmt.Sprintf("\ncollector %q:\n\n", c))
|
||||
|
||||
c.mtx.RLock()
|
||||
defer c.mtx.RUnlock()
|
||||
for iv, expected := range c.expected {
|
||||
report += fmt.Sprintf("interval %v\n", iv)
|
||||
report.WriteString(fmt.Sprintf("interval %v\n", iv))
|
||||
|
||||
var alerts []models.GettableAlerts
|
||||
for at, got := range c.collected {
|
||||
@@ -122,10 +124,10 @@ func (c *Collector) Check() string {
|
||||
for _, exp := range expected {
|
||||
found := len(exp) == 0 && len(alerts) == 0
|
||||
|
||||
report += "---\n"
|
||||
report.WriteString("---\n")
|
||||
|
||||
for _, e := range exp {
|
||||
report += fmt.Sprintf("- %v\n", c.opts.alertString(e))
|
||||
report.WriteString(fmt.Sprintf("- %v\n", c.opts.alertString(e)))
|
||||
}
|
||||
|
||||
for _, a := range alerts {
|
||||
@@ -136,10 +138,10 @@ func (c *Collector) Check() string {
|
||||
}
|
||||
|
||||
if found {
|
||||
report += " [ ✓ ]\n"
|
||||
report.WriteString(" [ ✓ ]\n")
|
||||
} else {
|
||||
c.t.Fail()
|
||||
report += " [ ✗ ]\n"
|
||||
report.WriteString(" [ ✗ ]\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,23 +163,23 @@ func (c *Collector) Check() string {
|
||||
}
|
||||
if totalExp != totalAct {
|
||||
c.t.Fail()
|
||||
report += fmt.Sprintf("\nExpected total of %d alerts, got %d", totalExp, totalAct)
|
||||
report.WriteString(fmt.Sprintf("\nExpected total of %d alerts, got %d", totalExp, totalAct))
|
||||
}
|
||||
|
||||
if c.t.Failed() {
|
||||
report += "\nreceived:\n"
|
||||
report.WriteString("\nreceived:\n")
|
||||
|
||||
for at, col := range c.collected {
|
||||
for _, alerts := range col {
|
||||
report += fmt.Sprintf("@ %v\n", at)
|
||||
report.WriteString(fmt.Sprintf("@ %v\n", at))
|
||||
for _, a := range alerts {
|
||||
report += fmt.Sprintf("- %v\n", c.opts.alertString(a))
|
||||
report.WriteString(fmt.Sprintf("- %v\n", c.opts.alertString(a)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return report
|
||||
return report.String()
|
||||
}
|
||||
|
||||
// alertsToString returns a string representation of the given Alerts. Use for
|
||||
|
||||
@@ -16,6 +16,7 @@ package test
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
@@ -306,12 +307,8 @@ func (ws *MockWebhook) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
labels = models.LabelSet{}
|
||||
annotations = models.LabelSet{}
|
||||
)
|
||||
for k, v := range a.Labels {
|
||||
labels[k] = v
|
||||
}
|
||||
for k, v := range a.Annotations {
|
||||
annotations[k] = v
|
||||
}
|
||||
maps.Copy(labels, a.Labels)
|
||||
maps.Copy(annotations, a.Annotations)
|
||||
|
||||
start := strfmt.DateTime(a.StartsAt)
|
||||
end := strfmt.DateTime(a.EndsAt)
|
||||
|
||||
@@ -367,7 +367,6 @@ func TestAlertMerge(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, p := range pairs {
|
||||
p := p
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
if res := p.A.Merge(p.B); !reflect.DeepEqual(p.Res, res) {
|
||||
t.Errorf("unexpected merged alert %#v", res)
|
||||
|
||||
Reference in New Issue
Block a user