diff --git a/go.mod b/go.mod index c00aa50..02d22b6 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.9.0 + github.com/stretchr/testify v1.7.0 // indirect github.com/xanzy/ssh-agent v0.3.1 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/net v0.0.0-20210929161516-d455829e376d // indirect diff --git a/go.sum b/go.sum index 7f5ab2d..a42823a 100644 --- a/go.sum +++ b/go.sum @@ -440,6 +440,7 @@ github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/internal/dashboardloader/dashboardloader.go b/internal/dashboardloader/dashboardloader.go index cea9740..a46a561 100644 --- a/internal/dashboardloader/dashboardloader.go +++ b/internal/dashboardloader/dashboardloader.go @@ -22,7 +22,7 @@ type Dashboard struct { Dashboard map[string]interface{} } -func Load(path string) map[string]Dashboard { +func Load(path string) (map[string]Dashboard, error) { dashboards := map[string]Dashboard{} err := filepath.Walk(path, func(path string, fi fs.FileInfo, err error) error { @@ -59,10 +59,10 @@ func Load(path string) map[string]Dashboard { }) if err != nil { - return nil + return nil, err } - return dashboards + return dashboards, nil } func readDashboardFile(path string, value *map[string]interface{}) error { @@ -75,9 +75,17 @@ func readDashboardFile(path string, value *map[string]interface{}) error { defer dashboardFile.Close() - byteValue, _ := ioutil.ReadAll(dashboardFile) + byteValue, err := ioutil.ReadAll(dashboardFile) + + if err != nil { + return err + } - json.Unmarshal([]byte(byteValue), &value) + err = json.Unmarshal([]byte(byteValue), &value) + + if err != nil { + return err + } return nil } diff --git a/internal/dashboardloader/dashboardloader_test.go b/internal/dashboardloader/dashboardloader_test.go new file mode 100644 index 0000000..170d5f3 --- /dev/null +++ b/internal/dashboardloader/dashboardloader_test.go @@ -0,0 +1,53 @@ +package dashboardloader + +import ( + "testing" +) + +func TestLoadInvalidPath(t *testing.T) { + dashboards, err := Load("./dev/blabla") + + if err == nil { + t.Fatal("load an path file must return an error") + } + + if len(dashboards) > 0 { + t.Fatal("load an invalid path must not return a dashboard struct") + } +} + +func TestLoadInvalidFile(t *testing.T) { + dashboards, err := Load("./testdata/invalid") + + if err == nil { + t.Fatal("load an invalid json file must return an error") + } + + if len(dashboards) > 0 { + t.Fatal("load an invalid json file must not return a dashboard struct") + } +} + +func TestLoadValidFile(t *testing.T) { + dashboards, err := Load("./testdata/valid") + + if err != nil { + t.Fatal("load an valid json file must not return an error") + } + + if len(dashboards) == 0 { + t.Fatal("load an valid json file must return a dashboard struct") + } +} + +func TestLoadEmptyFile(t *testing.T) { + dashboards, err := Load("./testdata/empty") + + if err == nil { + t.Fatal("load an empty json file must return an error") + } + + if len(dashboards) > 0 { + t.Fatal("load an empty json file must not return a dashboard struct") + } +} diff --git a/internal/dashboardloader/testdata/empty/empty.json b/internal/dashboardloader/testdata/empty/empty.json new file mode 100644 index 0000000..e69de29 diff --git a/internal/dashboardloader/testdata/invalid/invalid.json b/internal/dashboardloader/testdata/invalid/invalid.json new file mode 100644 index 0000000..a0edb3f --- /dev/null +++ b/internal/dashboardloader/testdata/invalid/invalid.json @@ -0,0 +1,15 @@ +{ + "checklist": "XXX", + "notes": "" +} +{ "checklist": "XXX", + "notes": "" +} +{ + "checklist": "XXX", + "notes": "" +} +{ + "checklist": "XXX", + "notes": "" +} \ No newline at end of file diff --git a/internal/dashboardloader/testdata/valid/valid.json b/internal/dashboardloader/testdata/valid/valid.json new file mode 100644 index 0000000..5c59632 --- /dev/null +++ b/internal/dashboardloader/testdata/valid/valid.json @@ -0,0 +1,139 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 17, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "smooth", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "reqps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "requests per second" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(http_requests_total{handler=~\"query.+\", job=\"thanos_query\"}[5m]))", + "interval": "", + "legendFormat": "requests per second", + "refId": "A" + } + ], + "title": "Http Requests Total", + "type": "timeseries" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-2d", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "dash_two", + "uid": "dash_two", + "version": 1 +} \ No newline at end of file diff --git a/internal/gitana/gitana.go b/internal/gitana/gitana.go index 1e88753..e179fb3 100644 --- a/internal/gitana/gitana.go +++ b/internal/gitana/gitana.go @@ -77,7 +77,11 @@ func start(ctx context.Context, pcmd command.Sync) error { return err } - dashboards := dashboardloader.Load(pcmd.Repository.Path) + dashboards, err := dashboardloader.Load(pcmd.Repository.Path) + + if err != nil { + return err + } if len(dashboards) == 0 { logrus.Warn("no dashboards found") diff --git a/internal/gitmanager/gitmanager_test.go b/internal/gitmanager/gitmanager_test.go new file mode 100644 index 0000000..14a8ba7 --- /dev/null +++ b/internal/gitmanager/gitmanager_test.go @@ -0,0 +1,49 @@ +package gitmanager + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetInvalidBranch(t *testing.T) { + r := &Repository{ + Url: "https://github.com/nicolastakashi/gitana", + Path: "/tmp/gitana/test", + Branch: "invalid", + } + + _, err := r.Get(context.TODO()) + + assert.NotNil(t, err, "Get invalid branch MUST return an error") + assert.Equal(t, err.Error(), "reference not found") +} + +func TestGetValidBranch(t *testing.T) { + r := &Repository{ + Url: "https://github.com/nicolastakashi/gitana", + Path: "/tmp/gitana/test", + Branch: "main", + } + + _, err := r.Get(context.TODO()) + + assert.Nil(t, err, "Get valid branch MUST not return an error") +} + +func TestGetAlreadyExistingRepo(t *testing.T) { + r := &Repository{ + Url: "https://github.com/nicolastakashi/gitana", + Path: "/tmp/gitana/test/pull", + Branch: "main", + } + + _, err := r.Get(context.TODO()) + + assert.Nil(t, err, "Get valid branch MUST not return an error") + + _, err = r.Get(context.TODO()) + + assert.Nil(t, err, "Get valid branch MUST not return an error") +}