Elasticsearch: fix types in test and add mock factory (#54582)

* refactor(elastic-test): add datasource mock factory

* refactor(elastic-test): use new factory and attempt to fix some type issues

* refactor(elastic-test): type fixes

* refactor(elastic-test): update test with mock changes

* refactor(elastic-test): remove commented code

Git history should be more than enough to go back to previous revisions instead of keeping commented code.

* refactor(elastic-test): use mock factory and fix type issues in language provider test

* Chore: rename mock parameter

* Chore: remove unnecessary conditional

* Chore: remove ts-expect-error
pull/54606/head^2
Matias Chomicki 3 years ago committed by GitHub
parent 638fb5dc6d
commit 5767c01a79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      .betterer.results
  2. 282
      public/app/plugins/datasource/elasticsearch/datasource.test.ts
  3. 37
      public/app/plugins/datasource/elasticsearch/language_provider.test.ts
  4. 53
      public/app/plugins/datasource/elasticsearch/mocks.ts

@ -6225,20 +6225,6 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts:5381": [ "public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"] [0, 0, 0, "Do not use any type assertions.", "0"]
], ],
"public/app/plugins/datasource/elasticsearch/datasource.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"]
],
"public/app/plugins/datasource/elasticsearch/datasource.ts:5381": [ "public/app/plugins/datasource/elasticsearch/datasource.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@ -6325,10 +6311,6 @@ exports[`better eslint`] = {
"public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.ts:5381": [ "public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"] [0, 0, 0, "Do not use any type assertions.", "0"]
], ],
"public/app/plugins/datasource/elasticsearch/language_provider.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/elasticsearch/language_provider.ts:5381": [ "public/app/plugins/datasource/elasticsearch/language_provider.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"],

