Add trend using tests. Use sinon for checking functions calls.

This commit is contained in:
Alexander Zobnin
2016-08-14 14:53:40 +03:00
parent d247fc8a99
commit e64ae98378
4 changed files with 176 additions and 5 deletions

View File

@@ -32,14 +32,16 @@
"jsdom": "~3.1.2", "jsdom": "~3.1.2",
"q": "~1.4.1", "q": "~1.4.1",
"chai": "~3.5.0", "chai": "~3.5.0",
"sinon-chai": "~2.8.0",
"moment": "~2.14.1" "moment": "~2.14.1"
}, },
"dependencies": { "dependencies": {
"babel-plugin-transform-es2015-modules-systemjs": "^6.5.0", "babel-plugin-transform-es2015-modules-systemjs": "^6.5.0",
"babel-plugin-transform-es2015-for-of": "^6.6.0", "babel-plugin-transform-es2015-for-of": "^6.6.0",
"babel-preset-es2015": "^6.5.0", "babel-preset-es2015": "^6.5.0",
"lodash": "~4.0.0", "lodash": "^2.4.1",
"mocha": "^2.4.5" "mocha": "^2.4.5",
"sinon": "~1.16.1"
}, },
"homepage": "http://grafana-zabbix.org" "homepage": "http://grafana-zabbix.org"
} }

View File

