mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 01:23:32 -06:00
* Fix: Fix queries (cached & non) count in usage insights * also keep deprecated error property * Fix & refactor tests
285 lines
7.4 KiB
TypeScript
285 lines
7.4 KiB
TypeScript
import {
|
|
CoreApp,
|
|
DataFrame,
|
|
DataQueryError,
|
|
getDefaultTimeRange,
|
|
DataSourceApi,
|
|
dateTime,
|
|
LoadingState,
|
|
PanelData,
|
|
DataQueryRequest,
|
|
} from '@grafana/data';
|
|
import { MetaAnalyticsEventName, reportMetaAnalytics } from '@grafana/runtime';
|
|
|
|
import { createDashboardModelFixture } from '../../dashboard/state/__fixtures__/dashboardFixtures';
|
|
|
|
import { emitDataRequestEvent } from './queryAnalytics';
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
const datasource = {
|
|
name: 'test',
|
|
id: 1,
|
|
uid: 'test',
|
|
} as DataSourceApi;
|
|
|
|
const dashboardModel = createDashboardModelFixture(
|
|
{ id: 1, title: 'Test Dashboard', uid: 'test' },
|
|
{ folderTitle: 'Test Folder' }
|
|
);
|
|
|
|
jest.mock('app/features/dashboard/services/DashboardSrv', () => ({
|
|
getDashboardSrv: () => {
|
|
return {
|
|
getCurrent: () => dashboardModel,
|
|
};
|
|
},
|
|
}));
|
|
|
|
jest.mock('@grafana/runtime', () => ({
|
|
...jest.requireActual('@grafana/runtime'),
|
|
reportMetaAnalytics: jest.fn(),
|
|
}));
|
|
|
|
const mockGetUrlSearchParams = jest.fn(() => {
|
|
return {};
|
|
});
|
|
jest.mock('@grafana/data', () => ({
|
|
...jest.requireActual('@grafana/data'),
|
|
urlUtil: {
|
|
getUrlSearchParams: () => mockGetUrlSearchParams(),
|
|
},
|
|
}));
|
|
|
|
const partiallyCachedSeries = [
|
|
{
|
|
refId: 'A',
|
|
meta: {
|
|
isCachedResponse: true,
|
|
},
|
|
fields: [],
|
|
length: 0,
|
|
},
|
|
{
|
|
refId: 'B',
|
|
fields: [],
|
|
length: 0,
|
|
},
|
|
];
|
|
|
|
const multipleDataframesWithSameRefId = [
|
|
{
|
|
refId: 'A',
|
|
meta: {
|
|
isCachedResponse: true,
|
|
},
|
|
fields: [],
|
|
length: 0,
|
|
},
|
|
{
|
|
refId: 'A',
|
|
fields: [],
|
|
length: 0,
|
|
},
|
|
];
|
|
|
|
function getTestData(
|
|
overrides: Partial<DataQueryRequest> = {},
|
|
series?: DataFrame[],
|
|
errors?: DataQueryError[]
|
|
): PanelData {
|
|
const now = dateTime();
|
|
return {
|
|
request: {
|
|
app: CoreApp.Dashboard,
|
|
startTime: now.unix(),
|
|
endTime: now.add(1, 's').unix(),
|
|
interval: '1s',
|
|
intervalMs: 1000,
|
|
range: getDefaultTimeRange(),
|
|
requestId: '1',
|
|
scopedVars: {},
|
|
targets: [],
|
|
timezone: 'utc',
|
|
...overrides,
|
|
},
|
|
series: series || [],
|
|
state: LoadingState.Done,
|
|
timeRange: getDefaultTimeRange(),
|
|
errors,
|
|
};
|
|
}
|
|
|
|
describe('emitDataRequestEvent', () => {
|
|
describe('From a dashboard panel', () => {
|
|
it('Should report meta analytics', () => {
|
|
const data = getTestData({
|
|
panelId: 2,
|
|
});
|
|
emitDataRequestEvent(datasource)(data);
|
|
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
expect(reportMetaAnalytics).toBeCalledWith(
|
|
expect.objectContaining({
|
|
eventName: MetaAnalyticsEventName.DataRequest,
|
|
datasourceName: datasource.name,
|
|
datasourceUid: datasource.uid,
|
|
datasourceType: datasource.type,
|
|
source: CoreApp.Dashboard,
|
|
panelId: 2,
|
|
dashboardUid: 'test', // from dashboard srv
|
|
dataSize: 0,
|
|
duration: 1,
|
|
totalQueries: 0,
|
|
cachedQueries: 0,
|
|
})
|
|
);
|
|
});
|
|
|
|
it('Should report meta analytics with counts for cached and total queries', () => {
|
|
const data = getTestData(
|
|
{
|
|
panelId: 2,
|
|
},
|
|
partiallyCachedSeries
|
|
);
|
|
emitDataRequestEvent(datasource)(data);
|
|
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
expect(reportMetaAnalytics).toBeCalledWith(
|
|
expect.objectContaining({
|
|
eventName: MetaAnalyticsEventName.DataRequest,
|
|
datasourceName: datasource.name,
|
|
datasourceUid: datasource.uid,
|
|
datasourceType: datasource.type,
|
|
source: CoreApp.Dashboard,
|
|
panelId: 2,
|
|
dashboardUid: 'test',
|
|
dataSize: 2,
|
|
duration: 1,
|
|
totalQueries: 2,
|
|
cachedQueries: 1,
|
|
})
|
|
);
|
|
});
|
|
|
|
it('Should report meta analytics with counts for cached and total queries when same refId spread across multiple DataFrames', () => {
|
|
const data = getTestData(
|
|
{
|
|
panelId: 2,
|
|
},
|
|
multipleDataframesWithSameRefId
|
|
);
|
|
emitDataRequestEvent(datasource)(data);
|
|
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
expect(reportMetaAnalytics).toBeCalledWith(
|
|
expect.objectContaining({
|
|
eventName: MetaAnalyticsEventName.DataRequest,
|
|
datasourceName: datasource.name,
|
|
datasourceUid: datasource.uid,
|
|
datasourceType: datasource.type,
|
|
source: CoreApp.Dashboard,
|
|
panelId: 2,
|
|
dashboardUid: 'test', // from dashboard srv
|
|
dataSize: 2,
|
|
duration: 1,
|
|
totalQueries: 1,
|
|
cachedQueries: 1,
|
|
})
|
|
);
|
|
});
|
|
|
|
it('Should not report meta analytics twice if the request receives multiple responses', () => {
|
|
const data = getTestData();
|
|
const fn = emitDataRequestEvent(datasource);
|
|
fn(data);
|
|
fn(data);
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
});
|
|
|
|
it('Should not report meta analytics in edit mode', () => {
|
|
mockGetUrlSearchParams.mockImplementationOnce(() => {
|
|
return { editPanel: 2 };
|
|
});
|
|
const data = getTestData();
|
|
emitDataRequestEvent(datasource)(data);
|
|
expect(reportMetaAnalytics).not.toBeCalled();
|
|
});
|
|
});
|
|
|
|
// Previously we filtered out Explore and Correlations events due to too many errors being generated while a user is building a query
|
|
// This tests that we send an event for both queries but do not record errors
|
|
describe('From Explore', () => {
|
|
const data = getTestData(
|
|
{
|
|
app: CoreApp.Explore,
|
|
},
|
|
undefined,
|
|
[{ message: 'test error' }]
|
|
);
|
|
|
|
it('Should report meta analytics', () => {
|
|
emitDataRequestEvent(datasource)(data);
|
|
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
expect(reportMetaAnalytics).toBeCalledWith(
|
|
expect.objectContaining({
|
|
eventName: MetaAnalyticsEventName.DataRequest,
|
|
source: CoreApp.Explore,
|
|
datasourceName: 'test',
|
|
datasourceUid: 'test',
|
|
dataSize: 0,
|
|
duration: 1,
|
|
totalQueries: 0,
|
|
})
|
|
);
|
|
});
|
|
|
|
it('Should not report errors', () => {
|
|
emitDataRequestEvent(datasource)(data);
|
|
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
expect(reportMetaAnalytics).toBeCalledWith(expect.not.objectContaining({ error: 'test error' }));
|
|
});
|
|
});
|
|
|
|
// Previously we filtered out Explore and Correlations events due to too many errors being generated while a user is building a query
|
|
// This tests that we send an event for both queries but do not record errors
|
|
describe('From Correlations', () => {
|
|
const data = getTestData(
|
|
{
|
|
app: CoreApp.Correlations,
|
|
},
|
|
undefined,
|
|
[{ message: 'some error' }]
|
|
);
|
|
|
|
it('Should report meta analytics', () => {
|
|
emitDataRequestEvent(datasource)(data);
|
|
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
expect(reportMetaAnalytics).toBeCalledWith(
|
|
expect.objectContaining({
|
|
eventName: MetaAnalyticsEventName.DataRequest,
|
|
source: CoreApp.Correlations,
|
|
datasourceName: 'test',
|
|
datasourceUid: 'test',
|
|
dataSize: 0,
|
|
duration: 1,
|
|
totalQueries: 0,
|
|
})
|
|
);
|
|
});
|
|
|
|
it('Should not report errors', () => {
|
|
emitDataRequestEvent(datasource)(data);
|
|
|
|
expect(reportMetaAnalytics).toBeCalledTimes(1);
|
|
expect(reportMetaAnalytics).toBeCalledWith(expect.not.objectContaining({ error: 'test error' }));
|
|
});
|
|
});
|
|
});
|