mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
30
alertmanager/alerts_test.go
Normal file
30
alertmanager/alerts_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package alertmanager_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/cloudflare/unsee/alertmanager"
|
||||
httpmock "gopkg.in/jarcoal/httpmock.v1"
|
||||
)
|
||||
|
||||
func TestAlertGroupsAPIResponseGet(t *testing.T) {
|
||||
log.SetOutput(ioutil.Discard) // disable logging to console
|
||||
httpmock.Activate()
|
||||
defer httpmock.DeactivateAndReset()
|
||||
mockJSON, err := ioutil.ReadFile("../mock/api/v1/alerts/groups")
|
||||
if err != nil {
|
||||
t.Errorf("Can't open mock 'alerts/groups' file: %s", err.Error())
|
||||
}
|
||||
httpmock.RegisterResponder("GET", "api/v1/alerts/groups", httpmock.NewBytesResponder(200, mockJSON))
|
||||
|
||||
response := alertmanager.AlertGroupsAPIResponse{}
|
||||
err = response.Get()
|
||||
if err != nil {
|
||||
t.Errorf("AlertGroupsAPIResponse.Get() failed: %s", err.Error())
|
||||
}
|
||||
if response.Status != "success" {
|
||||
t.Errorf("Invalid AlertGroupsAPIResponse status: %s", response.Status)
|
||||
}
|
||||
}
|
||||
79
alertmanager/remote_test.go
Normal file
79
alertmanager/remote_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package alertmanager
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
httpmock "gopkg.in/jarcoal/httpmock.v1"
|
||||
)
|
||||
|
||||
type joinURLTest struct {
|
||||
base string
|
||||
sub string
|
||||
url string
|
||||
}
|
||||
|
||||
var joinURLTests = []joinURLTest{
|
||||
joinURLTest{
|
||||
base: "http://localhost",
|
||||
sub: "/sub",
|
||||
url: "http://localhost/sub",
|
||||
},
|
||||
joinURLTest{
|
||||
base: "http://localhost",
|
||||
sub: "/sub/",
|
||||
url: "http://localhost/sub",
|
||||
},
|
||||
joinURLTest{
|
||||
base: "http://am.example.com",
|
||||
sub: "/api/v1/alerts",
|
||||
url: "http://am.example.com/api/v1/alerts",
|
||||
},
|
||||
}
|
||||
|
||||
func TestJoinURL(t *testing.T) {
|
||||
for _, testCase := range joinURLTests {
|
||||
url, err := joinURL(testCase.base, testCase.sub)
|
||||
if err != nil {
|
||||
t.Errorf("joinURL(%v, %v) failed: %s", testCase.base, testCase.sub, err.Error())
|
||||
}
|
||||
if url != testCase.url {
|
||||
t.Errorf("Invalid joined url from '%s' + '%s', expected '%s', got '%s'", testCase.base, testCase.sub, testCase.url, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type mockJSONResponse struct {
|
||||
status string
|
||||
integer int
|
||||
yes bool
|
||||
no bool
|
||||
}
|
||||
|
||||
func TestGetJSONFromURL(t *testing.T) {
|
||||
log.SetOutput(ioutil.Discard) // disable logging to console
|
||||
httpmock.Activate()
|
||||
defer httpmock.DeactivateAndReset()
|
||||
mockJSON := `{
|
||||
"response": "success",
|
||||
"integer": 123,
|
||||
"yes": true,
|
||||
"no": false
|
||||
}`
|
||||
httpmock.RegisterResponder("GET", "http://localhost/", httpmock.NewStringResponder(200, mockJSON))
|
||||
|
||||
response := mockJSONResponse{}
|
||||
err := getJSONFromURL("http://localhost/", time.Second, &response)
|
||||
if err != nil {
|
||||
t.Errorf("getJSONFromURL() failed: %s", err.Error())
|
||||
}
|
||||
|
||||
httpmock.RegisterResponder("GET", "http://localhost/404", httpmock.NewStringResponder(404, "Not found"))
|
||||
response = mockJSONResponse{}
|
||||
err = getJSONFromURL("http://localhost/404", time.Second, &response)
|
||||
if err == nil {
|
||||
t.Errorf("getJSONFromURL() on invalid url didn't return 404, response: %v", response)
|
||||
}
|
||||
}
|
||||
30
alertmanager/silences_test.go
Normal file
30
alertmanager/silences_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package alertmanager_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/cloudflare/unsee/alertmanager"
|
||||
httpmock "gopkg.in/jarcoal/httpmock.v1"
|
||||
)
|
||||
|
||||
func TestSilenceAPIResponseGet(t *testing.T) {
|
||||
log.SetOutput(ioutil.Discard) // disable logging to console
|
||||
httpmock.Activate()
|
||||
defer httpmock.DeactivateAndReset()
|
||||
mockJSON, err := ioutil.ReadFile("../mock/api/v1/silences")
|
||||
if err != nil {
|
||||
t.Errorf("Can't open mock 'silences' file: %s", err.Error())
|
||||
}
|
||||
httpmock.RegisterResponder("GET", "api/v1/silences", httpmock.NewBytesResponder(200, mockJSON))
|
||||
|
||||
response := alertmanager.SilenceAPIResponse{}
|
||||
err = response.Get()
|
||||
if err != nil {
|
||||
t.Errorf("SilenceAPIResponse.Get() failed: %s", err.Error())
|
||||
}
|
||||
if response.Status != "success" {
|
||||
t.Errorf("Invalid SilenceAPIResponse status: %s", response.Status)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cloudflare/unsee/filters"
|
||||
"github.com/cloudflare/unsee/models"
|
||||
)
|
||||
|
||||
@@ -3,12 +3,12 @@ package main
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
"html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type binaryFileSystem struct {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"startsAt": "2017-02-18T01:34:34Z",
|
||||
"endsAt": "0001-01-01T00:00:00Z",
|
||||
"createdAt": "2017-02-18T01:34:34Z",
|
||||
"createdBy": "john@unicorn.corp",
|
||||
"createdBy": "john@example.com",
|
||||
"comment": "Silenced instance"
|
||||
},
|
||||
{
|
||||
@@ -34,7 +34,7 @@
|
||||
"startsAt": "2017-02-18T01:34:34Z",
|
||||
"endsAt": "0001-01-01T00:00:00Z",
|
||||
"createdAt": "2017-02-18T01:34:34Z",
|
||||
"createdBy": "john@unicorn.corp",
|
||||
"createdBy": "john@example.com",
|
||||
"comment": "Silenced Host_Down alerts in the dev cluster"
|
||||
}
|
||||
],
|
||||
|
||||
87
transform/color_test.go
Normal file
87
transform/color_test.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package transform_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cloudflare/unsee/config"
|
||||
"github.com/cloudflare/unsee/models"
|
||||
"github.com/cloudflare/unsee/transform"
|
||||
)
|
||||
|
||||
type colorTest struct {
|
||||
config []string
|
||||
labels map[string]string
|
||||
colors map[string]string
|
||||
}
|
||||
|
||||
var colorTests = []colorTest{
|
||||
colorTest{
|
||||
labels: map[string]string{},
|
||||
},
|
||||
colorTest{
|
||||
labels: map[string]string{
|
||||
"node": "localhost",
|
||||
},
|
||||
},
|
||||
colorTest{
|
||||
config: []string{"node"},
|
||||
labels: map[string]string{
|
||||
"node": "localhost",
|
||||
},
|
||||
colors: map[string]string{
|
||||
"node": "localhost",
|
||||
},
|
||||
},
|
||||
colorTest{
|
||||
config: []string{"node", "instance"},
|
||||
labels: map[string]string{
|
||||
"node": "instance",
|
||||
"env": "instance",
|
||||
"instance": "server1",
|
||||
"job": "node_exporter",
|
||||
},
|
||||
colors: map[string]string{
|
||||
"node": "instance",
|
||||
"instance": "server1",
|
||||
},
|
||||
},
|
||||
colorTest{
|
||||
config: []string{"job", "node", "instance"},
|
||||
labels: map[string]string{
|
||||
"job": "node_ping",
|
||||
},
|
||||
colors: map[string]string{
|
||||
"job": "node_ping",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestColorLabel(t *testing.T) {
|
||||
for _, testCase := range colorTests {
|
||||
config.Config.ColorLabelsUnique = testCase.config
|
||||
colorStore := models.UnseeColorMap{}
|
||||
for key, value := range testCase.labels {
|
||||
transform.ColorLabel(colorStore, key, value)
|
||||
}
|
||||
for key, value := range testCase.colors {
|
||||
if label, found := colorStore[key]; found {
|
||||
if _, found := label[value]; !found {
|
||||
t.Errorf("Expected value '%s' for label '%s' not found in color map", value, key)
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Expected label '%s' not found in color map", key)
|
||||
}
|
||||
}
|
||||
for key, valueMap := range colorStore {
|
||||
if _, found := testCase.colors[key]; found {
|
||||
for value, _ := range valueMap {
|
||||
if value != testCase.colors[key] {
|
||||
t.Errorf("Unexpected value '%s' for label '%s' found in color map", value, key)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Unexpected label '%s' found in color map", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,12 @@ package transform
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"github.com/cloudflare/unsee/config"
|
||||
"github.com/cloudflare/unsee/models"
|
||||
"io"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cloudflare/unsee/config"
|
||||
"github.com/cloudflare/unsee/models"
|
||||
|
||||
"github.com/hansrodtang/randomcolor"
|
||||
)
|
||||
|
||||
|
||||
90
transform/jira_test.go
Normal file
90
transform/jira_test.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package transform_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cloudflare/unsee/models"
|
||||
"github.com/cloudflare/unsee/transform"
|
||||
)
|
||||
|
||||
type jiraTest struct {
|
||||
silence models.AlertmanagerSilence
|
||||
jiraID string
|
||||
jiraLink string
|
||||
}
|
||||
|
||||
var jiraRules = []string{
|
||||
"DEVOPS-[0-9]+@https://jira.example.com",
|
||||
"PROJECT-[0-9]+@https://example.com",
|
||||
}
|
||||
|
||||
var jiraTests = []jiraTest{
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "Lorem ipsum dolor sit amet",
|
||||
},
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "DVOPS-123",
|
||||
},
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "DEVOPS team",
|
||||
},
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "a project-1 b",
|
||||
},
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "a PROJECT- b",
|
||||
},
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "DEVOPS-1",
|
||||
},
|
||||
jiraID: "DEVOPS-1",
|
||||
jiraLink: "https://jira.example.com/browse/DEVOPS-1",
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "DEVOPS-123",
|
||||
},
|
||||
jiraID: "DEVOPS-123",
|
||||
jiraLink: "https://jira.example.com/browse/DEVOPS-123",
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "a DEVOPS-1 b",
|
||||
},
|
||||
jiraID: "DEVOPS-1",
|
||||
jiraLink: "https://jira.example.com/browse/DEVOPS-1",
|
||||
},
|
||||
jiraTest{
|
||||
silence: models.AlertmanagerSilence{
|
||||
Comment: "PROJECT-9",
|
||||
},
|
||||
jiraID: "PROJECT-9",
|
||||
jiraLink: "https://example.com/browse/PROJECT-9",
|
||||
},
|
||||
}
|
||||
|
||||
func TestDetectJIRAs(t *testing.T) {
|
||||
transform.ParseRules(jiraRules)
|
||||
for _, testCase := range jiraTests {
|
||||
jiraID, jiraLink := transform.DetectJIRAs(&testCase.silence)
|
||||
if jiraID != testCase.jiraID {
|
||||
t.Errorf("Invalid JIRA ID detected in silence comment '%s', expected '%s', got '%s'",
|
||||
testCase.silence.Comment, testCase.jiraID, jiraID)
|
||||
}
|
||||
if jiraID != testCase.jiraID {
|
||||
t.Errorf("Invalid JIRA link detected in silence comment '%s', expected '%s', got '%s'",
|
||||
testCase.silence.Comment, testCase.jiraLink, jiraLink)
|
||||
}
|
||||
}
|
||||
}
|
||||
102
transform/links_test.go
Normal file
102
transform/links_test.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package transform_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cloudflare/unsee/transform"
|
||||
)
|
||||
|
||||
type linkTest struct {
|
||||
before map[string]string
|
||||
after map[string]string
|
||||
links map[string]string
|
||||
}
|
||||
|
||||
var linkTests = []linkTest{
|
||||
linkTest{
|
||||
before: map[string]string{},
|
||||
after: map[string]string{},
|
||||
links: map[string]string{},
|
||||
},
|
||||
linkTest{
|
||||
before: map[string]string{
|
||||
"key1": "value 1",
|
||||
"key2": "value2",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"key1": "value 1",
|
||||
"key2": "value2",
|
||||
"level": "info",
|
||||
},
|
||||
links: map[string]string{},
|
||||
},
|
||||
linkTest{
|
||||
before: map[string]string{
|
||||
"key1": "value 1",
|
||||
"key2": "http://localhost",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"key1": "value 1",
|
||||
"level": "info",
|
||||
},
|
||||
links: map[string]string{
|
||||
"key2": "http://localhost",
|
||||
},
|
||||
},
|
||||
linkTest{
|
||||
before: map[string]string{
|
||||
"key1": "value 1",
|
||||
"key2": "https://example.com/abc",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"key1": "value 1",
|
||||
"level": "info",
|
||||
},
|
||||
links: map[string]string{
|
||||
"key2": "https://example.com/abc",
|
||||
},
|
||||
},
|
||||
linkTest{
|
||||
before: map[string]string{
|
||||
"key1": "value 1",
|
||||
"key2": "file://example/abc",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"key1": "value 1",
|
||||
"key2": "file://example/abc",
|
||||
"level": "info",
|
||||
},
|
||||
links: map[string]string{},
|
||||
},
|
||||
linkTest{
|
||||
before: map[string]string{
|
||||
"key1": "value 1",
|
||||
"key2": "ftp://example/abc",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"key1": "value 1",
|
||||
"level": "info",
|
||||
},
|
||||
links: map[string]string{
|
||||
"key2": "ftp://example/abc",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestDetectLinks(t *testing.T) {
|
||||
for _, testCase := range linkTests {
|
||||
after, links := transform.DetectLinks(testCase.before)
|
||||
if !reflect.DeepEqual(after, testCase.after) {
|
||||
t.Errorf("DetectLinks returned invalid annotation map, expected %v, got %v", testCase.after, after)
|
||||
}
|
||||
if !reflect.DeepEqual(links, testCase.links) {
|
||||
t.Errorf("DetectLinks returned invalid link map, expected %v, got %v", testCase.links, links)
|
||||
}
|
||||
}
|
||||
}
|
||||
56
transform/slices_test.go
Normal file
56
transform/slices_test.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package transform
|
||||
|
||||
import "testing"
|
||||
|
||||
type sliceTest struct {
|
||||
array []string
|
||||
value string
|
||||
found bool
|
||||
}
|
||||
|
||||
var sliceTests = []sliceTest{
|
||||
sliceTest{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "aa",
|
||||
found: true,
|
||||
},
|
||||
sliceTest{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "bb",
|
||||
found: true,
|
||||
},
|
||||
sliceTest{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "cc",
|
||||
found: true,
|
||||
},
|
||||
sliceTest{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "dd",
|
||||
found: true,
|
||||
},
|
||||
sliceTest{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "bbcc",
|
||||
found: false,
|
||||
},
|
||||
sliceTest{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "b",
|
||||
found: false,
|
||||
},
|
||||
sliceTest{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "",
|
||||
found: false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestStringInSlice(t *testing.T) {
|
||||
for _, testCase := range sliceTests {
|
||||
found := stringInSlice(testCase.array, testCase.value)
|
||||
if found != testCase.found {
|
||||
t.Errorf("Check if '%s' in slice %v returned %v, expected %v", testCase.value, testCase.array, found, testCase.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
71
transform/strip_test.go
Normal file
71
transform/strip_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package transform_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cloudflare/unsee/transform"
|
||||
)
|
||||
|
||||
type stripTest struct {
|
||||
strip []string
|
||||
before map[string]string
|
||||
after map[string]string
|
||||
}
|
||||
|
||||
var stripTests = []stripTest{
|
||||
stripTest{
|
||||
strip: []string{"env"},
|
||||
before: map[string]string{
|
||||
"host": "localhost",
|
||||
"env": "production",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"host": "localhost",
|
||||
"level": "info",
|
||||
},
|
||||
},
|
||||
stripTest{
|
||||
strip: []string{"server"},
|
||||
before: map[string]string{
|
||||
"host": "localhost",
|
||||
"env": "production",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"host": "localhost",
|
||||
"env": "production",
|
||||
"level": "info",
|
||||
},
|
||||
},
|
||||
stripTest{
|
||||
strip: []string{},
|
||||
before: map[string]string{
|
||||
"host": "localhost",
|
||||
"env": "production",
|
||||
"level": "info",
|
||||
},
|
||||
after: map[string]string{
|
||||
"host": "localhost",
|
||||
"env": "production",
|
||||
"level": "info",
|
||||
},
|
||||
},
|
||||
stripTest{
|
||||
strip: []string{"host"},
|
||||
before: map[string]string{
|
||||
"host": "localhost",
|
||||
},
|
||||
after: map[string]string{},
|
||||
},
|
||||
}
|
||||
|
||||
func TestStripLables(t *testing.T) {
|
||||
for _, testCase := range stripTests {
|
||||
labels := transform.StripLables(testCase.strip, testCase.before)
|
||||
if !reflect.DeepEqual(labels, testCase.after) {
|
||||
t.Errorf("StripLables failed, expected %v, got %v", testCase.after, labels)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user