The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/plugins/datasource/loki/datasource.test.ts

211 lines
6.4 KiB

import LokiDatasource from './datasource';
import { LokiQuery } from './types';
import { getQueryOptions } from 'test/helpers/getQueryOptions';
import { DataSourceApi } from '@grafana/ui';
import { DataFrame } from '@grafana/data';
import { BackendSrv } from 'app/core/services/backend_srv';
import { TemplateSrv } from 'app/features/templating/template_srv';
describe('LokiDatasource', () => {
const instanceSettings: any = {
url: 'myloggingurl',
};
const testResp = {
data: {
streams: [
{
entries: [{ ts: '2019-02-01T10:27:37.498180581Z', line: 'hello' }],
labels: '{}',
},
],
},
};
describe('when querying', () => {
const backendSrvMock = { datasourceRequest: jest.fn() };
const backendSrv = (backendSrvMock as unknown) as BackendSrv;
const templateSrvMock = ({
getAdhocFilters: (): any[] => [],
replace: (a: string) => a,
} as unknown) as TemplateSrv;
const testLimit = makeLimitTest(instanceSettings, backendSrvMock, backendSrv, templateSrvMock, testResp);
test('should use default max lines when no limit given', () => {
testLimit({
expectedLimit: 1000,
});
});
7 years ago
test('should use custom max lines if limit is set', () => {
testLimit({
maxLines: 20,
expectedLimit: 20,
});
});
test('should use custom maxDataPoints if set in request', () => {
testLimit({
maxDataPoints: 500,
expectedLimit: 500,
});
});
test('should use datasource maxLimit if maxDataPoints is higher', () => {
testLimit({
maxLines: 20,
maxDataPoints: 500,
expectedLimit: 20,
});
});
test('should return series data', async done => {
const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
const customSettings = { ...instanceSettings, jsonData: customData };
const ds = new LokiDatasource(customSettings, backendSrv, templateSrvMock);
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
const options = getQueryOptions<LokiQuery>({
targets: [{ expr: '{} foo', refId: 'B' }],
});
const res = await ds.query(options);
const dataFrame = res.data[0] as DataFrame;
expect(dataFrame.fields[1].values.get(0)).toBe('hello');
expect(dataFrame.meta.limit).toBe(20);
expect(dataFrame.meta.searchWords).toEqual(['(?i)foo']);
done();
});
});
describe('when performing testDataSource', () => {
let ds: DataSourceApi<any, any>;
let result: any;
describe('and call succeeds', () => {
beforeEach(async () => {
const backendSrv = ({
async datasourceRequest() {
return Promise.resolve({
status: 200,
data: {
values: ['avalue'],
},
});
},
} as unknown) as BackendSrv;
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
result = await ds.testDatasource();
});
it('should return successfully', () => {
expect(result.status).toBe('success');
});
});
describe('and call fails with 401 error', () => {
beforeEach(async () => {
const backendSrv = ({
async datasourceRequest() {
return Promise.reject({
statusText: 'Unauthorized',
status: 401,
data: {
message: 'Unauthorized',
},
});
},
} as unknown) as BackendSrv;
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
result = await ds.testDatasource();
});
it('should return error status and a detailed error message', () => {
expect(result.status).toEqual('error');
expect(result.message).toBe('Loki: Unauthorized. 401. Unauthorized');
});
});
describe('and call fails with 404 error', () => {
beforeEach(async () => {
const backendSrv = ({
async datasourceRequest() {
return Promise.reject({
statusText: 'Not found',
status: 404,
data: '404 page not found',
});
},
} as unknown) as BackendSrv;
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
result = await ds.testDatasource();
});
it('should return error status and a detailed error message', () => {
expect(result.status).toEqual('error');
expect(result.message).toBe('Loki: Not found. 404. 404 page not found');
});
});
describe('and call fails with 502 error', () => {
beforeEach(async () => {
const backendSrv = ({
async datasourceRequest() {
return Promise.reject({
statusText: 'Bad Gateway',
status: 502,
data: '',
});
},
} as unknown) as BackendSrv;
ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
result = await ds.testDatasource();
});
it('should return error status and a detailed error message', () => {
expect(result.status).toEqual('error');
expect(result.message).toBe('Loki: Bad Gateway. 502');
});
});
});
});
type LimitTestArgs = {
maxDataPoints?: number;
maxLines?: number;
expectedLimit: number;
};
function makeLimitTest(
instanceSettings: any,
backendSrvMock: any,
backendSrv: any,
templateSrvMock: any,
testResp: any
) {
return ({ maxDataPoints, maxLines, expectedLimit }: LimitTestArgs) => {
let settings = instanceSettings;
if (Number.isFinite(maxLines)) {
const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
settings = { ...instanceSettings, jsonData: customData };
}
const ds = new LokiDatasource(settings, backendSrv, templateSrvMock);
backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
const options = getQueryOptions<LokiQuery>({ targets: [{ expr: 'foo', refId: 'B' }] });
if (Number.isFinite(maxDataPoints)) {
options.maxDataPoints = maxDataPoints;
} else {
// By default is 500
delete options.maxDataPoints;
}
ds.query(options);
expect(backendSrvMock.datasourceRequest.mock.calls.length).toBe(1);
expect(backendSrvMock.datasourceRequest.mock.calls[0][0].url).toContain(`limit=${expectedLimit}`);
};
}