Alerting: Support up to N fake images (#51111)

This commit is contained in:
George Robinson 2022-06-20 14:34:53 +01:00 committed by GitHub
parent e889dfdc5c
commit 18c3456d13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 46 deletions

View File

@ -27,7 +27,7 @@ func TestSensuGoNotifier(t *testing.T) {
require.NoError(t, err)
tmpl.ExternalURL = externalURL
images := newFakeImageStore()
images := newFakeImageStore(2)
cases := []struct {
name string
@ -44,7 +44,7 @@ func TestSensuGoNotifier(t *testing.T) {
{
Alert: model.Alert{
Labels: model.LabelSet{"__alert_rule_uid__": "rule uid", "alertname": "alert1", "lbl1": "val1"},
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh", "__alertScreenshotToken__": "test-image"},
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh", "__alertScreenshotToken__": "test-image-1"},
},
},
},
@ -59,7 +59,7 @@ func TestSensuGoNotifier(t *testing.T) {
"metadata": map[string]interface{}{
"name": "default",
"labels": map[string]string{
"imageURL": "https://www.example.com/test-image.jpg",
"imageURL": "https://www.example.com/test-image-1.jpg",
"ruleURL": "http://localhost/alerting/list",
},
},
@ -87,7 +87,7 @@ func TestSensuGoNotifier(t *testing.T) {
{
Alert: model.Alert{
Labels: model.LabelSet{"__alert_rule_uid__": "rule uid", "alertname": "alert1", "lbl1": "val1"},
Annotations: model.LabelSet{"ann1": "annv1", "__alertScreenshotToken__": "test-image"},
Annotations: model.LabelSet{"ann1": "annv1", "__alertScreenshotToken__": "test-image-1"},
},
}, {
Alert: model.Alert{
@ -107,7 +107,7 @@ func TestSensuGoNotifier(t *testing.T) {
"metadata": map[string]interface{}{
"name": "grafana_rule_0",
"labels": map[string]string{
"imageURL": "https://www.example.com/test-image.jpg",
"imageURL": "https://www.example.com/test-image-1.jpg",
"ruleURL": "http://localhost/alerting/list",
},
},

View File

@ -3,6 +3,7 @@ package channels
import (
"context"
"encoding/base64"
"fmt"
"os"
"testing"
"time"
@ -11,10 +12,6 @@ import (
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
)
// deleteFunc deletes the fake image.
// nolint:unused
type deleteFunc func()
type fakeImageStore struct {
Images []*ngmodels.Image
}
@ -29,63 +26,79 @@ func (f *fakeImageStore) GetImage(_ context.Context, token string) (*ngmodels.Im
return nil, ngmodels.ErrImageNotFound
}
// newFakeImageStore returns an image store with a test image.
// The image has a token and a URL, but does not have a file on disk.
func newFakeImageStore() ImageStore {
return &fakeImageStore{
Images: []*ngmodels.Image{
{
Token: "test-image",
URL: "https://www.example.com/test-image.jpg",
CreatedAt: time.Now().UTC(),
},
},
// newFakeImageStore returns an image store with N test images.
// Each image has a token and a URL, but does not have a file on disk.
func newFakeImageStore(n int) ImageStore {
s := fakeImageStore{}
for i := 0; i < n; i++ {
s.Images = append(s.Images, &ngmodels.Image{
Token: fmt.Sprintf("test-image-%d", i),
URL: fmt.Sprintf("https://www.example.com/test-image-%d.jpg", 1),
CreatedAt: time.Now().UTC(),
})
}
return &s
}
// newFakeImageStoreWithFile returns an image store with a test image.
// The image has a token, path and a URL, where the path is 1x1 transparent
// PNG on disk. The test should call deleteFunc to delete the image from disk
// newFakeImageStoreWithFile returns an image store with N test images.
// Each image has a token, path and a URL, where the path is 1x1 transparent
// PNG on disk. The test should call deleteFunc to delete the images from disk
// at the end of the test.
// nolint:deadcode,unused
func newFakeImageStoreWithFile(t *testing.T) (ImageStore, deleteFunc) {
func newFakeImageStoreWithFile(t *testing.T, n int) ImageStore {
var (
files []string
s fakeImageStore
)
t.Cleanup(func() {
// remove all files from disk
for _, f := range files {
if err := os.Remove(f); err != nil {
t.Logf("failed to delete file: %s", err)
}
}
})
for i := 0; i < n; i++ {
file, err := newTestImage()
if err != nil {
t.Fatalf("failed to create test image: %s", err)
}
files = append(files, file)
s.Images = append(s.Images, &ngmodels.Image{
Token: fmt.Sprintf("test-image-%d", i),
Path: file,
URL: fmt.Sprintf("https://www.example.com/test-image-%d", i),
CreatedAt: time.Now().UTC(),
})
}
return &s
}
// nolint:deadcode,unused
func newTestImage() (string, error) {
f, err := os.CreateTemp("", "test-image-*.png")
if err != nil {
t.Fatalf("failed to create temp image: %s", err)
return "", fmt.Errorf("failed to create temp image: %s", err)
}
// 1x1 transparent PNG
b, err := base64.StdEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=")
if err != nil {
t.Fatalf("failed to decode PNG data: %s", err)
return f.Name(), fmt.Errorf("failed to decode PNG data: %s", err)
}
if _, err := f.Write(b); err != nil {
t.Fatalf("failed to write to file: %s", err)
return f.Name(), fmt.Errorf("failed to write to file: %s", err)
}
if err := f.Close(); err != nil {
t.Fatalf("failed to close file: %s", err)
return f.Name(), fmt.Errorf("failed to close file: %s", err)
}
fn := func() {
if err := os.Remove(f.Name()); err != nil {
t.Fatalf("failed to delete file: %s", err)
}
}
store := &fakeImageStore{
Images: []*ngmodels.Image{
{
Token: "test-image",
Path: f.Name(),
URL: "https://www.example.com/test-image.jpg",
CreatedAt: time.Now().UTC(),
},
},
}
return store, fn
return f.Name(), nil
}
// mockTimeNow replaces function timeNow to return constant time.