diff --git a/api/v2/api_test.go b/api/v2/api_test.go index 8f0c80a9..fa520756 100644 --- a/api/v2/api_test.go +++ b/api/v2/api_test.go @@ -15,7 +15,6 @@ package v2 import ( "bytes" - "encoding/json" "fmt" "io/ioutil" "net/http" @@ -236,92 +235,67 @@ func TestPostSilencesHandler(t *testing.T) { require.NoError(t, err) require.NoError(t, silences.Expire(expiredSid)) - for i, tc := range []struct { - sid string - start, end time.Time - expectedCode int - }{ - { - "unknownSid", - now.Add(time.Hour), - now.Add(time.Hour * 2), - 404, - }, - { - "", - now.Add(time.Hour), - now.Add(time.Hour * 2), - 200, - }, - { - unexpiredSid, - now.Add(time.Hour), - now.Add(time.Hour * 2), - 200, - }, - { - expiredSid, - now.Add(time.Hour), - now.Add(time.Hour * 2), - 200, - }, - } { - createdBy := "silenceCreator" - comment := "test" - matcherName := "a" - matcherValue := "b" - isRegex := false - startsAt := strfmt.DateTime(tc.start) - endsAt := strfmt.DateTime(tc.end) - - sil := open_api_models.PostableSilence{ - ID: tc.sid, - Silence: open_api_models.Silence{ - Matchers: open_api_models.Matchers{&open_api_models.Matcher{Name: &matcherName, Value: &matcherValue, IsRegex: &isRegex}}, - StartsAt: &startsAt, - EndsAt: &endsAt, - CreatedBy: &createdBy, - Comment: &comment, + t.Run("Silences CRUD", func(t *testing.T) { + for i, tc := range []struct { + name string + sid string + start, end time.Time + expectedCode int + }{ + { + "with an non-existent silence ID - it returns 404", + "unknownSid", + now.Add(time.Hour), + now.Add(time.Hour * 2), + 404, }, + { + "with no silence ID - it creates the silence", + "", + now.Add(time.Hour), + now.Add(time.Hour * 2), + 200, + }, + { + "with an active silence ID - it extends the silence", + unexpiredSid, + now.Add(time.Hour), + now.Add(time.Hour * 2), + 200, + }, + { + "with an expired silence ID - it re-creates the silence", + expiredSid, + now.Add(time.Hour), + now.Add(time.Hour * 2), + 200, + }, + } { + t.Run(tc.name, func(t *testing.T) { + silence, silenceBytes := createSilence(t, tc.sid, "silenceCreator", tc.start, tc.end) + + api := API{ + uptime: time.Now(), + silences: silences, + logger: log.NewNopLogger(), + } + + r, err := http.NewRequest("POST", "/api/v2/silence/${tc.sid}", bytes.NewReader(silenceBytes)) + require.NoError(t, err) + + w := httptest.NewRecorder() + p := runtime.TextProducer() + responder := api.postSilencesHandler(silence_ops.PostSilencesParams{ + HTTPRequest: r, + Silence: &silence, + }) + responder.WriteResponse(w, p) + body, _ := ioutil.ReadAll(w.Result().Body) + + require.Equal(t, tc.expectedCode, w.Code, fmt.Sprintf("test case: %d, response: %s", i, string(body))) + }) } - b, err := json.Marshal(&sil) - if err != nil { - t.Errorf("Unexpected error %v", err) - } - - api := API{ - uptime: time.Now(), - silences: silences, - logger: log.NewNopLogger(), - } - - r, err := http.NewRequest("POST", "/api/v2/silence/${tc.sid}", bytes.NewReader(b)) - require.NoError(t, err) - - w := httptest.NewRecorder() - p := runtime.TextProducer() - responder := api.postSilencesHandler(silence_ops.PostSilencesParams{ - HTTPRequest: r, - Silence: &sil, - }) - responder.WriteResponse(w, p) - body, _ := ioutil.ReadAll(w.Result().Body) - - require.Equal(t, tc.expectedCode, w.Code, fmt.Sprintf("test case: %d, response: %s", i, string(body))) - } -} - -func createSilenceMatcher(name, pattern string, matcherType silencepb.Matcher_Type) *silencepb.Matcher { - return &silencepb.Matcher{ - Name: name, - Pattern: pattern, - Type: matcherType, - } -} - -func createLabelMatcher(name, value string, matchType labels.MatchType) *labels.Matcher { - matcher, _ := labels.NewMatcher(matchType, name, value) - return matcher + }) } func TestCheckSilenceMatchesFilterLabels(t *testing.T) { @@ -333,72 +307,72 @@ func TestCheckSilenceMatchesFilterLabels(t *testing.T) { tests := []test{ { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchEqual)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchEqual)}, true, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)}, - []*labels.Matcher{createLabelMatcher("label", "novalue", labels.MatchEqual)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, + []*labels.Matcher{createLabelMatcher(t, "label", "novalue", labels.MatchEqual)}, false, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "(foo|bar)", silencepb.Matcher_REGEXP)}, - []*labels.Matcher{createLabelMatcher("label", "(foo|bar)", labels.MatchRegexp)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "(foo|bar)", silencepb.Matcher_REGEXP)}, + []*labels.Matcher{createLabelMatcher(t, "label", "(foo|bar)", labels.MatchRegexp)}, true, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "foo", silencepb.Matcher_REGEXP)}, - []*labels.Matcher{createLabelMatcher("label", "(foo|bar)", labels.MatchRegexp)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "foo", silencepb.Matcher_REGEXP)}, + []*labels.Matcher{createLabelMatcher(t, "label", "(foo|bar)", labels.MatchRegexp)}, false, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchRegexp)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchRegexp)}, false, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_REGEXP)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchEqual)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_REGEXP)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchEqual)}, false, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_EQUAL)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotEqual)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_EQUAL)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotEqual)}, true, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_REGEXP)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotRegexp)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_REGEXP)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotRegexp)}, true, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotEqual)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotEqual)}, false, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_REGEXP)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotRegexp)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_REGEXP)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotRegexp)}, false, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_EQUAL)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotRegexp)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_EQUAL)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotRegexp)}, false, }, { - []*silencepb.Matcher{createSilenceMatcher("label", "value", silencepb.Matcher_NOT_REGEXP)}, - []*labels.Matcher{createLabelMatcher("label", "value", labels.MatchNotEqual)}, + []*silencepb.Matcher{createSilenceMatcher(t, "label", "value", silencepb.Matcher_NOT_REGEXP)}, + []*labels.Matcher{createLabelMatcher(t, "label", "value", labels.MatchNotEqual)}, false, }, { []*silencepb.Matcher{ - createSilenceMatcher("label", "(foo|bar)", silencepb.Matcher_REGEXP), - createSilenceMatcher("label", "value", silencepb.Matcher_EQUAL), + createSilenceMatcher(t, "label", "(foo|bar)", silencepb.Matcher_REGEXP), + createSilenceMatcher(t, "label", "value", silencepb.Matcher_EQUAL), }, - []*labels.Matcher{createLabelMatcher("label", "(foo|bar)", labels.MatchRegexp)}, + []*labels.Matcher{createLabelMatcher(t, "label", "(foo|bar)", labels.MatchRegexp)}, true, }, } diff --git a/api/v2/testing.go b/api/v2/testing.go new file mode 100644 index 00000000..c813d350 --- /dev/null +++ b/api/v2/testing.go @@ -0,0 +1,70 @@ +// Copyright 2022 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v2 + +import ( + "encoding/json" + "testing" + "time" + + "github.com/go-openapi/strfmt" + "github.com/stretchr/testify/require" + + open_api_models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/pkg/labels" + "github.com/prometheus/alertmanager/silence/silencepb" +) + +func createSilence(t *testing.T, ID, creator string, start, ends time.Time) (open_api_models.PostableSilence, []byte) { + t.Helper() + + comment := "test" + matcherName := "a" + matcherValue := "b" + isRegex := false + startsAt := strfmt.DateTime(start) + endsAt := strfmt.DateTime(ends) + + sil := open_api_models.PostableSilence{ + ID: ID, + Silence: open_api_models.Silence{ + Matchers: open_api_models.Matchers{&open_api_models.Matcher{Name: &matcherName, Value: &matcherValue, IsRegex: &isRegex}}, + StartsAt: &startsAt, + EndsAt: &endsAt, + CreatedBy: &creator, + Comment: &comment, + }, + } + b, err := json.Marshal(&sil) + require.NoError(t, err) + + return sil, b +} + +func createSilenceMatcher(t *testing.T, name, pattern string, matcherType silencepb.Matcher_Type) *silencepb.Matcher { + t.Helper() + + return &silencepb.Matcher{ + Name: name, + Pattern: pattern, + Type: matcherType, + } +} + +func createLabelMatcher(t *testing.T, name, value string, matchType labels.MatchType) *labels.Matcher { + t.Helper() + + matcher, _ := labels.NewMatcher(matchType, name, value) + return matcher +}