Commit f4078e19 by bergquist

tests: for skipping with hidden folders

parent 11081010
...@@ -18,12 +18,18 @@ import ( ...@@ -18,12 +18,18 @@ import (
gocache "github.com/patrickmn/go-cache" gocache "github.com/patrickmn/go-cache"
) )
var (
checkDiskForChangesInterval time.Duration = time.Second * 3
)
type fileReader struct { type fileReader struct {
Cfg *DashboardsAsConfig Cfg *DashboardsAsConfig
Path string Path string
log log.Logger FolderId int64
dashboardRepo dashboards.Repository log log.Logger
cache *gocache.Cache dashboardRepo dashboards.Repository
cache *gocache.Cache
createWalkFunc func(fr *fileReader) filepath.WalkFunc
} }
func NewDashboardFileReader(cfg *DashboardsAsConfig, log log.Logger) (*fileReader, error) { func NewDashboardFileReader(cfg *DashboardsAsConfig, log log.Logger) (*fileReader, error) {
...@@ -37,34 +43,17 @@ func NewDashboardFileReader(cfg *DashboardsAsConfig, log log.Logger) (*fileReade ...@@ -37,34 +43,17 @@ func NewDashboardFileReader(cfg *DashboardsAsConfig, log log.Logger) (*fileReade
} }
return &fileReader{ return &fileReader{
Cfg: cfg, Cfg: cfg,
Path: path, Path: path,
log: log, log: log,
dashboardRepo: dashboards.GetRepository(), dashboardRepo: dashboards.GetRepository(),
cache: gocache.New(5*time.Minute, 30*time.Minute), cache: gocache.New(5*time.Minute, 30*time.Minute),
createWalkFunc: createWalkFn,
}, nil }, nil
} }
func (fr *fileReader) addCache(key string, json *dashboards.SaveDashboardItem) {
fr.cache.Add(key, json, time.Minute*10)
}
func (fr *fileReader) getCache(key string) (*dashboards.SaveDashboardItem, bool) {
obj, exist := fr.cache.Get(key)
if !exist {
return nil, exist
}
dash, ok := obj.(*dashboards.SaveDashboardItem)
if !ok {
return nil, ok
}
return dash, ok
}
func (fr *fileReader) ReadAndListen(ctx context.Context) error { func (fr *fileReader) ReadAndListen(ctx context.Context) error {
ticker := time.NewTicker(time.Second * 3) ticker := time.NewTicker(checkDiskForChangesInterval)
if err := fr.walkFolder(); err != nil { if err := fr.walkFolder(); err != nil {
fr.log.Error("failed to search for dashboards", "error", err) fr.log.Error("failed to search for dashboards", "error", err)
...@@ -95,7 +84,11 @@ func (fr *fileReader) walkFolder() error { ...@@ -95,7 +84,11 @@ func (fr *fileReader) walkFolder() error {
} }
} }
return filepath.Walk(fr.Path, func(path string, fileInfo os.FileInfo, err error) error { return filepath.Walk(fr.Path, fr.createWalkFunc(fr)) //omg this is so ugly :(
}
func createWalkFn(fr *fileReader) filepath.WalkFunc {
return func(path string, fileInfo os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
} }
...@@ -147,7 +140,7 @@ func (fr *fileReader) walkFolder() error { ...@@ -147,7 +140,7 @@ func (fr *fileReader) walkFolder() error {
fr.log.Debug("loading dashboard from disk into database.", "file", path) fr.log.Debug("loading dashboard from disk into database.", "file", path)
_, err = fr.dashboardRepo.SaveDashboard(dash) _, err = fr.dashboardRepo.SaveDashboard(dash)
return err return err
}) }
} }
func (fr *fileReader) readDashboardFromFile(path string) (*dashboards.SaveDashboardItem, error) { func (fr *fileReader) readDashboardFromFile(path string) (*dashboards.SaveDashboardItem, error) {
...@@ -172,7 +165,25 @@ func (fr *fileReader) readDashboardFromFile(path string) (*dashboards.SaveDashbo ...@@ -172,7 +165,25 @@ func (fr *fileReader) readDashboardFromFile(path string) (*dashboards.SaveDashbo
return nil, err return nil, err
} }
fr.addCache(path, dash) fr.addDashboardCache(path, dash)
return dash, nil return dash, nil
} }
func (fr *fileReader) addDashboardCache(key string, json *dashboards.SaveDashboardItem) {
fr.cache.Add(key, json, time.Minute*10)
}
func (fr *fileReader) getCache(key string) (*dashboards.SaveDashboardItem, bool) {
obj, exist := fr.cache.Get(key)
if !exist {
return nil, exist
}
dash, ok := obj.(*dashboards.SaveDashboardItem)
if !ok {
return nil, ok
}
return dash, ok
}
...@@ -2,6 +2,7 @@ package dashboards ...@@ -2,6 +2,7 @@ package dashboards
import ( import (
"os" "os"
"path/filepath"
"testing" "testing"
"time" "time"
...@@ -22,99 +23,156 @@ var ( ...@@ -22,99 +23,156 @@ var (
) )
func TestDashboardFileReader(t *testing.T) { func TestDashboardFileReader(t *testing.T) {
Convey("Reading dashboards from disk", t, func() { Convey("Dashboard file reader", t, func() {
bus.ClearBusHandlers() Convey("Reading dashboards from disk", func() {
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("Can read default dashboard", func() { bus.ClearBusHandlers()
cfg.Options["folder"] = defaultDashboards fakeRepo = &fakeDashboardRepo{}
reader, err := NewDashboardFileReader(cfg, logger) bus.AddHandler("test", mockGetDashboardQuery)
So(err, ShouldBeNil) dashboards.SetRepository(fakeRepo)
logger := log.New("test.logger")
err = reader.walkFolder() cfg := &DashboardsAsConfig{
So(err, ShouldBeNil) 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() { reader, err := NewDashboardFileReader(cfg, logger)
cfg.Options["folder"] = oneDashboard So(err, ShouldBeNil)
fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{ err = reader.walkFolder()
Updated: time.Now().Add(time.Hour), So(err, ShouldBeNil)
Slug: "grafana",
})
reader, err := NewDashboardFileReader(cfg, logger) So(len(fakeRepo.inserted), ShouldEqual, 2)
So(err, ShouldBeNil) })
err = reader.walkFolder() Convey("Should not update dashboards when db is newer", func() {
So(err, ShouldBeNil) 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() { reader, err := NewDashboardFileReader(cfg, logger)
cfg.Options["folder"] = oneDashboard So(err, ShouldBeNil)
stat, _ := os.Stat(oneDashboard + "/dashboard1.json") err = reader.walkFolder()
So(err, ShouldBeNil)
fakeRepo.getDashboard = append(fakeRepo.getDashboard, &models.Dashboard{ So(len(fakeRepo.inserted), ShouldEqual, 0)
Updated: stat.ModTime().AddDate(0, 0, -1),
Slug: "grafana",
}) })
reader, err := NewDashboardFileReader(cfg, logger) Convey("Can read default dashboard and replace old version in database", func() {
So(err, ShouldBeNil) cfg.Options["folder"] = oneDashboard
err = reader.walkFolder() stat, _ := os.Stat(oneDashboard + "/dashboard1.json")
So(err, ShouldBeNil)
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() { reader, err := NewDashboardFileReader(cfg, logger)
cfg := &DashboardsAsConfig{ So(err, ShouldBeNil)
Name: "Default",
Type: "file", err = reader.walkFolder()
OrgId: 1, So(err, ShouldBeNil)
Folder: "",
} So(len(fakeRepo.inserted), ShouldEqual, 1)
})
_, err := NewDashboardFileReader(cfg, logger) Convey("Invalid configuration should return error", func() {
So(err, ShouldNotBeNil) 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{ cfg := &DashboardsAsConfig{
Name: "Default", Name: "Default",
Type: "file", Type: "file",
OrgId: 1, OrgId: 1,
Folder: "", Folder: "",
Options: map[string]interface{}{ Options: map[string]interface{}{
"folder": brokenDashboards, "folder": defaultDashboards,
}, },
} }
_, err := NewDashboardFileReader(cfg, logger) reader, err := NewDashboardFileReader(cfg, log.New("test-logger"))
So(err, ShouldBeNil) 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 { type fakeDashboardRepo struct {
inserted []*dashboards.SaveDashboardItem inserted []*dashboards.SaveDashboardItem
getDashboard []*models.Dashboard getDashboard []*models.Dashboard
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment