|
|
@@ -6,6 +6,7 @@ import (
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
|
m "github.com/grafana/grafana/pkg/models"
|
|
|
+ "github.com/grafana/grafana/pkg/setting"
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
|
)
|
|
|
|
|
|
@@ -17,8 +18,35 @@ func TestAlertRuleExtraction(t *testing.T) {
|
|
|
return &FakeCondition{}, nil
|
|
|
})
|
|
|
|
|
|
- Convey("Parsing and validating alerts from dashboards", func() {
|
|
|
- json := `{
|
|
|
+ setting.NewConfigContext(&setting.CommandLineArgs{
|
|
|
+ HomePath: "../../../",
|
|
|
+ })
|
|
|
+
|
|
|
+ // mock data
|
|
|
+ defaultDs := &m.DataSource{Id: 12, OrgId: 1, Name: "I am default", IsDefault: true}
|
|
|
+ graphite2Ds := &m.DataSource{Id: 15, OrgId: 1, Name: "graphite2"}
|
|
|
+ influxDBDs := &m.DataSource{Id: 16, OrgId: 1, Name: "InfluxDB"}
|
|
|
+
|
|
|
+ bus.AddHandler("test", func(query *m.GetDataSourcesQuery) error {
|
|
|
+ query.Result = []*m.DataSource{defaultDs, graphite2Ds}
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+
|
|
|
+ bus.AddHandler("test", func(query *m.GetDataSourceByNameQuery) error {
|
|
|
+ if query.Name == defaultDs.Name {
|
|
|
+ query.Result = defaultDs
|
|
|
+ }
|
|
|
+ if query.Name == graphite2Ds.Name {
|
|
|
+ query.Result = graphite2Ds
|
|
|
+ }
|
|
|
+ if query.Name == influxDBDs.Name {
|
|
|
+ query.Result = influxDBDs
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+
|
|
|
+ json := `
|
|
|
+ {
|
|
|
"id": 57,
|
|
|
"title": "Graphite 4",
|
|
|
"originalTitle": "Graphite 4",
|
|
|
@@ -80,32 +108,16 @@ func TestAlertRuleExtraction(t *testing.T) {
|
|
|
]
|
|
|
}
|
|
|
]
|
|
|
- }`
|
|
|
+ }`
|
|
|
+
|
|
|
+ Convey("Parsing and validating dashboard containing graphite alerts", func() {
|
|
|
+
|
|
|
dashJson, err := simplejson.NewJson([]byte(json))
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
dash := m.NewDashboardFromJson(dashJson)
|
|
|
extractor := NewDashAlertExtractor(dash, 1)
|
|
|
|
|
|
- // mock data
|
|
|
- defaultDs := &m.DataSource{Id: 12, OrgId: 2, Name: "I am default", IsDefault: true}
|
|
|
- graphite2Ds := &m.DataSource{Id: 15, OrgId: 2, Name: "graphite2"}
|
|
|
-
|
|
|
- bus.AddHandler("test", func(query *m.GetDataSourcesQuery) error {
|
|
|
- query.Result = []*m.DataSource{defaultDs, graphite2Ds}
|
|
|
- return nil
|
|
|
- })
|
|
|
-
|
|
|
- bus.AddHandler("test", func(query *m.GetDataSourceByNameQuery) error {
|
|
|
- if query.Name == defaultDs.Name {
|
|
|
- query.Result = defaultDs
|
|
|
- }
|
|
|
- if query.Name == graphite2Ds.Name {
|
|
|
- query.Result = graphite2Ds
|
|
|
- }
|
|
|
- return nil
|
|
|
- })
|
|
|
-
|
|
|
alerts, err := extractor.GetAlerts()
|
|
|
|
|
|
Convey("Get rules without error", func() {
|
|
|
@@ -119,6 +131,9 @@ func TestAlertRuleExtraction(t *testing.T) {
|
|
|
So(v.DashboardId, ShouldEqual, 57)
|
|
|
So(v.Name, ShouldNotBeEmpty)
|
|
|
So(v.Message, ShouldNotBeEmpty)
|
|
|
+
|
|
|
+ settings := simplejson.NewFromAny(v.Settings)
|
|
|
+ So(settings.Get("interval").MustString(""), ShouldEqual, "")
|
|
|
}
|
|
|
|
|
|
Convey("should extract handler property", func() {
|
|
|
@@ -156,5 +171,317 @@ func TestAlertRuleExtraction(t *testing.T) {
|
|
|
})
|
|
|
})
|
|
|
})
|
|
|
+
|
|
|
+ Convey("Parse and validate dashboard containing influxdb alert", func() {
|
|
|
+
|
|
|
+ json2 := `{
|
|
|
+ "id": 4,
|
|
|
+ "title": "Influxdb",
|
|
|
+ "tags": [
|
|
|
+ "apa"
|
|
|
+ ],
|
|
|
+ "style": "dark",
|
|
|
+ "timezone": "browser",
|
|
|
+ "editable": true,
|
|
|
+ "hideControls": false,
|
|
|
+ "sharedCrosshair": false,
|
|
|
+ "rows": [
|
|
|
+ {
|
|
|
+ "collapse": false,
|
|
|
+ "editable": true,
|
|
|
+ "height": "450px",
|
|
|
+ "panels": [
|
|
|
+ {
|
|
|
+ "alert": {
|
|
|
+ "conditions": [
|
|
|
+ {
|
|
|
+ "evaluator": {
|
|
|
+ "params": [
|
|
|
+ 10
|
|
|
+ ],
|
|
|
+ "type": "gt"
|
|
|
+ },
|
|
|
+ "query": {
|
|
|
+ "params": [
|
|
|
+ "B",
|
|
|
+ "5m",
|
|
|
+ "now"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "reducer": {
|
|
|
+ "params": [],
|
|
|
+ "type": "avg"
|
|
|
+ },
|
|
|
+ "type": "query"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "frequency": "3s",
|
|
|
+ "handler": 1,
|
|
|
+ "name": "Influxdb",
|
|
|
+ "noDataState": "no_data",
|
|
|
+ "notifications": [
|
|
|
+ {
|
|
|
+ "id": 6
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "alerting": {},
|
|
|
+ "aliasColors": {
|
|
|
+ "logins.count.count": "#890F02"
|
|
|
+ },
|
|
|
+ "bars": false,
|
|
|
+ "datasource": "InfluxDB",
|
|
|
+ "editable": true,
|
|
|
+ "error": false,
|
|
|
+ "fill": 1,
|
|
|
+ "grid": {},
|
|
|
+ "id": 1,
|
|
|
+ "interval": ">10s",
|
|
|
+ "isNew": true,
|
|
|
+ "legend": {
|
|
|
+ "avg": false,
|
|
|
+ "current": false,
|
|
|
+ "max": false,
|
|
|
+ "min": false,
|
|
|
+ "show": true,
|
|
|
+ "total": false,
|
|
|
+ "values": false
|
|
|
+ },
|
|
|
+ "lines": true,
|
|
|
+ "linewidth": 2,
|
|
|
+ "links": [],
|
|
|
+ "nullPointMode": "connected",
|
|
|
+ "percentage": false,
|
|
|
+ "pointradius": 5,
|
|
|
+ "points": false,
|
|
|
+ "renderer": "flot",
|
|
|
+ "seriesOverrides": [],
|
|
|
+ "span": 10,
|
|
|
+ "stack": false,
|
|
|
+ "steppedLine": false,
|
|
|
+ "targets": [
|
|
|
+ {
|
|
|
+ "dsType": "influxdb",
|
|
|
+ "groupBy": [
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "$interval"
|
|
|
+ ],
|
|
|
+ "type": "time"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "datacenter"
|
|
|
+ ],
|
|
|
+ "type": "tag"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "none"
|
|
|
+ ],
|
|
|
+ "type": "fill"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "hide": false,
|
|
|
+ "measurement": "logins.count",
|
|
|
+ "policy": "default",
|
|
|
+ "query": "SELECT 8 * count(\"value\") FROM \"logins.count\" WHERE $timeFilter GROUP BY time($interval), \"datacenter\" fill(none)",
|
|
|
+ "rawQuery": true,
|
|
|
+ "refId": "B",
|
|
|
+ "resultFormat": "time_series",
|
|
|
+ "select": [
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "value"
|
|
|
+ ],
|
|
|
+ "type": "field"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "params": [],
|
|
|
+ "type": "count"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ "tags": []
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "dsType": "influxdb",
|
|
|
+ "groupBy": [
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "$interval"
|
|
|
+ ],
|
|
|
+ "type": "time"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "null"
|
|
|
+ ],
|
|
|
+ "type": "fill"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "hide": true,
|
|
|
+ "measurement": "cpu",
|
|
|
+ "policy": "default",
|
|
|
+ "refId": "A",
|
|
|
+ "resultFormat": "time_series",
|
|
|
+ "select": [
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "value"
|
|
|
+ ],
|
|
|
+ "type": "field"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "params": [],
|
|
|
+ "type": "mean"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "params": [
|
|
|
+ "value"
|
|
|
+ ],
|
|
|
+ "type": "field"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "params": [],
|
|
|
+ "type": "sum"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ "tags": []
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "thresholds": [
|
|
|
+ {
|
|
|
+ "colorMode": "critical",
|
|
|
+ "fill": true,
|
|
|
+ "line": true,
|
|
|
+ "op": "gt",
|
|
|
+ "value": 10
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "timeFrom": null,
|
|
|
+ "timeShift": null,
|
|
|
+ "title": "Panel Title",
|
|
|
+ "tooltip": {
|
|
|
+ "msResolution": false,
|
|
|
+ "ordering": "alphabetical",
|
|
|
+ "shared": true,
|
|
|
+ "sort": 0,
|
|
|
+ "value_type": "cumulative"
|
|
|
+ },
|
|
|
+ "type": "graph",
|
|
|
+ "xaxis": {
|
|
|
+ "mode": "time",
|
|
|
+ "name": null,
|
|
|
+ "show": true,
|
|
|
+ "values": []
|
|
|
+ },
|
|
|
+ "yaxes": [
|
|
|
+ {
|
|
|
+ "format": "short",
|
|
|
+ "logBase": 1,
|
|
|
+ "max": null,
|
|
|
+ "min": null,
|
|
|
+ "show": true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "format": "short",
|
|
|
+ "logBase": 1,
|
|
|
+ "max": null,
|
|
|
+ "min": null,
|
|
|
+ "show": true
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "editable": true,
|
|
|
+ "error": false,
|
|
|
+ "id": 2,
|
|
|
+ "isNew": true,
|
|
|
+ "limit": 10,
|
|
|
+ "links": [],
|
|
|
+ "show": "current",
|
|
|
+ "span": 2,
|
|
|
+ "stateFilter": [
|
|
|
+ "alerting"
|
|
|
+ ],
|
|
|
+ "title": "Alert status",
|
|
|
+ "type": "alertlist"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "title": "Row"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "time": {
|
|
|
+ "from": "now-5m",
|
|
|
+ "to": "now"
|
|
|
+ },
|
|
|
+ "timepicker": {
|
|
|
+ "now": true,
|
|
|
+ "refresh_intervals": [
|
|
|
+ "5s",
|
|
|
+ "10s",
|
|
|
+ "30s",
|
|
|
+ "1m",
|
|
|
+ "5m",
|
|
|
+ "15m",
|
|
|
+ "30m",
|
|
|
+ "1h",
|
|
|
+ "2h",
|
|
|
+ "1d"
|
|
|
+ ],
|
|
|
+ "time_options": [
|
|
|
+ "5m",
|
|
|
+ "15m",
|
|
|
+ "1h",
|
|
|
+ "6h",
|
|
|
+ "12h",
|
|
|
+ "24h",
|
|
|
+ "2d",
|
|
|
+ "7d",
|
|
|
+ "30d"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "templating": {
|
|
|
+ "list": []
|
|
|
+ },
|
|
|
+ "annotations": {
|
|
|
+ "list": []
|
|
|
+ },
|
|
|
+ "schemaVersion": 13,
|
|
|
+ "version": 120,
|
|
|
+ "links": [],
|
|
|
+ "gnetId": null
|
|
|
+ }`
|
|
|
+
|
|
|
+ dashJson, err := simplejson.NewJson([]byte(json2))
|
|
|
+ So(err, ShouldBeNil)
|
|
|
+ dash := m.NewDashboardFromJson(dashJson)
|
|
|
+ extractor := NewDashAlertExtractor(dash, 1)
|
|
|
+
|
|
|
+ alerts, err := extractor.GetAlerts()
|
|
|
+
|
|
|
+ Convey("Get rules without error", func() {
|
|
|
+ So(err, ShouldBeNil)
|
|
|
+ })
|
|
|
+
|
|
|
+ Convey("should be able to read interval", func() {
|
|
|
+ So(len(alerts), ShouldEqual, 1)
|
|
|
+
|
|
|
+ for _, alert := range alerts {
|
|
|
+ So(alert.DashboardId, ShouldEqual, 4)
|
|
|
+
|
|
|
+ conditions := alert.Settings.Get("conditions").MustArray()
|
|
|
+ cond := simplejson.NewFromAny(conditions[0])
|
|
|
+
|
|
|
+ So(cond.Get("query").Get("model").Get("interval").MustString(), ShouldEqual, ">10s")
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
})
|
|
|
}
|