Commit d0a565d8 by Daniel Lee

stackdriver: improve segments for group bys in query editor

parent add23d97
...@@ -29,6 +29,7 @@ func TestStackdriver(t *testing.T) { ...@@ -29,6 +29,7 @@ func TestStackdriver(t *testing.T) {
Model: simplejson.NewFromAny(map[string]interface{}{ Model: simplejson.NewFromAny(map[string]interface{}{
"target": "target", "target": "target",
"metricType": "a/metric/type", "metricType": "a/metric/type",
"view": "FULL",
}), }),
RefId: "A", RefId: "A",
}, },
...@@ -42,11 +43,12 @@ func TestStackdriver(t *testing.T) { ...@@ -42,11 +43,12 @@ func TestStackdriver(t *testing.T) {
So(len(queries), ShouldEqual, 1) So(len(queries), ShouldEqual, 1)
So(queries[0].RefID, ShouldEqual, "A") So(queries[0].RefID, ShouldEqual, "A")
So(queries[0].Target, ShouldEqual, "target") So(queries[0].Target, ShouldEqual, "target")
So(len(queries[0].Params), ShouldEqual, 4) So(len(queries[0].Params), ShouldEqual, 5)
So(queries[0].Params["interval.startTime"][0], ShouldEqual, "2018-03-15T13:00:00Z") So(queries[0].Params["interval.startTime"][0], ShouldEqual, "2018-03-15T13:00:00Z")
So(queries[0].Params["interval.endTime"][0], ShouldEqual, "2018-03-15T13:34:00Z") So(queries[0].Params["interval.endTime"][0], ShouldEqual, "2018-03-15T13:34:00Z")
So(queries[0].Params["aggregation.perSeriesAligner"][0], ShouldEqual, "ALIGN_NONE") So(queries[0].Params["aggregation.perSeriesAligner"][0], ShouldEqual, "ALIGN_NONE")
So(queries[0].Params["filter"][0], ShouldEqual, "metric.type=\"a/metric/type\"") So(queries[0].Params["filter"][0], ShouldEqual, "metric.type=\"a/metric/type\"")
So(queries[0].Params["view"][0], ShouldEqual, "FULL")
}) })
Convey("and query has aggregation mean set", func() { Convey("and query has aggregation mean set", func() {
...@@ -54,6 +56,7 @@ func TestStackdriver(t *testing.T) { ...@@ -54,6 +56,7 @@ func TestStackdriver(t *testing.T) {
"target": "target", "target": "target",
"metricType": "a/metric/type", "metricType": "a/metric/type",
"primaryAggregation": "REDUCE_MEAN", "primaryAggregation": "REDUCE_MEAN",
"view": "FULL",
}) })
queries, err := executor.buildQueries(tsdbQuery) queries, err := executor.buildQueries(tsdbQuery)
...@@ -62,13 +65,14 @@ func TestStackdriver(t *testing.T) { ...@@ -62,13 +65,14 @@ func TestStackdriver(t *testing.T) {
So(len(queries), ShouldEqual, 1) So(len(queries), ShouldEqual, 1)
So(queries[0].RefID, ShouldEqual, "A") So(queries[0].RefID, ShouldEqual, "A")
So(queries[0].Target, ShouldEqual, "target") So(queries[0].Target, ShouldEqual, "target")
So(len(queries[0].Params), ShouldEqual, 6) So(len(queries[0].Params), ShouldEqual, 7)
So(queries[0].Params["interval.startTime"][0], ShouldEqual, "2018-03-15T13:00:00Z") So(queries[0].Params["interval.startTime"][0], ShouldEqual, "2018-03-15T13:00:00Z")
So(queries[0].Params["interval.endTime"][0], ShouldEqual, "2018-03-15T13:34:00Z") So(queries[0].Params["interval.endTime"][0], ShouldEqual, "2018-03-15T13:34:00Z")
So(queries[0].Params["aggregation.crossSeriesReducer"][0], ShouldEqual, "REDUCE_MEAN") So(queries[0].Params["aggregation.crossSeriesReducer"][0], ShouldEqual, "REDUCE_MEAN")
So(queries[0].Params["aggregation.perSeriesAligner"][0], ShouldEqual, "ALIGN_MEAN") So(queries[0].Params["aggregation.perSeriesAligner"][0], ShouldEqual, "ALIGN_MEAN")
So(queries[0].Params["aggregation.alignmentPeriod"][0], ShouldEqual, "+60s") So(queries[0].Params["aggregation.alignmentPeriod"][0], ShouldEqual, "+60s")
So(queries[0].Params["filter"][0], ShouldEqual, "metric.type=\"a/metric/type\"") So(queries[0].Params["filter"][0], ShouldEqual, "metric.type=\"a/metric/type\"")
So(queries[0].Params["view"][0], ShouldEqual, "FULL")
}) })
Convey("and query has group bys", func() { Convey("and query has group bys", func() {
...@@ -77,6 +81,7 @@ func TestStackdriver(t *testing.T) { ...@@ -77,6 +81,7 @@ func TestStackdriver(t *testing.T) {
"metricType": "a/metric/type", "metricType": "a/metric/type",
"primaryAggregation": "REDUCE_NONE", "primaryAggregation": "REDUCE_NONE",
"groupBys": []interface{}{"metric.label.group1", "metric.label.group2"}, "groupBys": []interface{}{"metric.label.group1", "metric.label.group2"},
"view": "FULL",
}) })
queries, err := executor.buildQueries(tsdbQuery) queries, err := executor.buildQueries(tsdbQuery)
...@@ -85,13 +90,14 @@ func TestStackdriver(t *testing.T) { ...@@ -85,13 +90,14 @@ func TestStackdriver(t *testing.T) {
So(len(queries), ShouldEqual, 1) So(len(queries), ShouldEqual, 1)
So(queries[0].RefID, ShouldEqual, "A") So(queries[0].RefID, ShouldEqual, "A")
So(queries[0].Target, ShouldEqual, "target") So(queries[0].Target, ShouldEqual, "target")
So(len(queries[0].Params), ShouldEqual, 5) So(len(queries[0].Params), ShouldEqual, 6)
So(queries[0].Params["interval.startTime"][0], ShouldEqual, "2018-03-15T13:00:00Z") So(queries[0].Params["interval.startTime"][0], ShouldEqual, "2018-03-15T13:00:00Z")
So(queries[0].Params["interval.endTime"][0], ShouldEqual, "2018-03-15T13:34:00Z") So(queries[0].Params["interval.endTime"][0], ShouldEqual, "2018-03-15T13:34:00Z")
So(queries[0].Params["aggregation.perSeriesAligner"][0], ShouldEqual, "ALIGN_NONE") So(queries[0].Params["aggregation.perSeriesAligner"][0], ShouldEqual, "ALIGN_NONE")
So(queries[0].Params["aggregation.groupByFields"][0], ShouldEqual, "metric.label.group1") So(queries[0].Params["aggregation.groupByFields"][0], ShouldEqual, "metric.label.group1")
So(queries[0].Params["aggregation.groupByFields"][1], ShouldEqual, "metric.label.group2") So(queries[0].Params["aggregation.groupByFields"][1], ShouldEqual, "metric.label.group2")
So(queries[0].Params["filter"][0], ShouldEqual, "metric.type=\"a/metric/type\"") So(queries[0].Params["filter"][0], ShouldEqual, "metric.type=\"a/metric/type\"")
So(queries[0].Params["view"][0], ShouldEqual, "FULL")
}) })
}) })
......
...@@ -16,8 +16,8 @@ export default class StackdriverDatasource { ...@@ -16,8 +16,8 @@ export default class StackdriverDatasource {
refId: t.refId, refId: t.refId,
datasourceId: this.id, datasourceId: this.id,
metricType: t.metricType, metricType: t.metricType,
primaryAggregation: 'REDUCE_MEAN', //t.aggregation.crossSeriesReducer, primaryAggregation: t.aggregation.crossSeriesReducer,
// groupBys: t.aggregation.groupBys, groupBys: t.aggregation.groupBys,
view: t.view || 'FULL', view: t.view || 'FULL',
})); }));
......
...@@ -10,8 +10,8 @@ export interface LabelType { ...@@ -10,8 +10,8 @@ export interface LabelType {
export interface QueryMeta { export interface QueryMeta {
rawQuery: string; rawQuery: string;
rawQueryString: string; rawQueryString: string;
metricLabels: LabelType[]; metricLabels: { [key: string]: string[] };
resourceLabels: LabelType[]; resourceLabels: { [key: string]: string[] };
} }
export class StackdriverQueryCtrl extends QueryCtrl { export class StackdriverQueryCtrl extends QueryCtrl {
static templateUrl = 'partials/query.editor.html'; static templateUrl = 'partials/query.editor.html';
...@@ -152,34 +152,42 @@ export class StackdriverQueryCtrl extends QueryCtrl { ...@@ -152,34 +152,42 @@ export class StackdriverQueryCtrl extends QueryCtrl {
} }
getGroupBys() { getGroupBys() {
const metricLabels = Object.keys(this.metricLabels).map(l => { const metricLabels = Object.keys(this.metricLabels)
return this.uiSegmentSrv.newSegment({ .filter(ml => {
value: `metric.label.${l}`, return this.target.aggregation.groupBys.indexOf('metric.label.' + ml) === -1;
expandable: false, })
.map(l => {
return this.uiSegmentSrv.newSegment({
value: `metric.label.${l}`,
expandable: false,
});
}); });
});
const resourceLabels = Object.keys(this.resourceLabels).map(l => { const resourceLabels = Object.keys(this.resourceLabels)
return this.uiSegmentSrv.newSegment({ .filter(ml => {
value: `resource.label.${l}`, return this.target.aggregation.groupBys.indexOf('resource.label.' + ml) === -1;
expandable: false, })
.map(l => {
return this.uiSegmentSrv.newSegment({
value: `resource.label.${l}`,
expandable: false,
});
}); });
});
return Promise.resolve([...metricLabels, ...resourceLabels]); return Promise.resolve([...metricLabels, ...resourceLabels]);
} }
groupByChanged(segment, index) { groupByChanged(segment) {
this.target.aggregation.groupBys = _.reduce( segment.type = 'value';
this.groupBySegments,
function(memo, seg) { const reducer = (memo, seg) => {
if (!seg.fake) { if (!seg.fake) {
memo.push(seg.value); memo.push(seg.value);
} }
return memo; return memo;
}, };
[]
); this.target.aggregation.groupBys = this.groupBySegments.reduce(reducer, []);
this.ensurePlusButton(this.groupBySegments); this.ensurePlusButton(this.groupBySegments);
this.refresh(); this.refresh();
} }
......
import { StackdriverQueryCtrl } from '../query_ctrl';
describe('StackdriverQueryCtrl', () => {
let ctrl;
let result;
beforeEach(() => {
ctrl = createCtrlWithFakes();
});
describe('when labels are fetched', () => {
beforeEach(async () => {
ctrl.metricLabels = { 'metric-key-1': ['metric-value-1'] };
ctrl.resourceLabels = { 'resource-key-1': ['resource-value-1'] };
result = await ctrl.getGroupBys();
});
it('should populate group bys segments', () => {
expect(result.length).toBe(2);
expect(result[0].value).toBe('metric.label.metric-key-1');
expect(result[1].value).toBe('resource.label.resource-key-1');
});
});
describe('when a group by label is selected', () => {
beforeEach(async () => {
ctrl.metricLabels = {
'metric-key-1': ['metric-value-1'],
'metric-key-2': ['metric-value-2'],
};
ctrl.resourceLabels = {
'resource-key-1': ['resource-value-1'],
'resource-key-2': ['resource-value-2'],
};
ctrl.target.aggregation.groupBys = ['metric.label.metric-key-1', 'resource.label.resource-key-1'];
result = await ctrl.getGroupBys();
});
it('should not be used to populate group bys segments', () => {
expect(result.length).toBe(2);
expect(result[0].value).toBe('metric.label.metric-key-2');
expect(result[1].value).toBe('resource.label.resource-key-2');
});
});
describe('when a group by is selected', () => {
beforeEach(() => {
const segment = { value: 'groupby1' };
ctrl.groupBySegments = [segment];
ctrl.groupByChanged(segment);
});
it('should be added to group bys list', () => {
expect(ctrl.target.aggregation.groupBys.length).toBe(1);
});
});
});
function createCtrlWithFakes() {
StackdriverQueryCtrl.prototype.panelCtrl = {
events: { on: () => {} },
panel: { scopedVars: [], targets: [] },
refresh: () => {},
};
StackdriverQueryCtrl.prototype.target = createTarget();
StackdriverQueryCtrl.prototype.getMetricTypes = () => {
return Promise.resolve();
};
StackdriverQueryCtrl.prototype.getLabels = () => {
return Promise.resolve();
};
const fakeSegmentServer = {
newSegment: obj => {
return { value: obj.value };
},
newPlusButton: () => {},
};
return new StackdriverQueryCtrl(null, null, fakeSegmentServer, null);
}
function createTarget() {
return {
project: {
id: '',
name: '',
},
metricType: 'ametric',
refId: 'A',
aggregation: {
crossSeriesReducer: '',
alignmentPeriod: '',
perSeriesAligner: '',
groupBys: [],
},
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment