| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- package dashboards
- import (
- "os"
- "path/filepath"
- "testing"
- "time"
- "github.com/grafana/grafana/pkg/bus"
- "github.com/grafana/grafana/pkg/models"
- "github.com/grafana/grafana/pkg/services/dashboards"
- "github.com/grafana/grafana/pkg/log"
- . "github.com/smartystreets/goconvey/convey"
- )
- var (
- defaultDashboards string = "./test-dashboards/folder-one"
- brokenDashboards string = "./test-dashboards/broken-dashboards"
- oneDashboard string = "./test-dashboards/one-dashboard"
- fakeRepo *fakeDashboardRepo
- )
- func TestDashboardFileReader(t *testing.T) {
- Convey("Dashboard file reader", t, func() {
- bus.ClearBusHandlers()
- fakeRepo = &fakeDashboardRepo{}
- bus.AddHandler("test", mockGetDashboardQuery)
- dashboards.SetRepository(fakeRepo)
- logger := log.New("test.logger")
- Convey("Reading dashboards from disk", func() {
- cfg := &DashboardsAsConfig{
- Name: "Default",
- Type: "file",
- OrgId: 1,
- Folder: "",
- Options: map[string]interface{}{},
- }
- Convey("Can read default dashboard", func() {
- cfg.Options["path"] = defaultDashboards
- cfg.Folder = "Team A"
- reader, err := NewDashboardFileReader(cfg, logger)
- So(err, ShouldBeNil)
- err = reader.startWalkingDisk()
- So(err, ShouldBeNil)
- folders := 0
- dashboards := 0
- for _, i := range fakeRepo.inserted {
- if i.Dashboard.IsFolder {
- folders++
- } else {
- dashboards++
- }
- }
- So(folders, ShouldEqual, 1)
- So(dashboards, ShouldEqual, 2)
- })
- Convey("Can read default dashboard and replace old version in database", func() {
- cfg.Options["path"] = oneDashboard
- stat, _ := os.Stat(oneDashboard + "/dashboard1.json")
- 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)
- })
- 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.Options["path"] = brokenDashboards
- _, err := NewDashboardFileReader(cfg, logger)
- So(err, ShouldBeNil)
- })
- })
- 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 := getOrCreateFolderId(cfg, fakeRepo)
- So(err, ShouldEqual, ErrFolderNameMissing)
- })
- 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() {
- noFiles := map[string]os.FileInfo{}
- Convey("should skip dirs that starts with .", func() {
- shouldSkip := createWalkFn(noFiles)("path", &FakeFileInfo{isDirectory: true, name: ".folder"}, nil)
- So(shouldSkip, ShouldEqual, filepath.SkipDir)
- })
- Convey("should keep walking if file is not .json", func() {
- shouldSkip := createWalkFn(noFiles)("path", &FakeFileInfo{isDirectory: true, name: "folder"}, nil)
- So(shouldSkip, ShouldBeNil)
- })
- })
- Convey("Can use bpth path and folder as dashboard path", func() {
- cfg := &DashboardsAsConfig{
- Name: "Default",
- Type: "file",
- OrgId: 1,
- Folder: "",
- Options: map[string]interface{}{},
- }
- Convey("using path parameter", func() {
- cfg.Options["path"] = defaultDashboards
- reader, err := NewDashboardFileReader(cfg, log.New("test-logger"))
- So(err, ShouldBeNil)
- So(reader.Path, ShouldEqual, defaultDashboards)
- })
- Convey("using folder as options", func() {
- cfg.Options["folder"] = defaultDashboards
- reader, err := NewDashboardFileReader(cfg, log.New("test-logger"))
- So(err, ShouldBeNil)
- So(reader.Path, ShouldEqual, defaultDashboards)
- })
- })
- })
- }
- 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.SaveDashboardDTO
- provisioned []*models.DashboardProvisioning
- getDashboard []*models.Dashboard
- }
- func (repo *fakeDashboardRepo) SaveDashboard(json *dashboards.SaveDashboardDTO) (*models.Dashboard, error) {
- repo.inserted = append(repo.inserted, json)
- return json.Dashboard, nil
- }
- func (repo *fakeDashboardRepo) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) {
- return repo.provisioned, nil
- }
- func (repo *fakeDashboardRepo) SaveProvisionedDashboard(dto *dashboards.SaveDashboardDTO, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
- repo.inserted = append(repo.inserted, dto)
- repo.provisioned = append(repo.provisioned, provisioning)
- return dto.Dashboard, nil
- }
- func mockGetDashboardQuery(cmd *models.GetDashboardQuery) error {
- for _, d := range fakeRepo.getDashboard {
- if d.Slug == cmd.Slug {
- cmd.Result = d
- return nil
- }
- }
- return models.ErrDashboardNotFound
- }
|