@@ -1,15 +1,19 @@
import {Datasource} from "../module"; import {Datasource} from "../module";
import Q from "q"; import Q from "q";
import sinon from 'sinon';
import _ from 'lodash';
describe('ZabbixDatasource', function() { describe('ZabbixDatasource', function() {
var ctx = {}; var ctx = {};
var defined = sinon.match.defined;
beforeEach(function() { beforeEach(function() {
ctx.instanceSettings = { ctx.instanceSettings = {
jsonData: { jsonData: {
username: 'zabbix', username: 'zabbix',
password: 'zabbix', password: 'zabbix',
trends: false trends: true,
trendsFrom: '7d'
} }
}; };
ctx.$q = Q; ctx.$q = Q;
@@ -18,16 +22,32 @@ describe('ZabbixDatasource', function() {
ctx.zabbixAPIService = function() {}; ctx.zabbixAPIService = function() {};
ctx.ZabbixCachingProxy = function() {}; ctx.ZabbixCachingProxy = function() {};
ctx.QueryProcessor = function() {}; ctx.QueryProcessor = function() {};
ctx.ds = new Datasource(ctx.instanceSettings, ctx.$q, ctx.templateSrv, ctx.alertSrv, ctx.ds = new Datasource(ctx.instanceSettings, ctx.$q, ctx.templateSrv, ctx.alertSrv,
ctx.zabbixAPIService, ctx.ZabbixCachingProxy, ctx.QueryProcessor); ctx.zabbixAPIService, ctx.ZabbixCachingProxy, ctx.QueryProcessor);
ctx.ds.replaceTemplateVars = function(str) {
return str;
};
}); });
describe('When querying data', function() { describe('When querying data', function() {
ctx.options = {
targets: [
{
group: {filter: ""},
host: {filter: ""},
application: {filter: ""},
item: {filter: ""}
}
],
range: {from: 'now-7d', to: 'now'}
};
it('should return an empty array when no targets are set', function(done) { it('should return an empty array when no targets are set', function(done) {
var options = { var options = {
targets: [], targets: [],
range: {from: null, to: null} range: {from: 'now-6h', to: 'now'}
}; };
ctx.ds.query(options).then(function(result) { ctx.ds.query(options).then(function(result) {
expect(result.data).to.have.length(0); expect(result.data).to.have.length(0);
@@ -35,6 +55,38 @@ describe('ZabbixDatasource', function() {
}); });
}); });
it('should use trends if it enabled and time more than trendsFrom', function(done) {
var ranges = ['now-7d', 'now-168h', 'now-1M', 'now-1y'];
_.forEach(ranges, range => {
ctx.options.range.from = range;
ctx.ds.queryNumericData = sinon.spy();
ctx.ds.query(ctx.options);
// Check that useTrends options is true
expect(ctx.ds.queryNumericData)
.to.have.been.calledWith(defined, defined, defined, true);
});
done();
});
it('shouldnt use trends if it enabled and time less than trendsFrom', function(done) {
var ranges = ['now-6d', 'now-167h', 'now-1h', 'now-30m', 'now-30s'];
_.forEach(ranges, range => {
ctx.options.range.from = range;
ctx.ds.queryNumericData = sinon.spy();
ctx.ds.query(ctx.options);
// Check that useTrends options is false
expect(ctx.ds.queryNumericData)
.to.have.been.calledWith(defined, defined, defined, false);
});
done();
});
}); });
}); });

View File

@@ -0,0 +1,111 @@
import _ from 'lodash';
import moment from 'moment';
var units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
export function parse(text, roundUp) {
if (!text) { return undefined; }
if (moment.isMoment(text)) { return text; }
if (_.isDate(text)) { return moment(text); }
var time;
var mathString = '';
var index;
var parseString;
if (text.substring(0, 3) === 'now') {
time = moment();
mathString = text.substring('now'.length);
} else {
index = text.indexOf('||');
if (index === -1) {
parseString = text;
mathString = ''; // nothing else
} else {
parseString = text.substring(0, index);
mathString = text.substring(index + 2);
}
// We're going to just require ISO8601 timestamps, k?
time = moment(parseString, moment.ISO_8601);
}
if (!mathString.length) {
return time;
}
return parseDateMath(mathString, time, roundUp);
}
export function isValid(text) {
var date = parse(text);
if (!date) {
return false;
}
if (moment.isMoment(date)) {
return date.isValid();
}
return false;
}
export function parseDateMath(mathString, time, roundUp) {
var dateTime = time;
var i = 0;
var len = mathString.length;
while (i < len) {
var c = mathString.charAt(i++);
var type;
var num;
var unit;
if (c === '/') {
type = 0;
} else if (c === '+') {
type = 1;
} else if (c === '-') {
type = 2;
} else {
return undefined;
}
if (isNaN(mathString.charAt(i))) {
num = 1;
} else if (mathString.length === 2) {
num = mathString.charAt(i);
} else {
var numFrom = i;
while (!isNaN(mathString.charAt(i))) {
i++;
if (i > 10) { return undefined; }
}
num = parseInt(mathString.substring(numFrom, i), 10);
}
if (type === 0) {
// rounding is only allowed on whole, single, units (eg M or 1M, not 0.5M or 2M)
if (num !== 1) {
return undefined;
}
}
unit = mathString.charAt(i++);
if (!_.contains(units, unit)) {
return undefined;
} else {
if (type === 0) {
if (roundUp) {
dateTime.endOf(unit);
} else {
dateTime.startOf(unit);
}
} else if (type === 1) {
dateTime.add(num, unit);
} else if (type === 2) {
dateTime.subtract(num, unit);
}
}
}
return dateTime;
}

View File

@@ -4,6 +4,9 @@
import prunk from 'prunk'; import prunk from 'prunk';
import {jsdom} from 'jsdom'; import {jsdom} from 'jsdom';
import chai from 'chai'; import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import * as dateMath from './modules/datemath';
// Mock angular module // Mock angular module
var angularMocks = { var angularMocks = {
@@ -17,7 +20,9 @@ var angularMocks = {
}; };
var datemathMock = { var datemathMock = {
parse: function() {} parse: dateMath.parse,
parseDateMath: dateMath.parseDateMath,
isValid: dateMath.isValid
}; };
// Mock Grafana modules that are not available outside of the core project // Mock Grafana modules that are not available outside of the core project
@@ -39,5 +44,6 @@ global.Node = window.Node;
// Setup Chai // Setup Chai
chai.should(); chai.should();
chai.use(sinonChai);
global.assert = chai.assert; global.assert = chai.assert;
global.expect = chai.expect; global.expect = chai.expect;