From 8a39b32b5c24bc1055f2d47ad629752c2020eeaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 28 Sep 2015 16:28:19 +0200 Subject: [PATCH] refactor: moved elasticsearch specs to plugin folder and to typescript --- .../{bucketAgg.js => bucket_agg.js} | 2 +- .../datasource/elasticsearch/datasource.js | 8 +- .../datasource/elasticsearch/directives.js | 4 +- ...elasticResponse.js => elastic_response.js} | 2 +- .../{indexPattern.js => index_pattern.js} | 0 .../{metricAgg.js => metric_agg.js} | 2 +- .../{queryBuilder.js => query_builder.js} | 0 .../{queryCtrl.js => query_ctrl.js} | 0 .../{queryDef.js => query_def.js} | 0 .../elasticsearch/specs/datasource_specs.ts | 74 ++++ .../specs/elastic_response_specs.ts | 414 ++++++++++++++++++ .../specs/index_pattern_specs.ts | 51 +++ .../specs/query_builder_specs.ts | 123 ++++++ .../elasticsearch/specs/query_ctrl_specs.ts | 30 ++ .../influxdb/specs/query_builder_specs.ts | 2 +- .../specs/elasticsearch-indexPattern-specs.js | 52 --- .../specs/elasticsearch-querybuilder-specs.js | 124 ------ .../specs/elasticsearch-queryctrl-specs.js | 32 -- .../specs/elasticsearch-response-specs.js | 414 ------------------ public/test/specs/elasticsearch-specs.js | 77 ---- 20 files changed, 702 insertions(+), 709 deletions(-) rename public/app/plugins/datasource/elasticsearch/{bucketAgg.js => bucket_agg.js} (99%) rename public/app/plugins/datasource/elasticsearch/{elasticResponse.js => elastic_response.js} (99%) rename public/app/plugins/datasource/elasticsearch/{indexPattern.js => index_pattern.js} (100%) rename public/app/plugins/datasource/elasticsearch/{metricAgg.js => metric_agg.js} (99%) rename public/app/plugins/datasource/elasticsearch/{queryBuilder.js => query_builder.js} (100%) rename public/app/plugins/datasource/elasticsearch/{queryCtrl.js => query_ctrl.js} (100%) rename public/app/plugins/datasource/elasticsearch/{queryDef.js => query_def.js} (100%) create mode 100644 public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts create mode 100644 public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts create mode 100644 public/app/plugins/datasource/elasticsearch/specs/index_pattern_specs.ts create mode 100644 public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts create mode 100644 public/app/plugins/datasource/elasticsearch/specs/query_ctrl_specs.ts delete mode 100644 public/test/specs/elasticsearch-indexPattern-specs.js delete mode 100644 public/test/specs/elasticsearch-querybuilder-specs.js delete mode 100644 public/test/specs/elasticsearch-queryctrl-specs.js delete mode 100644 public/test/specs/elasticsearch-response-specs.js delete mode 100644 public/test/specs/elasticsearch-specs.js diff --git a/public/app/plugins/datasource/elasticsearch/bucketAgg.js b/public/app/plugins/datasource/elasticsearch/bucket_agg.js similarity index 99% rename from public/app/plugins/datasource/elasticsearch/bucketAgg.js rename to public/app/plugins/datasource/elasticsearch/bucket_agg.js index 33efa4cbf6a..00bba14af05 100644 --- a/public/app/plugins/datasource/elasticsearch/bucketAgg.js +++ b/public/app/plugins/datasource/elasticsearch/bucket_agg.js @@ -1,7 +1,7 @@ define([ 'angular', 'lodash', - './queryDef', + './query_def', ], function (angular, _, queryDef) { 'use strict'; diff --git a/public/app/plugins/datasource/elasticsearch/datasource.js b/public/app/plugins/datasource/elasticsearch/datasource.js index 5f7d3860cf3..9d6b8e4c834 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.js +++ b/public/app/plugins/datasource/elasticsearch/datasource.js @@ -3,10 +3,10 @@ define([ 'lodash', 'moment', 'kbn', - './queryBuilder', - './indexPattern', - './elasticResponse', - './queryCtrl', + './query_builder', + './index_pattern', + './elastic_response', + './query_ctrl', './directives' ], function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticResponse) { diff --git a/public/app/plugins/datasource/elasticsearch/directives.js b/public/app/plugins/datasource/elasticsearch/directives.js index 57656050cab..480ee79ad0a 100644 --- a/public/app/plugins/datasource/elasticsearch/directives.js +++ b/public/app/plugins/datasource/elasticsearch/directives.js @@ -1,7 +1,7 @@ define([ 'angular', - './bucketAgg', - './metricAgg', + './bucket_agg', + './metric_agg', ], function (angular) { 'use strict'; diff --git a/public/app/plugins/datasource/elasticsearch/elasticResponse.js b/public/app/plugins/datasource/elasticsearch/elastic_response.js similarity index 99% rename from public/app/plugins/datasource/elasticsearch/elasticResponse.js rename to public/app/plugins/datasource/elasticsearch/elastic_response.js index 5914e024c44..bfbcb2034ab 100644 --- a/public/app/plugins/datasource/elasticsearch/elasticResponse.js +++ b/public/app/plugins/datasource/elasticsearch/elastic_response.js @@ -1,6 +1,6 @@ define([ "lodash", - "./queryDef" + "./query_def" ], function (_, queryDef) { 'use strict'; diff --git a/public/app/plugins/datasource/elasticsearch/indexPattern.js b/public/app/plugins/datasource/elasticsearch/index_pattern.js similarity index 100% rename from public/app/plugins/datasource/elasticsearch/indexPattern.js rename to public/app/plugins/datasource/elasticsearch/index_pattern.js diff --git a/public/app/plugins/datasource/elasticsearch/metricAgg.js b/public/app/plugins/datasource/elasticsearch/metric_agg.js similarity index 99% rename from public/app/plugins/datasource/elasticsearch/metricAgg.js rename to public/app/plugins/datasource/elasticsearch/metric_agg.js index f2edd203e86..fd748a1f8b0 100644 --- a/public/app/plugins/datasource/elasticsearch/metricAgg.js +++ b/public/app/plugins/datasource/elasticsearch/metric_agg.js @@ -1,7 +1,7 @@ define([ 'angular', 'lodash', - './queryDef' + './query_def' ], function (angular, _, queryDef) { 'use strict'; diff --git a/public/app/plugins/datasource/elasticsearch/queryBuilder.js b/public/app/plugins/datasource/elasticsearch/query_builder.js similarity index 100% rename from public/app/plugins/datasource/elasticsearch/queryBuilder.js rename to public/app/plugins/datasource/elasticsearch/query_builder.js diff --git a/public/app/plugins/datasource/elasticsearch/queryCtrl.js b/public/app/plugins/datasource/elasticsearch/query_ctrl.js similarity index 100% rename from public/app/plugins/datasource/elasticsearch/queryCtrl.js rename to public/app/plugins/datasource/elasticsearch/query_ctrl.js diff --git a/public/app/plugins/datasource/elasticsearch/queryDef.js b/public/app/plugins/datasource/elasticsearch/query_def.js similarity index 100% rename from public/app/plugins/datasource/elasticsearch/queryDef.js rename to public/app/plugins/datasource/elasticsearch/query_def.js diff --git a/public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts new file mode 100644 index 00000000000..aecb16501b7 --- /dev/null +++ b/public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts @@ -0,0 +1,74 @@ +/// +/// + +import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common'; +import moment = require('moment'); +import angular = require('angular'); + +declare var helpers: any; + +describe('ElasticDatasource', function() { + var ctx = new helpers.ServiceTestContext(); + + beforeEach(angularMocks.module('grafana.services')); + beforeEach(ctx.providePhase(['templateSrv', 'backendSrv'])); + beforeEach(ctx.createService('ElasticDatasource')); + beforeEach(function() { + ctx.ds = new ctx.service({jsonData: {}}); + }); + + describe('When testing datasource with index pattern', function() { + beforeEach(function() { + ctx.ds = new ctx.service({ + url: 'http://es.com', + index: '[asd-]YYYY.MM.DD', + jsonData: { interval: 'Daily' } + }); + }); + + it('should translate index pattern to current day', function() { + var requestOptions; + ctx.backendSrv.datasourceRequest = function(options) { + requestOptions = options; + return ctx.$q.when({}); + }; + + ctx.ds.testDatasource(); + ctx.$rootScope.$apply(); + + var today = moment().format("YYYY.MM.DD"); + expect(requestOptions.url).to.be("http://es.com/asd-" + today + '/_stats'); + }); + }); + + describe('When issueing metric query with interval pattern', function() { + beforeEach(function() { + ctx.ds = new ctx.service({ + url: 'http://es.com', + index: '[asd-]YYYY.MM.DD', + jsonData: { interval: 'Daily' } + }); + }); + + it('should translate index pattern to current day', function() { + var requestOptions; + ctx.backendSrv.datasourceRequest = function(options) { + requestOptions = options; + return ctx.$q.when({data: {responses: []}}); + }; + + ctx.ds.query({ + range: { + from: moment([2015, 4, 30, 10]), + to: moment([2015, 5, 1, 10]) + }, + targets: [{ bucketAggs: [], metrics: [] }] + }); + + ctx.$rootScope.$apply(); + var parts = requestOptions.data.split('\n'); + var header = angular.fromJson(parts[0]); + expect(header.index).to.eql(['asd-2015.05.30', 'asd-2015.05.31', 'asd-2015.06.01']); + }); + }); +}); diff --git a/public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts new file mode 100644 index 00000000000..df810e3a9d9 --- /dev/null +++ b/public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts @@ -0,0 +1,414 @@ +/// + +import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'; + +declare var ElasticResponse: any; + +describe('ElasticResponse', function() { + var targets; + var response; + var result; + + describe('simple query and count', function() { + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'count', id: '1'}], + bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}], + }]; + response = { + responses: [{ + aggregations: { + "2": { + buckets: [ + { + doc_count: 10, + key: 1000 + }, + { + doc_count: 15, + key: 2000 + } + ] + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 1 series', function() { + expect(result.data.length).to.be(1); + expect(result.data[0].target).to.be('Count'); + expect(result.data[0].datapoints.length).to.be(2); + expect(result.data[0].datapoints[0][0]).to.be(10); + expect(result.data[0].datapoints[0][1]).to.be(1000); + }); + + }); + + describe('simple query count & avg aggregation', function() { + var result; + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'count', id: '1'}, {type: 'avg', field: 'value', id: '2'}], + bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}], + }]; + response = { + responses: [{ + aggregations: { + "3": { + buckets: [ + { + "2": {value: 88}, + doc_count: 10, + key: 1000 + }, + { + "2": {value: 99}, + doc_count: 15, + key: 2000 + } + ] + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 2 series', function() { + expect(result.data.length).to.be(2); + expect(result.data[0].datapoints.length).to.be(2); + expect(result.data[0].datapoints[0][0]).to.be(10); + expect(result.data[0].datapoints[0][1]).to.be(1000); + + expect(result.data[1].target).to.be("Average value"); + expect(result.data[1].datapoints[0][0]).to.be(88); + expect(result.data[1].datapoints[1][0]).to.be(99); + }); + + }); + + describe('single group by query one metric', function() { + var result; + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'count', id: '1'}], + bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}], + }]; + response = { + responses: [{ + aggregations: { + "2": { + buckets: [ + { + "3": { + buckets: [ + {doc_count: 1, key: 1000}, + {doc_count: 3, key: 2000} + ] + }, + doc_count: 4, + key: 'server1', + }, + { + "3": { + buckets: [ + {doc_count: 2, key: 1000}, + {doc_count: 8, key: 2000} + ] + }, + doc_count: 10, + key: 'server2', + }, + ] + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 2 series', function() { + expect(result.data.length).to.be(2); + expect(result.data[0].datapoints.length).to.be(2); + expect(result.data[0].target).to.be('server1'); + expect(result.data[1].target).to.be('server2'); + }); + }); + + describe('single group by query two metrics', function() { + var result; + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'count', id: '1'}, {type: 'avg', field: '@value', id: '4'}], + bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}], + }]; + response = { + responses: [{ + aggregations: { + "2": { + buckets: [ + { + "3": { + buckets: [ + { "4": {value: 10}, doc_count: 1, key: 1000}, + { "4": {value: 12}, doc_count: 3, key: 2000} + ] + }, + doc_count: 4, + key: 'server1', + }, + { + "3": { + buckets: [ + { "4": {value: 20}, doc_count: 1, key: 1000}, + { "4": {value: 32}, doc_count: 3, key: 2000} + ] + }, + doc_count: 10, + key: 'server2', + }, + ] + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 2 series', function() { + expect(result.data.length).to.be(4); + expect(result.data[0].datapoints.length).to.be(2); + expect(result.data[0].target).to.be('server1 Count'); + expect(result.data[1].target).to.be('server1 Average @value'); + expect(result.data[2].target).to.be('server2 Count'); + expect(result.data[3].target).to.be('server2 Average @value'); + }); + }); + + describe('with percentiles ', function() { + var result; + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'percentiles', settings: {percents: [75, 90]}, id: '1'}], + bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}], + }]; + response = { + responses: [{ + aggregations: { + "3": { + buckets: [ + { + "1": {values: {"75": 3.3, "90": 5.5}}, + doc_count: 10, + key: 1000 + }, + { + "1": {values: {"75": 2.3, "90": 4.5}}, + doc_count: 15, + key: 2000 + } + ] + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 2 series', function() { + expect(result.data.length).to.be(2); + expect(result.data[0].datapoints.length).to.be(2); + expect(result.data[0].target).to.be('p75'); + expect(result.data[1].target).to.be('p90'); + expect(result.data[0].datapoints[0][0]).to.be(3.3); + expect(result.data[0].datapoints[0][1]).to.be(1000); + expect(result.data[1].datapoints[1][0]).to.be(4.5); + }); + }); + + describe('with extended_stats', function() { + var result; + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'extended_stats', meta: {max: true, std_deviation_bounds_upper: true}, id: '1'}], + bucketAggs: [{type: 'terms', field: 'host', id: '3'}, {type: 'date_histogram', id: '4'}], + }]; + response = { + responses: [{ + aggregations: { + "3": { + buckets: [ + { + key: 'server1', + "4": { + buckets: [{ + "1": {max: 10.2, min: 5.5, std_deviation_bounds: {upper: 3, lower: -2}}, + doc_count: 10, + key: 1000 + }] + } + }, + { + key: 'server2', + "4": { + buckets: [{ + "1": {max: 10.2, min: 5.5, std_deviation_bounds: {upper: 3, lower: -2}}, + doc_count: 10, + key: 1000 + }] + } + }, + ] + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 4 series', function() { + expect(result.data.length).to.be(4); + expect(result.data[0].datapoints.length).to.be(1); + expect(result.data[0].target).to.be('server1 Max'); + expect(result.data[1].target).to.be('server1 Std Dev Upper'); + + expect(result.data[0].datapoints[0][0]).to.be(10.2); + expect(result.data[1].datapoints[0][0]).to.be(3); + }); + }); + + describe('single group by with alias pattern', function() { + var result; + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'count', id: '1'}], + alias: '{{term @host}} {{metric}} and!', + bucketAggs: [ + {type: 'terms', field: '@host', id: '2'}, + {type: 'date_histogram', field: '@timestamp', id: '3'} + ], + }]; + response = { + responses: [{ + aggregations: { + "2": { + buckets: [ + { + "3": { + buckets: [ + {doc_count: 1, key: 1000}, + {doc_count: 3, key: 2000} + ] + }, + doc_count: 4, + key: 'server1', + }, + { + "3": { + buckets: [ + {doc_count: 2, key: 1000}, + {doc_count: 8, key: 2000} + ] + }, + doc_count: 10, + key: 'server2', + }, + ] + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 2 series', function() { + expect(result.data.length).to.be(2); + expect(result.data[0].datapoints.length).to.be(2); + expect(result.data[0].target).to.be('server1 Count and!'); + expect(result.data[1].target).to.be('server2 Count and!'); + }); + }); + + describe('with two filters agg', function() { + var result; + + beforeEach(function() { + targets = [{ + refId: 'A', + metrics: [{type: 'count', id: '1'}], + bucketAggs: [ + { + id: '2', + type: 'filters', + settings: { + filters: [ + {query: '@metric:cpu' }, + {query: '@metric:logins.count' }, + ] + } + }, + {type: 'date_histogram', field: '@timestamp', id: '3'} + ], + }]; + response = { + responses: [{ + aggregations: { + "2": { + buckets: { + "@metric:cpu": { + "3": { + buckets: [ + {doc_count: 1, key: 1000}, + {doc_count: 3, key: 2000} + ] + }, + }, + "@metric:logins.count": { + "3": { + buckets: [ + {doc_count: 2, key: 1000}, + {doc_count: 8, key: 2000} + ] + }, + }, + } + } + } + }] + }; + + result = new ElasticResponse(targets, response).getTimeSeries(); + }); + + it('should return 2 series', function() { + expect(result.data.length).to.be(2); + expect(result.data[0].datapoints.length).to.be(2); + expect(result.data[0].target).to.be('@metric:cpu'); + expect(result.data[1].target).to.be('@metric:logins.count'); + }); + }); + +}); diff --git a/public/app/plugins/datasource/elasticsearch/specs/index_pattern_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/index_pattern_specs.ts new file mode 100644 index 00000000000..8f662bb075f --- /dev/null +++ b/public/app/plugins/datasource/elasticsearch/specs/index_pattern_specs.ts @@ -0,0 +1,51 @@ +/// +/// + +import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'; +import moment = require('moment'); + +declare var IndexPattern: any; + +describe('IndexPattern', function() { + + describe('when getting index for today', function() { + it('should return correct index name', function() { + var pattern = new IndexPattern('[asd-]YYYY.MM.DD', 'Daily'); + var expected = 'asd-' + moment().format('YYYY.MM.DD'); + + expect(pattern.getIndexForToday()).to.be(expected); + }); + }); + + describe('when getting index list for time range', function() { + + describe('no interval', function() { + it('should return correct index', function() { + var pattern = new IndexPattern('my-metrics'); + var from = new Date(2015, 4, 30, 1, 2, 3); + var to = new Date(2015, 5, 1, 12, 5 , 6); + expect(pattern.getIndexList(from, to)).to.eql('my-metrics'); + }); + }); + + describe('daily', function() { + + it('should return correct index list', function() { + var pattern = new IndexPattern('[asd-]YYYY.MM.DD', 'Daily'); + var from = new Date(1432940523000); + var to = new Date(1433153106000); + + var expected = [ + 'asd-2015.05.29', + 'asd-2015.05.30', + 'asd-2015.05.31', + 'asd-2015.06.01', + ]; + + expect(pattern.getIndexList(from, to)).to.eql(expected); + }); + + }); + }); + +}); diff --git a/public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts new file mode 100644 index 00000000000..c32b1463ca3 --- /dev/null +++ b/public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts @@ -0,0 +1,123 @@ +/// + +import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'; + +declare var ElasticQueryBuilder: any; + +describe('ElasticQueryBuilder', function() { + var builder; + + beforeEach(function() { + builder = new ElasticQueryBuilder({timeField: '@timestamp'}); + }); + + it('with defaults', function() { + var query = builder.build({ + metrics: [{type: 'Count', id: '0'}], + timeField: '@timestamp', + bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '1'}], + }); + + expect(query.query.filtered.filter.bool.must[0].range["@timestamp"].gte).to.be("$timeFrom"); + expect(query.aggs["1"].date_histogram.extended_bounds.min).to.be("$timeFrom"); + }); + + it('with raw query', function() { + var query = builder.build({ + rawQuery: '{"query": "$lucene_query"}', + }); + + expect(query.query).to.be("$lucene_query"); + }); + + it('with multiple bucket aggs', function() { + var query = builder.build({ + metrics: [{type: 'count', id: '1'}], + timeField: '@timestamp', + bucketAggs: [ + {type: 'terms', field: '@host', id: '2'}, + {type: 'date_histogram', field: '@timestamp', id: '3'} + ], + }); + + expect(query.aggs["2"].terms.field).to.be("@host"); + expect(query.aggs["2"].aggs["3"].date_histogram.field).to.be("@timestamp"); + }); + + it('with select field', function() { + var query = builder.build({ + metrics: [{type: 'avg', field: '@value', id: '1'}], + bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}], + }, 100, 1000); + + var aggs = query.aggs["2"].aggs; + expect(aggs["1"].avg.field).to.be("@value"); + }); + + it('with term agg and order by metric agg', function() { + var query = builder.build({ + metrics: [ + {type: 'count', id: '1'}, + {type: 'avg', field: '@value', id: '5'} + ], + bucketAggs: [ + {type: 'terms', field: '@host', settings: {size: 5, order: 'asc', orderBy: '5'}, id: '2' }, + {type: 'date_histogram', field: '@timestamp', id: '3'} + ], + }, 100, 1000); + + var firstLevel = query.aggs["2"]; + var secondLevel = firstLevel.aggs["3"]; + + expect(firstLevel.aggs["5"].avg.field).to.be("@value"); + expect(secondLevel.aggs["5"].avg.field).to.be("@value"); + }); + + it('with metric percentiles', function() { + var query = builder.build({ + metrics: [ + { + id: '1', + type: 'percentiles', + field: '@load_time', + settings: { + percents: [1,2,3,4] + } + } + ], + bucketAggs: [ + {type: 'date_histogram', field: '@timestamp', id: '3'} + ], + }, 100, 1000); + + var firstLevel = query.aggs["3"]; + + expect(firstLevel.aggs["1"].percentiles.field).to.be("@load_time"); + expect(firstLevel.aggs["1"].percentiles.percents).to.eql([1,2,3,4]); + }); + + it('with filters aggs', function() { + var query = builder.build({ + metrics: [{type: 'count', id: '1'}], + timeField: '@timestamp', + bucketAggs: [ + { + id: '2', + type: 'filters', + settings: { + filters: [ + {query: '@metric:cpu' }, + {query: '@metric:logins.count' }, + ] + } + }, + {type: 'date_histogram', field: '@timestamp', id: '4'} + ], + }); + + expect(query.aggs["2"].filters.filters["@metric:cpu"].query.query_string.query).to.be("@metric:cpu"); + expect(query.aggs["2"].filters.filters["@metric:logins.count"].query.query_string.query).to.be("@metric:logins.count"); + expect(query.aggs["2"].aggs["4"].date_histogram.field).to.be("@timestamp"); + }); + +}); diff --git a/public/app/plugins/datasource/elasticsearch/specs/query_ctrl_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/query_ctrl_specs.ts new file mode 100644 index 00000000000..d88e8446ead --- /dev/null +++ b/public/app/plugins/datasource/elasticsearch/specs/query_ctrl_specs.ts @@ -0,0 +1,30 @@ +/// +/// +/// + +import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common'; + +declare var helpers: any; + +describe('ElasticQueryCtrl', function() { + var ctx = new helpers.ControllerTestContext(); + + beforeEach(angularMocks.module('grafana.controllers')); + beforeEach(angularMocks.module('grafana.services')); + beforeEach(ctx.providePhase()); + beforeEach(ctx.createControllerPhase('ElasticQueryCtrl')); + + beforeEach(function() { + ctx.scope.target = {}; + ctx.scope.$parent = { get_data: sinon.spy() }; + + ctx.scope.datasource = ctx.datasource; + ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([])); + }); + + describe('init', function() { + beforeEach(function() { + ctx.scope.init(); + }); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/specs/query_builder_specs.ts b/public/app/plugins/datasource/influxdb/specs/query_builder_specs.ts index 024712341cc..65a2f453385 100644 --- a/public/app/plugins/datasource/influxdb/specs/query_builder_specs.ts +++ b/public/app/plugins/datasource/influxdb/specs/query_builder_specs.ts @@ -1,5 +1,5 @@ /// -// + import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'; declare var InfluxQueryBuilder: any; diff --git a/public/test/specs/elasticsearch-indexPattern-specs.js b/public/test/specs/elasticsearch-indexPattern-specs.js deleted file mode 100644 index 7a93c7be3a1..00000000000 --- a/public/test/specs/elasticsearch-indexPattern-specs.js +++ /dev/null @@ -1,52 +0,0 @@ -define([ - 'moment', - 'app/plugins/datasource/elasticsearch/indexPattern' -], function(moment, IndexPattern) { - 'use strict'; - - describe('IndexPattern', function() { - - describe('when getting index for today', function() { - it('should return correct index name', function() { - var pattern = new IndexPattern('[asd-]YYYY.MM.DD', 'Daily'); - var expected = 'asd-' + moment().format('YYYY.MM.DD'); - - expect(pattern.getIndexForToday()).to.be(expected); - }); - }); - - describe('when getting index list for time range', function() { - - describe('no interval', function() { - it('should return correct index', function() { - var pattern = new IndexPattern('my-metrics'); - var from = new Date(2015, 4, 30, 1, 2, 3); - var to = new Date(2015, 5, 1, 12, 5 , 6); - expect(pattern.getIndexList(from, to)).to.eql('my-metrics'); - }); - }); - - describe('daily', function() { - - it('should return correct index list', function() { - var pattern = new IndexPattern('[asd-]YYYY.MM.DD', 'Daily'); - var from = new Date(1432940523000); - var to = new Date(1433153106000); - - var expected = [ - 'asd-2015.05.29', - 'asd-2015.05.30', - 'asd-2015.05.31', - 'asd-2015.06.01', - ]; - - expect(pattern.getIndexList(from, to)).to.eql(expected); - }); - - }); - - }); - - }); - -}); diff --git a/public/test/specs/elasticsearch-querybuilder-specs.js b/public/test/specs/elasticsearch-querybuilder-specs.js deleted file mode 100644 index 467d3706e03..00000000000 --- a/public/test/specs/elasticsearch-querybuilder-specs.js +++ /dev/null @@ -1,124 +0,0 @@ -define([ - 'app/plugins/datasource/elasticsearch/queryBuilder' -], function(ElasticQueryBuilder) { - 'use strict'; - - describe('ElasticQueryBuilder', function() { - var builder; - - beforeEach(function() { - builder = new ElasticQueryBuilder({timeField: '@timestamp'}); - }); - - it('with defaults', function() { - var query = builder.build({ - metrics: [{type: 'Count', id: '0'}], - timeField: '@timestamp', - bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '1'}], - }); - - expect(query.query.filtered.filter.bool.must[0].range["@timestamp"].gte).to.be("$timeFrom"); - expect(query.aggs["1"].date_histogram.extended_bounds.min).to.be("$timeFrom"); - }); - - it('with raw query', function() { - var query = builder.build({ - rawQuery: '{"query": "$lucene_query"}', - }); - - expect(query.query).to.be("$lucene_query"); - }); - - it('with multiple bucket aggs', function() { - var query = builder.build({ - metrics: [{type: 'count', id: '1'}], - timeField: '@timestamp', - bucketAggs: [ - {type: 'terms', field: '@host', id: '2'}, - {type: 'date_histogram', field: '@timestamp', id: '3'} - ], - }); - - expect(query.aggs["2"].terms.field).to.be("@host"); - expect(query.aggs["2"].aggs["3"].date_histogram.field).to.be("@timestamp"); - }); - - it('with select field', function() { - var query = builder.build({ - metrics: [{type: 'avg', field: '@value', id: '1'}], - bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}], - }, 100, 1000); - - var aggs = query.aggs["2"].aggs; - expect(aggs["1"].avg.field).to.be("@value"); - }); - - it('with term agg and order by metric agg', function() { - var query = builder.build({ - metrics: [ - {type: 'count', id: '1'}, - {type: 'avg', field: '@value', id: '5'} - ], - bucketAggs: [ - {type: 'terms', field: '@host', settings: {size: 5, order: 'asc', orderBy: '5'}, id: '2' }, - {type: 'date_histogram', field: '@timestamp', id: '3'} - ], - }, 100, 1000); - - var firstLevel = query.aggs["2"]; - var secondLevel = firstLevel.aggs["3"]; - - expect(firstLevel.aggs["5"].avg.field).to.be("@value"); - expect(secondLevel.aggs["5"].avg.field).to.be("@value"); - }); - - it('with metric percentiles', function() { - var query = builder.build({ - metrics: [ - { - id: '1', - type: 'percentiles', - field: '@load_time', - settings: { - percents: [1,2,3,4] - } - } - ], - bucketAggs: [ - {type: 'date_histogram', field: '@timestamp', id: '3'} - ], - }, 100, 1000); - - var firstLevel = query.aggs["3"]; - - expect(firstLevel.aggs["1"].percentiles.field).to.be("@load_time"); - expect(firstLevel.aggs["1"].percentiles.percents).to.eql([1,2,3,4]); - }); - - it('with filters aggs', function() { - var query = builder.build({ - metrics: [{type: 'count', id: '1'}], - timeField: '@timestamp', - bucketAggs: [ - { - id: '2', - type: 'filters', - settings: { - filters: [ - {query: '@metric:cpu' }, - {query: '@metric:logins.count' }, - ] - } - }, - {type: 'date_histogram', field: '@timestamp', id: '4'} - ], - }); - - expect(query.aggs["2"].filters.filters["@metric:cpu"].query.query_string.query).to.be("@metric:cpu"); - expect(query.aggs["2"].filters.filters["@metric:logins.count"].query.query_string.query).to.be("@metric:logins.count"); - expect(query.aggs["2"].aggs["4"].date_histogram.field).to.be("@timestamp"); - }); - - }); - -}); diff --git a/public/test/specs/elasticsearch-queryctrl-specs.js b/public/test/specs/elasticsearch-queryctrl-specs.js deleted file mode 100644 index 3cda8e23350..00000000000 --- a/public/test/specs/elasticsearch-queryctrl-specs.js +++ /dev/null @@ -1,32 +0,0 @@ -define([ - './helpers', - 'app/plugins/datasource/elasticsearch/queryCtrl', - 'app/services/uiSegmentSrv' -], function(helpers) { - 'use strict'; - - describe('ElasticQueryCtrl', function() { - var ctx = new helpers.ControllerTestContext(); - - beforeEach(module('grafana.controllers')); - beforeEach(module('grafana.services')); - beforeEach(ctx.providePhase()); - beforeEach(ctx.createControllerPhase('ElasticQueryCtrl')); - - beforeEach(function() { - ctx.scope.target = {}; - ctx.scope.$parent = { get_data: sinon.spy() }; - - ctx.scope.datasource = ctx.datasource; - ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([])); - }); - - describe('init', function() { - beforeEach(function() { - ctx.scope.init(); - }); - - }); - - }); -}); diff --git a/public/test/specs/elasticsearch-response-specs.js b/public/test/specs/elasticsearch-response-specs.js deleted file mode 100644 index fe465df3129..00000000000 --- a/public/test/specs/elasticsearch-response-specs.js +++ /dev/null @@ -1,414 +0,0 @@ -define([ - 'app/plugins/datasource/elasticsearch/elasticResponse', -], function(ElasticResponse) { - 'use strict'; - - describe('ElasticResponse', function() { - var targets; - var response; - var result; - - describe('simple query and count', function() { - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'count', id: '1'}], - bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}], - }]; - response = { - responses: [{ - aggregations: { - "2": { - buckets: [ - { - doc_count: 10, - key: 1000 - }, - { - doc_count: 15, - key: 2000 - } - ] - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 1 series', function() { - expect(result.data.length).to.be(1); - expect(result.data[0].target).to.be('Count'); - expect(result.data[0].datapoints.length).to.be(2); - expect(result.data[0].datapoints[0][0]).to.be(10); - expect(result.data[0].datapoints[0][1]).to.be(1000); - }); - - }); - - describe('simple query count & avg aggregation', function() { - var result; - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'count', id: '1'}, {type: 'avg', field: 'value', id: '2'}], - bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}], - }]; - response = { - responses: [{ - aggregations: { - "3": { - buckets: [ - { - "2": {value: 88}, - doc_count: 10, - key: 1000 - }, - { - "2": {value: 99}, - doc_count: 15, - key: 2000 - } - ] - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 2 series', function() { - expect(result.data.length).to.be(2); - expect(result.data[0].datapoints.length).to.be(2); - expect(result.data[0].datapoints[0][0]).to.be(10); - expect(result.data[0].datapoints[0][1]).to.be(1000); - - expect(result.data[1].target).to.be("Average value"); - expect(result.data[1].datapoints[0][0]).to.be(88); - expect(result.data[1].datapoints[1][0]).to.be(99); - }); - - }); - - describe('single group by query one metric', function() { - var result; - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'count', id: '1'}], - bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}], - }]; - response = { - responses: [{ - aggregations: { - "2": { - buckets: [ - { - "3": { - buckets: [ - {doc_count: 1, key: 1000}, - {doc_count: 3, key: 2000} - ] - }, - doc_count: 4, - key: 'server1', - }, - { - "3": { - buckets: [ - {doc_count: 2, key: 1000}, - {doc_count: 8, key: 2000} - ] - }, - doc_count: 10, - key: 'server2', - }, - ] - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 2 series', function() { - expect(result.data.length).to.be(2); - expect(result.data[0].datapoints.length).to.be(2); - expect(result.data[0].target).to.be('server1'); - expect(result.data[1].target).to.be('server2'); - }); - }); - - describe('single group by query two metrics', function() { - var result; - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'count', id: '1'}, {type: 'avg', field: '@value', id: '4'}], - bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}], - }]; - response = { - responses: [{ - aggregations: { - "2": { - buckets: [ - { - "3": { - buckets: [ - { "4": {value: 10}, doc_count: 1, key: 1000}, - { "4": {value: 12}, doc_count: 3, key: 2000} - ] - }, - doc_count: 4, - key: 'server1', - }, - { - "3": { - buckets: [ - { "4": {value: 20}, doc_count: 1, key: 1000}, - { "4": {value: 32}, doc_count: 3, key: 2000} - ] - }, - doc_count: 10, - key: 'server2', - }, - ] - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 2 series', function() { - expect(result.data.length).to.be(4); - expect(result.data[0].datapoints.length).to.be(2); - expect(result.data[0].target).to.be('server1 Count'); - expect(result.data[1].target).to.be('server1 Average @value'); - expect(result.data[2].target).to.be('server2 Count'); - expect(result.data[3].target).to.be('server2 Average @value'); - }); - }); - - describe('with percentiles ', function() { - var result; - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'percentiles', settings: {percents: [75, 90]}, id: '1'}], - bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}], - }]; - response = { - responses: [{ - aggregations: { - "3": { - buckets: [ - { - "1": {values: {"75": 3.3, "90": 5.5}}, - doc_count: 10, - key: 1000 - }, - { - "1": {values: {"75": 2.3, "90": 4.5}}, - doc_count: 15, - key: 2000 - } - ] - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 2 series', function() { - expect(result.data.length).to.be(2); - expect(result.data[0].datapoints.length).to.be(2); - expect(result.data[0].target).to.be('p75'); - expect(result.data[1].target).to.be('p90'); - expect(result.data[0].datapoints[0][0]).to.be(3.3); - expect(result.data[0].datapoints[0][1]).to.be(1000); - expect(result.data[1].datapoints[1][0]).to.be(4.5); - }); - }); - - describe('with extended_stats', function() { - var result; - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'extended_stats', meta: {max: true, std_deviation_bounds_upper: true}, id: '1'}], - bucketAggs: [{type: 'terms', field: 'host', id: '3'}, {type: 'date_histogram', id: '4'}], - }]; - response = { - responses: [{ - aggregations: { - "3": { - buckets: [ - { - key: 'server1', - "4": { - buckets: [{ - "1": {max: 10.2, min: 5.5, std_deviation_bounds: {upper: 3, lower: -2}}, - doc_count: 10, - key: 1000 - }] - } - }, - { - key: 'server2', - "4": { - buckets: [{ - "1": {max: 10.2, min: 5.5, std_deviation_bounds: {upper: 3, lower: -2}}, - doc_count: 10, - key: 1000 - }] - } - }, - ] - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 4 series', function() { - expect(result.data.length).to.be(4); - expect(result.data[0].datapoints.length).to.be(1); - expect(result.data[0].target).to.be('server1 Max'); - expect(result.data[1].target).to.be('server1 Std Dev Upper'); - - expect(result.data[0].datapoints[0][0]).to.be(10.2); - expect(result.data[1].datapoints[0][0]).to.be(3); - }); - }); - - describe('single group by with alias pattern', function() { - var result; - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'count', id: '1'}], - alias: '{{term @host}} {{metric}} and!', - bucketAggs: [ - {type: 'terms', field: '@host', id: '2'}, - {type: 'date_histogram', field: '@timestamp', id: '3'} - ], - }]; - response = { - responses: [{ - aggregations: { - "2": { - buckets: [ - { - "3": { - buckets: [ - {doc_count: 1, key: 1000}, - {doc_count: 3, key: 2000} - ] - }, - doc_count: 4, - key: 'server1', - }, - { - "3": { - buckets: [ - {doc_count: 2, key: 1000}, - {doc_count: 8, key: 2000} - ] - }, - doc_count: 10, - key: 'server2', - }, - ] - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 2 series', function() { - expect(result.data.length).to.be(2); - expect(result.data[0].datapoints.length).to.be(2); - expect(result.data[0].target).to.be('server1 Count and!'); - expect(result.data[1].target).to.be('server2 Count and!'); - }); - }); - - describe('with two filters agg', function() { - var result; - - beforeEach(function() { - targets = [{ - refId: 'A', - metrics: [{type: 'count', id: '1'}], - bucketAggs: [ - { - id: '2', - type: 'filters', - settings: { - filters: [ - {query: '@metric:cpu' }, - {query: '@metric:logins.count' }, - ] - } - }, - {type: 'date_histogram', field: '@timestamp', id: '3'} - ], - }]; - response = { - responses: [{ - aggregations: { - "2": { - buckets: { - "@metric:cpu": { - "3": { - buckets: [ - {doc_count: 1, key: 1000}, - {doc_count: 3, key: 2000} - ] - }, - }, - "@metric:logins.count": { - "3": { - buckets: [ - {doc_count: 2, key: 1000}, - {doc_count: 8, key: 2000} - ] - }, - }, - } - } - } - }] - }; - - result = new ElasticResponse(targets, response).getTimeSeries(); - }); - - it('should return 2 series', function() { - expect(result.data.length).to.be(2); - expect(result.data[0].datapoints.length).to.be(2); - expect(result.data[0].target).to.be('@metric:cpu'); - expect(result.data[1].target).to.be('@metric:logins.count'); - }); - }); - - }); -}); diff --git a/public/test/specs/elasticsearch-specs.js b/public/test/specs/elasticsearch-specs.js deleted file mode 100644 index 784108a2fd0..00000000000 --- a/public/test/specs/elasticsearch-specs.js +++ /dev/null @@ -1,77 +0,0 @@ -define([ - './helpers', - 'moment', - 'angular', - 'app/plugins/datasource/elasticsearch/datasource', -], function(helpers, moment, angular) { - 'use strict'; - - describe('ElasticDatasource', function() { - var ctx = new helpers.ServiceTestContext(); - - beforeEach(module('grafana.services')); - beforeEach(ctx.providePhase(['templateSrv', 'backendSrv'])); - beforeEach(ctx.createService('ElasticDatasource')); - beforeEach(function() { - ctx.ds = new ctx.service({jsonData: {}}); - }); - - describe('When testing datasource with index pattern', function() { - beforeEach(function() { - ctx.ds = new ctx.service({ - url: 'http://es.com', - index: '[asd-]YYYY.MM.DD', - jsonData: { interval: 'Daily' } - }); - }); - - it('should translate index pattern to current day', function() { - var requestOptions; - ctx.backendSrv.datasourceRequest = function(options) { - requestOptions = options; - return ctx.$q.when({}); - }; - - ctx.ds.testDatasource(); - ctx.$rootScope.$apply(); - - var today = moment().format("YYYY.MM.DD"); - expect(requestOptions.url).to.be("http://es.com/asd-" + today + '/_stats'); - }); - }); - - describe('When issueing metric query with interval pattern', function() { - beforeEach(function() { - ctx.ds = new ctx.service({ - url: 'http://es.com', - index: '[asd-]YYYY.MM.DD', - jsonData: { interval: 'Daily' } - }); - }); - - it('should translate index pattern to current day', function() { - var requestOptions; - ctx.backendSrv.datasourceRequest = function(options) { - requestOptions = options; - return ctx.$q.when({data: {responses: []}}); - }; - - ctx.ds.query({ - range: { - from: moment([2015, 4, 30, 10]), - to: moment([2015, 5, 1, 10]) - }, - targets: [{ bucketAggs: [], metrics: [] }] - }); - - ctx.$rootScope.$apply(); - var parts = requestOptions.data.split('\n'); - var header = angular.fromJson(parts[0]); - expect(header.index).to.eql(['asd-2015.05.30', 'asd-2015.05.31', 'asd-2015.06.01']); - }); - - }); - - }); - -});