mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TestData: attach labels to series results (#18653)
This commit is contained in:
44
pkg/tsdb/testdata/scenarios.go
vendored
44
pkg/tsdb/testdata/scenarios.go
vendored
@@ -423,6 +423,7 @@ func getPredictablePulse(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.Query
|
|||||||
series := newSeriesForQuery(query)
|
series := newSeriesForQuery(query)
|
||||||
series.Points = *points
|
series.Points = *points
|
||||||
queryRes.Series = append(queryRes.Series, series)
|
queryRes.Series = append(queryRes.Series, series)
|
||||||
|
attachLabels(query, queryRes)
|
||||||
return queryRes
|
return queryRes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,6 +473,7 @@ func getPredictableCSVWave(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.Que
|
|||||||
series := newSeriesForQuery(query)
|
series := newSeriesForQuery(query)
|
||||||
series.Points = *points
|
series.Points = *points
|
||||||
queryRes.Series = append(queryRes.Series, series)
|
queryRes.Series = append(queryRes.Series, series)
|
||||||
|
attachLabels(query, queryRes)
|
||||||
return queryRes
|
return queryRes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,9 +519,51 @@ func getRandomWalk(query *tsdb.Query, tsdbQuery *tsdb.TsdbQuery) *tsdb.QueryResu
|
|||||||
|
|
||||||
queryRes := tsdb.NewQueryResult()
|
queryRes := tsdb.NewQueryResult()
|
||||||
queryRes.Series = append(queryRes.Series, series)
|
queryRes.Series = append(queryRes.Series, series)
|
||||||
|
attachLabels(query, queryRes)
|
||||||
return 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 {
|
func getRandomWalkTable(query *tsdb.Query, tsdbQuery *tsdb.TsdbQuery) *tsdb.QueryResult {
|
||||||
timeWalkerMs := tsdbQuery.TimeRange.GetFromAsMsEpoch()
|
timeWalkerMs := tsdbQuery.TimeRange.GetFromAsMsEpoch()
|
||||||
to := tsdbQuery.TimeRange.GetToAsMsEpoch()
|
to := tsdbQuery.TimeRange.GetToAsMsEpoch()
|
||||||
|
|||||||
13
pkg/tsdb/testdata/scenarios_test.go
vendored
13
pkg/tsdb/testdata/scenarios_test.go
vendored
@@ -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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,19 @@
|
|||||||
<label class="gf-form-label query-keyword">Alias</label>
|
<label class="gf-form-label query-keyword">Alias</label>
|
||||||
<input type="text" class="gf-form-input max-width-7" placeholder="optional" ng-model="ctrl.target.alias" ng-change="ctrl.refresh()" ng-model-onblur>
|
<input type="text" class="gf-form-input max-width-7" placeholder="optional" ng-model="ctrl.target.alias" ng-change="ctrl.refresh()" ng-model-onblur>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div ng-if="ctrl.showLabels" class="gf-form gf-form--grow">
|
||||||
|
<label class="gf-form-label query-keyword">
|
||||||
|
Labels
|
||||||
|
<info-popover mode="right-normal">
|
||||||
|
Set labels using a key=value syntax:<br/>
|
||||||
|
{key="value", key2="value"}<br/>
|
||||||
|
key="value", key2="value"<br/>
|
||||||
|
key=value, key2=value<br/>
|
||||||
|
</info-popover>
|
||||||
|
</label>
|
||||||
|
<input type="text" class="gf-form-input gf-form--grow" placeholder='key=value, key2=value2' ng-model="ctrl.target.labels" ng-change="ctrl.refresh()" ng-model-onblur>
|
||||||
|
</div>
|
||||||
|
<div ng-if="!ctrl.showLabels" class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ export const defaultCSVWave: any = {
|
|||||||
valuesCSV: '0,0,2,2,1,1',
|
valuesCSV: '0,0,2,2,1,1',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showLabelsFor = ['random_walk', 'predictable_pulse', 'predictable_csv_wave'];
|
||||||
|
|
||||||
export class TestDataQueryCtrl extends QueryCtrl {
|
export class TestDataQueryCtrl extends QueryCtrl {
|
||||||
static templateUrl = 'partials/query.editor.html';
|
static templateUrl = 'partials/query.editor.html';
|
||||||
|
|
||||||
@@ -27,6 +29,8 @@ export class TestDataQueryCtrl extends QueryCtrl {
|
|||||||
newPointTime: any;
|
newPointTime: any;
|
||||||
selectedPoint: any;
|
selectedPoint: any;
|
||||||
|
|
||||||
|
showLabels = false;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor($scope: any, $injector: any) {
|
constructor($scope: any, $injector: any) {
|
||||||
super($scope, $injector);
|
super($scope, $injector);
|
||||||
@@ -35,6 +39,7 @@ export class TestDataQueryCtrl extends QueryCtrl {
|
|||||||
this.scenarioList = [];
|
this.scenarioList = [];
|
||||||
this.newPointTime = dateTime();
|
this.newPointTime = dateTime();
|
||||||
this.selectedPoint = { text: 'Select point', value: null };
|
this.selectedPoint = { text: 'Select point', value: null };
|
||||||
|
this.showLabels = showLabelsFor.includes(this.target.scenarioId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPoints() {
|
getPoints() {
|
||||||
@@ -75,6 +80,7 @@ export class TestDataQueryCtrl extends QueryCtrl {
|
|||||||
scenarioChanged() {
|
scenarioChanged() {
|
||||||
this.scenario = _.find(this.scenarioList, { id: this.target.scenarioId });
|
this.scenario = _.find(this.scenarioList, { id: this.target.scenarioId });
|
||||||
this.target.stringInput = this.scenario.stringInput;
|
this.target.stringInput = this.scenario.stringInput;
|
||||||
|
this.showLabels = showLabelsFor.includes(this.target.scenarioId);
|
||||||
|
|
||||||
if (this.target.scenarioId === 'manual_entry') {
|
if (this.target.scenarioId === 'manual_entry') {
|
||||||
this.target.points = this.target.points || [];
|
this.target.points = this.target.points || [];
|
||||||
|
|||||||
Reference in New Issue
Block a user