mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki: refactor mock instance creation and clean up datasource test (#54176)
* refactor(loki-test): move mock creation to mock module * refactor(loki-test): allow to pass custom settings to the mock constructor * refactor(loki-test): refactor mock factory in datasource test * refactor(loki-test): revert change in undefined test case for dsMaxLines * refactor(loki-test): move type assertion to mock definition * refactor(loki-test): fix more type issues * refactor(loki-explore-query-editor): refactor test to use createLokiDatasource() and fix type issues * refactor(loki-test): replace makeMockLokiDatasource with metadataRequest factory * fix: remove any * fix(loki-test): fix remaining usages of any * Fix: add missing exported type
This commit is contained in:
@@ -83,7 +83,7 @@ exports[`no enzyme tests`] = {
|
||||
"public/app/plugins/datasource/influxdb/components/ConfigEditor.test.tsx:57753101": [
|
||||
[0, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx:1488067923": [
|
||||
"public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx:2984948507": [
|
||||
[0, 26, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx:146069464": [
|
||||
@@ -7126,11 +7126,6 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/jaeger/util.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx: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"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/components/LokiLabelBrowser.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
@@ -7163,15 +7158,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "7"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/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"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/datasource.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
@@ -7185,11 +7171,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/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"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/language_provider.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
@@ -7210,10 +7191,6 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/loki/live_streams_result_transformer.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/mocks.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
|
||||
@@ -2,19 +2,22 @@ import { mount, shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import { ExploreMode, LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data';
|
||||
import { LoadingState, PanelData, toUtc, TimeRange, HistoryItem } from '@grafana/data';
|
||||
import { TemplateSrv } from '@grafana/runtime';
|
||||
|
||||
import { LokiDatasource } from '../datasource';
|
||||
import LokiLanguageProvider from '../language_provider';
|
||||
import { makeMockLokiDatasource } from '../mocks';
|
||||
import { createLokiDatasource } from '../mocks';
|
||||
import { LokiQuery } from '../types';
|
||||
|
||||
import { LokiExploreQueryEditor } from './LokiExploreQueryEditor';
|
||||
import { LokiExploreQueryEditor, Props } from './LokiExploreQueryEditor';
|
||||
import { LokiOptionFields } from './LokiOptionFields';
|
||||
|
||||
const setup = (renderMethod: any, propOverrides?: object) => {
|
||||
const datasource: LokiDatasource = makeMockLokiDatasource({});
|
||||
const setup = (renderMethod: (c: JSX.Element) => ReturnType<typeof shallow> | ReturnType<typeof mount>) => {
|
||||
const datasource: LokiDatasource = createLokiDatasource({} as unknown as TemplateSrv);
|
||||
datasource.languageProvider = new LokiLanguageProvider(datasource);
|
||||
jest.spyOn(datasource, 'metadataRequest').mockResolvedValue([]);
|
||||
|
||||
const onRunQuery = jest.fn();
|
||||
const onChange = jest.fn();
|
||||
const query: LokiQuery = { expr: '', refId: 'A', maxLines: 0 };
|
||||
@@ -58,21 +61,18 @@ const setup = (renderMethod: any, propOverrides?: object) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
const history: any[] = [];
|
||||
const exploreMode: ExploreMode = ExploreMode.Logs;
|
||||
const history: Array<HistoryItem<LokiQuery>> = [];
|
||||
|
||||
const props: any = {
|
||||
const props: Props = {
|
||||
query,
|
||||
data,
|
||||
range,
|
||||
datasource,
|
||||
exploreMode,
|
||||
history,
|
||||
onChange,
|
||||
onRunQuery,
|
||||
};
|
||||
|
||||
Object.assign(props, { ...props, ...propOverrides });
|
||||
return renderMethod(<LokiExploreQueryEditor {...props} />);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { LokiQuery, LokiOptions } from '../types';
|
||||
import { LokiOptionFields } from './LokiOptionFields';
|
||||
import { LokiQueryField } from './LokiQueryField';
|
||||
|
||||
type Props = QueryEditorProps<LokiDatasource, LokiQuery, LokiOptions>;
|
||||
export type Props = QueryEditorProps<LokiDatasource, LokiQuery, LokiOptions>;
|
||||
|
||||
export const LokiExploreQueryEditor = memo((props: Props) => {
|
||||
const { query, data, datasource, history, onChange, onRunQuery, range } = props;
|
||||
|
||||
@@ -53,9 +53,48 @@ exports[`LokiExploreQueryEditor should render component 1`] = `
|
||||
}
|
||||
data-testid="loki-editor-explore"
|
||||
datasource={
|
||||
Object {
|
||||
"getTimeRangeParams": [Function],
|
||||
"interpolateString": [Function],
|
||||
LokiDatasource {
|
||||
"annotations": Object {
|
||||
"QueryEditor": Object {
|
||||
"$$typeof": Symbol(react.memo),
|
||||
"compare": null,
|
||||
"type": [Function],
|
||||
},
|
||||
},
|
||||
"getLogRowContext": [Function],
|
||||
"id": 0,
|
||||
"instanceSettings": Object {
|
||||
"access": "direct",
|
||||
"id": 0,
|
||||
"jsonData": Object {
|
||||
"maxLines": "20",
|
||||
},
|
||||
"meta": Object {
|
||||
"baseUrl": "",
|
||||
"id": "id",
|
||||
"info": Object {
|
||||
"author": Object {
|
||||
"name": "Test",
|
||||
},
|
||||
"description": "",
|
||||
"links": Array [],
|
||||
"logos": Object {
|
||||
"large": "",
|
||||
"small": "",
|
||||
},
|
||||
"screenshots": Array [],
|
||||
"updated": "",
|
||||
"version": "",
|
||||
},
|
||||
"module": "",
|
||||
"name": "name",
|
||||
"type": "datasource",
|
||||
},
|
||||
"name": "",
|
||||
"type": "",
|
||||
"uid": "",
|
||||
"url": "myloggingurl",
|
||||
},
|
||||
"languageProvider": LokiLanguageProvider {
|
||||
"cleanText": [Function],
|
||||
"datasource": [Circular],
|
||||
@@ -245,7 +284,42 @@ exports[`LokiExploreQueryEditor should render component 1`] = `
|
||||
"start": [Function],
|
||||
"started": false,
|
||||
},
|
||||
"metadataRequest": [Function],
|
||||
"maxLines": 20,
|
||||
"meta": Object {
|
||||
"baseUrl": "",
|
||||
"id": "id",
|
||||
"info": Object {
|
||||
"author": Object {
|
||||
"name": "Test",
|
||||
},
|
||||
"description": "",
|
||||
"links": Array [],
|
||||
"logos": Object {
|
||||
"large": "",
|
||||
"small": "",
|
||||
},
|
||||
"screenshots": Array [],
|
||||
"updated": "",
|
||||
"version": "",
|
||||
},
|
||||
"module": "",
|
||||
"name": "name",
|
||||
"type": "datasource",
|
||||
},
|
||||
"metadataRequest": [MockFunction],
|
||||
"name": "",
|
||||
"prepareLogRowContextQueryTarget": [Function],
|
||||
"runLiveQuery": [Function],
|
||||
"streamOptionsProvider": [Function],
|
||||
"streams": LiveStreams {
|
||||
"streams": Object {},
|
||||
},
|
||||
"templateSrv": Object {},
|
||||
"timeSrv": Object {
|
||||
"timeRange": [Function],
|
||||
},
|
||||
"type": "",
|
||||
"uid": "",
|
||||
}
|
||||
}
|
||||
history={Array []}
|
||||
|
||||
@@ -14,36 +14,21 @@ import {
|
||||
FieldType,
|
||||
LogRowModel,
|
||||
MutableDataFrame,
|
||||
toUtc,
|
||||
} from '@grafana/data';
|
||||
import { BackendSrvRequest, FetchResponse, setBackendSrv, getBackendSrv, BackendSrv } from '@grafana/runtime';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
|
||||
import { initialCustomVariableModelState } from '../../../features/variables/custom/reducer';
|
||||
import { CustomVariableModel } from '../../../features/variables/types';
|
||||
|
||||
import { LokiDatasource } from './datasource';
|
||||
import { makeMockLokiDatasource } from './mocks';
|
||||
import { createMetadataRequest, createLokiDatasource } from './mocks';
|
||||
import { LokiOptions, LokiQuery, LokiQueryType } from './types';
|
||||
|
||||
const rawRange = {
|
||||
from: toUtc('2018-04-25 10:00'),
|
||||
to: toUtc('2018-04-25 11:00'),
|
||||
};
|
||||
|
||||
const timeSrvStub = {
|
||||
timeRange: () => ({
|
||||
from: rawRange.from,
|
||||
to: rawRange.to,
|
||||
raw: rawRange,
|
||||
}),
|
||||
} as unknown as TimeSrv;
|
||||
|
||||
const templateSrvStub = {
|
||||
getAdhocFilters: jest.fn(() => [] as any[]),
|
||||
replace: jest.fn((a: string, ...rest: any) => a),
|
||||
};
|
||||
getAdhocFilters: jest.fn(() => [] as unknown[]),
|
||||
replace: jest.fn((a: string, ...rest: unknown[]) => a),
|
||||
} as unknown as TemplateSrv;
|
||||
|
||||
const testFrame: DataFrame = {
|
||||
refId: 'A',
|
||||
@@ -131,22 +116,16 @@ describe('LokiDatasource', () => {
|
||||
describe('when doing logs queries with limits', () => {
|
||||
const runTest = async (
|
||||
queryMaxLines: number | undefined,
|
||||
dsMaxLines: number | undefined,
|
||||
dsMaxLines: string | undefined,
|
||||
expectedMaxLines: number
|
||||
) => {
|
||||
let settings = {
|
||||
url: 'myloggingurl',
|
||||
const settings = {
|
||||
jsonData: {
|
||||
maxLines: dsMaxLines,
|
||||
},
|
||||
} as DataSourceInstanceSettings<LokiOptions>;
|
||||
|
||||
const templateSrvMock = {
|
||||
getAdhocFilters: (): any[] => [],
|
||||
replace: (a: string) => a,
|
||||
} as unknown as TemplateSrv;
|
||||
|
||||
const ds = new LokiDatasource(settings, templateSrvMock, timeSrvStub);
|
||||
const ds = createLokiDatasource(templateSrvStub, settings);
|
||||
|
||||
// we need to check the final query before it is sent out,
|
||||
// and applyTemplateVariables is a convenient place to do that.
|
||||
@@ -166,7 +145,7 @@ describe('LokiDatasource', () => {
|
||||
};
|
||||
|
||||
it('should use datasource max lines when no query max lines', async () => {
|
||||
await runTest(undefined, 40, 40);
|
||||
await runTest(undefined, '40', 40);
|
||||
});
|
||||
|
||||
it('should use query max lines, if exists', async () => {
|
||||
@@ -174,30 +153,22 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('should use query max lines, if both exist, even if it is higher than ds max lines', async () => {
|
||||
await runTest(80, 40, 80);
|
||||
await runTest(80, '40', 80);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When using adhoc filters', () => {
|
||||
const DEFAULT_EXPR = 'rate({bar="baz", job="foo"} |= "bar" [5m])';
|
||||
const query: LokiQuery = { expr: DEFAULT_EXPR, refId: 'A' };
|
||||
const originalAdhocFiltersMock = templateSrvStub.getAdhocFilters();
|
||||
const ds = new LokiDatasource(
|
||||
{} as DataSourceInstanceSettings,
|
||||
templateSrvStub as unknown as TemplateSrv,
|
||||
timeSrvStub
|
||||
);
|
||||
|
||||
afterAll(() => {
|
||||
templateSrvStub.getAdhocFilters.mockReturnValue(originalAdhocFiltersMock);
|
||||
});
|
||||
const mockedGetAdhocFilters = templateSrvStub.getAdhocFilters as jest.Mock;
|
||||
const ds = createLokiDatasource(templateSrvStub);
|
||||
|
||||
it('should not modify expression with no filters', async () => {
|
||||
expect(ds.applyTemplateVariables(query, {}).expr).toBe(DEFAULT_EXPR);
|
||||
});
|
||||
|
||||
it('should add filters to expression', async () => {
|
||||
templateSrvStub.getAdhocFilters.mockReturnValue([
|
||||
mockedGetAdhocFilters.mockReturnValue([
|
||||
{
|
||||
key: 'k1',
|
||||
operator: '=',
|
||||
@@ -216,7 +187,7 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('should add escaping if needed to regex filter expressions', async () => {
|
||||
templateSrvStub.getAdhocFilters.mockReturnValue([
|
||||
mockedGetAdhocFilters.mockReturnValue([
|
||||
{
|
||||
key: 'k1',
|
||||
operator: '=~',
|
||||
@@ -239,7 +210,7 @@ describe('LokiDatasource', () => {
|
||||
let variable: CustomVariableModel;
|
||||
|
||||
beforeEach(() => {
|
||||
ds = createLokiDSForTests();
|
||||
ds = createLokiDatasource(templateSrvStub);
|
||||
variable = { ...initialCustomVariableModelState };
|
||||
});
|
||||
|
||||
@@ -281,8 +252,12 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
describe('when performing testDataSource', () => {
|
||||
let ds: LokiDatasource;
|
||||
beforeEach(() => {
|
||||
ds = createLokiDatasource(templateSrvStub);
|
||||
});
|
||||
|
||||
it('should return successfully when call succeeds with labels', async () => {
|
||||
const ds = createLokiDSForTests({} as TemplateSrv);
|
||||
ds.metadataRequest = () => Promise.resolve(['avalue']);
|
||||
|
||||
const result = await ds.testDatasource();
|
||||
@@ -294,7 +269,6 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('should return error when call succeeds without labels', async () => {
|
||||
const ds = createLokiDSForTests({} as TemplateSrv);
|
||||
ds.metadataRequest = () => Promise.resolve([]);
|
||||
|
||||
const result = await ds.testDatasource();
|
||||
@@ -306,7 +280,6 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('should return error status with no details when call fails with no details', async () => {
|
||||
const ds = createLokiDSForTests({} as TemplateSrv);
|
||||
ds.metadataRequest = () => Promise.reject({});
|
||||
|
||||
const result = await ds.testDatasource();
|
||||
@@ -318,7 +291,6 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('should return error status with details when call fails with details', async () => {
|
||||
const ds = createLokiDSForTests({} as TemplateSrv);
|
||||
ds.metadataRequest = () =>
|
||||
Promise.reject({
|
||||
data: {
|
||||
@@ -336,10 +308,10 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
describe('when calling annotationQuery', () => {
|
||||
const getTestContext = (frame: DataFrame, options: any = []) => {
|
||||
const getTestContext = (frame: DataFrame, options = {}) => {
|
||||
const query = makeAnnotationQueryRequest(options);
|
||||
|
||||
const ds = createLokiDSForTests();
|
||||
const ds = createLokiDatasource(templateSrvStub);
|
||||
const response: DataQueryResponse = {
|
||||
data: [frame],
|
||||
};
|
||||
@@ -477,20 +449,22 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
describe('metricFindQuery', () => {
|
||||
const getTestContext = (mock: LokiDatasource) => {
|
||||
const ds = createLokiDSForTests();
|
||||
ds.metadataRequest = mock.metadataRequest;
|
||||
const getTestContext = () => {
|
||||
const ds = createLokiDatasource(templateSrvStub);
|
||||
jest
|
||||
.spyOn(ds, 'metadataRequest')
|
||||
.mockImplementation(
|
||||
createMetadataRequest(
|
||||
{ label1: ['value1', 'value2'], label2: ['value3', 'value4'] },
|
||||
{ '{label1="value1", label2="value2"}': [{ label5: 'value5' }] }
|
||||
)
|
||||
);
|
||||
|
||||
return { ds };
|
||||
};
|
||||
|
||||
const mock = makeMockLokiDatasource(
|
||||
{ label1: ['value1', 'value2'], label2: ['value3', 'value4'] },
|
||||
{ '{label1="value1", label2="value2"}': [{ label5: 'value5' }] }
|
||||
);
|
||||
|
||||
it(`should return label names for Loki`, async () => {
|
||||
const { ds } = getTestContext(mock);
|
||||
const { ds } = getTestContext();
|
||||
|
||||
const res = await ds.metricFindQuery('label_names()');
|
||||
|
||||
@@ -498,7 +472,7 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it(`should return label values for Loki when no matcher`, async () => {
|
||||
const { ds } = getTestContext(mock);
|
||||
const { ds } = getTestContext();
|
||||
|
||||
const res = await ds.metricFindQuery('label_values(label1)');
|
||||
|
||||
@@ -506,7 +480,7 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it(`should return label values for Loki with matcher`, async () => {
|
||||
const { ds } = getTestContext(mock);
|
||||
const { ds } = getTestContext();
|
||||
|
||||
const res = await ds.metricFindQuery('label_values({label1="value1", label2="value2"},label5)');
|
||||
|
||||
@@ -514,7 +488,7 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it(`should return empty array when incorrect query for Loki`, async () => {
|
||||
const { ds } = getTestContext(mock);
|
||||
const { ds } = getTestContext();
|
||||
|
||||
const res = await ds.metricFindQuery('incorrect_query');
|
||||
|
||||
@@ -524,11 +498,15 @@ describe('LokiDatasource', () => {
|
||||
|
||||
describe('modifyQuery', () => {
|
||||
describe('when called with ADD_FILTER', () => {
|
||||
let ds: LokiDatasource;
|
||||
beforeEach(() => {
|
||||
ds = createLokiDatasource(templateSrvStub);
|
||||
});
|
||||
|
||||
describe('and query has no parser', () => {
|
||||
it('then the correct label should be added for logs query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: '{bar="baz"}' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -538,7 +516,6 @@ describe('LokiDatasource', () => {
|
||||
it('then the correctly escaped label should be added for logs query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: '{bar="baz"}' };
|
||||
const action = { options: { key: 'job', value: '\\test' }, type: 'ADD_FILTER' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -548,7 +525,6 @@ describe('LokiDatasource', () => {
|
||||
it('then the correct label should be added for metrics query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: 'rate({bar="baz"}[5m])' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -558,7 +534,6 @@ describe('LokiDatasource', () => {
|
||||
it('then the correct label should be added for logs query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: '{bar="baz"} | logfmt' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -567,7 +542,6 @@ describe('LokiDatasource', () => {
|
||||
it('then the correct label should be added for metrics query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: 'rate({bar="baz"} | logfmt [5m])' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -579,10 +553,14 @@ describe('LokiDatasource', () => {
|
||||
|
||||
describe('when called with ADD_FILTER_OUT', () => {
|
||||
describe('and query has no parser', () => {
|
||||
let ds: LokiDatasource;
|
||||
beforeEach(() => {
|
||||
ds = createLokiDatasource(templateSrvStub);
|
||||
});
|
||||
|
||||
it('then the correct label should be added for logs query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: '{bar="baz"}' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER_OUT' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -592,7 +570,6 @@ describe('LokiDatasource', () => {
|
||||
it('then the correctly escaped label should be added for logs query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: '{bar="baz"}' };
|
||||
const action = { options: { key: 'job', value: '"test' }, type: 'ADD_FILTER_OUT' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -602,17 +579,20 @@ describe('LokiDatasource', () => {
|
||||
it('then the correct label should be added for metrics query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: 'rate({bar="baz"}[5m])' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER_OUT' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
expect(result.expr).toEqual('rate({bar="baz", job!="grafana"}[5m])');
|
||||
});
|
||||
describe('and query has parser', () => {
|
||||
let ds: LokiDatasource;
|
||||
beforeEach(() => {
|
||||
ds = createLokiDatasource(templateSrvStub);
|
||||
});
|
||||
|
||||
it('then the correct label should be added for logs query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: '{bar="baz"} | logfmt' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER_OUT' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -621,7 +601,6 @@ describe('LokiDatasource', () => {
|
||||
it('then the correct label should be added for metrics query', () => {
|
||||
const query: LokiQuery = { refId: 'A', expr: 'rate({bar="baz"} | logfmt [5m])' };
|
||||
const action = { options: { key: 'job', value: 'grafana' }, type: 'ADD_FILTER_OUT' };
|
||||
const ds = createLokiDSForTests();
|
||||
const result = ds.modifyQuery(query, action);
|
||||
|
||||
expect(result.refId).toEqual('A');
|
||||
@@ -649,7 +628,7 @@ describe('LokiDatasource', () => {
|
||||
getAdhocFilters: (): AdHocFilter[] => adHocFilters,
|
||||
replace: (a: string) => a,
|
||||
} as unknown as TemplateSrv;
|
||||
ds = createLokiDSForTests(templateSrvMock);
|
||||
ds = createLokiDatasource(templateSrvMock);
|
||||
});
|
||||
describe('and query has no parser', () => {
|
||||
it('then the correct label should be added for logs query', () => {
|
||||
@@ -684,7 +663,7 @@ describe('LokiDatasource', () => {
|
||||
getAdhocFilters: (): AdHocFilter[] => adHocFilters,
|
||||
replace: (a: string) => a,
|
||||
} as unknown as TemplateSrv;
|
||||
ds = createLokiDSForTests(templateSrvMock);
|
||||
ds = createLokiDatasource(templateSrvMock);
|
||||
});
|
||||
describe('and query has no parser', () => {
|
||||
it('then the correct label should be added for logs query', () => {
|
||||
@@ -707,7 +686,7 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
describe('prepareLogRowContextQueryTarget', () => {
|
||||
const ds = createLokiDSForTests();
|
||||
const ds = createLokiDatasource(templateSrvStub);
|
||||
it('creates query with only labels from /labels API', async () => {
|
||||
const row: LogRowModel = {
|
||||
rowIndex: 0,
|
||||
@@ -758,8 +737,12 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
describe('logs volume data provider', () => {
|
||||
let ds: LokiDatasource;
|
||||
beforeEach(() => {
|
||||
ds = createLokiDatasource(templateSrvStub);
|
||||
});
|
||||
|
||||
it('creates provider for logs query', () => {
|
||||
const ds = createLokiDSForTests();
|
||||
const options = getQueryOptions<LokiQuery>({
|
||||
targets: [{ expr: '{label=value}', refId: 'A' }],
|
||||
});
|
||||
@@ -768,7 +751,6 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('does not create provider for metrics query', () => {
|
||||
const ds = createLokiDSForTests();
|
||||
const options = getQueryOptions<LokiQuery>({
|
||||
targets: [{ expr: 'rate({label=value}[1m])', refId: 'A' }],
|
||||
});
|
||||
@@ -777,7 +759,6 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('creates provider if at least one query is a logs query', () => {
|
||||
const ds = createLokiDSForTests();
|
||||
const options = getQueryOptions<LokiQuery>({
|
||||
targets: [
|
||||
{ expr: 'rate({label=value}[1m])', refId: 'A' },
|
||||
@@ -789,7 +770,6 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('does not create provider if there is only an instant logs query', () => {
|
||||
const ds = createLokiDSForTests();
|
||||
const options = getQueryOptions<LokiQuery>({
|
||||
targets: [{ expr: '{label=value', refId: 'A', queryType: LokiQueryType.Instant }],
|
||||
});
|
||||
@@ -799,8 +779,12 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
describe('importing queries', () => {
|
||||
let ds: LokiDatasource;
|
||||
beforeEach(() => {
|
||||
ds = createLokiDatasource(templateSrvStub);
|
||||
});
|
||||
|
||||
it('keeps all labels when no labels are loaded', async () => {
|
||||
const ds = createLokiDSForTests();
|
||||
ds.getResource = () => Promise.resolve({ data: [] });
|
||||
const queries = await ds.importFromAbstractQueries([
|
||||
{
|
||||
@@ -815,7 +799,6 @@ describe('LokiDatasource', () => {
|
||||
});
|
||||
|
||||
it('filters out non existing labels', async () => {
|
||||
const ds = createLokiDSForTests();
|
||||
ds.getResource = () => Promise.resolve({ data: ['foo'] });
|
||||
const queries = await ds.importFromAbstractQueries([
|
||||
{
|
||||
@@ -833,7 +816,7 @@ describe('LokiDatasource', () => {
|
||||
|
||||
describe('applyTemplateVariables', () => {
|
||||
it('should add the adhoc filter to the query', () => {
|
||||
const ds = createLokiDSForTests();
|
||||
const ds = createLokiDatasource(templateSrvStub);
|
||||
const spy = jest.spyOn(ds, 'addAdHocFilters');
|
||||
ds.applyTemplateVariables({ expr: '{test}', refId: 'A' }, {});
|
||||
expect(spy).toHaveBeenCalledWith('{test}');
|
||||
@@ -847,23 +830,7 @@ function assertAdHocFilters(query: string, expectedResults: string, ds: LokiData
|
||||
expect(result).toEqual(expectedResults);
|
||||
}
|
||||
|
||||
function createLokiDSForTests(
|
||||
templateSrvMock = {
|
||||
getAdhocFilters: (): any[] => [],
|
||||
replace: (a: string) => a,
|
||||
} as unknown as TemplateSrv
|
||||
): LokiDatasource {
|
||||
const instanceSettings = {
|
||||
url: 'myloggingurl',
|
||||
} as DataSourceInstanceSettings;
|
||||
|
||||
const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
|
||||
const customSettings: DataSourceInstanceSettings = { ...instanceSettings, jsonData: customData };
|
||||
|
||||
return new LokiDatasource(customSettings, templateSrvMock, timeSrvStub as TimeSrv);
|
||||
}
|
||||
|
||||
function makeAnnotationQueryRequest(options: any): AnnotationQueryRequest<LokiQuery> {
|
||||
function makeAnnotationQueryRequest(options = {}): AnnotationQueryRequest<LokiQuery> {
|
||||
const timeRange = {
|
||||
from: dateTime(),
|
||||
to: dateTime(),
|
||||
@@ -872,7 +839,9 @@ function makeAnnotationQueryRequest(options: any): AnnotationQueryRequest<LokiQu
|
||||
annotation: {
|
||||
expr: '{test=test}',
|
||||
refId: '',
|
||||
datasource: 'loki',
|
||||
datasource: {
|
||||
type: 'loki',
|
||||
},
|
||||
enable: true,
|
||||
name: 'test-annotation',
|
||||
iconColor: 'red',
|
||||
@@ -880,7 +849,7 @@ function makeAnnotationQueryRequest(options: any): AnnotationQueryRequest<LokiQu
|
||||
},
|
||||
dashboard: {
|
||||
id: 1,
|
||||
} as any,
|
||||
},
|
||||
range: {
|
||||
...timeRange,
|
||||
raw: timeRange,
|
||||
|
||||
@@ -2,10 +2,11 @@ import Plain from 'slate-plain-serializer';
|
||||
|
||||
import { AbstractLabelOperator } from '@grafana/data';
|
||||
import { TypeaheadInput } from '@grafana/ui';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
|
||||
import { LokiDatasource } from './datasource';
|
||||
import LanguageProvider, { LokiHistoryItem } from './language_provider';
|
||||
import { makeMockLokiDatasource } from './mocks';
|
||||
import { createLokiDatasource, createMetadataRequest } from './mocks';
|
||||
import { LokiQueryType } from './types';
|
||||
|
||||
jest.mock('app/store/store', () => ({
|
||||
@@ -21,7 +22,7 @@ jest.mock('app/store/store', () => ({
|
||||
}));
|
||||
|
||||
describe('Language completion provider', () => {
|
||||
const datasource = makeMockLokiDatasource({});
|
||||
const datasource = setup({});
|
||||
|
||||
describe('query suggestions', () => {
|
||||
it('returns no suggestions on empty context', async () => {
|
||||
@@ -90,7 +91,7 @@ describe('Language completion provider', () => {
|
||||
|
||||
describe('fetchSeries', () => {
|
||||
it('should use match[] parameter', () => {
|
||||
const datasource = makeMockLokiDatasource({}, { '{foo="bar"}': [{ label1: 'label_val1' }] });
|
||||
const datasource = setup({}, { '{foo="bar"}': [{ label1: 'label_val1' }] });
|
||||
const languageProvider = new LanguageProvider(datasource);
|
||||
const fetchSeries = languageProvider.fetchSeries;
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
@@ -105,11 +106,11 @@ describe('Language completion provider', () => {
|
||||
|
||||
describe('fetchSeriesLabels', () => {
|
||||
it('should interpolate variable in series', () => {
|
||||
const datasource: LokiDatasource = {
|
||||
metadataRequest: () => ({ data: { data: [] as any[] } }),
|
||||
getTimeRangeParams: () => ({ start: 0, end: 1 }),
|
||||
interpolateString: (string: string) => string.replace(/\$/, 'interpolated-'),
|
||||
} as any as LokiDatasource;
|
||||
const datasource = setup({});
|
||||
jest.spyOn(datasource, 'getTimeRangeParams').mockReturnValue({ start: 0, end: 1 });
|
||||
jest
|
||||
.spyOn(datasource, 'interpolateString')
|
||||
.mockImplementation((string: string) => string.replace(/\$/, 'interpolated-'));
|
||||
|
||||
const languageProvider = new LanguageProvider(datasource);
|
||||
const fetchSeriesLabels = languageProvider.fetchSeriesLabels;
|
||||
@@ -126,7 +127,7 @@ describe('Language completion provider', () => {
|
||||
|
||||
describe('label key suggestions', () => {
|
||||
it('returns all label suggestions on empty selector', async () => {
|
||||
const datasource = makeMockLokiDatasource({ label1: [], label2: [] });
|
||||
const datasource = setup({ label1: [], label2: [] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const input = createTypeaheadInput('{}', '', '', 1);
|
||||
const result = await provider.provideCompletionItems(input);
|
||||
@@ -143,7 +144,7 @@ describe('Language completion provider', () => {
|
||||
});
|
||||
|
||||
it('returns all label suggestions on selector when starting to type', async () => {
|
||||
const datasource = makeMockLokiDatasource({ label1: [], label2: [] });
|
||||
const datasource = setup({ label1: [], label2: [] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const input = createTypeaheadInput('{l}', '', '', 2);
|
||||
const result = await provider.provideCompletionItems(input);
|
||||
@@ -162,10 +163,7 @@ describe('Language completion provider', () => {
|
||||
|
||||
describe('label suggestions facetted', () => {
|
||||
it('returns facetted label suggestions based on selector', async () => {
|
||||
const datasource = makeMockLokiDatasource(
|
||||
{ label1: [], label2: [] },
|
||||
{ '{foo="bar"}': [{ label1: 'label_val1' }] }
|
||||
);
|
||||
const datasource = setup({ label1: [], label2: [] }, { '{foo="bar"}': [{ label1: 'label_val1' }] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const input = createTypeaheadInput('{foo="bar",}', '', '', 11);
|
||||
const result = await provider.provideCompletionItems(input);
|
||||
@@ -174,10 +172,7 @@ describe('Language completion provider', () => {
|
||||
});
|
||||
|
||||
it('returns facetted label suggestions for multipule selectors', async () => {
|
||||
const datasource = makeMockLokiDatasource(
|
||||
{ label1: [], label2: [] },
|
||||
{ '{baz="42",foo="bar"}': [{ label2: 'label_val2' }] }
|
||||
);
|
||||
const datasource = setup({ label1: [], label2: [] }, { '{baz="42",foo="bar"}': [{ label2: 'label_val2' }] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const input = createTypeaheadInput('{baz="42",foo="bar",}', '', '', 20);
|
||||
const result = await provider.provideCompletionItems(input);
|
||||
@@ -188,7 +183,7 @@ describe('Language completion provider', () => {
|
||||
|
||||
describe('label suggestions', () => {
|
||||
it('returns label values suggestions from Loki', async () => {
|
||||
const datasource = makeMockLokiDatasource({ label1: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const datasource = setup({ label1: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const input = createTypeaheadInput('{label1=}', '=', 'label1');
|
||||
let result = await provider.provideCompletionItems(input);
|
||||
@@ -206,7 +201,7 @@ describe('Language completion provider', () => {
|
||||
]);
|
||||
});
|
||||
it('returns label values suggestions from Loki when re-editing', async () => {
|
||||
const datasource = makeMockLokiDatasource({ label1: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const datasource = setup({ label1: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const input = createTypeaheadInput('{label1="label1_v"}', 'label1_v', 'label1', 17, [
|
||||
'attr-value',
|
||||
@@ -228,7 +223,7 @@ describe('Language completion provider', () => {
|
||||
|
||||
describe('label values', () => {
|
||||
it('should fetch label values if not cached', async () => {
|
||||
const datasource = makeMockLokiDatasource({ testkey: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const datasource = setup({ testkey: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const requestSpy = jest.spyOn(provider, 'request');
|
||||
const labelValues = await provider.fetchLabelValues('testkey');
|
||||
@@ -237,7 +232,7 @@ describe('Language completion provider', () => {
|
||||
});
|
||||
|
||||
it('should return cached values', async () => {
|
||||
const datasource = makeMockLokiDatasource({ testkey: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const datasource = setup({ testkey: ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const requestSpy = jest.spyOn(provider, 'request');
|
||||
const labelValues = await provider.fetchLabelValues('testkey');
|
||||
@@ -250,7 +245,7 @@ describe('Language completion provider', () => {
|
||||
});
|
||||
|
||||
it('should encode special characters', async () => {
|
||||
const datasource = makeMockLokiDatasource({ '`\\"testkey': ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const datasource = setup({ '`\\"testkey': ['label1_val1', 'label1_val2'], label2: [] });
|
||||
const provider = await getLanguageProvider(datasource);
|
||||
const requestSpy = jest.spyOn(provider, 'request');
|
||||
await provider.fetchLabelValues('`\\"testkey');
|
||||
@@ -262,9 +257,9 @@ describe('Language completion provider', () => {
|
||||
|
||||
describe('Request URL', () => {
|
||||
it('should contain range params', async () => {
|
||||
const datasourceWithLabels = makeMockLokiDatasource({ other: [] });
|
||||
const datasourceWithLabels = setup({ other: [] });
|
||||
const rangeParams = datasourceWithLabels.getTimeRangeParams();
|
||||
const datasourceSpy = jest.spyOn(datasourceWithLabels as any, 'metadataRequest');
|
||||
const datasourceSpy = jest.spyOn(datasourceWithLabels, 'metadataRequest');
|
||||
|
||||
const instance = new LanguageProvider(datasourceWithLabels);
|
||||
instance.fetchLabels();
|
||||
@@ -274,7 +269,7 @@ describe('Request URL', () => {
|
||||
});
|
||||
|
||||
describe('Query imports', () => {
|
||||
const datasource = makeMockLokiDatasource({});
|
||||
const datasource = setup({});
|
||||
|
||||
it('returns empty queries', async () => {
|
||||
const instance = new LanguageProvider(datasource);
|
||||
@@ -334,3 +329,21 @@ function createTypeaheadInput(
|
||||
labelKey,
|
||||
};
|
||||
}
|
||||
|
||||
function setup(
|
||||
labelsAndValues: Record<string, string[]>,
|
||||
series?: Record<string, Array<Record<string, string>>>
|
||||
): LokiDatasource {
|
||||
const datasource = createLokiDatasource({} as unknown as TemplateSrv);
|
||||
|
||||
const rangeMock = {
|
||||
start: 1560153109000,
|
||||
end: 1560163909000,
|
||||
};
|
||||
|
||||
jest.spyOn(datasource, 'getTimeRangeParams').mockReturnValue(rangeMock);
|
||||
jest.spyOn(datasource, 'metadataRequest').mockImplementation(createMetadataRequest(labelsAndValues, series));
|
||||
jest.spyOn(datasource, 'interpolateString').mockImplementation((string: string) => string);
|
||||
|
||||
return datasource;
|
||||
}
|
||||
|
||||
@@ -1,57 +1,96 @@
|
||||
import { DataSourceSettings } from '@grafana/data';
|
||||
import { DataSourceInstanceSettings, DataSourceSettings, PluginType, toUtc } from '@grafana/data';
|
||||
import { TemplateSrv } from '@grafana/runtime';
|
||||
|
||||
import { getMockDataSource } from '../../../features/datasources/__mocks__';
|
||||
|
||||
import { LokiDatasource } from './datasource';
|
||||
import { LokiOptions } from './types';
|
||||
|
||||
interface Labels {
|
||||
[label: string]: string[];
|
||||
}
|
||||
|
||||
interface Series {
|
||||
[label: string]: string;
|
||||
}
|
||||
|
||||
interface SeriesForSelector {
|
||||
[selector: string]: Series[];
|
||||
}
|
||||
|
||||
export function makeMockLokiDatasource(labelsAndValues: Labels, series?: SeriesForSelector): LokiDatasource {
|
||||
// added % to allow urlencoded labelKeys. Note, that this is not confirm with Loki, as loki does not allow specialcharacters in labelKeys, but needed for tests.
|
||||
const lokiLabelsAndValuesEndpointRegex = /^label\/([%\w]*)\/values/;
|
||||
const lokiSeriesEndpointRegex = /^series/;
|
||||
|
||||
const lokiLabelsEndpoint = 'labels';
|
||||
const rangeMock = {
|
||||
start: 1560153109000,
|
||||
end: 1560163909000,
|
||||
};
|
||||
|
||||
const labels = Object.keys(labelsAndValues);
|
||||
return {
|
||||
getTimeRangeParams: () => rangeMock,
|
||||
metadataRequest: (url: string, params?: { [key: string]: string }) => {
|
||||
if (url === lokiLabelsEndpoint) {
|
||||
return labels;
|
||||
} else {
|
||||
const labelsMatch = url.match(lokiLabelsAndValuesEndpointRegex);
|
||||
const seriesMatch = url.match(lokiSeriesEndpointRegex);
|
||||
if (labelsMatch) {
|
||||
return labelsAndValues[labelsMatch[1]] || [];
|
||||
} else if (seriesMatch && series && params) {
|
||||
return series[params['match[]']] || [];
|
||||
} else {
|
||||
throw new Error(`Unexpected url error, ${url}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
interpolateString: (string: string) => string,
|
||||
} as any;
|
||||
}
|
||||
|
||||
export function createDefaultConfigOptions(): DataSourceSettings<LokiOptions> {
|
||||
return getMockDataSource<LokiOptions>({
|
||||
jsonData: { maxLines: '531' },
|
||||
});
|
||||
}
|
||||
|
||||
const rawRange = {
|
||||
from: toUtc('2018-04-25 10:00'),
|
||||
to: toUtc('2018-04-25 11:00'),
|
||||
};
|
||||
|
||||
const defaultTimeSrvMock = {
|
||||
timeRange: () => ({
|
||||
from: rawRange.from,
|
||||
to: rawRange.to,
|
||||
raw: rawRange,
|
||||
}),
|
||||
};
|
||||
|
||||
export function createLokiDatasource(
|
||||
templateSrvMock: TemplateSrv,
|
||||
settings: Partial<DataSourceInstanceSettings<LokiOptions>> = {},
|
||||
timeSrvStub = defaultTimeSrvMock
|
||||
): LokiDatasource {
|
||||
const customSettings: DataSourceInstanceSettings<LokiOptions> = {
|
||||
url: 'myloggingurl',
|
||||
id: 0,
|
||||
uid: '',
|
||||
type: '',
|
||||
name: '',
|
||||
meta: {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
type: PluginType.datasource,
|
||||
module: '',
|
||||
baseUrl: '',
|
||||
info: {
|
||||
author: {
|
||||
name: 'Test',
|
||||
},
|
||||
description: '',
|
||||
links: [],
|
||||
logos: {
|
||||
large: '',
|
||||
small: '',
|
||||
},
|
||||
screenshots: [],
|
||||
updated: '',
|
||||
version: '',
|
||||
},
|
||||
},
|
||||
jsonData: {
|
||||
maxLines: '20',
|
||||
},
|
||||
access: 'direct',
|
||||
...settings,
|
||||
};
|
||||
|
||||
// @ts-expect-error
|
||||
return new LokiDatasource(customSettings, templateSrvMock, timeSrvStub);
|
||||
}
|
||||
|
||||
export function createMetadataRequest(
|
||||
labelsAndValues: Record<string, string[]>,
|
||||
series?: Record<string, Array<Record<string, string>>>
|
||||
) {
|
||||
// added % to allow urlencoded labelKeys. Note, that this is not confirm with Loki, as loki does not allow specialcharacters in labelKeys, but needed for tests.
|
||||
const lokiLabelsAndValuesEndpointRegex = /^label\/([%\w]*)\/values/;
|
||||
const lokiSeriesEndpointRegex = /^series/;
|
||||
const lokiLabelsEndpoint = 'labels';
|
||||
const labels = Object.keys(labelsAndValues);
|
||||
|
||||
return async function metadataRequestMock(url: string, params?: Record<string, string | number>) {
|
||||
if (url === lokiLabelsEndpoint) {
|
||||
return labels;
|
||||
} else {
|
||||
const labelsMatch = url.match(lokiLabelsAndValuesEndpointRegex);
|
||||
const seriesMatch = url.match(lokiSeriesEndpointRegex);
|
||||
if (labelsMatch) {
|
||||
return labelsAndValues[labelsMatch[1]] || [];
|
||||
} else if (seriesMatch && series && params) {
|
||||
return series[params['match[]']] || [];
|
||||
} else {
|
||||
throw new Error(`Unexpected url error, ${url}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user