From d247fc8a99ceeaf02b48c4f4dc412488cea662de Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Sun, 14 Aug 2016 11:58:23 +0300 Subject: [PATCH 1/5] Initial unit tests (using Mocha and Chai asserts). --- .jshintrc | 9 +++- Gruntfile.js | 39 +++++++++++++++-- package.json | 13 ++++-- .../specs/datasource_specs.js | 40 +++++++++++++++++ src/datasource-zabbix/specs/test-main.js | 43 +++++++++++++++++++ 5 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 src/datasource-zabbix/specs/datasource_specs.js create mode 100644 src/datasource-zabbix/specs/test-main.js diff --git a/.jshintrc b/.jshintrc index fe86382..300d6de 100644 --- a/.jshintrc +++ b/.jshintrc @@ -34,6 +34,13 @@ "define": true, "require": true, "Chromath": false, - "setImmediate": true + "setImmediate": true, + "expect": true, + "it": true, + "describe": true, + "sinon": true, + "module": true, + "beforeEach": true, + "inject": true } } diff --git a/Gruntfile.js b/Gruntfile.js index 646705d..7c5c08d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -40,11 +40,13 @@ module.exports = function(grunt) { babel: { options: { - sourceMap: true, - presets: ["es2015"], - plugins: ['transform-es2015-modules-systemjs', "transform-es2015-for-of"], + presets: ["es2015"] }, dist: { + options: { + sourceMap: true, + plugins: ['transform-es2015-modules-systemjs', "transform-es2015-for-of"] + }, files: [{ cwd: 'src', expand: true, @@ -57,6 +59,34 @@ module.exports = function(grunt) { dest: 'dist/' }] }, + distTestNoSystemJs: { + files: [{ + cwd: 'src', + expand: true, + src: ['**/*.js'], + dest: 'dist/test' + }] + }, + distTestsSpecsNoSystemJs: { + files: [{ + expand: true, + cwd: 'specs', + src: ['**/*.js'], + dest: 'dist/test/specs' + }] + } + }, + + mochaTest: { + test: { + options: { + reporter: 'spec' + }, + src: [ + 'dist/test/datasource-zabbix/specs/test-main.js', + 'dist/test/datasource-zabbix/specs/*_specs.js' + ] + } }, sass: { @@ -77,6 +107,7 @@ module.exports = function(grunt) { 'copy:src_to_dist', 'copy:pluginDef', 'babel', - 'sass' + 'sass', + 'mochaTest' ]); }; diff --git a/package.json b/package.json index b4b96f1..d433b0e 100644 --- a/package.json +++ b/package.json @@ -23,16 +23,23 @@ "grunt-contrib-copy": "~0.8.2", "grunt-contrib-watch": "^0.6.1", "grunt-contrib-uglify": "~0.11.0", + "grunt-mocha-test": "~0.12.7", "grunt-systemjs-builder": "^0.2.5", "load-grunt-tasks": "~3.2.0", "grunt-execute": "~0.2.2", - "grunt-contrib-clean": "~0.6.0" + "grunt-contrib-clean": "~0.6.0", + "prunk": "~1.2.1", + "jsdom": "~3.1.2", + "q": "~1.4.1", + "chai": "~3.5.0", + "moment": "~2.14.1" }, "dependencies": { "babel-plugin-transform-es2015-modules-systemjs": "^6.5.0", - "babel-plugin-transform-es2015-for-of": "^6.5.0", + "babel-plugin-transform-es2015-for-of": "^6.6.0", "babel-preset-es2015": "^6.5.0", - "lodash": "~4.0.0" + "lodash": "~4.0.0", + "mocha": "^2.4.5" }, "homepage": "http://grafana-zabbix.org" } diff --git a/src/datasource-zabbix/specs/datasource_specs.js b/src/datasource-zabbix/specs/datasource_specs.js new file mode 100644 index 0000000..9f8faff --- /dev/null +++ b/src/datasource-zabbix/specs/datasource_specs.js @@ -0,0 +1,40 @@ +import {Datasource} from "../module"; +import Q from "q"; + +describe('ZabbixDatasource', function() { + var ctx = {}; + + beforeEach(function() { + ctx.instanceSettings = { + jsonData: { + username: 'zabbix', + password: 'zabbix', + trends: false + } + }; + ctx.$q = Q; + ctx.templateSrv = {}; + ctx.alertSrv = {}; + 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); + }); + + describe('When querying data', function() { + + it('should return an empty array when no targets are set', function(done) { + var options = { + targets: [], + range: {from: null, to: null} + }; + ctx.ds.query(options).then(function(result) { + expect(result.data).to.have.length(0); + done(); + }); + }); + + }); + +}); diff --git a/src/datasource-zabbix/specs/test-main.js b/src/datasource-zabbix/specs/test-main.js new file mode 100644 index 0000000..cc846f1 --- /dev/null +++ b/src/datasource-zabbix/specs/test-main.js @@ -0,0 +1,43 @@ +// JSHint options +/* globals global: false */ + +import prunk from 'prunk'; +import {jsdom} from 'jsdom'; +import chai from 'chai'; + +// Mock angular module +var angularMocks = { + module: function() { + return { + directive: function() {}, + service: function() {}, + factory: function() {} + }; + } +}; + +var datemathMock = { + parse: function() {} +}; + +// Mock Grafana modules that are not available outside of the core project +// Required for loading module.js +prunk.mock('./css/query-editor.css!', 'no css, dude.'); +prunk.mock('app/plugins/sdk', { + QueryCtrl: null +}); +prunk.mock('app/core/utils/datemath', datemathMock); +prunk.mock('angular', angularMocks); +prunk.mock('jquery', 'module not found'); + +// Setup jsdom +// Required for loading angularjs +global.document = jsdom(''); +global.window = global.document.parentWindow; +global.navigator = window.navigator = {}; +global.Node = window.Node; + +// Setup Chai +chai.should(); +global.assert = chai.assert; +global.expect = chai.expect; From e64ae9837823f12ac98318b701863e77b0cbf542 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Sun, 14 Aug 2016 14:53:40 +0300 Subject: [PATCH 2/5] Add trend using tests. Use sinon for checking functions calls. --- package.json | 6 +- .../specs/datasource_specs.js | 56 ++++++++- .../specs/modules/datemath.js | 111 ++++++++++++++++++ src/datasource-zabbix/specs/test-main.js | 8 +- 4 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 src/datasource-zabbix/specs/modules/datemath.js diff --git a/package.json b/package.json index d433b0e..67de01a 100644 --- a/package.json +++ b/package.json @@ -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" } diff --git a/src/datasource-zabbix/specs/datasource_specs.js b/src/datasource-zabbix/specs/datasource_specs.js index 9f8faff..4b292d8 100644 --- a/src/datasource-zabbix/specs/datasource_specs.js +++ b/src/datasource-zabbix/specs/datasource_specs.js @@ -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(); + }); + }); }); diff --git a/src/datasource-zabbix/specs/modules/datemath.js b/src/datasource-zabbix/specs/modules/datemath.js new file mode 100644 index 0000000..fd97ab8 --- /dev/null +++ b/src/datasource-zabbix/specs/modules/datemath.js @@ -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; +} diff --git a/src/datasource-zabbix/specs/test-main.js b/src/datasource-zabbix/specs/test-main.js index cc846f1..23fa7c1 100644 --- a/src/datasource-zabbix/specs/test-main.js +++ b/src/datasource-zabbix/specs/test-main.js @@ -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; From a8079316d7b83ca4be8e730110929346a641c77d Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Wed, 9 Nov 2016 15:00:36 +0300 Subject: [PATCH 3/5] Update datemath mock to lodash 4. --- src/datasource-zabbix/specs/modules/datemath.js | 2 +- src/datasource-zabbix/specs/test-main.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/datasource-zabbix/specs/modules/datemath.js b/src/datasource-zabbix/specs/modules/datemath.js index fd97ab8..efbf0bf 100644 --- a/src/datasource-zabbix/specs/modules/datemath.js +++ b/src/datasource-zabbix/specs/modules/datemath.js @@ -91,7 +91,7 @@ export function parseDateMath(mathString, time, roundUp) { } unit = mathString.charAt(i++); - if (!_.contains(units, unit)) { + if (!_.includes(units, unit)) { return undefined; } else { if (type === 0) { diff --git a/src/datasource-zabbix/specs/test-main.js b/src/datasource-zabbix/specs/test-main.js index 23fa7c1..cdaec55 100644 --- a/src/datasource-zabbix/specs/test-main.js +++ b/src/datasource-zabbix/specs/test-main.js @@ -4,7 +4,7 @@ import prunk from 'prunk'; import {jsdom} from 'jsdom'; import chai from 'chai'; -import sinon from 'sinon'; +// import sinon from 'sinon'; import sinonChai from 'sinon-chai'; import * as dateMath from './modules/datemath'; From f8419f04a979a0dd96deb7f8148d8a84dd799779 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Wed, 9 Nov 2016 16:52:12 +0300 Subject: [PATCH 4/5] Tests: added tests for template variables replacing. --- src/datasource-zabbix/datasource.js | 4 +- .../specs/datasource_specs.js | 75 ++++++++++++++++--- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/datasource-zabbix/datasource.js b/src/datasource-zabbix/datasource.js index f2176c2..b860833 100644 --- a/src/datasource-zabbix/datasource.js +++ b/src/datasource-zabbix/datasource.js @@ -449,7 +449,7 @@ function formatMetric(metricObj) { * template variables, for example * /CPU $cpu_item.*time/ where $cpu_item is system,user,iowait */ -function zabbixTemplateFormat(value) { +export function zabbixTemplateFormat(value) { if (typeof value === 'string') { return utils.escapeRegex(value); } @@ -468,7 +468,7 @@ function zabbixTemplateFormat(value) { */ function replaceTemplateVars(templateSrv, target, scopedVars) { var replacedTarget = templateSrv.replace(target, scopedVars, zabbixTemplateFormat); - if (target !== replacedTarget && !utils.regexPattern.test(replacedTarget)) { + if (target !== replacedTarget && !utils.isRegex(replacedTarget)) { replacedTarget = '/^' + replacedTarget + '$/'; } return replacedTarget; diff --git a/src/datasource-zabbix/specs/datasource_specs.js b/src/datasource-zabbix/specs/datasource_specs.js index 4b292d8..fc44a5c 100644 --- a/src/datasource-zabbix/specs/datasource_specs.js +++ b/src/datasource-zabbix/specs/datasource_specs.js @@ -1,13 +1,14 @@ import {Datasource} from "../module"; +import {zabbixTemplateFormat} from "../datasource"; import Q from "q"; import sinon from 'sinon'; import _ from 'lodash'; -describe('ZabbixDatasource', function() { +describe('ZabbixDatasource', () => { var ctx = {}; var defined = sinon.match.defined; - beforeEach(function() { + beforeEach(() => { ctx.instanceSettings = { jsonData: { username: 'zabbix', @@ -19,19 +20,19 @@ describe('ZabbixDatasource', function() { ctx.$q = Q; ctx.templateSrv = {}; ctx.alertSrv = {}; - ctx.zabbixAPIService = function() {}; - ctx.ZabbixCachingProxy = function() {}; - ctx.QueryProcessor = function() {}; + ctx.zabbixAPIService = () => {}; + ctx.ZabbixCachingProxy = () => {}; + ctx.QueryProcessor = () => {}; 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() { + describe('When querying data', () => { + beforeEach(() => { + ctx.ds.replaceTemplateVars = (str) => { return str; }; + }); + ctx.options = { targets: [ { @@ -83,10 +84,62 @@ describe('ZabbixDatasource', function() { expect(ctx.ds.queryNumericData) .to.have.been.calledWith(defined, defined, defined, false); }); - done(); }); }); + describe('When replacing template variables', () => { + + function testReplacingVariable(target, varValue, expectedResult, done) { + ctx.ds.templateSrv.replace = () => { + return zabbixTemplateFormat(varValue); + }; + + let 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', (done) => { + let target = '$host'; + let template_var_value = 'AaBbCc0123 .-_'; + let 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', (done) => { + let target = '$host'; + let template_var_value = 'backend01'; + let 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', (done) => { + let target = '$host'; + let template_var_value = ['backend01', 'backend02']; + let expected_result = '/^(backend01|backend02)$/'; + + testReplacingVariable(target, template_var_value, expected_result, done); + }); + + }); + }); From cb5461a472cc1fa0b48caf4bce7a1b6c91fcb2c6 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Wed, 9 Nov 2016 20:14:04 +0300 Subject: [PATCH 5/5] Tests: added tests for template variable query, issue #303. --- .../specs/datasource_specs.js | 112 ++++++++++++++++-- 1 file changed, 102 insertions(+), 10 deletions(-) diff --git a/src/datasource-zabbix/specs/datasource_specs.js b/src/datasource-zabbix/specs/datasource_specs.js index fc44a5c..923d99a 100644 --- a/src/datasource-zabbix/specs/datasource_specs.js +++ b/src/datasource-zabbix/specs/datasource_specs.js @@ -5,8 +5,8 @@ import sinon from 'sinon'; import _ from 'lodash'; describe('ZabbixDatasource', () => { - var ctx = {}; - var defined = sinon.match.defined; + let ctx = {}; + let defined = sinon.match.defined; beforeEach(() => { ctx.instanceSettings = { @@ -30,7 +30,7 @@ describe('ZabbixDatasource', () => { describe('When querying data', () => { beforeEach(() => { - ctx.ds.replaceTemplateVars = (str) => { return str; }; + ctx.ds.replaceTemplateVars = (str) => str; }); ctx.options = { @@ -45,19 +45,19 @@ describe('ZabbixDatasource', () => { range: {from: 'now-7d', to: 'now'} }; - it('should return an empty array when no targets are set', function(done) { - var options = { + it('should return an empty array when no targets are set', (done) => { + let options = { targets: [], range: {from: 'now-6h', to: 'now'} }; - ctx.ds.query(options).then(function(result) { + ctx.ds.query(options).then(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']; + it('should use trends if it enabled and time more than trendsFrom', (done) => { + let ranges = ['now-7d', 'now-168h', 'now-1M', 'now-1y']; _.forEach(ranges, range => { ctx.options.range.from = range; @@ -72,8 +72,8 @@ describe('ZabbixDatasource', () => { 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']; + it('shouldnt use trends if it enabled and time less than trendsFrom', (done) => { + let ranges = ['now-6d', 'now-167h', 'now-1h', 'now-30m', 'now-30s']; _.forEach(ranges, range => { ctx.options.range.from = range; @@ -139,7 +139,99 @@ describe('ZabbixDatasource', () => { testReplacingVariable(target, template_var_value, expected_result, done); }); + }); + describe('When invoking metricFindQuery()', () => { + beforeEach(() => { + ctx.ds.replaceTemplateVars = (str) => str; + ctx.ds.zabbixCache = { + getGroups: () => Q.when([]) + }; + ctx.ds.queryProcessor = { + getGroups: () => Q.when([]), + getHosts: () => Q.when([]), + getApps: () => Q.when([]), + getItems: () => Q.when([]) + }; + }); + + it('should return groups', (done) => { + const tests = [ + {query: '*', expect: '/.*/'}, + {query: '', expect: ''}, + {query: 'Backend', expect: 'Backend'}, + {query: 'Back*', expect: 'Back*'} + ]; + + let getGroups = sinon.spy(ctx.ds.zabbixCache, 'getGroups'); + for (const test of tests) { + ctx.ds.metricFindQuery(test.query); + expect(getGroups).to.have.been.calledWith(test.expect); + getGroups.reset(); + } + done(); + }); + + it('should return hosts', (done) => { + const tests = [ + {query: '*.*', expect: '/.*/'}, + {query: '.', expect: ''}, + {query: 'Backend.*', expect: 'Backend'}, + {query: 'Back*.', expect: 'Back*'} + ]; + + let getHosts = sinon.spy(ctx.ds.queryProcessor, 'getHosts'); + for (const test of tests) { + ctx.ds.metricFindQuery(test.query); + expect(getHosts).to.have.been.calledWith(test.expect); + getHosts.reset(); + } + done(); + }); + + it('should return applications', (done) => { + const tests = [ + {query: '*.*.*', expect: ['/.*/', '/.*/']}, + {query: '.*.', expect: ['', '/.*/']}, + {query: 'Backend.backend01.*', expect: ['Backend', 'backend01']}, + {query: 'Back*.*.', expect: ['Back*', '/.*/']} + ]; + + let getApps = sinon.spy(ctx.ds.queryProcessor, 'getApps'); + for (const test of tests) { + ctx.ds.metricFindQuery(test.query); + expect(getApps).to.have.been.calledWith(test.expect[0], test.expect[1]); + getApps.reset(); + } + done(); + }); + + it('should return items', (done) => { + const tests = [ + {query: '*.*.*.*', expect: ['/.*/', '/.*/', '']}, + {query: '.*.*.*', expect: ['', '/.*/', '']}, + {query: 'Backend.backend01.*.*', expect: ['Backend', 'backend01', '']}, + {query: 'Back*.*.cpu.*', expect: ['Back*', '/.*/', 'cpu']} + ]; + + let getItems = sinon.spy(ctx.ds.queryProcessor, 'getItems'); + for (const test of tests) { + ctx.ds.metricFindQuery(test.query); + expect(getItems) + .to.have.been.calledWith(test.expect[0], test.expect[1], test.expect[2]); + getItems.reset(); + } + done(); + }); + + it('should invoke method with proper arguments', (done) => { + let query = '*.*'; + + let getHosts = sinon.spy(ctx.ds.queryProcessor, 'getHosts'); + ctx.ds.metricFindQuery(query); + expect(getHosts).to.have.been.calledWith('/.*/'); + done(); + }); }); });