|
|
@@ -2,6 +2,7 @@ package dashboards
|
|
|
|
|
|
import (
|
|
|
"os"
|
|
|
+ "path/filepath"
|
|
|
"testing"
|
|
|
"time"
|
|
|
|
|
|
@@ -22,99 +23,156 @@ var (
|
|
|
)
|
|
|
|
|
|
func TestDashboardFileReader(t *testing.T) {
|
|
|
- Convey("Reading dashboards from disk", t, func() {
|
|
|
- bus.ClearBusHandlers()
|
|
|
- fakeRepo = &fakeDashboardRepo{}
|
|
|
-
|
|
|
- bus.AddHandler("test", mockGetDashboardQuery)
|
|
|
- dashboards.SetRepository(fakeRepo)
|
|
|
- logger := log.New("test.logger")
|
|
|
-
|
|
|
- cfg := &DashboardsAsConfig{
|
|
|
- Name: "Default",
|
|
|
- Type: "file",
|
|
|
- OrgId: 1,
|
|
|
- Folder: "",
|
|
|
- Options: map[string]interface{}{},
|
|
|
- }
|
|
|
+ Convey("Dashboard file reader", t, func() {
|
|
|
+ Convey("Reading dashboards from disk", func() {
|
|
|
|
|
|
- Convey("Can read default dashboard", func() {
|
|
|
- cfg.Options["folder"] = defaultDashboards
|
|
|
+ bus.ClearBusHandlers()
|
|
|
+ fakeRepo = &fakeDashboardRepo{}
|
|
|
|
|
|
- reader, err := NewDashboardFileReader(cfg, logger)
|
|
|
- So(err, ShouldBeNil)
|
|
|
+ bus.AddHandler("test", mockGetDashboardQuery)
|
|
|
+ dashboards.SetRepository(fakeRepo)
|
|
|
+ logger := log.New("test.logger")
|
|
|
|
|
|
- err = reader.walkFolder()
|
|
|
- So(err, ShouldBeNil)
|
|
|
+ cfg := &DashboardsAsConfig{
|
|
|
+ Name: "Default",
|
|
|
+ Type: "file",
|
|
|
+ OrgId: 1,
|
|
|
+ Folder: "",
|
|
|
+ Options: map[string]interface{}{},
|
|
|
+ }
|
|
|
|
|
|
- So(len(fakeRepo.inserted), ShouldEqual, 2)
|
|
|
- })
|
|
|
+ Convey("Can read default dashboard", func() {
|
|
|
+ cfg.Options["folder"] = defaultDashboards
|
|
|
|
|
|
- Convey("Should not update dashboards when db is newer", func() {
|
|
|
- cfg.Options["folder"] = oneDashboard
|
|
|
+ reader, err := NewDashboardFileReader(cfg, logger)
|
|
|
+ So(err, ShouldBeNil)
|
|
|
|
|
|
- fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{
|
|
|
- Updated: time.Now().Add(time.Hour),
|
|
|
- Slug: "grafana",
|
|
|
- })
|
|
|
+ err = reader.walkFolder()
|
|
|
+ So(err, ShouldBeNil)
|
|
|
|
|
|
- reader, err := NewDashboardFileReader(cfg, logger)
|
|
|
- So(err, ShouldBeNil)
|
|
|
+ So(len(fakeRepo.inserted), ShouldEqual, 2)
|
|
|
+ })
|
|
|
|
|
|
- err = reader.walkFolder()
|
|
|
- So(err, ShouldBeNil)
|
|
|
+ Convey("Should not update dashboards when db is newer", func() {
|
|
|
+ cfg.Options["folder"] = oneDashboard
|
|
|
|
|
|
- So(len(fakeRepo.inserted), ShouldEqual, 0)
|
|
|
- })
|
|
|
+ fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{
|
|
|
+ Updated: time.Now().Add(time.Hour),
|
|
|
+ Slug: "grafana",
|
|
|
+ })
|
|
|
|
|
|
- Convey("Can read default dashboard and replace old version in database", func() {
|
|
|
- cfg.Options["folder"] = oneDashboard
|
|
|
+ reader, err := NewDashboardFileReader(cfg, logger)
|
|
|
+ So(err, ShouldBeNil)
|
|
|
|
|
|
- stat, _ := os.Stat(oneDashboard + "/dashboard1.json")
|
|
|
+ err = reader.walkFolder()
|
|
|
+ So(err, ShouldBeNil)
|
|
|
|
|
|
- fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{
|
|
|
- Updated: stat.ModTime().AddDate(0, 0, -1),
|
|
|
- Slug: "grafana",
|
|
|
+ So(len(fakeRepo.inserted), ShouldEqual, 0)
|
|
|
})
|
|
|
|
|
|
- reader, err := NewDashboardFileReader(cfg, logger)
|
|
|
- So(err, ShouldBeNil)
|
|
|
+ Convey("Can read default dashboard and replace old version in database", func() {
|
|
|
+ cfg.Options["folder"] = oneDashboard
|
|
|
|
|
|
- err = reader.walkFolder()
|
|
|
- So(err, ShouldBeNil)
|
|
|
+ stat, _ := os.Stat(oneDashboard + "/dashboard1.json")
|
|
|
|
|
|
- So(len(fakeRepo.inserted), ShouldEqual, 1)
|
|
|
- })
|
|
|
+ fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{
|
|
|
+ Updated: stat.ModTime().AddDate(0, 0, -1),
|
|
|
+ Slug: "grafana",
|
|
|
+ })
|
|
|
|
|
|
- Convey("Invalid configuration should return error", func() {
|
|
|
- cfg := &DashboardsAsConfig{
|
|
|
- Name: "Default",
|
|
|
- Type: "file",
|
|
|
- OrgId: 1,
|
|
|
- Folder: "",
|
|
|
- }
|
|
|
+ reader, err := NewDashboardFileReader(cfg, logger)
|
|
|
+ So(err, ShouldBeNil)
|
|
|
+
|
|
|
+ err = reader.walkFolder()
|
|
|
+ So(err, ShouldBeNil)
|
|
|
+
|
|
|
+ So(len(fakeRepo.inserted), ShouldEqual, 1)
|
|
|
+ })
|
|
|
|
|
|
- _, err := NewDashboardFileReader(cfg, logger)
|
|
|
- So(err, ShouldNotBeNil)
|
|
|
+ Convey("Invalid configuration should return error", func() {
|
|
|
+ cfg := &DashboardsAsConfig{
|
|
|
+ Name: "Default",
|
|
|
+ Type: "file",
|
|
|
+ OrgId: 1,
|
|
|
+ Folder: "",
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err := NewDashboardFileReader(cfg, logger)
|
|
|
+ So(err, ShouldNotBeNil)
|
|
|
+ })
|
|
|
+
|
|
|
+ Convey("Broken dashboards should not cause error", func() {
|
|
|
+ cfg := &DashboardsAsConfig{
|
|
|
+ Name: "Default",
|
|
|
+ Type: "file",
|
|
|
+ OrgId: 1,
|
|
|
+ Folder: "",
|
|
|
+ Options: map[string]interface{}{
|
|
|
+ "folder": brokenDashboards,
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err := NewDashboardFileReader(cfg, logger)
|
|
|
+ So(err, ShouldBeNil)
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
- Convey("Broken dashboards should not cause error", func() {
|
|
|
+ Convey("Walking", func() {
|
|
|
cfg := &DashboardsAsConfig{
|
|
|
Name: "Default",
|
|
|
Type: "file",
|
|
|
OrgId: 1,
|
|
|
Folder: "",
|
|
|
Options: map[string]interface{}{
|
|
|
- "folder": brokenDashboards,
|
|
|
+ "folder": defaultDashboards,
|
|
|
},
|
|
|
}
|
|
|
|
|
|
- _, err := NewDashboardFileReader(cfg, logger)
|
|
|
+ reader, err := NewDashboardFileReader(cfg, log.New("test-logger"))
|
|
|
So(err, ShouldBeNil)
|
|
|
+
|
|
|
+ Convey("should skip dirs that starts with .", func() {
|
|
|
+ shouldSkip := reader.createWalkFunc(reader)("path", &FakeFileInfo{isDirectory: true, name: ".folder"}, nil)
|
|
|
+ So(shouldSkip, ShouldEqual, filepath.SkipDir)
|
|
|
+ })
|
|
|
+
|
|
|
+ Convey("should keep walking if file is not .json", func() {
|
|
|
+ shouldSkip := reader.createWalkFunc(reader)("path", &FakeFileInfo{isDirectory: true, name: "folder"}, nil)
|
|
|
+ So(shouldSkip, ShouldBeNil)
|
|
|
+ })
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+type FakeFileInfo struct {
|
|
|
+ isDirectory bool
|
|
|
+ name string
|
|
|
+}
|
|
|
+
|
|
|
+func (ffi *FakeFileInfo) IsDir() bool {
|
|
|
+ return ffi.isDirectory
|
|
|
+}
|
|
|
+
|
|
|
+func (ffi FakeFileInfo) Size() int64 {
|
|
|
+ return 1
|
|
|
+}
|
|
|
+
|
|
|
+func (ffi FakeFileInfo) Mode() os.FileMode {
|
|
|
+ return 0777
|
|
|
+}
|
|
|
+
|
|
|
+func (ffi FakeFileInfo) Name() string {
|
|
|
+ return ffi.name
|
|
|
+}
|
|
|
+
|
|
|
+func (ffi FakeFileInfo) ModTime() time.Time {
|
|
|
+ return time.Time{}
|
|
|
+}
|
|
|
+
|
|
|
+func (ffi FakeFileInfo) Sys() interface{} {
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
type fakeDashboardRepo struct {
|
|
|
inserted []*dashboards.SaveDashboardItem
|
|
|
getDashboard []*models.Dashboard
|