Files
grafana/pkg/services/ngalert/store/image_test.go
Joe Blubaugh 687e79538b Alerting: Add a general screenshot service and alerting-specific image service. (#49293)
This commit adds a pkg/services/screenshot package for taking and uploading screenshots of Grafana dashboards. It supports taking screenshots of both dashboards and individual panels within a dashboard, using the rendering service.

The screenshot package has the following services, most of which can be composed:

BrowserScreenshotService (Takes screenshots with headless Chrome)
CachableScreenshotService (Caches screenshots taken with another service such as BrowserScreenshotService)
NoopScreenshotService (A no-op screenshot service for tests)
SingleFlightScreenshotService (Prevents duplicate screenshots when taking screenshots of the same dashboard or panel in parallel)
ScreenshotUnavailableService (A screenshot service that returns ErrScreenshotsUnavailable)
UploadingScreenshotService (A screenshot service that uploads taken screenshots)

The screenshot package does not support wire dependency injection yet. ngalert constructs its own version of the service. See https://github.com/grafana/grafana/issues/49296

This PR also adds an ImageScreenshotService to ngAlert. This is used to take screenshots with a screenshotservice and then store their location reference for use by alert instances and notifiers.
2022-05-22 22:33:49 +08:00

130 lines
2.7 KiB
Go

//go:build integration
// +build integration
package store_test
import (
"context"
"testing"
"time"
"github.com/gofrs/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/services/ngalert/tests"
)
func createTestImg(fakeUrl string, fakePath string) *store.Image {
return &store.Image{
ID: 0,
Token: "",
Path: fakeUrl + "local",
URL: fakeUrl,
}
}
func addID(img *store.Image, id int64) *store.Image {
img.ID = id
return img
}
func addToken(img *store.Image) *store.Image {
token, err := uuid.NewV4()
if err != nil {
panic("wat")
}
img.Token = token.String()
return img
}
func TestSaveAndGetImage(t *testing.T) {
mockTimeNow()
ctx := context.Background()
_, dbstore := tests.SetupTestEnv(t, baseIntervalSeconds)
// Here are some images to save.
imgs := []struct {
name string
img *store.Image
errors bool
}{
{
"with file path",
createTestImg("", "path"),
false,
},
{
"with URL",
createTestImg("url", ""),
false,
},
{
"ID already set, should not change",
addToken(addID(createTestImg("Foo", ""), 123)),
true,
},
}
for _, test := range imgs {
t.Run(test.name, func(t *testing.T) {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
err := dbstore.SaveImage(ctx, test.img)
if test.errors {
require.Error(t, err)
return
}
require.NoError(t, err)
returned, err := dbstore.GetImage(ctx, test.img.Token)
assert.NoError(t, err, "Shouldn't error when getting the image")
assert.Equal(t, test.img, returned)
// Save again to test update path.
err = dbstore.SaveImage(ctx, test.img)
require.NoError(t, err, "Should have no error on second write")
returned, err = dbstore.GetImage(ctx, test.img.Token)
assert.NoError(t, err, "Shouldn't error when getting the image a second time")
assert.Equal(t, test.img, returned)
})
}
}
func TestDeleteExpiredImages(t *testing.T) {
mockTimeNow()
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
_, dbstore := tests.SetupTestEnv(t, baseIntervalSeconds)
// Save two images.
imgs := []*store.Image{
createTestImg("", ""),
createTestImg("", ""),
}
for _, img := range imgs {
err := dbstore.SaveImage(ctx, img)
require.NoError(t, err)
}
// Wait until timeout.
for i := 0; i < 120; i++ {
store.TimeNow()
}
// Call expired
err := dbstore.DeleteExpiredImages(ctx)
require.NoError(t, err)
// All images are gone.
img, err := dbstore.GetImage(ctx, imgs[0].Token)
require.Nil(t, img)
require.Error(t, err)
img, err = dbstore.GetImage(ctx, imgs[1].Token)
require.Nil(t, img)
require.Error(t, err)
}