|
|
|
|
@ -2,6 +2,7 @@ package dashboards |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"os" |
|
|
|
|
"path/filepath" |
|
|
|
|
"testing" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
@ -22,7 +23,7 @@ var ( |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
func TestDashboardFileReader(t *testing.T) { |
|
|
|
|
Convey("Reading dashboards from disk", t, func() { |
|
|
|
|
Convey("Dashboard file reader", t, func() { |
|
|
|
|
bus.ClearBusHandlers() |
|
|
|
|
fakeRepo = &fakeDashboardRepo{} |
|
|
|
|
|
|
|
|
|
@ -30,91 +31,191 @@ func TestDashboardFileReader(t *testing.T) { |
|
|
|
|
dashboards.SetRepository(fakeRepo) |
|
|
|
|
logger := log.New("test.logger") |
|
|
|
|
|
|
|
|
|
cfg := &DashboardsAsConfig{ |
|
|
|
|
Name: "Default", |
|
|
|
|
Type: "file", |
|
|
|
|
OrgId: 1, |
|
|
|
|
Folder: "", |
|
|
|
|
Options: map[string]interface{}{}, |
|
|
|
|
} |
|
|
|
|
Convey("Reading dashboards from disk", func() { |
|
|
|
|
|
|
|
|
|
Convey("Can read default dashboard", func() { |
|
|
|
|
cfg.Options["folder"] = defaultDashboards |
|
|
|
|
cfg := &DashboardsAsConfig{ |
|
|
|
|
Name: "Default", |
|
|
|
|
Type: "file", |
|
|
|
|
OrgId: 1, |
|
|
|
|
Folder: "", |
|
|
|
|
Options: map[string]interface{}{}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
reader, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
Convey("Can read default dashboard", func() { |
|
|
|
|
cfg.Options["folder"] = defaultDashboards |
|
|
|
|
cfg.Folder = "Team A" |
|
|
|
|
|
|
|
|
|
err = reader.walkFolder() |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
reader, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
|
|
|
|
|
So(len(fakeRepo.inserted), ShouldEqual, 2) |
|
|
|
|
}) |
|
|
|
|
err = reader.startWalkingDisk() |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
|
|
|
|
|
folders := 0 |
|
|
|
|
dashboards := 0 |
|
|
|
|
|
|
|
|
|
Convey("Should not update dashboards when db is newer", func() { |
|
|
|
|
cfg.Options["folder"] = oneDashboard |
|
|
|
|
for _, i := range fakeRepo.inserted { |
|
|
|
|
if i.Dashboard.IsFolder { |
|
|
|
|
folders++ |
|
|
|
|
} else { |
|
|
|
|
dashboards++ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{ |
|
|
|
|
Updated: time.Now().Add(time.Hour), |
|
|
|
|
Slug: "grafana", |
|
|
|
|
So(dashboards, ShouldEqual, 2) |
|
|
|
|
So(folders, ShouldEqual, 1) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
reader, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
Convey("Should not update dashboards when db is newer", func() { |
|
|
|
|
cfg.Options["folder"] = oneDashboard |
|
|
|
|
|
|
|
|
|
err = reader.walkFolder() |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{ |
|
|
|
|
Updated: time.Now().Add(time.Hour), |
|
|
|
|
Slug: "grafana", |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
So(len(fakeRepo.inserted), ShouldEqual, 0) |
|
|
|
|
}) |
|
|
|
|
reader, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
|
|
|
|
|
err = reader.startWalkingDisk() |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
|
|
|
|
|
So(len(fakeRepo.inserted), ShouldEqual, 0) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
Convey("Can read default dashboard and replace old version in database", func() { |
|
|
|
|
cfg.Options["folder"] = oneDashboard |
|
|
|
|
|
|
|
|
|
Convey("Can read default dashboard and replace old version in database", func() { |
|
|
|
|
cfg.Options["folder"] = oneDashboard |
|
|
|
|
stat, _ := os.Stat(oneDashboard + "/dashboard1.json") |
|
|
|
|
|
|
|
|
|
stat, _ := os.Stat(oneDashboard + "/dashboard1.json") |
|
|
|
|
fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{ |
|
|
|
|
Updated: stat.ModTime().AddDate(0, 0, -1), |
|
|
|
|
Slug: "grafana", |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{ |
|
|
|
|
Updated: stat.ModTime().AddDate(0, 0, -1), |
|
|
|
|
Slug: "grafana", |
|
|
|
|
reader, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
|
|
|
|
|
err = reader.startWalkingDisk() |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
|
|
|
|
|
So(len(fakeRepo.inserted), ShouldEqual, 1) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
reader, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
Convey("Invalid configuration should return error", func() { |
|
|
|
|
cfg := &DashboardsAsConfig{ |
|
|
|
|
Name: "Default", |
|
|
|
|
Type: "file", |
|
|
|
|
OrgId: 1, |
|
|
|
|
Folder: "", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = reader.walkFolder() |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
_, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldNotBeNil) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
So(len(fakeRepo.inserted), ShouldEqual, 1) |
|
|
|
|
Convey("Broken dashboards should not cause error", func() { |
|
|
|
|
cfg.Options["folder"] = brokenDashboards |
|
|
|
|
|
|
|
|
|
_, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
Convey("Invalid configuration should return error", func() { |
|
|
|
|
Convey("Should not create new folder if folder name is missing", func() { |
|
|
|
|
cfg := &DashboardsAsConfig{ |
|
|
|
|
Name: "Default", |
|
|
|
|
Type: "file", |
|
|
|
|
OrgId: 1, |
|
|
|
|
Folder: "", |
|
|
|
|
Options: map[string]interface{}{ |
|
|
|
|
"folder": defaultDashboards, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_, err := NewDashboardFileReader(cfg, logger) |
|
|
|
|
So(err, ShouldNotBeNil) |
|
|
|
|
_, err := getOrCreateFolderId(cfg, fakeRepo) |
|
|
|
|
So(err, ShouldEqual, ErrFolderNameMissing) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
Convey("Broken dashboards should not cause error", func() { |
|
|
|
|
Convey("can get or Create dashboard folder", func() { |
|
|
|
|
cfg := &DashboardsAsConfig{ |
|
|
|
|
Name: "Default", |
|
|
|
|
Type: "file", |
|
|
|
|
OrgId: 1, |
|
|
|
|
Folder: "TEAM A", |
|
|
|
|
Options: map[string]interface{}{ |
|
|
|
|
"folder": defaultDashboards, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
folderId, err := getOrCreateFolderId(cfg, fakeRepo) |
|
|
|
|
So(err, ShouldBeNil) |
|
|
|
|
inserted := false |
|
|
|
|
for _, d := range fakeRepo.inserted { |
|
|
|
|
if d.Dashboard.IsFolder && d.Dashboard.Id == folderId { |
|
|
|
|
inserted = true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
So(len(fakeRepo.inserted), ShouldEqual, 1) |
|
|
|
|
So(inserted, ShouldBeTrue) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
Convey("Walking the folder with dashboards", 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.createWalk(reader, 0)("path", &FakeFileInfo{isDirectory: true, name: ".folder"}, nil) |
|
|
|
|
So(shouldSkip, ShouldEqual, filepath.SkipDir) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
Convey("should keep walking if file is not .json", func() { |
|
|
|
|
shouldSkip := reader.createWalk(reader, 0)("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 |
|
|
|
|
|