Add dist/ directory to repo to correspond development guide.
http://docs.grafana.org/plugins/development/
This commit is contained in:
317
dist/test/datasource-zabbix/specs/datasource_specs.js
vendored
Normal file
317
dist/test/datasource-zabbix/specs/datasource_specs.js
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
"use strict";
|
||||
|
||||
var _module = require("../module");
|
||||
|
||||
var _datasource = require("../datasource");
|
||||
|
||||
var _q = require("q");
|
||||
|
||||
var _q2 = _interopRequireDefault(_q);
|
||||
|
||||
var _sinon = require("sinon");
|
||||
|
||||
var _sinon2 = _interopRequireDefault(_sinon);
|
||||
|
||||
var _lodash = require("lodash");
|
||||
|
||||
var _lodash2 = _interopRequireDefault(_lodash);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
describe('ZabbixDatasource', function () {
|
||||
var ctx = {};
|
||||
var defined = _sinon2.default.match.defined;
|
||||
|
||||
beforeEach(function () {
|
||||
ctx.instanceSettings = {
|
||||
jsonData: {
|
||||
username: 'zabbix',
|
||||
password: 'zabbix',
|
||||
trends: true,
|
||||
trendsFrom: '7d'
|
||||
}
|
||||
};
|
||||
ctx.templateSrv = {};
|
||||
ctx.alertSrv = {};
|
||||
ctx.zabbix = function () {};
|
||||
|
||||
ctx.ds = new _module.Datasource(ctx.instanceSettings, ctx.templateSrv, ctx.alertSrv, ctx.zabbix);
|
||||
});
|
||||
|
||||
describe('When querying data', function () {
|
||||
beforeEach(function () {
|
||||
ctx.ds.replaceTemplateVars = function (str) {
|
||||
return str;
|
||||
};
|
||||
});
|
||||
|
||||
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: 'now-6h', to: 'now' }
|
||||
};
|
||||
ctx.ds.query(options).then(function (result) {
|
||||
expect(result.data).to.have.length(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should use trends if it enabled and time more than trendsFrom', function (done) {
|
||||
var ranges = ['now-7d', 'now-168h', 'now-1M', 'now-1y'];
|
||||
|
||||
_lodash2.default.forEach(ranges, function (range) {
|
||||
ctx.options.range.from = range;
|
||||
ctx.ds.queryNumericData = _sinon2.default.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'];
|
||||
|
||||
_lodash2.default.forEach(ranges, function (range) {
|
||||
ctx.options.range.from = range;
|
||||
ctx.ds.queryNumericData = _sinon2.default.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();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When replacing template variables', function () {
|
||||
|
||||
function testReplacingVariable(target, varValue, expectedResult, done) {
|
||||
ctx.ds.templateSrv.replace = function () {
|
||||
return (0, _datasource.zabbixTemplateFormat)(varValue);
|
||||
};
|
||||
|
||||
var result = ctx.ds.replaceTemplateVars(target);
|
||||
expect(result).to.equal(expectedResult);
|
||||
done();
|
||||
}
|
||||
|
||||
/*
|
||||
* Alphanumerics, spaces, dots, dashes and underscores
|
||||
* are allowed in Zabbix host name.
|
||||
* 'AaBbCc0123 .-_'
|
||||
*/
|
||||
it('should return properly escaped regex', function (done) {
|
||||
var target = '$host';
|
||||
var template_var_value = 'AaBbCc0123 .-_';
|
||||
var expected_result = '/^AaBbCc0123 \\.-_$/';
|
||||
|
||||
testReplacingVariable(target, template_var_value, expected_result, done);
|
||||
});
|
||||
|
||||
/*
|
||||
* Single-value variable
|
||||
* $host = backend01
|
||||
* $host => /^backend01|backend01$/
|
||||
*/
|
||||
it('should return proper regex for single value', function (done) {
|
||||
var target = '$host';
|
||||
var template_var_value = 'backend01';
|
||||
var expected_result = '/^backend01$/';
|
||||
|
||||
testReplacingVariable(target, template_var_value, expected_result, done);
|
||||
});
|
||||
|
||||
/*
|
||||
* Multi-value variable
|
||||
* $host = [backend01, backend02]
|
||||
* $host => /^(backend01|backend01)$/
|
||||
*/
|
||||
it('should return proper regex for multi-value', function (done) {
|
||||
var target = '$host';
|
||||
var template_var_value = ['backend01', 'backend02'];
|
||||
var expected_result = '/^(backend01|backend02)$/';
|
||||
|
||||
testReplacingVariable(target, template_var_value, expected_result, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When invoking metricFindQuery()', function () {
|
||||
beforeEach(function () {
|
||||
ctx.ds.replaceTemplateVars = function (str) {
|
||||
return str;
|
||||
};
|
||||
ctx.ds.zabbix = {
|
||||
getGroups: function getGroups() {
|
||||
return _q2.default.when([]);
|
||||
},
|
||||
getHosts: function getHosts() {
|
||||
return _q2.default.when([]);
|
||||
},
|
||||
getApps: function getApps() {
|
||||
return _q2.default.when([]);
|
||||
},
|
||||
getItems: function getItems() {
|
||||
return _q2.default.when([]);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('should return groups', function (done) {
|
||||
var tests = [{ query: '*', expect: '/.*/' }, { query: '', expect: '' }, { query: 'Backend', expect: 'Backend' }, { query: 'Back*', expect: 'Back*' }];
|
||||
|
||||
var getGroups = _sinon2.default.spy(ctx.ds.zabbix, 'getGroups');
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = tests[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var test = _step.value;
|
||||
|
||||
ctx.ds.metricFindQuery(test.query);
|
||||
expect(getGroups).to.have.been.calledWith(test.expect);
|
||||
getGroups.reset();
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return hosts', function (done) {
|
||||
var tests = [{ query: '*.*', expect: '/.*/' }, { query: '.', expect: '' }, { query: 'Backend.*', expect: 'Backend' }, { query: 'Back*.', expect: 'Back*' }];
|
||||
|
||||
var getHosts = _sinon2.default.spy(ctx.ds.zabbix, 'getHosts');
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = tests[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var test = _step2.value;
|
||||
|
||||
ctx.ds.metricFindQuery(test.query);
|
||||
expect(getHosts).to.have.been.calledWith(test.expect);
|
||||
getHosts.reset();
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return applications', function (done) {
|
||||
var tests = [{ query: '*.*.*', expect: ['/.*/', '/.*/'] }, { query: '.*.', expect: ['', '/.*/'] }, { query: 'Backend.backend01.*', expect: ['Backend', 'backend01'] }, { query: 'Back*.*.', expect: ['Back*', '/.*/'] }];
|
||||
|
||||
var getApps = _sinon2.default.spy(ctx.ds.zabbix, 'getApps');
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = tests[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var test = _step3.value;
|
||||
|
||||
ctx.ds.metricFindQuery(test.query);
|
||||
expect(getApps).to.have.been.calledWith(test.expect[0], test.expect[1]);
|
||||
getApps.reset();
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return items', function (done) {
|
||||
var tests = [{ query: '*.*.*.*', expect: ['/.*/', '/.*/', ''] }, { query: '.*.*.*', expect: ['', '/.*/', ''] }, { query: 'Backend.backend01.*.*', expect: ['Backend', 'backend01', ''] }, { query: 'Back*.*.cpu.*', expect: ['Back*', '/.*/', 'cpu'] }];
|
||||
|
||||
var getItems = _sinon2.default.spy(ctx.ds.zabbix, 'getItems');
|
||||
var _iteratorNormalCompletion4 = true;
|
||||
var _didIteratorError4 = false;
|
||||
var _iteratorError4 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator4 = tests[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
||||
var test = _step4.value;
|
||||
|
||||
ctx.ds.metricFindQuery(test.query);
|
||||
expect(getItems).to.have.been.calledWith(test.expect[0], test.expect[1], test.expect[2]);
|
||||
getItems.reset();
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError4 = true;
|
||||
_iteratorError4 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
||||
_iterator4.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError4) {
|
||||
throw _iteratorError4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should invoke method with proper arguments', function (done) {
|
||||
var query = '*.*';
|
||||
|
||||
var getHosts = _sinon2.default.spy(ctx.ds.zabbix, 'getHosts');
|
||||
ctx.ds.metricFindQuery(query);
|
||||
expect(getHosts).to.have.been.calledWith('/.*/');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
135
dist/test/datasource-zabbix/specs/modules/datemath.js
vendored
Normal file
135
dist/test/datasource-zabbix/specs/modules/datemath.js
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.parse = parse;
|
||||
exports.isValid = isValid;
|
||||
exports.parseDateMath = parseDateMath;
|
||||
|
||||
var _lodash = require('lodash');
|
||||
|
||||
var _lodash2 = _interopRequireDefault(_lodash);
|
||||
|
||||
var _moment = require('moment');
|
||||
|
||||
var _moment2 = _interopRequireDefault(_moment);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
|
||||
|
||||
function parse(text, roundUp) {
|
||||
if (!text) {
|
||||
return undefined;
|
||||
}
|
||||
if (_moment2.default.isMoment(text)) {
|
||||
return text;
|
||||
}
|
||||
if (_lodash2.default.isDate(text)) {
|
||||
return (0, _moment2.default)(text);
|
||||
}
|
||||
|
||||
var time;
|
||||
var mathString = '';
|
||||
var index;
|
||||
var parseString;
|
||||
|
||||
if (text.substring(0, 3) === 'now') {
|
||||
time = (0, _moment2.default)();
|
||||
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 = (0, _moment2.default)(parseString, _moment2.default.ISO_8601);
|
||||
}
|
||||
|
||||
if (!mathString.length) {
|
||||
return time;
|
||||
}
|
||||
|
||||
return parseDateMath(mathString, time, roundUp);
|
||||
}
|
||||
|
||||
function isValid(text) {
|
||||
var date = parse(text);
|
||||
if (!date) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_moment2.default.isMoment(date)) {
|
||||
return date.isValid();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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 (!_lodash2.default.includes(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;
|
||||
}
|
||||
66
dist/test/datasource-zabbix/specs/test-main.js
vendored
Normal file
66
dist/test/datasource-zabbix/specs/test-main.js
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
var _prunk = require('prunk');
|
||||
|
||||
var _prunk2 = _interopRequireDefault(_prunk);
|
||||
|
||||
var _jsdom = require('jsdom');
|
||||
|
||||
var _chai = require('chai');
|
||||
|
||||
var _chai2 = _interopRequireDefault(_chai);
|
||||
|
||||
var _sinonChai = require('sinon-chai');
|
||||
|
||||
var _sinonChai2 = _interopRequireDefault(_sinonChai);
|
||||
|
||||
var _datemath = require('./modules/datemath');
|
||||
|
||||
var dateMath = _interopRequireWildcard(_datemath);
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
// Mock angular module
|
||||
|
||||
// import sinon from 'sinon';
|
||||
var angularMocks = {
|
||||
module: function module() {
|
||||
return {
|
||||
directive: function directive() {},
|
||||
service: function service() {},
|
||||
factory: function factory() {}
|
||||
};
|
||||
}
|
||||
}; // JSHint options
|
||||
/* globals global: false */
|
||||
|
||||
var datemathMock = {
|
||||
parse: dateMath.parse,
|
||||
parseDateMath: dateMath.parseDateMath,
|
||||
isValid: dateMath.isValid
|
||||
};
|
||||
|
||||
// Mock Grafana modules that are not available outside of the core project
|
||||
// Required for loading module.js
|
||||
_prunk2.default.mock('./css/query-editor.css!', 'no css, dude.');
|
||||
_prunk2.default.mock('app/plugins/sdk', {
|
||||
QueryCtrl: null
|
||||
});
|
||||
_prunk2.default.mock('app/core/utils/datemath', datemathMock);
|
||||
_prunk2.default.mock('angular', angularMocks);
|
||||
_prunk2.default.mock('jquery', 'module not found');
|
||||
|
||||
// Setup jsdom
|
||||
// Required for loading angularjs
|
||||
global.document = (0, _jsdom.jsdom)('<html><head><script></script></head><body></body></html>');
|
||||
global.window = global.document.parentWindow;
|
||||
global.navigator = window.navigator = {};
|
||||
global.Node = window.Node;
|
||||
|
||||
// Setup Chai
|
||||
_chai2.default.should();
|
||||
_chai2.default.use(_sinonChai2.default);
|
||||
global.assert = _chai2.default.assert;
|
||||
global.expect = _chai2.default.expect;
|
||||
Reference in New Issue
Block a user