import { ArrayVector, DataFrame, DataSourceInstanceSettings, DataSourceSettings, FieldType, PluginType, toUtc, } from '@grafana/data'; import { TemplateSrv } from '@grafana/runtime'; import { getMockDataSource } from '../../../features/datasources/__mocks__'; import { LokiDatasource } from './datasource'; import { LokiOptions } from './types'; export function createDefaultConfigOptions(): DataSourceSettings { return getMockDataSource({ jsonData: { maxLines: '531' }, }); } const rawRange = { from: toUtc('2018-04-25 10:00'), to: toUtc('2018-04-25 11:00'), }; const defaultTimeSrvMock = { timeRange: jest.fn().mockReturnValue({ from: rawRange.from, to: rawRange.to, raw: rawRange, }), }; const defaultTemplateSrvMock = { replace: (input: string) => input, }; export function createLokiDatasource( templateSrvMock: Partial = defaultTemplateSrvMock, settings: Partial> = {}, timeSrvStub = defaultTimeSrvMock ): LokiDatasource { const customSettings: DataSourceInstanceSettings = { 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: '', }, }, readOnly: false, jsonData: { maxLines: '20', }, access: 'direct', ...settings, }; // @ts-expect-error return new LokiDatasource(customSettings, templateSrvMock, timeSrvStub); } export function createMetadataRequest( labelsAndValues: Record, series?: Record>> ) { // 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) { 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}`); } } }; } export function getMockFrames() { const logFrameA: DataFrame = { refId: 'A', fields: [ { name: 'Time', type: FieldType.time, config: {}, values: new ArrayVector([3, 4]), }, { name: 'Line', type: FieldType.string, config: {}, values: new ArrayVector(['line1', 'line2']), }, { name: 'labels', type: FieldType.other, config: {}, values: new ArrayVector([ { label: 'value', }, { otherLabel: 'other value', }, ]), }, { name: 'tsNs', type: FieldType.string, config: {}, values: new ArrayVector(['3000000', '4000000']), }, { name: 'id', type: FieldType.string, config: {}, values: new ArrayVector(['id1', 'id2']), }, ], length: 2, }; const logFrameB: DataFrame = { refId: 'A', fields: [ { name: 'Time', type: FieldType.time, config: {}, values: new ArrayVector([1, 2]), }, { name: 'Line', type: FieldType.string, config: {}, values: new ArrayVector(['line3', 'line4']), }, { name: 'labels', type: FieldType.other, config: {}, values: new ArrayVector([ { otherLabel: 'other value', }, ]), }, { name: 'tsNs', type: FieldType.string, config: {}, values: new ArrayVector(['1000000', '2000000']), }, { name: 'id', type: FieldType.string, config: {}, values: new ArrayVector(['id3', 'id4']), }, ], meta: { stats: [{ displayName: 'Ingester: total reached', value: 1 }], }, length: 2, }; const metricFrameA: DataFrame = { refId: 'A', fields: [ { name: 'Time', type: FieldType.time, config: {}, values: new ArrayVector([3000000, 4000000]), }, { name: 'Value', type: FieldType.number, config: {}, values: new ArrayVector([5, 4]), }, ], meta: { stats: [{ displayName: 'Ingester: total reached', value: 1 }], }, length: 2, }; const metricFrameB: DataFrame = { refId: 'A', fields: [ { name: 'Time', type: FieldType.time, config: {}, values: new ArrayVector([1000000, 2000000]), }, { name: 'Value', type: FieldType.number, config: {}, values: new ArrayVector([6, 7]), }, ], meta: { stats: [{ displayName: 'Ingester: total reached', value: 2 }], }, length: 2, }; const metricFrameC: DataFrame = { refId: 'A', name: 'some-time-series', fields: [ { name: 'Time', type: FieldType.time, config: {}, values: new ArrayVector([3000000, 4000000]), }, { name: 'Value', type: FieldType.number, config: {}, values: new ArrayVector([6, 7]), }, ], meta: { stats: [{ displayName: 'Ingester: total reached', value: 2 }], }, length: 2, }; return { logFrameA, logFrameB, metricFrameA, metricFrameB, metricFrameC, }; }