Add trend using tests. Use sinon for checking functions calls.
This commit is contained in:
@@ -32,14 +32,16 @@
|
||||
"jsdom": "~3.1.2",
|
||||
"q": "~1.4.1",
|
||||
"chai": "~3.5.0",
|
||||
"sinon-chai": "~2.8.0",
|
||||
"moment": "~2.14.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-plugin-transform-es2015-modules-systemjs": "^6.5.0",
|
||||
"babel-plugin-transform-es2015-for-of": "^6.6.0",
|
||||
"babel-preset-es2015": "^6.5.0",
|
||||
"lodash": "~4.0.0",
|
||||
"mocha": "^2.4.5"
|
||||
"lodash": "^2.4.1",
|
||||
"mocha": "^2.4.5",
|
||||
"sinon": "~1.16.1"
|
||||
},
|
||||
"homepage": "http://grafana-zabbix.org"
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import {Datasource} from "../module";
|
||||
import Q from "q";
|
||||
import sinon from 'sinon';
|
||||
import _ from 'lodash';
|
||||
|
||||
describe('ZabbixDatasource', function() {
|
||||
var ctx = {};
|
||||
var defined = sinon.match.defined;
|
||||
|
||||
beforeEach(function() {
|
||||
ctx.instanceSettings = {
|
||||
jsonData: {
|
||||
username: 'zabbix',
|
||||
password: 'zabbix',
|
||||
trends: false
|
||||
trends: true,
|
||||
trendsFrom: '7d'
|
||||
}
|
||||
};
|
||||
ctx.$q = Q;
|
||||
@@ -18,16 +22,32 @@ describe('ZabbixDatasource', function() {
|
||||
ctx.zabbixAPIService = function() {};
|
||||
ctx.ZabbixCachingProxy = function() {};
|
||||
ctx.QueryProcessor = function() {};
|
||||
|
||||
ctx.ds = new Datasource(ctx.instanceSettings, ctx.$q, ctx.templateSrv, ctx.alertSrv,
|
||||
ctx.zabbixAPIService, ctx.ZabbixCachingProxy, ctx.QueryProcessor);
|
||||
|
||||
ctx.ds.replaceTemplateVars = function(str) {
|
||||
return str;
|
||||
};
|
||||
});
|
||||
|
||||
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) {
|
||||
var options = {
|
||||
targets: [],
|
||||
range: {from: null, to: null}
|
||||
range: {from: 'now-6h', to: 'now'}
|
||||
};
|
||||
ctx.ds.query(options).then(function(result) {
|
||||
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();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
111
src/datasource-zabbix/specs/modules/datemath.js
Normal file
111
src/datasource-zabbix/specs/modules/datemath.js
Normal 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;
|
||||
}
|
||||
@@ -4,6 +4,9 @@
|
||||
import prunk from 'prunk';
|
||||
import {jsdom} from 'jsdom';
|
||||
import chai from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import sinonChai from 'sinon-chai';
|
||||
import * as dateMath from './modules/datemath';
|
||||
|
||||
// Mock angular module
|
||||
var angularMocks = {
|
||||
@@ -17,7 +20,9 @@ var angularMocks = {
|
||||
};
|
||||
|
||||
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
|
||||
@@ -39,5 +44,6 @@ global.Node = window.Node;
|
||||
|
||||
// Setup Chai
|
||||
chai.should();
|
||||
chai.use(sinonChai);
|
||||
global.assert = chai.assert;
|
||||
global.expect = chai.expect;
|
||||
|
||||
Reference in New Issue
Block a user