From 7666e7bfe3c4de13c3162d06d414285580300648 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Sep 2018 14:42:47 +0200 Subject: [PATCH] stackdriver: break out aggretation logic into its own directive and controller. also adds tests for new dropdown population logic --- .../partials/query.aggregation.html | 42 ++++++++++ .../stackdriver/partials/query.editor.html | 43 +--------- .../stackdriver/query_aggregation_ctrl.ts | 73 +++++++++++++++++ .../datasource/stackdriver/query_ctrl.ts | 37 +-------- .../specs/query_aggregation_ctrl.test.ts | 81 +++++++++++++++++++ 5 files changed, 201 insertions(+), 75 deletions(-) create mode 100755 public/app/plugins/datasource/stackdriver/partials/query.aggregation.html create mode 100644 public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts create mode 100644 public/app/plugins/datasource/stackdriver/specs/query_aggregation_ctrl.test.ts diff --git a/public/app/plugins/datasource/stackdriver/partials/query.aggregation.html b/public/app/plugins/datasource/stackdriver/partials/query.aggregation.html new file mode 100755 index 00000000000..f48d0d9f565 --- /dev/null +++ b/public/app/plugins/datasource/stackdriver/partials/query.aggregation.html @@ -0,0 +1,42 @@ +
+
+ +
+ +
+
+ +
+
+
+ +
+ +
+ +
+
+
+
+
+ +
+ +
+ +
+
+
+
+
\ No newline at end of file diff --git a/public/app/plugins/datasource/stackdriver/partials/query.editor.html b/public/app/plugins/datasource/stackdriver/partials/query.editor.html index 891dab6d93c..71ae3dc6328 100755 --- a/public/app/plugins/datasource/stackdriver/partials/query.editor.html +++ b/public/app/plugins/datasource/stackdriver/partials/query.editor.html @@ -31,48 +31,7 @@
-
-
- -
- -
-
- -
-
-
- -
- -
- -
-
-
-
-
- -
- -
- -
-
-
-
-
+
Alias By diff --git a/public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts b/public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts new file mode 100644 index 00000000000..79161e0ca8c --- /dev/null +++ b/public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts @@ -0,0 +1,73 @@ +import angular from 'angular'; +import _ from 'lodash'; +import * as options from './constants'; + +export class StackdriverAggregation { + constructor() { + return { + templateUrl: 'public/app/plugins/datasource/stackdriver/partials/query.aggregation.html', + controller: 'StackdriverAggregationCtrl', + restrict: 'E', + scope: { + target: '=', + refresh: '&', + }, + }; + } +} + +export class StackdriverAggregationCtrl { + target: any; + alignOptions: any[]; + aggOptions: any[]; + refresh: () => void; + + constructor(private $scope) { + this.aggOptions = options.aggOptions; + this.alignOptions = options.alignOptions; + $scope.alignmentPeriods = options.alignmentPeriods; + $scope.getAlignOptions = this.getAlignOptions; + $scope.getAggOptions = this.getAggOptions; + $scope.onAlignmentChange = this.onAlignmentChange; + $scope.onAggregationChange = this.onAggregationChange; + this.refresh = $scope.refresh; + } + + onAlignmentChange(newVal) { + if (newVal === 'ALIGN_NONE') { + this.target.aggregation.crossSeriesReducer = 'REDUCE_NONE'; + } + this.refresh(); + } + + onAggregationChange(newVal) { + if (newVal !== 'REDUCE_NONE') { + const newAlignmentOption = options.alignOptions.find(o => o.value !== 'ALIGN_NONE'); + this.target.aggregation.perSeriesAligner = newAlignmentOption ? newAlignmentOption.value : ''; + } + this.refresh(); + } + + getAlignOptions() { + return !this.target.valueType + ? options.alignOptions + : options.alignOptions.filter(i => { + return ( + i.valueTypes.indexOf(this.target.valueType) !== -1 && i.metricKinds.indexOf(this.target.metricKind) !== -1 + ); + }); + } + + getAggOptions() { + return !this.target.metricKind + ? options.aggOptions + : options.aggOptions.filter(i => { + return ( + i.valueTypes.indexOf(this.target.valueType) !== -1 && i.metricKinds.indexOf(this.target.metricKind) !== -1 + ); + }); + } +} + +angular.module('grafana.controllers').directive('stackdriverAggregation', StackdriverAggregation); +angular.module('grafana.controllers').controller('StackdriverAggregationCtrl', StackdriverAggregationCtrl); diff --git a/public/app/plugins/datasource/stackdriver/query_ctrl.ts b/public/app/plugins/datasource/stackdriver/query_ctrl.ts index db276650e65..be98e9bf3ec 100644 --- a/public/app/plugins/datasource/stackdriver/query_ctrl.ts +++ b/public/app/plugins/datasource/stackdriver/query_ctrl.ts @@ -1,8 +1,8 @@ import _ from 'lodash'; import { QueryCtrl } from 'app/plugins/sdk'; import appEvents from 'app/core/app_events'; -import * as options from './constants'; import { FilterSegments, DefaultRemoveFilterValue } from './filter_segments'; +import './query_aggregation_ctrl'; export interface QueryMeta { rawQuery: string; @@ -55,8 +55,6 @@ export class StackdriverQueryCtrl extends QueryCtrl { valueType: '', }; - alignOptions: any[]; - aggOptions: any[]; groupBySegments: any[]; removeSegment: any; showHelp: boolean; @@ -74,9 +72,6 @@ export class StackdriverQueryCtrl extends QueryCtrl { this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope); this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope); - this.stackdriverConstants = options; - this.aggOptions = options.aggOptions; - this.alignOptions = options.alignOptions; this.getCurrentProject() .then(this.getMetricTypes.bind(this)) @@ -155,6 +150,9 @@ export class StackdriverQueryCtrl extends QueryCtrl { this.metricLabels = data.results[this.target.refId].meta.metricLabels; this.resourceLabels = data.results[this.target.refId].meta.resourceLabels; + + this.target.valueType = data.results[this.target.refId].meta.valueType; + this.target.metricKind = data.results[this.target.refId].meta.metricKind; resolve(); } catch (error) { resolve(); @@ -264,31 +262,6 @@ export class StackdriverQueryCtrl extends QueryCtrl { } } - getAlignOptions() { - return !this.target.valueType - ? options.alignOptions - : options.alignOptions.filter(i => { - return ( - i.valueTypes.indexOf(this.target.valueType) !== -1 && i.metricKinds.indexOf(this.target.metricKind) !== -1 - ); - }); - } - - getAggOptions() { - if (this.target.aggregation.perSeriesAligner === 'ALIGN_NONE') { - this.target.aggregation.crossSeriesReducer = options.aggOptions[0].value; - return options.aggOptions.slice(0, 1); - } - - return !this.target.metricKind - ? options.aggOptions - : options.aggOptions.filter(i => { - return ( - i.valueTypes.indexOf(this.target.valueType) !== -1 && i.metricKinds.indexOf(this.target.metricKind) !== -1 - ); - }); - } - onDataReceived(dataList) { this.lastQueryError = null; this.lastQueryMeta = null; @@ -297,8 +270,6 @@ export class StackdriverQueryCtrl extends QueryCtrl { if (anySeriesFromQuery) { this.lastQueryMeta = anySeriesFromQuery.meta; this.lastQueryMeta.rawQueryString = decodeURIComponent(this.lastQueryMeta.rawQuery); - this.target.valueType = anySeriesFromQuery.meta.valueType; - this.target.metricKind = anySeriesFromQuery.meta.metricKind; } } diff --git a/public/app/plugins/datasource/stackdriver/specs/query_aggregation_ctrl.test.ts b/public/app/plugins/datasource/stackdriver/specs/query_aggregation_ctrl.test.ts new file mode 100644 index 00000000000..aebd2a12dd6 --- /dev/null +++ b/public/app/plugins/datasource/stackdriver/specs/query_aggregation_ctrl.test.ts @@ -0,0 +1,81 @@ +import { StackdriverAggregationCtrl } from '../query_aggregation_ctrl'; + +describe('StackdriverAggregationCtrl', () => { + let ctrl; + describe('aggregation and alignment options', () => { + beforeEach(() => { + ctrl = createCtrlWithFakes(); + }); + describe('when new query result is returned from the server', () => { + describe('and result is double and gauge', () => { + beforeEach(async () => { + ctrl.target.valueType = 'DOUBLE'; + ctrl.target.metricKind = 'GAUGE'; + }); + + it('should populate all aggregate options except two', () => { + const result = ctrl.getAggOptions(); + expect(result.length).toBe(11); + expect(result.map(o => o.value)).toEqual( + expect.not.arrayContaining(['REDUCE_COUNT_TRUE', 'REDUCE_COUNT_FALSE']) + ); + }); + + it('should populate all alignment options except two', () => { + const result = ctrl.getAlignOptions(); + console.log(result.map(o => o.value)); + expect(result.length).toBe(10); + expect(result.map(o => o.value)).toEqual( + expect.not.arrayContaining(['REDUCE_COUNT_TRUE', 'REDUCE_COUNT_FALSE']) + ); + }); + }); + }); + + describe('when a user a user select ALIGN_NONE and a reducer is selected', () => { + beforeEach(async () => { + ctrl.target.aggregation.crossSeriesReducer = 'RANDOM_REDUCER'; + ctrl.onAlignmentChange('ALIGN_NONE'); + }); + it('should set REDUCE_NONE as selected aggregation', () => { + expect(ctrl.target.aggregation.crossSeriesReducer).toBe('REDUCE_NONE'); + }); + }); + + describe('when a user a user select a reducer and no alignment is selected', () => { + beforeEach(async () => { + ctrl.target.aggregation.crossSeriesReducer = 'REDUCE_NONE'; + ctrl.target.aggregation.perSeriesAligner = 'ALIGN_NONE'; + ctrl.onAggregationChange('ALIGN_NONE'); + }); + + it('should set an alignment', () => { + expect(ctrl.target.aggregation.perSeriesAligner).not.toBe('ALIGN_NONE'); + }); + }); + }); +}); + +function createCtrlWithFakes() { + StackdriverAggregationCtrl.prototype.target = createTarget(); + return new StackdriverAggregationCtrl({ refresh: () => {} }); +} + +function createTarget(existingFilters?: string[]) { + return { + project: { + id: '', + name: '', + }, + metricType: 'ametric', + refId: 'A', + aggregation: { + crossSeriesReducer: '', + alignmentPeriod: '', + perSeriesAligner: '', + groupBys: [], + }, + filters: existingFilters || [], + aliasBy: '', + }; +}