@ -6,23 +6,27 @@ import {
CoreApp, CoreApp,
DataLink, DataLink,
DataQueryRequest, DataQueryRequest,
DataQueryResponse,
DataSourceInstanceSettings, DataSourceInstanceSettings,
DataSourcePluginMeta,
dateMath, dateMath,
DateTime, DateTime,
dateTime, dateTime,
Field, Field,
MutableDataFrame, MutableDataFrame,
RawTimeRange,
TimeRange, TimeRange,
toUtc, toUtc,
} from '@grafana/data'; } from '@grafana/data';
import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; import { BackendSrvRequest, FetchResponse } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { TemplateSrv } from 'app/features/templating/template_srv';
import { createFetchResponse } from '../../../../test/helpers/createFetchResponse'; import { createFetchResponse } from '../../../../test/helpers/createFetchResponse';
import { Filters } from './components/QueryEditor/BucketAggregationsEditor/aggregations'; import { Filters } from './components/QueryEditor/BucketAggregationsEditor/aggregations';
import { ElasticDatasource, enhanceDataFrame } from './datasource'; import { ElasticDatasource, enhanceDataFrame } from './datasource';
import { createElasticDatasource } from './mocks';
import { ElasticsearchOptions, ElasticsearchQuery } from './types'; import { ElasticsearchOptions, ElasticsearchQuery } from './types';
const ELASTICSEARCH_MOCK_URL = 'http://elasticsearch.local'; const ELASTICSEARCH_MOCK_URL = 'http://elasticsearch.local';
@ -41,6 +45,17 @@ jest.mock('@grafana/runtime', () => ({
const TIMESRV_START = [2022, 8, 21, 6, 10, 10]; const TIMESRV_START = [2022, 8, 21, 6, 10, 10];
const TIMESRV_END = [2022, 8, 24, 6, 10, 21]; const TIMESRV_END = [2022, 8, 24, 6, 10, 21];
const DATAQUERY_BASE = {
requestId: '1',
interval: '',
intervalMs: 0,
scopedVars: {
test: { text: '', value: '' },
},
timezone: '',
app: 'test',
startTime: 0,
};
jest.mock('app/features/dashboard/services/TimeSrv', () => ({ jest.mock('app/features/dashboard/services/TimeSrv', () => ({
...(jest.requireActual('app/features/dashboard/services/TimeSrv') as unknown as object), ...(jest.requireActual('app/features/dashboard/services/TimeSrv') as unknown as object),
@ -58,73 +73,65 @@ const createTimeRange = (from: DateTime, to: DateTime): TimeRange => ({
}, },
}); });
interface Args { interface TestContext {
data?: any; data?: Data;
from?: string; from?: string;
jsonData?: any; jsonData?: Partial<ElasticsearchOptions>;
database?: string; database?: string;
mockImplementation?: (options: BackendSrvRequest) => Observable<FetchResponse>; fetchMockImplementation?: (options: BackendSrvRequest) => Observable<FetchResponse>;
}
interface Data {
[key: string]: undefined | string | string[] | number | Data | Data[];
} }
function getTestContext({ function getTestContext({
data = {}, data = { responses: [] },
from = 'now-5m', from = 'now-5m',
jsonData = {}, jsonData,
database = '[asd-]YYYY.MM.DD', database = '[test-]YYYY.MM.DD',
mockImplementation = undefined, fetchMockImplementation = undefined,
}: Args = {}) { }: TestContext = {}) {
jest.clearAllMocks();
const defaultMock = (options: BackendSrvRequest) => of(createFetchResponse(data)); const defaultMock = (options: BackendSrvRequest) => of(createFetchResponse(data));
const fetchMock = jest.spyOn(backendSrv, 'fetch'); const fetchMock = jest.spyOn(backendSrv, 'fetch');
fetchMock.mockImplementation(mockImplementation ?? defaultMock); fetchMock.mockImplementation(fetchMockImplementation ?? defaultMock);
const templateSrv: any = { const timeSrv = {
replace: jest.fn((text?: string) => {
if (text?.startsWith('$')) {
return `resolvedVariable`;
} else {
return text;
}
}),
getAdhocFilters: jest.fn(() => []),
};
const timeSrv: any = {
time: { from, to: 'now' }, time: { from, to: 'now' },
}; timeRange: () => ({
timeSrv.timeRange = jest.fn(() => {
return {
from: dateMath.parse(timeSrv.time.from, false), from: dateMath.parse(timeSrv.time.from, false),
to: dateMath.parse(timeSrv.time.to, true), to: dateMath.parse(timeSrv.time.to, true),
}; }),
}); setTime: (time: RawTimeRange) => {
timeSrv.time = time;
},
} as TimeSrv;
timeSrv.setTime = jest.fn((time) => { const settings: Partial<DataSourceInstanceSettings<ElasticsearchOptions>> = { url: ELASTICSEARCH_MOCK_URL };
timeSrv.time = time; settings.jsonData = jsonData as ElasticsearchOptions;
});
const instanceSettings: DataSourceInstanceSettings<ElasticsearchOptions> = { const templateSrv = {
id: 1, replace: (text?: string) => {
meta: {} as DataSourcePluginMeta, if (text?.startsWith('$')) {
name: 'test-elastic', return `resolvedVariable`;
type: 'type', } else {
uid: 'uid', return text;
access: 'proxy', }
url: ELASTICSEARCH_MOCK_URL, },
database, getAdhocFilters: () => [],
jsonData, } as unknown as TemplateSrv;
readOnly: false,
};
const ds = new ElasticDatasource(instanceSettings, templateSrv); const ds = createElasticDatasource(settings, templateSrv);
return { timeSrv, ds, fetchMock }; return { timeSrv, ds, fetchMock };
} }
describe('ElasticDatasource', function (this: any) { describe('ElasticDatasource', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('When calling getTagValues', () => { describe('When calling getTagValues', () => {
it('should respect the currently selected time range', () => { it('should respect the currently selected time range', () => {
const data = { const data = {
@ -175,22 +182,23 @@ describe('ElasticDatasource', function (this: any) {
const today = toUtc().format('YYYY.MM.DD'); const today = toUtc().format('YYYY.MM.DD');
expect(fetchMock).toHaveBeenCalledTimes(1); expect(fetchMock).toHaveBeenCalledTimes(1);
expect(fetchMock.mock.calls[0][0].url).toBe(`${ELASTICSEARCH_MOCK_URL}/asd-${today}/_mapping`); expect(fetchMock.mock.calls[0][0].url).toBe(`${ELASTICSEARCH_MOCK_URL}/test-${today}/_mapping`);
}); });
}); });
describe('When issuing metric query with interval pattern', () => { describe('When issuing metric query with interval pattern', () => {
async function runScenario() { async function runScenario() {
const range = { from: toUtc([2015, 4, 30, 10]), to: toUtc([2015, 5, 1, 10]) }; const range = { from: toUtc([2015, 4, 30, 10]), to: toUtc([2015, 5, 1, 10]), raw: { from: '', to: '' } };
const targets = [ const targets: ElasticsearchQuery[] = [
{ {
refId: 'test',
alias: '$varAlias', alias: '$varAlias',
bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '1' }], bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '1' }],
metrics: [{ type: 'count', id: '1' }], metrics: [{ type: 'count', id: '1' }],
query: 'escape\\:test', query: 'escape\\:test',
}, },
]; ];
const query: any = { range, targets }; const query = { ...DATAQUERY_BASE, range, targets };
const data = { const data = {
responses: [ responses: [
{ {
@ -209,7 +217,7 @@ describe('ElasticDatasource', function (this: any) {
}; };
const { ds, fetchMock } = getTestContext({ jsonData: { interval: 'Daily', esVersion: '7.10.0' }, data }); const { ds, fetchMock } = getTestContext({ jsonData: { interval: 'Daily', esVersion: '7.10.0' }, data });
let result: any = {}; let result: DataQueryResponse = { data: [] };
await expect(ds.query(query)).toEmitValuesWith((received) => { await expect(ds.query(query)).toEmitValuesWith((received) => {
expect(received.length).toBe(1); expect(received.length).toBe(1);
expect(received[0]).toEqual({ expect(received[0]).toEqual({
@ -218,7 +226,7 @@ describe('ElasticDatasource', function (this: any) {
datapoints: [[10, 1000]], datapoints: [[10, 1000]],
metric: 'count', metric: 'count',
props: {}, props: {},
refId: undefined, refId: 'test',
target: 'resolvedVariable', target: 'resolvedVariable',
}, },
], ],
@ -237,7 +245,7 @@ describe('ElasticDatasource', function (this: any) {
it('should translate index pattern to current day', async () => { it('should translate index pattern to current day', async () => {
const { header } = await runScenario(); const { header } = await runScenario();
expect(header.index).toEqual(['asd-2015.05.30', 'asd-2015.05.31', 'asd-2015.06.01']); expect(header.index).toEqual(['test-2015.05.30', 'test-2015.05.31', 'test-2015.06.01']);
}); });
it('should not resolve the variable in the original alias field in the query', async () => { it('should not resolve the variable in the original alias field in the query', async () => {
@ -291,7 +299,7 @@ describe('ElasticDatasource', function (this: any) {
} as DataQueryRequest<ElasticsearchQuery>; } as DataQueryRequest<ElasticsearchQuery>;
const queryBuilderSpy = jest.spyOn(ds.queryBuilder, 'getLogsQuery'); const queryBuilderSpy = jest.spyOn(ds.queryBuilder, 'getLogsQuery');
let response: any = {}; let response: DataQueryResponse = { data: [] };
await expect(ds.query(query)).toEmitValuesWith((received) => { await expect(ds.query(query)).toEmitValuesWith((received) => {
expect(received.length).toBe(1); expect(received.length).toBe(1);
@ -328,8 +336,10 @@ describe('ElasticDatasource', function (this: any) {
describe('When issuing document query', () => { describe('When issuing document query', () => {
async function runScenario() { async function runScenario() {
const range = createTimeRange(dateTime([2015, 4, 30, 10]), dateTime([2015, 5, 1, 10])); const range = createTimeRange(dateTime([2015, 4, 30, 10]), dateTime([2015, 5, 1, 10]));
const targets = [{ refId: 'A', metrics: [{ type: 'raw_document', id: '1' }], query: 'test' }]; const targets: ElasticsearchQuery[] = [
const query: any = { range, targets }; { refId: 'A', metrics: [{ type: 'raw_document', id: '1' }], query: 'test' },
];
const query = { ...DATAQUERY_BASE, range, targets };
const data = { responses: [] }; const data = { responses: [] };
const { ds, fetchMock } = getTestContext({ jsonData: { esVersion: '7.10.0' }, data, database: 'test' }); const { ds, fetchMock } = getTestContext({ jsonData: { esVersion: '7.10.0' }, data, database: 'test' });
@ -420,7 +430,7 @@ describe('ElasticDatasource', function (this: any) {
}; };
const { ds } = getTestContext({ const { ds } = getTestContext({
mockImplementation: () => throwError(response), fetchMockImplementation: () => throwError(response),
from: undefined, from: undefined,
jsonData: { esVersion: '7.10.0' }, jsonData: { esVersion: '7.10.0' },
}); });
@ -465,102 +475,6 @@ describe('ElasticDatasource', function (this: any) {
}); });
}); });
// describe('When getting fields', () => {
// const data = {
// metricbeat: {
// mappings: {
// metricsets: {
// _all: {},
// _meta: {
// test: 'something',
// },
// properties: {
// '@timestamp': { type: 'date' },
// __timestamp: { type: 'date' },
// '@timestampnano': { type: 'date_nanos' },
// beat: {
// properties: {
// name: {
// fields: { raw: { type: 'keyword' } },
// type: 'string',
// },
// hostname: { type: 'string' },
// },
// },
// system: {
// properties: {
// cpu: {
// properties: {
// system: { type: 'float' },
// user: { type: 'float' },
// },
// },
// process: {
// properties: {
// cpu: {
// properties: {
// total: { type: 'float' },
// },
// },
// name: { type: 'string' },
// },
// },
// },
// },
// },
// },
// },
// },
// };
// it('should return nested fields', async () => {
// const { ds } = getTestContext({ data, jsonData: { esVersion: 50 }, database: 'metricbeat' });
// await expect(ds.getFields()).toEmitValuesWith((received) => {
// expect(received.length).toBe(1);
// const fieldObjects = received[0];
// const fields = map(fieldObjects, 'text');
// expect(fields).toEqual([
// '@timestamp',
// '__timestamp',
// '@timestampnano',
// 'beat.name.raw',
// 'beat.name',
// 'beat.hostname',
// 'system.cpu.system',
// 'system.cpu.user',
// 'system.process.cpu.total',
// 'system.process.name',
// ]);
// });
// });
// it('should return number fields', async () => {
// const { ds } = getTestContext({ data, jsonData: { esVersion: 50 }, database: 'metricbeat' });
// await expect(ds.getFields(['number'])).toEmitValuesWith((received) => {
// expect(received.length).toBe(1);
// const fieldObjects = received[0];
// const fields = map(fieldObjects, 'text');
// expect(fields).toEqual(['system.cpu.system', 'system.cpu.user', 'system.process.cpu.total']);
// });
// });
// it('should return date fields', async () => {
// const { ds } = getTestContext({ data, jsonData: { esVersion: 50 }, database: 'metricbeat' });
// await expect(ds.getFields(['date'])).toEmitValuesWith((received) => {
// expect(received.length).toBe(1);
// const fieldObjects = received[0];
// const fields = map(fieldObjects, 'text');
// expect(fields).toEqual(['@timestamp', '__timestamp', '@timestampnano']);
// });
// });
// });
describe('When getting field mappings on indices with gaps', () => { describe('When getting field mappings on indices with gaps', () => {
const basicResponse = { const basicResponse = {
metricbeat: { metricbeat: {
@ -580,55 +494,13 @@ describe('ElasticDatasource', function (this: any) {
}, },
}; };
// const alternateResponse = {
// metricbeat: {
// mappings: {
// metricsets: {
// _all: {},
// properties: {
// '@timestamp': { type: 'date' },
// },
// },
// },
// },
// };
// it('should return fields of the newest available index', async () => {
// const twoDaysBefore = toUtc().subtract(2, 'day').format('YYYY.MM.DD');
// const threeDaysBefore = toUtc().subtract(3, 'day').format('YYYY.MM.DD');
// const baseUrl = `${ELASTICSEARCH_MOCK_URL}/asd-${twoDaysBefore}/_mapping`;
// const alternateUrl = `${ELASTICSEARCH_MOCK_URL}/asd-${threeDaysBefore}/_mapping`;
// const { ds, timeSrv } = getTestContext({
// from: 'now-2w',
// jsonData: { interval: 'Daily', esVersion: 50 },
// mockImplementation: (options) => {
// if (options.url === baseUrl) {
// return of(createFetchResponse(basicResponse));
// } else if (options.url === alternateUrl) {
// return of(createFetchResponse(alternateResponse));
// }
// return throwError({ status: 404 });
// },
// });
// const range = timeSrv.timeRange();
// await expect(ds.getFields(undefined, range)).toEmitValuesWith((received) => {
// expect(received.length).toBe(1);
// const fieldObjects = received[0];
// const fields = map(fieldObjects, 'text');
// expect(fields).toEqual(['@timestamp', 'beat.hostname']);
// });
// });
it('should not retry when ES is down', async () => { it('should not retry when ES is down', async () => {
const twoDaysBefore = toUtc().subtract(2, 'day').format('YYYY.MM.DD'); const twoDaysBefore = toUtc().subtract(2, 'day').format('YYYY.MM.DD');
const { ds, timeSrv, fetchMock } = getTestContext({ const { ds, timeSrv, fetchMock } = getTestContext({
from: 'now-2w', from: 'now-2w',
jsonData: { interval: 'Daily', esVersion: '7.10.0' }, jsonData: { interval: 'Daily', esVersion: '7.10.0' },
mockImplementation: (options) => { fetchMockImplementation: (options) => {
if (options.url === `${ELASTICSEARCH_MOCK_URL}/asd-${twoDaysBefore}/_mapping`) { if (options.url === `${ELASTICSEARCH_MOCK_URL}/asd-${twoDaysBefore}/_mapping`) {
return of(createFetchResponse(basicResponse)); return of(createFetchResponse(basicResponse));
} }
@ -649,7 +521,7 @@ describe('ElasticDatasource', function (this: any) {
const { ds, timeSrv, fetchMock } = getTestContext({ const { ds, timeSrv, fetchMock } = getTestContext({
from: 'now-2w', from: 'now-2w',
jsonData: { interval: 'Daily', esVersion: '7.10.0' }, jsonData: { interval: 'Daily', esVersion: '7.10.0' },
mockImplementation: (options) => { fetchMockImplementation: (options) => {
return throwError({ status: 404 }); return throwError({ status: 404 });
}, },
}); });
@ -824,7 +696,7 @@ describe('ElasticDatasource', function (this: any) {
describe('When issuing aggregation query on es5.x', () => { describe('When issuing aggregation query on es5.x', () => {
async function runScenario() { async function runScenario() {
const range = createTimeRange(dateTime([2015, 4, 30, 10]), dateTime([2015, 5, 1, 10])); const range = createTimeRange(dateTime([2015, 4, 30, 10]), dateTime([2015, 5, 1, 10]));
const targets = [ const targets: ElasticsearchQuery[] = [
{ {
refId: 'A', refId: 'A',
bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '2' }], bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '2' }],
@ -832,7 +704,7 @@ describe('ElasticDatasource', function (this: any) {
query: 'test', query: 'test',
}, },
]; ];
const query: any = { range, targets }; const query = { ...DATAQUERY_BASE, range, targets };
const data = { responses: [] }; const data = { responses: [] };
const { ds, fetchMock } = getTestContext({ jsonData: { esVersion: '7.10.0' }, data, database: 'test' }); const { ds, fetchMock } = getTestContext({ jsonData: { esVersion: '7.10.0' }, data, database: 'test' });
@ -926,7 +798,7 @@ describe('ElasticDatasource', function (this: any) {
describe('query', () => { describe('query', () => {
it('should replace range as integer not string', async () => { it('should replace range as integer not string', async () => {
const { ds } = getTestContext({ jsonData: { interval: 'Daily', esVersion: '7.10.0', timeField: '@time' } }); const { ds } = getTestContext({ jsonData: { interval: 'Daily', esVersion: '7.10.0', timeField: '@time' } });
const postMock = jest.fn((url: string, data: any) => of(createFetchResponse({ responses: [] }))); const postMock = jest.fn((url: string, data) => of(createFetchResponse({ responses: [] })));
ds['post'] = postMock; ds['post'] = postMock;
await expect(ds.query(createElasticQuery())).toEmitValuesWith((received) => { await expect(ds.query(createElasticQuery())).toEmitValuesWith((received) => {
@ -1140,7 +1012,11 @@ const createElasticQuery = (): DataQueryRequest<ElasticsearchQuery> => {
range: { range: {
from: dateTime([2015, 4, 30, 10]), from: dateTime([2015, 4, 30, 10]),
to: dateTime([2015, 5, 1, 10]), to: dateTime([2015, 5, 1, 10]),
} as any, raw: {
from: '',
to: '',
},
},
targets: [ targets: [
{ {
refId: '', refId: '',

@ -1,36 +1,29 @@
import { AbstractLabelOperator, AbstractQuery, DataSourceInstanceSettings } from '@grafana/data'; import { AbstractLabelOperator, AbstractQuery } from '@grafana/data';
import { TemplateSrv } from '../../../features/templating/template_srv'; import { TemplateSrv } from '../../../features/templating/template_srv';
import { ElasticDatasource } from './datasource'; import { ElasticDatasource } from './datasource';
import LanguageProvider from './language_provider'; import LanguageProvider from './language_provider';
import { ElasticsearchOptions, ElasticsearchQuery } from './types'; import { createElasticDatasource } from './mocks';
import { ElasticsearchQuery } from './types';
const templateSrvStub = {
getAdhocFilters: jest.fn(() => [] as any[]),
replace: jest.fn((a: string) => a),
} as any;
const dataSource = new ElasticDatasource(
{
url: 'http://es.com',
database: '[asd-]YYYY.MM.DD',
jsonData: {
interval: 'Daily',
esVersion: '2.0.0',
timeField: '@time',
},
} as DataSourceInstanceSettings<ElasticsearchOptions>,
templateSrvStub as TemplateSrv
);
const baseLogsQuery: Partial<ElasticsearchQuery> = { const baseLogsQuery: Partial<ElasticsearchQuery> = {
metrics: [{ type: 'logs', id: '1' }], metrics: [{ type: 'logs', id: '1' }],
}; };
describe('transform abstract query to elasticsearch query', () => { describe('transform abstract query to elasticsearch query', () => {
let datasource: ElasticDatasource;
beforeEach(() => {
const templateSrvStub = {
getAdhocFilters: jest.fn(() => []),
replace: jest.fn((a: string) => a),
} as unknown as TemplateSrv;
datasource = createElasticDatasource({}, templateSrvStub);
});
it('With some labels', () => { it('With some labels', () => {
const instance = new LanguageProvider(dataSource); const instance = new LanguageProvider(datasource);
const abstractQuery: AbstractQuery = { const abstractQuery: AbstractQuery = {
refId: 'bar', refId: 'bar',
labelMatchers: [ labelMatchers: [
@ -50,7 +43,7 @@ describe('transform abstract query to elasticsearch query', () => {
}); });
it('Empty query', () => { it('Empty query', () => {
const instance = new LanguageProvider(dataSource); const instance = new LanguageProvider(datasource);
const abstractQuery = { labelMatchers: [], refId: 'foo' }; const abstractQuery = { labelMatchers: [], refId: 'foo' };
const result = instance.importFromAbstractQuery(abstractQuery); const result = instance.importFromAbstractQuery(abstractQuery);

@ -0,0 +1,53 @@
import { DataSourceInstanceSettings, PluginType } from '@grafana/data';
import { TemplateSrv } from 'app/features/templating/template_srv';
import { ElasticDatasource } from './datasource';
import { ElasticsearchOptions } from './types';
export function createElasticDatasource(
settings: Partial<DataSourceInstanceSettings<ElasticsearchOptions>> = {},
templateSrv: TemplateSrv
) {
const { jsonData, ...rest } = settings;
const instanceSettings: DataSourceInstanceSettings<ElasticsearchOptions> = {
id: 1,
meta: {
id: 'id',
name: 'name',
type: PluginType.datasource,
module: '',
baseUrl: '',
info: {
author: {
name: 'Test',
},
description: '',
links: [],
logos: {
large: '',
small: '',
},
screenshots: [],
updated: '',
version: '',
},
},
readOnly: false,
name: 'test-elastic',
type: 'type',
uid: 'uid',
access: 'proxy',
url: '',
jsonData: {
timeField: '',
esVersion: '',
timeInterval: '',
...jsonData,
},
database: '[test-]YYYY.MM.DD',
...rest,
};
return new ElasticDatasource(instanceSettings, templateSrv);
}
Loading…
Cancel
Save