mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactor: moved graphite specs into plugins directory
This commit is contained in:
parent
cb7424ce5e
commit
7e434fc019
@ -25,6 +25,7 @@ module.exports = function(config) {
|
||||
browsers: ['PhantomJS'],
|
||||
captureTimeout: 60000,
|
||||
singleRun: true,
|
||||
autoWatchBatchDelay: 1000,
|
||||
|
||||
});
|
||||
|
||||
|
@ -5,9 +5,9 @@ define([
|
||||
'config',
|
||||
'app/core/utils/datemath',
|
||||
'./directives',
|
||||
'./queryCtrl',
|
||||
'./funcEditor',
|
||||
'./addGraphiteFunc',
|
||||
'./query_ctrl',
|
||||
'./func_editor',
|
||||
'./add_graphite_func',
|
||||
],
|
||||
function (angular, _, $, config, dateMath) {
|
||||
'use strict';
|
||||
|
120
public/app/plugins/datasource/graphite/specs/datasource_specs.ts
Normal file
120
public/app/plugins/datasource/graphite/specs/datasource_specs.ts
Normal file
@ -0,0 +1,120 @@
|
||||
///<amd-dependency path="app/plugins/datasource/graphite/datasource" />
|
||||
///<amd-dependency path="test/specs/helpers" name="helpers" />
|
||||
|
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||
declare var helpers: any;
|
||||
|
||||
describe('graphiteDatasource', function() {
|
||||
var ctx = new helpers.ServiceTestContext();
|
||||
|
||||
beforeEach(angularMocks.module('grafana.services'));
|
||||
beforeEach(ctx.providePhase(['backendSrv']));
|
||||
|
||||
beforeEach(ctx.createService('GraphiteDatasource'));
|
||||
beforeEach(function() {
|
||||
ctx.ds = new ctx.service({ url: [''] });
|
||||
});
|
||||
|
||||
describe('When querying influxdb with one target using query editor target spec', function() {
|
||||
var query = {
|
||||
rangeRaw: { from: 'now-1h', to: 'now' },
|
||||
targets: [{ target: 'prod1.count' }, {target: 'prod2.count'}],
|
||||
maxDataPoints: 500,
|
||||
};
|
||||
|
||||
var results;
|
||||
var requestOptions;
|
||||
|
||||
beforeEach(function() {
|
||||
ctx.backendSrv.datasourceRequest = function(options) {
|
||||
requestOptions = options;
|
||||
return ctx.$q.when({data: [{ target: 'prod1.count', datapoints: [[10, 1], [12,1]] }]});
|
||||
};
|
||||
|
||||
ctx.ds.query(query).then(function(data) { results = data; });
|
||||
ctx.$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should generate the correct query', function() {
|
||||
expect(requestOptions.url).to.be('/render');
|
||||
});
|
||||
|
||||
it('should query correctly', function() {
|
||||
var params = requestOptions.data.split('&');
|
||||
expect(params).to.contain('target=prod1.count');
|
||||
expect(params).to.contain('target=prod2.count');
|
||||
expect(params).to.contain('from=-1h');
|
||||
expect(params).to.contain('until=now');
|
||||
});
|
||||
|
||||
it('should exclude undefined params', function() {
|
||||
var params = requestOptions.data.split('&');
|
||||
expect(params).to.not.contain('cacheTimeout=undefined');
|
||||
});
|
||||
|
||||
it('should return series list', function() {
|
||||
expect(results.data.length).to.be(1);
|
||||
expect(results.data[0].target).to.be('prod1.count');
|
||||
});
|
||||
|
||||
it('should convert to millisecond resolution', function() {
|
||||
expect(results.data[0].datapoints[0][0]).to.be(10);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('building graphite params', function() {
|
||||
|
||||
it('should uri escape targets', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'prod1.{test,test2}'}, {target: 'prod2.count'}]
|
||||
});
|
||||
expect(results).to.contain('target=prod1.%7Btest%2Ctest2%7D');
|
||||
});
|
||||
|
||||
it('should replace target placeholder', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1'}, {target: 'series2'}, {target: 'asPercent(#A,#B)'}]
|
||||
});
|
||||
expect(results[2]).to.be('target=asPercent(series1%2Cseries2)');
|
||||
});
|
||||
|
||||
it('should replace target placeholder for hidden series', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1', hide: true}, {target: 'sumSeries(#A)', hide: true}, {target: 'asPercent(#A,#B)'}]
|
||||
});
|
||||
expect(results[0]).to.be('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))'));
|
||||
});
|
||||
|
||||
it('should replace target placeholder when nesting query references', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1'}, {target: 'sumSeries(#A)'}, {target: 'asPercent(#A,#B)'}]
|
||||
});
|
||||
expect(results[2]).to.be('target=' + encodeURIComponent("asPercent(series1,sumSeries(series1))"));
|
||||
});
|
||||
|
||||
it('should fix wrong minute interval parameters', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: "summarize(prod.25m.count, '25m', 'sum')" }]
|
||||
});
|
||||
expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.25m.count, '25min', 'sum')"));
|
||||
});
|
||||
|
||||
it('should fix wrong month interval parameters', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: "summarize(prod.5M.count, '5M', 'sum')" }]
|
||||
});
|
||||
expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.5M.count, '5mon', 'sum')"));
|
||||
});
|
||||
|
||||
it('should ignore empty targets', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1'}, {target: ''}]
|
||||
});
|
||||
expect(results.length).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
127
public/app/plugins/datasource/graphite/specs/gfunc_specs.ts
Normal file
127
public/app/plugins/datasource/graphite/specs/gfunc_specs.ts
Normal file
@ -0,0 +1,127 @@
|
||||
///<amd-dependency path="app/plugins/datasource/graphite/gfunc" name="gfunc" />
|
||||
|
||||
import {describe, beforeEach, it, sinon, expect} from 'test/lib/common';
|
||||
|
||||
declare var gfunc: any;
|
||||
|
||||
describe('when creating func instance from func names', function() {
|
||||
it('should return func instance', function() {
|
||||
var func = gfunc.createFuncInstance('sumSeries');
|
||||
expect(func).to.be.ok();
|
||||
expect(func.def.name).to.equal('sumSeries');
|
||||
expect(func.def.params.length).to.equal(5);
|
||||
expect(func.def.defaultParams.length).to.equal(1);
|
||||
});
|
||||
|
||||
it('should return func instance with shortName', function() {
|
||||
var func = gfunc.createFuncInstance('sum');
|
||||
expect(func).to.be.ok();
|
||||
});
|
||||
|
||||
it('should return func instance from funcDef', function() {
|
||||
var func = gfunc.createFuncInstance('sum');
|
||||
var func2 = gfunc.createFuncInstance(func.def);
|
||||
expect(func2).to.be.ok();
|
||||
});
|
||||
|
||||
it('func instance should have text representation', function() {
|
||||
var func = gfunc.createFuncInstance('groupByNode');
|
||||
func.params[0] = 5;
|
||||
func.params[1] = 'avg';
|
||||
func.updateText();
|
||||
expect(func.text).to.equal("groupByNode(5, avg)");
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rendering func instance', function() {
|
||||
|
||||
it('should handle single metric param', function() {
|
||||
var func = gfunc.createFuncInstance('sumSeries');
|
||||
expect(func.render('hello.metric')).to.equal("sumSeries(hello.metric)");
|
||||
});
|
||||
|
||||
it('should include default params if options enable it', function() {
|
||||
var func = gfunc.createFuncInstance('scaleToSeconds', { withDefaultParams: true });
|
||||
expect(func.render('hello')).to.equal("scaleToSeconds(hello, 1)");
|
||||
});
|
||||
|
||||
it('should handle int or interval params with number', function() {
|
||||
var func = gfunc.createFuncInstance('movingMedian');
|
||||
func.params[0] = '5';
|
||||
expect(func.render('hello')).to.equal("movingMedian(hello, 5)");
|
||||
});
|
||||
|
||||
it('should handle int or interval params with interval string', function() {
|
||||
var func = gfunc.createFuncInstance('movingMedian');
|
||||
func.params[0] = '5min';
|
||||
expect(func.render('hello')).to.equal("movingMedian(hello, '5min')");
|
||||
});
|
||||
|
||||
it('should handle metric param and int param and string param', function() {
|
||||
var func = gfunc.createFuncInstance('groupByNode');
|
||||
func.params[0] = 5;
|
||||
func.params[1] = 'avg';
|
||||
expect(func.render('hello.metric')).to.equal("groupByNode(hello.metric, 5, 'avg')");
|
||||
});
|
||||
|
||||
it('should handle function with no metric param', function() {
|
||||
var func = gfunc.createFuncInstance('randomWalk');
|
||||
func.params[0] = 'test';
|
||||
expect(func.render(undefined)).to.equal("randomWalk('test')");
|
||||
});
|
||||
|
||||
it('should handle function multiple series params', function() {
|
||||
var func = gfunc.createFuncInstance('asPercent');
|
||||
func.params[0] = '#B';
|
||||
expect(func.render('#A')).to.equal("asPercent(#A, #B)");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when requesting function categories', function() {
|
||||
it('should return function categories', function() {
|
||||
var catIndex = gfunc.getCategories();
|
||||
expect(catIndex.Special.length).to.be.greaterThan(8);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updating func param', function() {
|
||||
it('should update param value and update text representation', function() {
|
||||
var func = gfunc.createFuncInstance('summarize', { withDefaultParams: true });
|
||||
func.updateParam('1h', 0);
|
||||
expect(func.params[0]).to.be('1h');
|
||||
expect(func.text).to.be('summarize(1h, sum, false)');
|
||||
});
|
||||
|
||||
it('should parse numbers as float', function() {
|
||||
var func = gfunc.createFuncInstance('scale');
|
||||
func.updateParam('0.001', 0);
|
||||
expect(func.params[0]).to.be('0.001');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updating func param with optional second parameter', function() {
|
||||
it('should update value and text', function() {
|
||||
var func = gfunc.createFuncInstance('aliasByNode');
|
||||
func.updateParam('1', 0);
|
||||
expect(func.params[0]).to.be('1');
|
||||
});
|
||||
|
||||
it('should slit text and put value in second param', function() {
|
||||
var func = gfunc.createFuncInstance('aliasByNode');
|
||||
func.updateParam('4,-5', 0);
|
||||
expect(func.params[0]).to.be('4');
|
||||
expect(func.params[1]).to.be('-5');
|
||||
expect(func.text).to.be('aliasByNode(4, -5)');
|
||||
});
|
||||
|
||||
it('should remove second param when empty string is set', function() {
|
||||
var func = gfunc.createFuncInstance('aliasByNode');
|
||||
func.updateParam('4,-5', 0);
|
||||
func.updateParam('', 1);
|
||||
expect(func.params[0]).to.be('4');
|
||||
expect(func.params[1]).to.be(undefined);
|
||||
expect(func.text).to.be('aliasByNode(4)');
|
||||
});
|
||||
});
|
||||
|
178
public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts
Normal file
178
public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts
Normal file
@ -0,0 +1,178 @@
|
||||
///<amd-dependency path="app/plugins/datasource/graphite/gfunc" name="gfunc"/>
|
||||
///<amd-dependency path="app/plugins/datasource/graphite/query_ctrl" />
|
||||
///<amd-dependency path="app/services/uiSegmentSrv" />
|
||||
///<amd-dependency path="test/specs/helpers" name="helpers" />
|
||||
|
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||
|
||||
declare var gfunc: any;
|
||||
declare var helpers: any;
|
||||
|
||||
describe('GraphiteQueryCtrl', function() {
|
||||
var ctx = new helpers.ControllerTestContext();
|
||||
|
||||
beforeEach(angularMocks.module('grafana.controllers'));
|
||||
beforeEach(angularMocks.module('grafana.services'));
|
||||
beforeEach(ctx.providePhase());
|
||||
beforeEach(ctx.createControllerPhase('GraphiteQueryCtrl'));
|
||||
|
||||
beforeEach(function() {
|
||||
ctx.scope.target = {target: 'aliasByNode(scaleToSeconds(test.prod.*,1),2)'};
|
||||
|
||||
ctx.scope.datasource = ctx.datasource;
|
||||
ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([]));
|
||||
});
|
||||
|
||||
describe('init', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
it('should validate metric key exists', function() {
|
||||
expect(ctx.scope.datasource.metricFindQuery.getCall(0).args[0]).to.be('test.prod.*');
|
||||
});
|
||||
|
||||
it('should delete last segment if no metrics are found', function() {
|
||||
expect(ctx.scope.segments[2].value).to.be('select metric');
|
||||
});
|
||||
|
||||
it('should parse expression and build function model', function() {
|
||||
expect(ctx.scope.functions.length).to.be(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when adding function', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'test.prod.*.count';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
ctx.scope.addFunction(gfunc.getFuncDef('aliasByNode'));
|
||||
});
|
||||
|
||||
it('should add function with correct node number', function() {
|
||||
expect(ctx.scope.functions[0].params[0]).to.be(2);
|
||||
});
|
||||
|
||||
it('should update target', function() {
|
||||
expect(ctx.scope.target.target).to.be('aliasByNode(test.prod.*.count, 2)');
|
||||
});
|
||||
|
||||
it('should call get_data', function() {
|
||||
expect(ctx.scope.$parent.get_data.called).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when adding function before any metric segment', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = '';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: true}]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
ctx.scope.addFunction(gfunc.getFuncDef('asPercent'));
|
||||
});
|
||||
|
||||
it('should add function and remove select metric link', function() {
|
||||
expect(ctx.scope.segments.length).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when initalizing target without metric expression and only function', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'asPercent(#A, #B)';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should not add select metric segment', function() {
|
||||
expect(ctx.scope.segments.length).to.be(0);
|
||||
});
|
||||
|
||||
it('should add both series refs as params', function() {
|
||||
expect(ctx.scope.functions[0].params.length).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when initializing a target with single param func using variable', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'movingAverage(prod.count, $var)';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should add 2 segments', function() {
|
||||
expect(ctx.scope.segments.length).to.be(2);
|
||||
});
|
||||
|
||||
it('should add function param', function() {
|
||||
expect(ctx.scope.functions[0].params.length).to.be(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when initalizing target without metric expression and function with series-ref', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'asPercent(metric.node.count, #A)';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should add segments', function() {
|
||||
expect(ctx.scope.segments.length).to.be(3);
|
||||
});
|
||||
|
||||
it('should have correct func params', function() {
|
||||
expect(ctx.scope.functions[0].params.length).to.be(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when getting altSegments and metricFindQuery retuns empty array', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'test.count';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.getAltSegments(1).then(function(results) {
|
||||
ctx.altSegments = results;
|
||||
});
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should have no segments', function() {
|
||||
expect(ctx.altSegments.length).to.be(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('targetChanged', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
ctx.scope.target.target = '';
|
||||
ctx.scope.targetChanged();
|
||||
});
|
||||
|
||||
it('should rebuld target after expression model', function() {
|
||||
expect(ctx.scope.target.target).to.be('aliasByNode(scaleToSeconds(test.prod.*, 1), 2)');
|
||||
});
|
||||
|
||||
it('should call get_data', function() {
|
||||
expect(ctx.scope.$parent.get_data.called).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
@ -7,10 +7,15 @@ var it = _global.it;
|
||||
var sinon = _global.sinon;
|
||||
var expect = _global.expect;
|
||||
|
||||
var angularMocks = {
|
||||
module: _global.module,
|
||||
};
|
||||
|
||||
export {
|
||||
beforeEach,
|
||||
describe,
|
||||
it,
|
||||
sinon,
|
||||
expect
|
||||
expect,
|
||||
angularMocks,
|
||||
}
|
||||
|
@ -1,130 +0,0 @@
|
||||
define([
|
||||
'app/plugins/datasource/graphite/gfunc'
|
||||
], function(gfunc) {
|
||||
'use strict';
|
||||
|
||||
describe('when creating func instance from func names', function() {
|
||||
|
||||
it('should return func instance', function() {
|
||||
var func = gfunc.createFuncInstance('sumSeries');
|
||||
expect(func).to.be.ok();
|
||||
expect(func.def.name).to.equal('sumSeries');
|
||||
expect(func.def.params.length).to.equal(5);
|
||||
expect(func.def.defaultParams.length).to.equal(1);
|
||||
});
|
||||
|
||||
it('should return func instance with shortName', function() {
|
||||
var func = gfunc.createFuncInstance('sum');
|
||||
expect(func).to.be.ok();
|
||||
});
|
||||
|
||||
it('should return func instance from funcDef', function() {
|
||||
var func = gfunc.createFuncInstance('sum');
|
||||
var func2 = gfunc.createFuncInstance(func.def);
|
||||
expect(func2).to.be.ok();
|
||||
});
|
||||
|
||||
it('func instance should have text representation', function() {
|
||||
var func = gfunc.createFuncInstance('groupByNode');
|
||||
func.params[0] = 5;
|
||||
func.params[1] = 'avg';
|
||||
func.updateText();
|
||||
expect(func.text).to.equal("groupByNode(5, avg)");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when rendering func instance', function() {
|
||||
|
||||
it('should handle single metric param', function() {
|
||||
var func = gfunc.createFuncInstance('sumSeries');
|
||||
expect(func.render('hello.metric')).to.equal("sumSeries(hello.metric)");
|
||||
});
|
||||
|
||||
it('should include default params if options enable it', function() {
|
||||
var func = gfunc.createFuncInstance('scaleToSeconds', { withDefaultParams: true });
|
||||
expect(func.render('hello')).to.equal("scaleToSeconds(hello, 1)");
|
||||
});
|
||||
|
||||
it('should handle int or interval params with number', function() {
|
||||
var func = gfunc.createFuncInstance('movingMedian');
|
||||
func.params[0] = '5';
|
||||
expect(func.render('hello')).to.equal("movingMedian(hello, 5)");
|
||||
});
|
||||
|
||||
it('should handle int or interval params with interval string', function() {
|
||||
var func = gfunc.createFuncInstance('movingMedian');
|
||||
func.params[0] = '5min';
|
||||
expect(func.render('hello')).to.equal("movingMedian(hello, '5min')");
|
||||
});
|
||||
|
||||
it('should handle metric param and int param and string param', function() {
|
||||
var func = gfunc.createFuncInstance('groupByNode');
|
||||
func.params[0] = 5;
|
||||
func.params[1] = 'avg';
|
||||
expect(func.render('hello.metric')).to.equal("groupByNode(hello.metric, 5, 'avg')");
|
||||
});
|
||||
|
||||
it('should handle function with no metric param', function() {
|
||||
var func = gfunc.createFuncInstance('randomWalk');
|
||||
func.params[0] = 'test';
|
||||
expect(func.render(undefined)).to.equal("randomWalk('test')");
|
||||
});
|
||||
|
||||
it('should handle function multiple series params', function() {
|
||||
var func = gfunc.createFuncInstance('asPercent');
|
||||
func.params[0] = '#B';
|
||||
expect(func.render('#A')).to.equal("asPercent(#A, #B)");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when requesting function categories', function() {
|
||||
it('should return function categories', function() {
|
||||
var catIndex = gfunc.getCategories();
|
||||
expect(catIndex.Special.length).to.be.greaterThan(8);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updating func param', function() {
|
||||
it('should update param value and update text representation', function() {
|
||||
var func = gfunc.createFuncInstance('summarize', { withDefaultParams: true });
|
||||
func.updateParam('1h', 0);
|
||||
expect(func.params[0]).to.be('1h');
|
||||
expect(func.text).to.be('summarize(1h, sum, false)');
|
||||
});
|
||||
|
||||
it('should parse numbers as float', function() {
|
||||
var func = gfunc.createFuncInstance('scale');
|
||||
func.updateParam('0.001', 0);
|
||||
expect(func.params[0]).to.be('0.001');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updating func param with optional second parameter', function() {
|
||||
it('should update value and text', function() {
|
||||
var func = gfunc.createFuncInstance('aliasByNode');
|
||||
func.updateParam('1', 0);
|
||||
expect(func.params[0]).to.be('1');
|
||||
});
|
||||
|
||||
it('should slit text and put value in second param', function() {
|
||||
var func = gfunc.createFuncInstance('aliasByNode');
|
||||
func.updateParam('4,-5', 0);
|
||||
expect(func.params[0]).to.be('4');
|
||||
expect(func.params[1]).to.be('-5');
|
||||
expect(func.text).to.be('aliasByNode(4, -5)');
|
||||
});
|
||||
|
||||
it('should remove second param when empty string is set', function() {
|
||||
var func = gfunc.createFuncInstance('aliasByNode');
|
||||
func.updateParam('4,-5', 0);
|
||||
func.updateParam('', 1);
|
||||
expect(func.params[0]).to.be('4');
|
||||
expect(func.params[1]).to.be(undefined);
|
||||
expect(func.text).to.be('aliasByNode(4)');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,122 +0,0 @@
|
||||
define([
|
||||
'./helpers',
|
||||
'app/plugins/datasource/graphite/datasource'
|
||||
], function(helpers) {
|
||||
'use strict';
|
||||
|
||||
describe('graphiteDatasource', function() {
|
||||
var ctx = new helpers.ServiceTestContext();
|
||||
|
||||
beforeEach(module('grafana.services'));
|
||||
beforeEach(ctx.providePhase(['backendSrv']));
|
||||
|
||||
beforeEach(ctx.createService('GraphiteDatasource'));
|
||||
beforeEach(function() {
|
||||
ctx.ds = new ctx.service({ url: [''] });
|
||||
});
|
||||
|
||||
describe('When querying influxdb with one target using query editor target spec', function() {
|
||||
var query = {
|
||||
rangeRaw: { from: 'now-1h', to: 'now' },
|
||||
targets: [{ target: 'prod1.count' }, {target: 'prod2.count'}],
|
||||
maxDataPoints: 500,
|
||||
};
|
||||
|
||||
var results;
|
||||
var requestOptions;
|
||||
|
||||
beforeEach(function() {
|
||||
ctx.backendSrv.datasourceRequest = function(options) {
|
||||
requestOptions = options;
|
||||
return ctx.$q.when({data: [{ target: 'prod1.count', datapoints: [[10, 1], [12,1]] }]});
|
||||
};
|
||||
|
||||
ctx.ds.query(query).then(function(data) { results = data; });
|
||||
ctx.$rootScope.$apply();
|
||||
});
|
||||
|
||||
it('should generate the correct query', function() {
|
||||
expect(requestOptions.url).to.be('/render');
|
||||
});
|
||||
|
||||
it('should query correctly', function() {
|
||||
var params = requestOptions.data.split('&');
|
||||
expect(params).to.contain('target=prod1.count');
|
||||
expect(params).to.contain('target=prod2.count');
|
||||
expect(params).to.contain('from=-1h');
|
||||
expect(params).to.contain('until=now');
|
||||
});
|
||||
|
||||
it('should exclude undefined params', function() {
|
||||
var params = requestOptions.data.split('&');
|
||||
expect(params).to.not.contain('cacheTimeout=undefined');
|
||||
});
|
||||
|
||||
it('should return series list', function() {
|
||||
expect(results.data.length).to.be(1);
|
||||
expect(results.data[0].target).to.be('prod1.count');
|
||||
});
|
||||
|
||||
it('should convert to millisecond resolution', function() {
|
||||
expect(results.data[0].datapoints[0][0]).to.be(10);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('building graphite params', function() {
|
||||
|
||||
it('should uri escape targets', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'prod1.{test,test2}'}, {target: 'prod2.count'}]
|
||||
});
|
||||
expect(results).to.contain('target=prod1.%7Btest%2Ctest2%7D');
|
||||
});
|
||||
|
||||
it('should replace target placeholder', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1'}, {target: 'series2'}, {target: 'asPercent(#A,#B)'}]
|
||||
});
|
||||
expect(results[2]).to.be('target=asPercent(series1%2Cseries2)');
|
||||
});
|
||||
|
||||
it('should replace target placeholder for hidden series', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1', hide: true}, {target: 'sumSeries(#A)', hide: true}, {target: 'asPercent(#A,#B)'}]
|
||||
});
|
||||
expect(results[0]).to.be('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))'));
|
||||
});
|
||||
|
||||
it('should replace target placeholder when nesting query references', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1'}, {target: 'sumSeries(#A)'}, {target: 'asPercent(#A,#B)'}]
|
||||
});
|
||||
expect(results[2]).to.be('target=' + encodeURIComponent("asPercent(series1,sumSeries(series1))"));
|
||||
});
|
||||
|
||||
it('should fix wrong minute interval parameters', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: "summarize(prod.25m.count, '25m', 'sum')" }]
|
||||
});
|
||||
expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.25m.count, '25min', 'sum')"));
|
||||
});
|
||||
|
||||
it('should fix wrong month interval parameters', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: "summarize(prod.5M.count, '5M', 'sum')" }]
|
||||
});
|
||||
expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.5M.count, '5mon', 'sum')"));
|
||||
});
|
||||
|
||||
it('should ignore empty targets', function() {
|
||||
var results = ctx.ds.buildGraphiteParams({
|
||||
targets: [{target: 'series1'}, {target: ''}]
|
||||
});
|
||||
expect(results.length).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,179 +0,0 @@
|
||||
define([
|
||||
'./helpers',
|
||||
'app/plugins/datasource/graphite/gfunc',
|
||||
'app/plugins/datasource/graphite/queryCtrl',
|
||||
'app/services/uiSegmentSrv'
|
||||
], function(helpers, gfunc) {
|
||||
'use strict';
|
||||
|
||||
describe('GraphiteQueryCtrl', function() {
|
||||
var ctx = new helpers.ControllerTestContext();
|
||||
|
||||
beforeEach(module('grafana.controllers'));
|
||||
beforeEach(module('grafana.services'));
|
||||
beforeEach(ctx.providePhase());
|
||||
beforeEach(ctx.createControllerPhase('GraphiteQueryCtrl'));
|
||||
|
||||
beforeEach(function() {
|
||||
ctx.scope.target = {target: 'aliasByNode(scaleToSeconds(test.prod.*,1),2)'};
|
||||
|
||||
ctx.scope.datasource = ctx.datasource;
|
||||
ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([]));
|
||||
});
|
||||
|
||||
describe('init', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
it('should validate metric key exists', function() {
|
||||
expect(ctx.scope.datasource.metricFindQuery.getCall(0).args[0]).to.be('test.prod.*');
|
||||
});
|
||||
|
||||
it('should delete last segment if no metrics are found', function() {
|
||||
expect(ctx.scope.segments[2].value).to.be('select metric');
|
||||
});
|
||||
|
||||
it('should parse expression and build function model', function() {
|
||||
expect(ctx.scope.functions.length).to.be(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when adding function', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'test.prod.*.count';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
ctx.scope.addFunction(gfunc.getFuncDef('aliasByNode'));
|
||||
});
|
||||
|
||||
it('should add function with correct node number', function() {
|
||||
expect(ctx.scope.functions[0].params[0]).to.be(2);
|
||||
});
|
||||
|
||||
it('should update target', function() {
|
||||
expect(ctx.scope.target.target).to.be('aliasByNode(test.prod.*.count, 2)');
|
||||
});
|
||||
|
||||
it('should call get_data', function() {
|
||||
expect(ctx.scope.$parent.get_data.called).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when adding function before any metric segment', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = '';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: true}]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
ctx.scope.addFunction(gfunc.getFuncDef('asPercent'));
|
||||
});
|
||||
|
||||
it('should add function and remove select metric link', function() {
|
||||
expect(ctx.scope.segments.length).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when initalizing target without metric expression and only function', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'asPercent(#A, #B)';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should not add select metric segment', function() {
|
||||
expect(ctx.scope.segments.length).to.be(0);
|
||||
});
|
||||
|
||||
it('should add both series refs as params', function() {
|
||||
expect(ctx.scope.functions[0].params.length).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when initializing a target with single param func using variable', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'movingAverage(prod.count, $var)';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should add 2 segments', function() {
|
||||
expect(ctx.scope.segments.length).to.be(2);
|
||||
});
|
||||
|
||||
it('should add function param', function() {
|
||||
expect(ctx.scope.functions[0].params.length).to.be(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('when initalizing target without metric expression and function with series-ref', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'asPercent(metric.node.count, #A)';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should add segments', function() {
|
||||
expect(ctx.scope.segments.length).to.be(3);
|
||||
});
|
||||
|
||||
it('should have correct func params', function() {
|
||||
expect(ctx.scope.functions[0].params.length).to.be(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when getting altSegments and metricFindQuery retuns empty array', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.target.target = 'test.count';
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.getAltSegments(1).then(function(results) {
|
||||
ctx.altSegments = results;
|
||||
});
|
||||
ctx.scope.$digest();
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
});
|
||||
|
||||
it('should have no segments', function() {
|
||||
expect(ctx.altSegments.length).to.be(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('targetChanged', function() {
|
||||
beforeEach(function() {
|
||||
ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
|
||||
ctx.scope.init();
|
||||
ctx.scope.$digest();
|
||||
|
||||
ctx.scope.$parent = { get_data: sinon.spy() };
|
||||
ctx.scope.target.target = '';
|
||||
ctx.scope.targetChanged();
|
||||
});
|
||||
|
||||
it('should rebuld target after expression model', function() {
|
||||
expect(ctx.scope.target.target).to.be('aliasByNode(scaleToSeconds(test.prod.*, 1), 2)');
|
||||
});
|
||||
|
||||
it('should call get_data', function() {
|
||||
expect(ctx.scope.$parent.get_data.called).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
@ -113,7 +113,7 @@ require([
|
||||
var specs = [];
|
||||
|
||||
for (var file in window.__karma__.files) {
|
||||
if (/base\/test\/specs.*/.test(file)) {
|
||||
if (/specs.*/.test(file)) {
|
||||
file = file2moduleName(file);
|
||||
specs.push(file);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user