Chore: Jaeger ds to use new fetch api (#31969)

pull/32014/head
Zoltán Bedi 4 years ago committed by GitHub
parent 0d92425bb8
commit fe763d7d92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 194
      public/app/plugins/datasource/jaeger/datasource.test.ts
  2. 13
      public/app/plugins/datasource/jaeger/datasource.ts

@ -1,21 +1,32 @@
import { JaegerDatasource, JaegerQuery } from './datasource';
import {
ArrayVector,
DataQueryRequest,
DataSourceInstanceSettings,
dateTime,
FieldType,
PluginType,
dateTime,
ArrayVector,
} from '@grafana/data';
import { BackendSrv, BackendSrvRequest, getBackendSrv, setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { of, throwError } from 'rxjs';
import { createFetchResponse } from 'test/helpers/createFetchResponse';
import { JaegerDatasource, JaegerQuery } from './datasource';
import { testResponse } from './testResponse';
jest.mock('@grafana/runtime', () => ({
...((jest.requireActual('@grafana/runtime') as unknown) as object),
getBackendSrv: () => backendSrv,
}));
describe('JaegerDatasource', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('returns trace when queried', async () => {
await withMockedBackendSrv(makeBackendSrvMock('12345'), async () => {
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.query(defaultQuery).toPromise();
expect(response.data[0].fields).toMatchObject(
setupFetchMock({ data: [testResponse] });
const ds = new JaegerDatasource(defaultSettings);
await expect(ds.query(defaultQuery)).toEmitValuesWith((val) => {
expect(val[0].data[0].fields).toMatchObject(
[
{ name: 'traceID', values: ['3fa414edcef6ad90', '3fa414edcef6ad90'] },
{ name: 'spanID', values: ['3fa414edcef6ad90', '0f5c1808567e4403'] },
@ -59,20 +70,19 @@ describe('JaegerDatasource', () => {
});
it('returns trace when traceId with special characters is queried', async () => {
await withMockedBackendSrv(makeBackendSrvMock('a/b'), async () => {
const ds = new JaegerDatasource(defaultSettings);
const query = {
...defaultQuery,
targets: [
{
query: 'a/b',
refId: '1',
},
],
};
await ds.query(query).toPromise();
// there is expect makeBackendSrvMock checking correct encoding
});
const mock = setupFetchMock({ data: [testResponse] });
const ds = new JaegerDatasource(defaultSettings);
const query = {
...defaultQuery,
targets: [
{
query: 'a/b',
refId: '1',
},
],
};
await ds.query(query).toPromise();
expect(mock).toBeCalledWith({ url: `${defaultSettings.url}/api/traces/a%2Fb` });
});
it('returns empty response if trace id is not specified', async () => {
@ -93,120 +103,75 @@ describe('JaegerDatasource', () => {
describe('when performing testDataSource', () => {
describe('and call succeeds', () => {
it('should return successfully', async () => {
const backendSrvMock = makeTestDatasourceMock(
Promise.resolve({
statusText: 'OK',
status: 200,
data: {
data: ['service1'],
},
})
);
setupFetchMock({ data: ['service1'] });
await withMockedBackendSrv(backendSrvMock, async () => {
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('success');
expect(response.message).toBe('Data source connected and services found.');
});
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('success');
expect(response.message).toBe('Data source connected and services found.');
});
});
describe('and call succeeds, but returns no services', () => {
it('should display an error', async () => {
const backendSrvMock = makeTestDatasourceMock(
Promise.resolve({
statusText: 'OK',
status: 200,
})
);
setupFetchMock(undefined);
await withMockedBackendSrv(backendSrvMock, async () => {
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('error');
expect(response.message).toBe(
'Data source connected, but no services received. Verify that Jaeger is configured properly.'
);
});
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('error');
expect(response.message).toBe(
'Data source connected, but no services received. Verify that Jaeger is configured properly.'
);
});
});
describe('and call returns error with message', () => {
it('should return the formatted error', async () => {
const backendSrvMock = {
datasourceRequest(options: BackendSrvRequest): Promise<any> {
return Promise.reject({
statusText: 'Not found',
status: 404,
data: {
message: '404 page not found',
},
});
},
} as BackendSrv;
await withMockedBackendSrv(backendSrvMock, async () => {
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('error');
expect(response.message).toBe('Jaeger: Not found. 404. 404 page not found');
});
setupFetchMock(
undefined,
throwError({
statusText: 'Not found',
status: 404,
data: {
message: '404 page not found',
},
})
);
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('error');
expect(response.message).toBe('Jaeger: Not found. 404. 404 page not found');
});
});
describe('and call returns error without message', () => {
it('should return JSON error', async () => {
const backendSrvMock = {
datasourceRequest(options: BackendSrvRequest): Promise<any> {
return Promise.reject({
statusText: 'Bad gateway',
status: 502,
data: {
errors: ['Could not connect to Jaeger backend'],
},
});
},
} as BackendSrv;
await withMockedBackendSrv(backendSrvMock, async () => {
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('error');
expect(response.message).toBe('Jaeger: Bad gateway. 502. {"errors":["Could not connect to Jaeger backend"]}');
});
setupFetchMock(
undefined,
throwError({
statusText: 'Bad gateway',
status: 502,
data: {
errors: ['Could not connect to Jaeger backend'],
},
})
);
const ds = new JaegerDatasource(defaultSettings);
const response = await ds.testDatasource();
expect(response.status).toEqual('error');
expect(response.message).toBe('Jaeger: Bad gateway. 502. {"errors":["Could not connect to Jaeger backend"]}');
});
});
});
function makeTestDatasourceMock(result: Promise<any>) {
return {
datasourceRequest(options: BackendSrvRequest): Promise<any> {
return result;
},
} as BackendSrv;
}
function makeBackendSrvMock(traceId: string) {
return {
datasourceRequest(options: BackendSrvRequest): Promise<any> {
expect(options.url.substr(options.url.length - 17, options.url.length)).toBe(
`/api/traces/${encodeURIComponent(traceId)}`
);
return Promise.resolve({
data: {
data: [testResponse],
},
});
},
} as any;
}
function setupFetchMock(response: any, mock?: any) {
const defaultMock = () => mock ?? of(createFetchResponse(response));
async function withMockedBackendSrv(srv: BackendSrv, fn: () => Promise<void>) {
const oldSrv = getBackendSrv();
setBackendSrv(srv);
await fn();
setBackendSrv(oldSrv);
const fetchMock = jest.spyOn(backendSrv, 'fetch');
fetchMock.mockImplementation(defaultMock);
return fetchMock;
}
const defaultSettings: DataSourceInstanceSettings = {
@ -214,6 +179,7 @@ const defaultSettings: DataSourceInstanceSettings = {
uid: '0',
type: 'tracing',
name: 'jaeger',
url: 'http://grafana.com',
meta: {
id: 'jaeger',
name: 'jaeger',

@ -10,11 +10,10 @@ import {
MutableDataFrame,
} from '@grafana/data';
import { BackendSrvRequest, getBackendSrv } from '@grafana/runtime';
import { from, Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { serializeParams } from 'app/core/utils/fetch';
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { createTraceFrame } from './responseTransform';
export type JaegerQuery = {
@ -100,16 +99,14 @@ export class JaegerDatasource extends DataSourceApi<JaegerQuery> {
}
private _request(apiUrl: string, data?: any, options?: Partial<BackendSrvRequest>): Observable<Record<string, any>> {
// Hack for proxying metadata requests
const baseUrl = `/api/datasources/proxy/${this.instanceSettings.id}`;
const params = data ? serializeParams(data) : '';
const url = `${baseUrl}${apiUrl}${params.length ? `?${params}` : ''}`;
const url = `${this.instanceSettings.url}${apiUrl}${params.length ? `?${params}` : ''}`;
const req = {
...options,
url,
};
return from(getBackendSrv().datasourceRequest(req));
return getBackendSrv().fetch(req);
}
}

Loading…
Cancel
Save