|
@@ -1,20 +1,25 @@
|
|
|
-import angular from 'angular';
|
|
|
|
|
|
|
+import angular, { IQService } from 'angular';
|
|
|
import * as dateMath from '@grafana/ui/src/utils/datemath';
|
|
import * as dateMath from '@grafana/ui/src/utils/datemath';
|
|
|
import _ from 'lodash';
|
|
import _ from 'lodash';
|
|
|
import { ElasticDatasource } from '../datasource';
|
|
import { ElasticDatasource } from '../datasource';
|
|
|
import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper';
|
|
import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper';
|
|
|
|
|
+import { BackendSrv } from 'app/core/services/backend_srv';
|
|
|
|
|
+import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
|
|
|
|
+import { TemplateSrv } from 'app/features/templating/template_srv';
|
|
|
|
|
+import { DataSourceInstanceSettings } from '@grafana/ui';
|
|
|
|
|
+import { ElasticsearchOptions } from '../types';
|
|
|
|
|
|
|
|
describe('ElasticDatasource', function(this: any) {
|
|
describe('ElasticDatasource', function(this: any) {
|
|
|
- const backendSrv = {
|
|
|
|
|
|
|
+ const backendSrv: any = {
|
|
|
datasourceRequest: jest.fn(),
|
|
datasourceRequest: jest.fn(),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const $rootScope = {
|
|
|
|
|
|
|
+ const $rootScope: any = {
|
|
|
$on: jest.fn(),
|
|
$on: jest.fn(),
|
|
|
appEvent: jest.fn(),
|
|
appEvent: jest.fn(),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const templateSrv = {
|
|
|
|
|
|
|
+ const templateSrv: any = {
|
|
|
replace: jest.fn(text => {
|
|
replace: jest.fn(text => {
|
|
|
if (text.startsWith('$')) {
|
|
if (text.startsWith('$')) {
|
|
|
return `resolvedVariable`;
|
|
return `resolvedVariable`;
|
|
@@ -25,12 +30,12 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
getAdhocFilters: jest.fn(() => []),
|
|
getAdhocFilters: jest.fn(() => []),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- const timeSrv = {
|
|
|
|
|
|
|
+ const timeSrv: any = {
|
|
|
time: { from: 'now-1h', to: 'now' },
|
|
time: { from: 'now-1h', to: 'now' },
|
|
|
timeRange: jest.fn(() => {
|
|
timeRange: jest.fn(() => {
|
|
|
return {
|
|
return {
|
|
|
- from: dateMath.parse(this.time.from, false),
|
|
|
|
|
- to: dateMath.parse(this.time.to, true),
|
|
|
|
|
|
|
+ from: dateMath.parse(timeSrv.time.from, false),
|
|
|
|
|
+ to: dateMath.parse(timeSrv.time.to, true),
|
|
|
};
|
|
};
|
|
|
}),
|
|
}),
|
|
|
setTime: jest.fn(time => {
|
|
setTime: jest.fn(time => {
|
|
@@ -43,18 +48,24 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
backendSrv,
|
|
backendSrv,
|
|
|
} as any;
|
|
} as any;
|
|
|
|
|
|
|
|
- function createDatasource(instanceSettings) {
|
|
|
|
|
- instanceSettings.jsonData = instanceSettings.jsonData || {};
|
|
|
|
|
- ctx.ds = new ElasticDatasource(instanceSettings, {}, backendSrv, templateSrv, timeSrv);
|
|
|
|
|
|
|
+ function createDatasource(instanceSettings: DataSourceInstanceSettings<ElasticsearchOptions>) {
|
|
|
|
|
+ instanceSettings.jsonData = instanceSettings.jsonData || ({} as ElasticsearchOptions);
|
|
|
|
|
+ ctx.ds = new ElasticDatasource(
|
|
|
|
|
+ instanceSettings,
|
|
|
|
|
+ {} as IQService,
|
|
|
|
|
+ backendSrv as BackendSrv,
|
|
|
|
|
+ templateSrv as TemplateSrv,
|
|
|
|
|
+ timeSrv as TimeSrv
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
describe('When testing datasource with index pattern', () => {
|
|
describe('When testing datasource with index pattern', () => {
|
|
|
beforeEach(() => {
|
|
beforeEach(() => {
|
|
|
createDatasource({
|
|
createDatasource({
|
|
|
url: 'http://es.com',
|
|
url: 'http://es.com',
|
|
|
- index: '[asd-]YYYY.MM.DD',
|
|
|
|
|
- jsonData: { interval: 'Daily', esVersion: '2' },
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ database: '[asd-]YYYY.MM.DD',
|
|
|
|
|
+ jsonData: { interval: 'Daily', esVersion: 2 } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
it('should translate index pattern to current day', () => {
|
|
it('should translate index pattern to current day', () => {
|
|
@@ -77,9 +88,9 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
beforeEach(async () => {
|
|
beforeEach(async () => {
|
|
|
createDatasource({
|
|
createDatasource({
|
|
|
url: 'http://es.com',
|
|
url: 'http://es.com',
|
|
|
- index: '[asd-]YYYY.MM.DD',
|
|
|
|
|
- jsonData: { interval: 'Daily', esVersion: '2' },
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ database: '[asd-]YYYY.MM.DD',
|
|
|
|
|
+ jsonData: { interval: 'Daily', esVersion: 2 } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
|
|
|
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
|
requestOptions = options;
|
|
requestOptions = options;
|
|
@@ -142,15 +153,110 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ describe('When issuing logs query with interval pattern', () => {
|
|
|
|
|
+ let query, queryBuilderSpy;
|
|
|
|
|
+
|
|
|
|
|
+ beforeEach(async () => {
|
|
|
|
|
+ createDatasource({
|
|
|
|
|
+ url: 'http://es.com',
|
|
|
|
|
+ database: 'mock-index',
|
|
|
|
|
+ jsonData: { interval: 'Daily', esVersion: 2, timeField: '@timestamp' } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
|
|
+
|
|
|
|
|
+ ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
|
|
|
+ return Promise.resolve({
|
|
|
|
|
+ data: {
|
|
|
|
|
+ responses: [
|
|
|
|
|
+ {
|
|
|
|
|
+ aggregations: {
|
|
|
|
|
+ '2': {
|
|
|
|
|
+ buckets: [
|
|
|
|
|
+ {
|
|
|
|
|
+ doc_count: 10,
|
|
|
|
|
+ key: 1000,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ doc_count: 15,
|
|
|
|
|
+ key: 2000,
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ hits: {
|
|
|
|
|
+ hits: [
|
|
|
|
|
+ {
|
|
|
|
|
+ '@timestamp': ['2019-06-24T09:51:19.765Z'],
|
|
|
|
|
+ _id: 'fdsfs',
|
|
|
|
|
+ _type: '_doc',
|
|
|
|
|
+ _index: 'mock-index',
|
|
|
|
|
+ _source: {
|
|
|
|
|
+ '@timestamp': '2019-06-24T09:51:19.765Z',
|
|
|
|
|
+ host: 'djisaodjsoad',
|
|
|
|
|
+ message: 'hello, i am a message',
|
|
|
|
|
+ },
|
|
|
|
|
+ fields: {
|
|
|
|
|
+ '@timestamp': ['2019-06-24T09:51:19.765Z'],
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ '@timestamp': ['2019-06-24T09:52:19.765Z'],
|
|
|
|
|
+ _id: 'kdospaidopa',
|
|
|
|
|
+ _type: '_doc',
|
|
|
|
|
+ _index: 'mock-index',
|
|
|
|
|
+ _source: {
|
|
|
|
|
+ '@timestamp': '2019-06-24T09:52:19.765Z',
|
|
|
|
|
+ host: 'dsalkdakdop',
|
|
|
|
|
+ message: 'hello, i am also message',
|
|
|
|
|
+ },
|
|
|
|
|
+ fields: {
|
|
|
|
|
+ '@timestamp': ['2019-06-24T09:52:19.765Z'],
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ query = {
|
|
|
|
|
+ range: {
|
|
|
|
|
+ from: toUtc([2015, 4, 30, 10]),
|
|
|
|
|
+ to: toUtc([2019, 7, 1, 10]),
|
|
|
|
|
+ },
|
|
|
|
|
+ targets: [
|
|
|
|
|
+ {
|
|
|
|
|
+ alias: '$varAlias',
|
|
|
|
|
+ refId: 'A',
|
|
|
|
|
+ bucketAggs: [{ type: 'date_histogram', settings: { interval: 'auto' }, id: '2' }],
|
|
|
|
|
+ metrics: [{ type: 'count', id: '1' }],
|
|
|
|
|
+ query: 'escape\\:test',
|
|
|
|
|
+ interval: '10s',
|
|
|
|
|
+ isLogsQuery: true,
|
|
|
|
|
+ timeField: '@timestamp',
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ queryBuilderSpy = jest.spyOn(ctx.ds.queryBuilder, 'getLogsQuery');
|
|
|
|
|
+ await ctx.ds.query(query);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ it('should call getLogsQuery()', () => {
|
|
|
|
|
+ expect(queryBuilderSpy).toHaveBeenCalled();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
describe('When issuing document query', () => {
|
|
describe('When issuing document query', () => {
|
|
|
let requestOptions, parts, header;
|
|
let requestOptions, parts, header;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
beforeEach(() => {
|
|
|
createDatasource({
|
|
createDatasource({
|
|
|
url: 'http://es.com',
|
|
url: 'http://es.com',
|
|
|
- index: 'test',
|
|
|
|
|
- jsonData: { esVersion: '2' },
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ database: 'test',
|
|
|
|
|
+ jsonData: { esVersion: 2 } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
|
|
|
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
|
requestOptions = options;
|
|
requestOptions = options;
|
|
@@ -187,7 +293,11 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
|
|
|
|
|
describe('When getting fields', () => {
|
|
describe('When getting fields', () => {
|
|
|
beforeEach(() => {
|
|
beforeEach(() => {
|
|
|
- createDatasource({ url: 'http://es.com', index: 'metricbeat', jsonData: { esVersion: 50 } });
|
|
|
|
|
|
|
+ createDatasource({
|
|
|
|
|
+ url: 'http://es.com',
|
|
|
|
|
+ database: 'metricbeat',
|
|
|
|
|
+ jsonData: { esVersion: 50 } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
|
|
|
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
|
return Promise.resolve({
|
|
return Promise.resolve({
|
|
@@ -279,7 +389,11 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
|
|
|
|
|
describe('When getting fields from ES 7.0', () => {
|
|
describe('When getting fields from ES 7.0', () => {
|
|
|
beforeEach(() => {
|
|
beforeEach(() => {
|
|
|
- createDatasource({ url: 'http://es.com', index: 'genuine.es7._mapping.response', jsonData: { esVersion: 70 } });
|
|
|
|
|
|
|
+ createDatasource({
|
|
|
|
|
+ url: 'http://es.com',
|
|
|
|
|
+ database: 'genuine.es7._mapping.response',
|
|
|
|
|
+ jsonData: { esVersion: 70 } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
|
|
|
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
|
return Promise.resolve({
|
|
return Promise.resolve({
|
|
@@ -430,9 +544,9 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
beforeEach(() => {
|
|
beforeEach(() => {
|
|
|
createDatasource({
|
|
createDatasource({
|
|
|
url: 'http://es.com',
|
|
url: 'http://es.com',
|
|
|
- index: 'test',
|
|
|
|
|
- jsonData: { esVersion: '5' },
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ database: 'test',
|
|
|
|
|
+ jsonData: { esVersion: 5 } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
|
|
|
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
|
requestOptions = options;
|
|
requestOptions = options;
|
|
@@ -473,9 +587,9 @@ describe('ElasticDatasource', function(this: any) {
|
|
|
beforeEach(() => {
|
|
beforeEach(() => {
|
|
|
createDatasource({
|
|
createDatasource({
|
|
|
url: 'http://es.com',
|
|
url: 'http://es.com',
|
|
|
- index: 'test',
|
|
|
|
|
- jsonData: { esVersion: '5' },
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ database: 'test',
|
|
|
|
|
+ jsonData: { esVersion: 5 } as ElasticsearchOptions,
|
|
|
|
|
+ } as DataSourceInstanceSettings<ElasticsearchOptions>);
|
|
|
|
|
|
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
ctx.backendSrv.datasourceRequest = jest.fn(options => {
|
|
|
requestOptions = options;
|
|
requestOptions = options;
|