Rendering: Add light theme for errors (#41616)

* Add light theme for error rendering

* Fix lint

* Update images and add rendering_limit_x images
This commit is contained in:
Selene 2021-11-17 12:18:47 +01:00 committed by GitHub
parent dad54d499b
commit 9f7942099b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 111 additions and 6 deletions

View File

@ -65,6 +65,7 @@ func (hs *HTTPServer) RenderToPng(c *models.ReqContext) {
ConcurrentLimit: hs.Cfg.RendererConcurrentRequestLimit,
DeviceScaleFactor: scale,
Headers: headers,
Theme: rendering.ThemeDark,
})
if err != nil {
if errors.Is(err, rendering.ErrTimeout) {

View File

@ -206,6 +206,7 @@ func (n *notificationService) renderAndUploadImage(evalCtx *EvalContext, timeout
OrgID: evalCtx.Rule.OrgID,
OrgRole: models.ROLE_ADMIN,
ConcurrentLimit: setting.AlertingRenderLimit,
Theme: rendering.ThemeDark,
}
ref, err := evalCtx.GetDashboardUID()

View File

@ -365,7 +365,7 @@ func (s *testRenderService) RenderCSV(ctx context.Context, opts rendering.CSVOpt
return nil, nil
}
func (s *testRenderService) RenderErrorImage(err error) (*rendering.RenderResult, error) {
func (s *testRenderService) RenderErrorImage(theme rendering.Theme, err error) (*rendering.RenderResult, error) {
if s.renderErrorImageProvider != nil {
return s.renderErrorImageProvider(err)
}

View File

@ -19,6 +19,13 @@ const (
RenderPNG RenderType = "png"
)
type Theme string
const (
ThemeLight Theme = "light"
ThemeDark Theme = "dark"
)
type Opts struct {
Width int
Height int
@ -32,6 +39,7 @@ type Opts struct {
ConcurrentLimit int
DeviceScaleFactor float64
Headers map[string][]string
Theme Theme
}
type CSVOpts struct {
@ -63,6 +71,6 @@ type Service interface {
Version() string
Render(ctx context.Context, opts Opts) (*RenderResult, error)
RenderCSV(ctx context.Context, opts CSVOpts) (*RenderCSVResult, error)
RenderErrorImage(error error) (*RenderResult, error)
RenderErrorImage(theme Theme, error error) (*RenderResult, error)
GetRenderUser(key string) (*RenderUser, bool)
}

View File

@ -156,9 +156,18 @@ func (rs *RenderingService) Version() string {
return rs.version
}
func (rs *RenderingService) RenderErrorImage(_ error) (*RenderResult, error) {
imgUrl := "public/img/rendering_error.png"
imgPath := filepath.Join(setting.HomePath, imgUrl)
func (rs *RenderingService) RenderErrorImage(theme Theme, err error) (*RenderResult, error) {
if theme == "" {
theme = ThemeDark
}
imgUrl := "public/img/rendering_%s_%s.png"
if errors.Is(err, ErrTimeout) {
imgUrl = fmt.Sprintf(imgUrl, "timeout", theme)
} else {
imgUrl = fmt.Sprintf(imgUrl, "error", theme)
}
imgPath := filepath.Join(rs.Cfg.HomePath, imgUrl)
if _, err := os.Stat(imgPath); errors.Is(err, os.ErrNotExist) {
return nil, err
}
@ -188,8 +197,13 @@ func (rs *RenderingService) Render(ctx context.Context, opts Opts) (*RenderResul
func (rs *RenderingService) render(ctx context.Context, opts Opts) (*RenderResult, error) {
if int(atomic.LoadInt32(&rs.inProgressCount)) > opts.ConcurrentLimit {
theme := ThemeDark
if opts.Theme != "" {
theme = opts.Theme
}
filePath := fmt.Sprintf("public/img/rendering_limit_%s.png", theme)
return &RenderResult{
FilePath: filepath.Join(setting.HomePath, "public/img/rendering_limit.png"),
FilePath: filepath.Join(rs.Cfg.HomePath, filePath),
}, nil
}

View File

@ -1,9 +1,13 @@
package rendering
import (
"context"
"errors"
"path/filepath"
"testing"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -58,3 +62,80 @@ func TestGetUrl(t *testing.T) {
})
})
}
func TestRenderErrorImage(t *testing.T) {
path, err := filepath.Abs("../../../")
require.NoError(t, err)
rs := RenderingService{
Cfg: &setting.Cfg{
HomePath: path,
},
}
t.Run("No theme set returns error image with dark theme", func(t *testing.T) {
result, err := rs.RenderErrorImage("", nil)
require.NoError(t, err)
assert.Equal(t, result.FilePath, path+"/public/img/rendering_error_dark.png")
})
t.Run("Timeout error returns timeout error image", func(t *testing.T) {
result, err := rs.RenderErrorImage(ThemeLight, ErrTimeout)
require.NoError(t, err)
assert.Equal(t, result.FilePath, path+"/public/img/rendering_timeout_light.png")
})
t.Run("Generic error returns error image", func(t *testing.T) {
result, err := rs.RenderErrorImage(ThemeLight, errors.New("an error"))
require.NoError(t, err)
assert.Equal(t, result.FilePath, path+"/public/img/rendering_error_light.png")
})
t.Run("Unknown image path returns error", func(t *testing.T) {
result, err := rs.RenderErrorImage("abc", errors.New("random error"))
assert.Error(t, err)
assert.Nil(t, result)
})
}
func TestRenderLimitImage(t *testing.T) {
path, err := filepath.Abs("../../../")
require.NoError(t, err)
rs := RenderingService{
Cfg: &setting.Cfg{
HomePath: path,
},
inProgressCount: 2,
}
tests := []struct {
name string
theme Theme
expected string
}{
{
name: "Light theme returns light image",
theme: ThemeLight,
expected: path + "/public/img/rendering_limit_light.png",
},
{
name: "Dark theme returns dark image",
theme: ThemeDark,
expected: path + "/public/img/rendering_limit_dark.png",
},
{
name: "No theme returns dark image",
theme: "",
expected: path + "/public/img/rendering_limit_dark.png",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
opts := Opts{Theme: tc.theme, ConcurrentLimit: 1}
result, err := rs.Render(context.Background(), opts)
assert.NoError(t, err)
assert.Equal(t, tc.expected, result.FilePath)
})
}
}

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB