From e6fbf358c8920db109bcc30e6588832560346681 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Wed, 21 Aug 2019 07:50:13 -0700 Subject: [PATCH] TestData: attach labels to series results (#18653) --- pkg/tsdb/testdata/scenarios.go | 44 +++++++++++++++++++ pkg/tsdb/testdata/scenarios_test.go | 13 ++++++ .../testdata/partials/query.editor.html | 14 +++++- .../plugins/datasource/testdata/query_ctrl.ts | 6 +++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/pkg/tsdb/testdata/scenarios.go b/pkg/tsdb/testdata/scenarios.go index fa24e8dc087..b560c034580 100644 --- a/pkg/tsdb/testdata/scenarios.go +++ b/pkg/tsdb/testdata/scenarios.go @@ -423,6 +423,7 @@ func getPredictablePulse(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.Query series := newSeriesForQuery(query) series.Points = *points queryRes.Series = append(queryRes.Series, series) + attachLabels(query, queryRes) return queryRes } @@ -472,6 +473,7 @@ func getPredictableCSVWave(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.Que series := newSeriesForQuery(query) series.Points = *points queryRes.Series = append(queryRes.Series, series) + attachLabels(query, queryRes) return queryRes } @@ -517,9 +519,51 @@ func getRandomWalk(query *tsdb.Query, tsdbQuery *tsdb.TsdbQuery) *tsdb.QueryResu queryRes := tsdb.NewQueryResult() queryRes.Series = append(queryRes.Series, series) + attachLabels(query, queryRes) return queryRes } +/** + * Looks for a labels request and adds them as tags + * + * '{job="foo", instance="bar"} => {job: "foo", instance: "bar"}` + */ +func attachLabels(query *tsdb.Query, queryRes *tsdb.QueryResult) { + labelText := query.Model.Get("labels").MustString("") + if labelText == "" { + return + } + + tags := parseLabels(labelText) + for _, series := range queryRes.Series { + series.Tags = tags + } +} + +// generous parser: +// {job="foo", instance="bar"} +// job="foo", instance="bar" +// job=foo, instance=bar +// should all equal {job=foo, instance=bar} + +func parseLabels(text string) map[string]string { + var tags map[string]string + text = strings.Trim(text, `{}`) + if len(text) < 2 { + return tags + } + tags = make(map[string]string) + + for _, keyval := range strings.Split(text, ",") { + idx := strings.Index(keyval, "=") + key := strings.TrimSpace(keyval[:idx]) + val := strings.TrimSpace(keyval[idx+1:]) + tags[key] = val + } + + return tags +} + func getRandomWalkTable(query *tsdb.Query, tsdbQuery *tsdb.TsdbQuery) *tsdb.QueryResult { timeWalkerMs := tsdbQuery.TimeRange.GetFromAsMsEpoch() to := tsdbQuery.TimeRange.GetToAsMsEpoch() diff --git a/pkg/tsdb/testdata/scenarios_test.go b/pkg/tsdb/testdata/scenarios_test.go index 307f5e4affe..610ba624f3d 100644 --- a/pkg/tsdb/testdata/scenarios_test.go +++ b/pkg/tsdb/testdata/scenarios_test.go @@ -92,3 +92,16 @@ func TestTestdataScenarios(t *testing.T) { }) }) } + +func TestToLabels(t *testing.T) { + Convey("read labels", t, func() { + tags := make(map[string]string) + tags["job"] = "foo" + tags["instance"] = "bar" + + So(parseLabels(`{job="foo", instance="bar"}`), ShouldEqual, tags) + So(parseLabels(`job="foo", instance="bar"`), ShouldEqual, tags) + So(parseLabels(`job=foo, instance=bar`), ShouldEqual, tags) + So(parseLabels(`job = foo,instance = bar`), ShouldEqual, tags) + }) +} diff --git a/public/app/plugins/datasource/testdata/partials/query.editor.html b/public/app/plugins/datasource/testdata/partials/query.editor.html index e6368472cc4..197123deb70 100644 --- a/public/app/plugins/datasource/testdata/partials/query.editor.html +++ b/public/app/plugins/datasource/testdata/partials/query.editor.html @@ -14,7 +14,19 @@ -
+
+ + +
+
diff --git a/public/app/plugins/datasource/testdata/query_ctrl.ts b/public/app/plugins/datasource/testdata/query_ctrl.ts index 94b0c742968..b311cf212be 100644 --- a/public/app/plugins/datasource/testdata/query_ctrl.ts +++ b/public/app/plugins/datasource/testdata/query_ctrl.ts @@ -18,6 +18,8 @@ export const defaultCSVWave: any = { valuesCSV: '0,0,2,2,1,1', }; +const showLabelsFor = ['random_walk', 'predictable_pulse', 'predictable_csv_wave']; + export class TestDataQueryCtrl extends QueryCtrl { static templateUrl = 'partials/query.editor.html'; @@ -27,6 +29,8 @@ export class TestDataQueryCtrl extends QueryCtrl { newPointTime: any; selectedPoint: any; + showLabels = false; + /** @ngInject */ constructor($scope: any, $injector: any) { super($scope, $injector); @@ -35,6 +39,7 @@ export class TestDataQueryCtrl extends QueryCtrl { this.scenarioList = []; this.newPointTime = dateTime(); this.selectedPoint = { text: 'Select point', value: null }; + this.showLabels = showLabelsFor.includes(this.target.scenarioId); } getPoints() { @@ -75,6 +80,7 @@ export class TestDataQueryCtrl extends QueryCtrl { scenarioChanged() { this.scenario = _.find(this.scenarioList, { id: this.target.scenarioId }); this.target.stringInput = this.scenario.stringInput; + this.showLabels = showLabelsFor.includes(this.target.scenarioId); if (this.target.scenarioId === 'manual_entry') { this.target.points = this.target.points || [];