diff --git a/pkg/services/screenshot/option.go b/pkg/services/screenshot/option.go index e84d2ed3a55..f19381abdae 100644 --- a/pkg/services/screenshot/option.go +++ b/pkg/services/screenshot/option.go @@ -9,16 +9,20 @@ import ( ) var ( - DefaultTheme = models.ThemeDark - DefaultTimeout = 15 * time.Second + DefaultFrom = "now-1h" + DefaultTo = "now" DefaultHeight = 500 DefaultWidth = 1000 + DefaultTheme = models.ThemeDark + DefaultTimeout = 15 * time.Second ) // ScreenshotOptions are the options for taking a screenshot. type ScreenshotOptions struct { DashboardUID string PanelID int64 + From string + To string Width int Height int Theme models.Theme @@ -27,6 +31,12 @@ type ScreenshotOptions struct { // SetDefaults sets default values for missing or invalid options. func (s ScreenshotOptions) SetDefaults() ScreenshotOptions { + if s.From == "" { + s.From = DefaultFrom + } + if s.To == "" { + s.To = DefaultTo + } if s.Width <= 0 { s.Width = DefaultWidth } @@ -48,6 +58,8 @@ func (s ScreenshotOptions) Hash() []byte { h := fnv.New64() _, _ = h.Write([]byte(s.DashboardUID)) _, _ = h.Write([]byte(strconv.FormatInt(s.PanelID, 10))) + _, _ = h.Write([]byte(s.From)) + _, _ = h.Write([]byte(s.To)) _, _ = h.Write([]byte(strconv.FormatInt(int64(s.Width), 10))) _, _ = h.Write([]byte(strconv.FormatInt(int64(s.Height), 10))) _, _ = h.Write([]byte(s.Theme)) diff --git a/pkg/services/screenshot/option_test.go b/pkg/services/screenshot/option_test.go index 50552c1431b..2187b032391 100644 --- a/pkg/services/screenshot/option_test.go +++ b/pkg/services/screenshot/option_test.go @@ -12,6 +12,30 @@ func TestScreenshotOptions(t *testing.T) { o = o.SetDefaults() assert.Equal(t, ScreenshotOptions{ + From: DefaultFrom, + To: DefaultTo, + Width: DefaultWidth, + Height: DefaultHeight, + Theme: DefaultTheme, + Timeout: DefaultTimeout, + }, o) + + o.From = "now-6h" + o = o.SetDefaults() + assert.Equal(t, ScreenshotOptions{ + From: "now-6h", + To: DefaultTo, + Width: DefaultWidth, + Height: DefaultHeight, + Theme: DefaultTheme, + Timeout: DefaultTimeout, + }, o) + + o.To = "now-2h" + o = o.SetDefaults() + assert.Equal(t, ScreenshotOptions{ + From: "now-6h", + To: "now-2h", Width: DefaultWidth, Height: DefaultHeight, Theme: DefaultTheme, @@ -21,6 +45,8 @@ func TestScreenshotOptions(t *testing.T) { o.Width = 100 o = o.SetDefaults() assert.Equal(t, ScreenshotOptions{ + From: "now-6h", + To: "now-2h", Width: 100, Height: DefaultHeight, Theme: DefaultTheme, @@ -30,6 +56,8 @@ func TestScreenshotOptions(t *testing.T) { o.Height = 100 o = o.SetDefaults() assert.Equal(t, ScreenshotOptions{ + From: "now-6h", + To: "now-2h", Width: 100, Height: 100, Theme: DefaultTheme, @@ -39,6 +67,8 @@ func TestScreenshotOptions(t *testing.T) { o.Theme = "Not a theme" o = o.SetDefaults() assert.Equal(t, ScreenshotOptions{ + From: "now-6h", + To: "now-2h", Width: 100, Height: 100, Theme: DefaultTheme, @@ -47,6 +77,8 @@ func TestScreenshotOptions(t *testing.T) { o.Timeout = DefaultTimeout + 1 assert.Equal(t, ScreenshotOptions{ + From: "now-6h", + To: "now-2h", Width: 100, Height: 100, Theme: DefaultTheme, @@ -59,21 +91,27 @@ func TestScreenshotOptions_Hash(t *testing.T) { assert.Equal(t, []byte{0xd9, 0x83, 0x82, 0x18, 0x6c, 0x3d, 0x7d, 0x47}, o.Hash()) o = o.SetDefaults() - assert.Equal(t, []byte{0x6, 0x7, 0x97, 0x6, 0x53, 0xf, 0x8b, 0xf1}, o.Hash()) + assert.Equal(t, []byte{0x3, 0x52, 0x33, 0x5f, 0xed, 0x96, 0x47, 0xb5}, o.Hash()) + + o.From = "now-6h" + assert.Equal(t, []byte{0x1b, 0x61, 0xc4, 0x40, 0x1f, 0xae, 0xa0, 0xe0}, o.Hash()) + + o.To = "now-2h" + assert.Equal(t, []byte{0x2, 0x4f, 0xfd, 0xd5, 0x68, 0xdd, 0xd1, 0x99}, o.Hash()) o.Width = 100 o = o.SetDefaults() - assert.Equal(t, []byte{0x25, 0x50, 0xb4, 0x4b, 0x43, 0xcd, 0x3, 0x49}, o.Hash()) + assert.Equal(t, []byte{0x16, 0x6c, 0xd, 0xad, 0x9f, 0x32, 0x9d, 0x1}, o.Hash()) o.Height = 100 o = o.SetDefaults() - assert.Equal(t, []byte{0x51, 0xe2, 0x6f, 0x2c, 0x62, 0x7b, 0x3b, 0xc5}, o.Hash()) + assert.Equal(t, []byte{0x2, 0x82, 0x96, 0x68, 0x2b, 0x57, 0x7d, 0xdd}, o.Hash()) o.Theme = "Not a theme" o = o.SetDefaults() - assert.Equal(t, []byte{0x51, 0xe2, 0x6f, 0x2c, 0x62, 0x7b, 0x3b, 0xc5}, o.Hash()) + assert.Equal(t, []byte{0x2, 0x82, 0x96, 0x68, 0x2b, 0x57, 0x7d, 0xdd}, o.Hash()) // the timeout should not change the sum o.Timeout = DefaultTimeout + 1 - assert.Equal(t, []byte{0x51, 0xe2, 0x6f, 0x2c, 0x62, 0x7b, 0x3b, 0xc5}, o.Hash()) + assert.Equal(t, []byte{0x2, 0x82, 0x96, 0x68, 0x2b, 0x57, 0x7d, 0xdd}, o.Hash()) } diff --git a/pkg/services/screenshot/screenshot.go b/pkg/services/screenshot/screenshot.go index 468e3202d35..e8d6b41b695 100644 --- a/pkg/services/screenshot/screenshot.go +++ b/pkg/services/screenshot/screenshot.go @@ -92,14 +92,17 @@ func (s *HeadlessScreenshotService) Take(ctx context.Context, opts ScreenshotOpt return nil, err } + opts = opts.SetDefaults() + u := url.URL{} u.Path = path.Join("d-solo", q.Result.Uid, q.Result.Slug) p := u.Query() p.Add("orgId", strconv.FormatInt(q.Result.OrgId, 10)) p.Add("panelId", strconv.FormatInt(opts.PanelID, 10)) + p.Add("from", opts.From) + p.Add("to", opts.To) u.RawQuery = p.Encode() - opts = opts.SetDefaults() renderOpts := rendering.Opts{ AuthOpts: rendering.AuthOpts{ OrgID: q.Result.OrgId, diff --git a/pkg/services/screenshot/screenshot_test.go b/pkg/services/screenshot/screenshot_test.go index caeea6a98b2..d4382bbd960 100644 --- a/pkg/services/screenshot/screenshot_test.go +++ b/pkg/services/screenshot/screenshot_test.go @@ -34,6 +34,7 @@ func TestHeadlessScreenshotService(t *testing.T) { assert.EqualError(t, err, "Dashboard not found") assert.Nil(t, screenshot) + // should take a screenshot d.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) { q := args.Get(1).(*models.GetDashboardQuery) q.Result = &models.Dashboard{Id: 1, Uid: "foo", Slug: "bar", OrgId: 2} @@ -54,10 +55,12 @@ func TestHeadlessScreenshotService(t *testing.T) { Width: DefaultWidth, Height: DefaultHeight, Theme: DefaultTheme, - Path: "d-solo/foo/bar?orgId=2&panelId=4", + Path: "d-solo/foo/bar?from=now-6h&orgId=2&panelId=4&to=now-2h", ConcurrentLimit: setting.AlertingRenderLimit, } + opts.From = "now-6h" + opts.To = "now-2h" opts.DashboardUID = "foo" opts.PanelID = 4 r.EXPECT().