mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Cloud Monitoring: Remove dependencies (#79282)
This commit is contained in:
parent
8ff0cfddf4
commit
e27e2f66ba
@ -1,11 +1,9 @@
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { TemplateSrvMock } from 'app/features/templating/template_srv.mock';
|
||||
import { TemplateSrv, getTemplateSrv } from '@grafana/runtime';
|
||||
|
||||
import Datasource from '../datasource';
|
||||
|
||||
export const createMockDatasource = (overrides?: Partial<Datasource>) => {
|
||||
const templateSrv = new TemplateSrvMock({ ALIGN_DELTA: 'delta' }) as unknown as TemplateSrv;
|
||||
const templateSrv = getTemplateSrv() as unknown as TemplateSrv;
|
||||
|
||||
const datasource: Partial<Datasource> = {
|
||||
intervalMs: 0,
|
||||
@ -17,7 +15,6 @@ export const createMockDatasource = (overrides?: Partial<Datasource>) => {
|
||||
filterMetricsByType: jest.fn().mockResolvedValue([]),
|
||||
getSLOServices: jest.fn().mockResolvedValue([]),
|
||||
migrateQuery: jest.fn().mockImplementation((query) => query),
|
||||
timeSrv: getTimeSrv(),
|
||||
...overrides,
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@ import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { openMenu } from 'react-select-event';
|
||||
|
||||
import { TemplateSrvMock } from 'app/features/templating/template_srv.mock';
|
||||
import { CustomVariableModel } from '@grafana/data';
|
||||
|
||||
import { createMockDatasource } from '../__mocks__/cloudMonitoringDatasource';
|
||||
import { createMockMetricDescriptor } from '../__mocks__/cloudMonitoringMetricDescriptor';
|
||||
@ -12,10 +12,21 @@ import { MetricKind, ValueTypes } from '../types/query';
|
||||
|
||||
import { Alignment } from './Alignment';
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getTemplateSrv: () => new TemplateSrvMock({}),
|
||||
}));
|
||||
let getTempVars = () => [] as CustomVariableModel[];
|
||||
let replace = () => '';
|
||||
|
||||
jest.mock('@grafana/runtime', () => {
|
||||
return {
|
||||
__esModule: true,
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getTemplateSrv: () => ({
|
||||
replace: replace,
|
||||
getVariables: getTempVars,
|
||||
updateTimeRange: jest.fn(),
|
||||
containsTemplate: jest.fn(),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Alignment', () => {
|
||||
it('renders alignment fields', () => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useDebounce } from 'react-use';
|
||||
|
||||
import { QueryEditorProps, toOption } from '@grafana/data';
|
||||
import { QueryEditorProps, getDefaultTimeRange, toOption } from '@grafana/data';
|
||||
import { EditorField, EditorRows } from '@grafana/experimental';
|
||||
import { Input } from '@grafana/ui';
|
||||
|
||||
@ -22,7 +22,7 @@ export const defaultQuery: (datasource: CloudMonitoringDatasource) => TimeSeries
|
||||
});
|
||||
|
||||
export const AnnotationQueryEditor = (props: Props) => {
|
||||
const { datasource, query, onRunQuery, data, onChange } = props;
|
||||
const { datasource, query, onRunQuery, data, onChange, range } = props;
|
||||
const meta = data?.series.length ? data?.series[0].meta : {};
|
||||
const customMetaData = meta?.custom ?? {};
|
||||
const timeSeriesList = { ...defaultQuery(datasource), ...query.timeSeriesList };
|
||||
@ -73,6 +73,7 @@ export const AnnotationQueryEditor = (props: Props) => {
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range || getDefaultTimeRange()}
|
||||
/>
|
||||
<EditorField label="Title" htmlFor="annotation-query-title">
|
||||
<Input id="annotation-query-title" value={title} onChange={handleTitleChange} />
|
||||
|
@ -3,9 +3,8 @@ import React, { PureComponent } from 'react';
|
||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||
import { ConfigSection, DataSourceDescription } from '@grafana/experimental';
|
||||
import { ConnectionConfig } from '@grafana/google-sdk';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { reportInteraction, config } from '@grafana/runtime';
|
||||
import { Divider, SecureSocksProxySettings } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
|
||||
import { CloudMonitoringOptions, CloudMonitoringSecureJsonData } from '../../types/types';
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { getDefaultTimeRange } from '@grafana/data';
|
||||
|
||||
import { createMockDatasource } from '../__mocks__/cloudMonitoringDatasource';
|
||||
import { createMockQuery } from '../__mocks__/cloudMonitoringQuery';
|
||||
import { QueryType } from '../types/query';
|
||||
@ -22,6 +24,7 @@ const defaultProps = {
|
||||
onRunQuery: jest.fn(),
|
||||
query: createMockQuery(),
|
||||
datasource: createMockDatasource(),
|
||||
range: getDefaultTimeRange(),
|
||||
};
|
||||
|
||||
describe('MetricQueryEditor', () => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { SelectableValue, TimeRange } from '@grafana/data';
|
||||
import { EditorRows, Stack } from '@grafana/experimental';
|
||||
|
||||
import CloudMonitoringDatasource from '../datasource';
|
||||
@ -21,6 +21,7 @@ export interface Props {
|
||||
onRunQuery: () => void;
|
||||
query: CloudMonitoringQuery;
|
||||
datasource: CloudMonitoringDatasource;
|
||||
range: TimeRange;
|
||||
}
|
||||
|
||||
export const defaultTimeSeriesList: (dataSource: CloudMonitoringDatasource) => TimeSeriesList = (dataSource) => ({
|
||||
@ -45,6 +46,7 @@ function Editor({
|
||||
onRunQuery,
|
||||
customMetaData,
|
||||
variableOptionGroup,
|
||||
range,
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
const onChangeTimeSeriesList = useCallback(
|
||||
(timeSeriesList: TimeSeriesList) => {
|
||||
@ -96,6 +98,7 @@ function Editor({
|
||||
query={query.timeSeriesList}
|
||||
aliasBy={query.aliasBy}
|
||||
onChangeAliasBy={(aliasBy: string) => onQueryChange({ ...query, aliasBy })}
|
||||
range={range}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import { TemplateSrvMock } from 'app/features/templating/template_srv.mock';
|
||||
import { CustomVariableModel } from '@grafana/data';
|
||||
|
||||
import { createMockMetricDescriptor } from '../__mocks__/cloudMonitoringMetricDescriptor';
|
||||
import { createMockTimeSeriesList } from '../__mocks__/cloudMonitoringQuery';
|
||||
@ -10,10 +10,21 @@ import { MetricKind, ValueTypes } from '../types/query';
|
||||
|
||||
import { Preprocessor } from './Preprocessor';
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getTemplateSrv: () => new TemplateSrvMock({}),
|
||||
}));
|
||||
let getTempVars = () => [] as CustomVariableModel[];
|
||||
let replace = () => '';
|
||||
|
||||
jest.mock('@grafana/runtime', () => {
|
||||
return {
|
||||
__esModule: true,
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getTemplateSrv: () => ({
|
||||
replace: replace,
|
||||
getVariables: getTempVars,
|
||||
updateTimeRange: jest.fn(),
|
||||
containsTemplate: jest.fn(),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Preprocessor', () => {
|
||||
it('only provides "None" as an option if no metric descriptor is provided', () => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { isEqual } from 'lodash';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { QueryEditorProps, toOption } from '@grafana/data';
|
||||
import { QueryEditorProps, getDefaultTimeRange, toOption } from '@grafana/data';
|
||||
import { EditorRows } from '@grafana/experimental';
|
||||
import { ConfirmModal } from '@grafana/ui';
|
||||
|
||||
@ -19,7 +19,7 @@ import { MetricQueryEditor, SLOQueryEditor } from './';
|
||||
export type Props = QueryEditorProps<CloudMonitoringDatasource, CloudMonitoringQuery, CloudMonitoringOptions>;
|
||||
|
||||
export const QueryEditor = (props: Props) => {
|
||||
const { datasource, query: oldQ, onRunQuery, onChange } = props;
|
||||
const { datasource, query: oldQ, onRunQuery, onChange, range } = props;
|
||||
const [modalIsOpen, setModalIsOpen] = useState<boolean>(false);
|
||||
// Migrate query if needed
|
||||
const [migrated, setMigrated] = useState(false);
|
||||
@ -130,6 +130,7 @@ export const QueryEditor = (props: Props) => {
|
||||
onRunQuery={onRunQuery}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range || getDefaultTimeRange()}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
@ -3,8 +3,8 @@ import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { openMenu, select } from 'react-select-event';
|
||||
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { CustomVariableModel, getDefaultTimeRange } from '@grafana/data';
|
||||
import { getTemplateSrv } from '@grafana/runtime';
|
||||
|
||||
import { createMockDatasource } from '../__mocks__/cloudMonitoringDatasource';
|
||||
import { createMockMetricDescriptor } from '../__mocks__/cloudMonitoringMetricDescriptor';
|
||||
@ -22,19 +22,49 @@ const defaultProps = {
|
||||
onChangeAliasBy: jest.fn(),
|
||||
};
|
||||
|
||||
let getTempVars = () => [] as CustomVariableModel[];
|
||||
let replace = () => '';
|
||||
|
||||
jest.mock('@grafana/runtime', () => {
|
||||
return {
|
||||
__esModule: true,
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getTemplateSrv: () => ({
|
||||
replace: replace,
|
||||
getVariables: getTempVars,
|
||||
updateTimeRange: jest.fn(),
|
||||
containsTemplate: jest.fn(),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('VisualMetricQueryEditor', () => {
|
||||
beforeEach(() => {
|
||||
getTempVars = () => [] as CustomVariableModel[];
|
||||
replace = () => '';
|
||||
});
|
||||
it('renders metrics fields', async () => {
|
||||
const onChange = jest.fn();
|
||||
const query = createMockTimeSeriesList();
|
||||
const datasource = createMockDatasource();
|
||||
const range = getDefaultTimeRange();
|
||||
|
||||
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
|
||||
render(
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(await screen.findByLabelText('Service')).toBeInTheDocument();
|
||||
expect(await screen.findByLabelText('Metric name')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('can select a service', async () => {
|
||||
replace = (target?: string) => target || '';
|
||||
const onChange = jest.fn();
|
||||
const query = createMockTimeSeriesList();
|
||||
const mockMetricDescriptor = createMockMetricDescriptor();
|
||||
@ -42,8 +72,17 @@ describe('VisualMetricQueryEditor', () => {
|
||||
getMetricTypes: jest.fn().mockResolvedValue([mockMetricDescriptor]),
|
||||
getLabels: jest.fn().mockResolvedValue([]),
|
||||
});
|
||||
const range = getDefaultTimeRange();
|
||||
|
||||
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
|
||||
render(
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range}
|
||||
/>
|
||||
);
|
||||
|
||||
const service = await screen.findByLabelText('Service');
|
||||
openMenu(service);
|
||||
@ -56,6 +95,7 @@ describe('VisualMetricQueryEditor', () => {
|
||||
});
|
||||
|
||||
it('can select a metric name', async () => {
|
||||
replace = (target?: string) => target || '';
|
||||
const onChange = jest.fn();
|
||||
const query = createMockTimeSeriesList();
|
||||
const mockMetricDescriptor = createMockMetricDescriptor({ displayName: 'metricName_test', type: 'test_type' });
|
||||
@ -64,8 +104,17 @@ describe('VisualMetricQueryEditor', () => {
|
||||
filterMetricsByType: jest.fn().mockResolvedValue([createMockMetricDescriptor(), mockMetricDescriptor]),
|
||||
getLabels: jest.fn().mockResolvedValue([]),
|
||||
});
|
||||
const range = getDefaultTimeRange();
|
||||
|
||||
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
|
||||
render(
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range}
|
||||
/>
|
||||
);
|
||||
|
||||
const service = await screen.findByLabelText('Service');
|
||||
openMenu(service);
|
||||
@ -112,14 +161,24 @@ describe('VisualMetricQueryEditor', () => {
|
||||
]),
|
||||
});
|
||||
const query = createMockTimeSeriesList();
|
||||
const range = getDefaultTimeRange();
|
||||
|
||||
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
|
||||
render(
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range}
|
||||
/>
|
||||
);
|
||||
const service = await screen.findByLabelText('Service');
|
||||
openMenu(service);
|
||||
expect(screen.getAllByLabelText('Select option').length).toEqual(2);
|
||||
});
|
||||
|
||||
it('resets query to default when service changes', async () => {
|
||||
replace = (target?: string) => target || '';
|
||||
const query = createMockTimeSeriesList({ filters: ['metric.test_label', '=', 'test', 'AND'] });
|
||||
const onChange = jest.fn();
|
||||
const datasource = createMockDatasource({
|
||||
@ -132,8 +191,17 @@ describe('VisualMetricQueryEditor', () => {
|
||||
getLabels: jest.fn().mockResolvedValue([]),
|
||||
});
|
||||
const defaultQuery = { ...query, ...defaultTimeSeriesList(datasource), filters: ['metric.type', '=', 'type2'] };
|
||||
const range = getDefaultTimeRange();
|
||||
|
||||
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
|
||||
render(
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText('metric.test_label')).toBeInTheDocument();
|
||||
const service = await screen.findByLabelText('Service');
|
||||
@ -147,6 +215,7 @@ describe('VisualMetricQueryEditor', () => {
|
||||
});
|
||||
|
||||
it('resets query to defaults (except filters) when metric changes', async () => {
|
||||
replace = (target?: string) => target || '';
|
||||
const groupBys = ['metric.test_groupby'];
|
||||
const query = createMockTimeSeriesList({
|
||||
filters: ['metric.test_label', '=', 'test', 'AND', 'metric.type', '=', 'type'],
|
||||
@ -168,11 +237,20 @@ describe('VisualMetricQueryEditor', () => {
|
||||
createMockMetricDescriptor({ type: 'type2', displayName: 'metricName2', metricKind: MetricKind.GAUGE }),
|
||||
]),
|
||||
getLabels: jest.fn().mockResolvedValue({ 'metric.test_groupby': '' }),
|
||||
templateSrv: new TemplateSrv(),
|
||||
templateSrv: getTemplateSrv(),
|
||||
});
|
||||
const defaultQuery = { ...query, ...defaultTimeSeriesList(datasource), filters: query.filters };
|
||||
const range = getDefaultTimeRange();
|
||||
|
||||
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
|
||||
render(
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range}
|
||||
/>
|
||||
);
|
||||
expect(document.body).toHaveTextContent('metric.test_label');
|
||||
expect(await screen.findByText('Delta')).toBeInTheDocument();
|
||||
expect(await screen.findByText('metric.test_groupby')).toBeInTheDocument();
|
||||
@ -193,22 +271,28 @@ describe('VisualMetricQueryEditor', () => {
|
||||
});
|
||||
|
||||
it('updates labels on time range change', async () => {
|
||||
const timeSrv = getTimeSrv();
|
||||
replace = (target?: string) => target || '';
|
||||
const range = getDefaultTimeRange();
|
||||
const query = createMockTimeSeriesList();
|
||||
const onChange = jest.fn();
|
||||
const datasource = createMockDatasource({
|
||||
getMetricTypes: jest.fn().mockResolvedValue([createMockMetricDescriptor()]),
|
||||
getLabels: jest
|
||||
.fn()
|
||||
.mockResolvedValue(
|
||||
timeSrv.time.from === 'now-6h' ? { 'metric.test_groupby': '' } : { 'metric.test_groupby_1': '' }
|
||||
.mockImplementation(async (_metricType, _refId, _projectName, _, timeRange) =>
|
||||
timeRange.raw.from === 'now-6h' ? { 'metric.test_groupby': '' } : { 'metric.test_groupby_1': '' }
|
||||
),
|
||||
templateSrv: new TemplateSrv(),
|
||||
timeSrv,
|
||||
templateSrv: getTemplateSrv(),
|
||||
});
|
||||
|
||||
const { rerender } = render(
|
||||
<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={range}
|
||||
/>
|
||||
);
|
||||
|
||||
const service = await screen.findByLabelText('Service');
|
||||
@ -225,13 +309,17 @@ describe('VisualMetricQueryEditor', () => {
|
||||
const groupBy = await screen.findByLabelText('Group by');
|
||||
openMenu(groupBy);
|
||||
await waitFor(() => expect(document.body).toHaveTextContent('metric.test_groupby'));
|
||||
timeSrv.setTime({ from: 'now-12h', to: 'now' });
|
||||
const datasourceUpdated = createMockDatasource({
|
||||
timeSrv,
|
||||
getLabels: jest.fn().mockResolvedValue({ 'metric.test_groupby_1': '' }),
|
||||
});
|
||||
range.from.subtract('6', 'h');
|
||||
range.raw.from = 'now-12h';
|
||||
|
||||
rerender(
|
||||
<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasourceUpdated} query={query} />
|
||||
<VisualMetricQueryEditor
|
||||
{...defaultProps}
|
||||
onChange={onChange}
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
range={{ ...range }}
|
||||
/>
|
||||
);
|
||||
openMenu(groupBy);
|
||||
await waitFor(() => expect(document.body).toHaveTextContent('metric.test_groupby_1'));
|
||||
|
@ -30,6 +30,7 @@ export interface Props {
|
||||
variableOptionGroup: SelectableValue<string>;
|
||||
aliasBy?: string;
|
||||
onChangeAliasBy: (aliasBy: string) => void;
|
||||
range: TimeRange;
|
||||
}
|
||||
|
||||
export function Editor({
|
||||
@ -41,6 +42,7 @@ export function Editor({
|
||||
customMetaData,
|
||||
aliasBy,
|
||||
onChangeAliasBy,
|
||||
range,
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
const [labels, setLabels] = useState<{ [k: string]: string[] }>({});
|
||||
const [metricDescriptors, setMetricDescriptors] = useState<MetricDescriptor[]>([]);
|
||||
@ -48,7 +50,7 @@ export function Editor({
|
||||
const [metrics, setMetrics] = useState<Array<SelectableValue<string>>>([]);
|
||||
const [services, setServices] = useState<Array<SelectableValue<string>>>([]);
|
||||
const [service, setService] = useState<string>('');
|
||||
const [timeRange, setTimeRange] = useState<TimeRange>({ ...datasource.timeSrv.timeRange() });
|
||||
const [timeRange, setTimeRange] = useState<TimeRange>({ ...range });
|
||||
|
||||
const useTime = (time: TimeRange) => {
|
||||
if (
|
||||
@ -60,7 +62,7 @@ export function Editor({
|
||||
}
|
||||
};
|
||||
|
||||
useTime(datasource.timeSrv.timeRange());
|
||||
useTime(range);
|
||||
|
||||
const theme = useTheme2();
|
||||
const selectStyles = getSelectStyles(theme);
|
||||
|
@ -1,16 +1,38 @@
|
||||
import { get } from 'lodash';
|
||||
import { lastValueFrom, of } from 'rxjs';
|
||||
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { CustomVariableModel } from '@grafana/data';
|
||||
import { getTemplateSrv } from '@grafana/runtime';
|
||||
|
||||
import { createMockInstanceSetttings } from './__mocks__/cloudMonitoringInstanceSettings';
|
||||
import { createMockQuery } from './__mocks__/cloudMonitoringQuery';
|
||||
import Datasource from './datasource';
|
||||
import { CloudMonitoringQuery, PreprocessorType, QueryType, MetricKind } from './types/query';
|
||||
|
||||
let getTempVars = () => [] as CustomVariableModel[];
|
||||
let replace = () => '';
|
||||
|
||||
jest.mock('@grafana/runtime', () => {
|
||||
return {
|
||||
__esModule: true,
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getTemplateSrv: () => ({
|
||||
replace: replace,
|
||||
getVariables: getTempVars,
|
||||
updateTimeRange: jest.fn(),
|
||||
containsTemplate: jest.fn(),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Cloud Monitoring Datasource', () => {
|
||||
describe('interpolateVariablesInQueries', () => {
|
||||
beforeEach(() => {
|
||||
getTempVars = () => [] as CustomVariableModel[];
|
||||
replace = () => '';
|
||||
});
|
||||
it('should leave a query unchanged if there are no template variables', () => {
|
||||
replace = (target?: string) => target || '';
|
||||
const mockInstanceSettings = createMockInstanceSetttings();
|
||||
const ds = new Datasource(mockInstanceSettings);
|
||||
const query = createMockQuery();
|
||||
@ -19,7 +41,7 @@ describe('Cloud Monitoring Datasource', () => {
|
||||
});
|
||||
|
||||
it('should correctly apply template variables for metricQuery (deprecated)', () => {
|
||||
const templateSrv = new TemplateSrv();
|
||||
const templateSrv = getTemplateSrv();
|
||||
templateSrv.replace = jest.fn().mockReturnValue('project-variable');
|
||||
const mockInstanceSettings = createMockInstanceSetttings();
|
||||
const ds = new Datasource(mockInstanceSettings, templateSrv);
|
||||
@ -30,7 +52,7 @@ describe('Cloud Monitoring Datasource', () => {
|
||||
});
|
||||
|
||||
it('should correctly apply template variables for timeSeriesList', () => {
|
||||
const templateSrv = new TemplateSrv();
|
||||
const templateSrv = getTemplateSrv();
|
||||
templateSrv.replace = jest.fn().mockReturnValue('project-variable');
|
||||
const mockInstanceSettings = createMockInstanceSetttings();
|
||||
const ds = new Datasource(mockInstanceSettings, templateSrv);
|
||||
@ -41,7 +63,7 @@ describe('Cloud Monitoring Datasource', () => {
|
||||
});
|
||||
|
||||
it('should correctly apply template variables for timeSeriesQuery', () => {
|
||||
const templateSrv = new TemplateSrv();
|
||||
const templateSrv = getTemplateSrv();
|
||||
templateSrv.replace = jest.fn().mockReturnValue('project-variable');
|
||||
const mockInstanceSettings = createMockInstanceSetttings();
|
||||
const ds = new Datasource(mockInstanceSettings, templateSrv);
|
||||
@ -54,6 +76,10 @@ describe('Cloud Monitoring Datasource', () => {
|
||||
|
||||
describe('migrateQuery', () => {
|
||||
describe('should migrate the query to the new format', () => {
|
||||
beforeEach(() => {
|
||||
getTempVars = () => [] as CustomVariableModel[];
|
||||
replace = () => '';
|
||||
});
|
||||
[
|
||||
{
|
||||
description: 'a list query with a metric type and no filters',
|
||||
@ -210,6 +236,10 @@ describe('Cloud Monitoring Datasource', () => {
|
||||
});
|
||||
|
||||
describe('filterQuery', () => {
|
||||
beforeEach(() => {
|
||||
getTempVars = () => [] as CustomVariableModel[];
|
||||
replace = () => '';
|
||||
});
|
||||
[
|
||||
{
|
||||
description: 'should filter out queries with no metric type',
|
||||
@ -275,7 +305,12 @@ describe('Cloud Monitoring Datasource', () => {
|
||||
});
|
||||
|
||||
describe('getLabels', () => {
|
||||
beforeEach(() => {
|
||||
getTempVars = () => [] as CustomVariableModel[];
|
||||
replace = () => '';
|
||||
});
|
||||
it('should get labels', async () => {
|
||||
replace = (target?: string) => target || '';
|
||||
const mockInstanceSettings = createMockInstanceSetttings();
|
||||
const ds = new Datasource(mockInstanceSettings);
|
||||
ds.backendSrv = {
|
||||
|
@ -9,10 +9,16 @@ import {
|
||||
ScopedVars,
|
||||
SelectableValue,
|
||||
TimeRange,
|
||||
getDefaultTimeRange,
|
||||
} from '@grafana/data';
|
||||
import { DataSourceWithBackend, getBackendSrv, toDataQueryResponse, BackendSrv } from '@grafana/runtime';
|
||||
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import {
|
||||
DataSourceWithBackend,
|
||||
getBackendSrv,
|
||||
toDataQueryResponse,
|
||||
BackendSrv,
|
||||
getTemplateSrv,
|
||||
TemplateSrv,
|
||||
} from '@grafana/runtime';
|
||||
|
||||
import { CloudMonitoringAnnotationSupport } from './annotationSupport';
|
||||
import { SLO_BURN_RATE_SELECTOR_NAME } from './constants';
|
||||
@ -31,8 +37,7 @@ export default class CloudMonitoringDatasource extends DataSourceWithBackend<
|
||||
|
||||
constructor(
|
||||
private instanceSettings: DataSourceInstanceSettings<CloudMonitoringOptions>,
|
||||
public templateSrv: TemplateSrv = getTemplateSrv(),
|
||||
readonly timeSrv: TimeSrv = getTimeSrv()
|
||||
public templateSrv: TemplateSrv = getTemplateSrv()
|
||||
) {
|
||||
super(instanceSettings);
|
||||
this.authenticationType = instanceSettings.jsonData.authenticationType || 'jwt';
|
||||
@ -107,7 +112,7 @@ export default class CloudMonitoringDatasource extends DataSourceWithBackend<
|
||||
),
|
||||
},
|
||||
],
|
||||
range: timeRange ?? this.timeSrv.timeRange(),
|
||||
range: timeRange || getDefaultTimeRange(),
|
||||
};
|
||||
|
||||
const queries = options.targets;
|
||||
|
@ -1,27 +1,28 @@
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { createFetchResponse } from 'test/helpers/createFetchResponse';
|
||||
|
||||
import { DataQueryRequest, DataSourceInstanceSettings, toUtc } from '@grafana/data';
|
||||
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; // will use the version in __mocks__
|
||||
|
||||
import { initialCustomVariableModelState } from '../../../../features/variables/custom/reducer';
|
||||
import { CustomVariableModel } from '../../../../features/variables/types';
|
||||
import CloudMonitoringDataSource from '../datasource';
|
||||
import { CloudMonitoringQuery } from '../types/query';
|
||||
import { CloudMonitoringOptions } from '../types/types';
|
||||
|
||||
let getTempVars = () => [] as CustomVariableModel[];
|
||||
let replace = () => '';
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
__esModule: true,
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getBackendSrv: () => backendSrv,
|
||||
getTemplateSrv: () => ({
|
||||
replace: replace,
|
||||
getVariables: getTempVars,
|
||||
updateTimeRange: jest.fn(),
|
||||
containsTemplate: jest.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
type Args = { response?: unknown; throws?: boolean; templateSrv?: TemplateSrv };
|
||||
|
||||
const fetchMock = jest.spyOn(backendSrv, 'fetch');
|
||||
|
||||
function getTestcontext({ response = {}, throws = false, templateSrv = new TemplateSrv() }: Args = {}) {
|
||||
function getTestcontext({ response = {}, throws = false, templateSrv = getTemplateSrv() }: Args = {}) {
|
||||
jest.clearAllMocks();
|
||||
|
||||
const instanceSettings = {
|
||||
@ -30,18 +31,7 @@ function getTestcontext({ response = {}, throws = false, templateSrv = new Templ
|
||||
},
|
||||
} as unknown as DataSourceInstanceSettings<CloudMonitoringOptions>;
|
||||
|
||||
const timeSrv = {
|
||||
timeRange: () => ({
|
||||
from: toUtc('2017-08-22T20:00:00Z'),
|
||||
to: toUtc('2017-08-22T23:59:00Z'),
|
||||
}),
|
||||
} as TimeSrv;
|
||||
|
||||
throws
|
||||
? fetchMock.mockImplementation(() => throwError(response))
|
||||
: fetchMock.mockImplementation(() => of(createFetchResponse(response)));
|
||||
|
||||
const ds = new CloudMonitoringDataSource(instanceSettings, templateSrv, timeSrv);
|
||||
const ds = new CloudMonitoringDataSource(instanceSettings, templateSrv);
|
||||
|
||||
return { ds };
|
||||
}
|
||||
@ -89,46 +79,15 @@ describe('CloudMonitoringDataSource', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('When loading labels', () => {
|
||||
describe('and no aggregation was specified', () => {
|
||||
it('should use default values', async () => {
|
||||
const { ds } = getTestcontext();
|
||||
await ds.getLabels('cpu', 'a', 'default-proj');
|
||||
|
||||
await expect(fetchMock.mock.calls[0][0].data.queries[0].timeSeriesList).toMatchObject({
|
||||
crossSeriesReducer: 'REDUCE_NONE',
|
||||
groupBys: [],
|
||||
filters: ['metric.type', '=', 'cpu'],
|
||||
projectName: 'default-proj',
|
||||
view: 'HEADERS',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('and an aggregation was specified', () => {
|
||||
it('should use the provided aggregation', async () => {
|
||||
const { ds } = getTestcontext();
|
||||
await ds.getLabels('sql', 'b', 'default-proj', {
|
||||
crossSeriesReducer: 'REDUCE_MEAN',
|
||||
groupBys: ['metadata.system_label.name'],
|
||||
});
|
||||
|
||||
await expect(fetchMock.mock.calls[0][0].data.queries[0].timeSeriesList).toMatchObject({
|
||||
crossSeriesReducer: 'REDUCE_MEAN',
|
||||
groupBys: ['metadata.system_label.name'],
|
||||
filters: ['metric.type', '=', 'sql'],
|
||||
projectName: 'default-proj',
|
||||
view: 'HEADERS',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when interpolating a template variable for the filter', () => {
|
||||
beforeEach(() => {
|
||||
getTempVars = () => [] as CustomVariableModel[];
|
||||
replace = (target?: string) => target || '';
|
||||
});
|
||||
describe('and is single value variable', () => {
|
||||
it('should replace the variable with the value', () => {
|
||||
const templateSrv = initTemplateSrv('filtervalue1');
|
||||
const { ds } = getTestcontext({ templateSrv });
|
||||
replace = () => 'filtervalue1';
|
||||
const { ds } = getTestcontext();
|
||||
const interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '${test}'], {});
|
||||
|
||||
expect(interpolated.length).toBe(3);
|
||||
@ -138,8 +97,8 @@ describe('CloudMonitoringDataSource', () => {
|
||||
|
||||
describe('and is single value variable for the label part', () => {
|
||||
it('should replace the variable with the value and not with regex formatting', () => {
|
||||
const templateSrv = initTemplateSrv('resource.label.zone');
|
||||
const { ds } = getTestcontext({ templateSrv });
|
||||
replace = () => 'resource.label.zone';
|
||||
const { ds } = getTestcontext();
|
||||
const interpolated = ds.interpolateFilters(['${test}', '=~', 'europe-north-1a'], {});
|
||||
|
||||
expect(interpolated.length).toBe(3);
|
||||
@ -148,26 +107,30 @@ describe('CloudMonitoringDataSource', () => {
|
||||
});
|
||||
|
||||
describe('and is multi value variable', () => {
|
||||
beforeEach(() => {
|
||||
getTempVars = () => [] as CustomVariableModel[];
|
||||
replace = (target?: string) => target || '';
|
||||
});
|
||||
it('should replace the variable with a regex expression', () => {
|
||||
const templateSrv = initTemplateSrv(['filtervalue1', 'filtervalue2'], true);
|
||||
const { ds } = getTestcontext({ templateSrv });
|
||||
const interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '[[test]]'], {});
|
||||
replace = () => '(filtervalue1|filtervalue2)';
|
||||
const { ds } = getTestcontext();
|
||||
const interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '${test}'], {});
|
||||
|
||||
expect(interpolated[2]).toBe('(filtervalue1|filtervalue2)');
|
||||
});
|
||||
|
||||
it('should not escape a regex', () => {
|
||||
const templateSrv = initTemplateSrv('/[a-Z]*.html', true);
|
||||
const { ds } = getTestcontext({ templateSrv });
|
||||
const interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '[[test]]'], {});
|
||||
replace = () => '/[a-Z]*.html';
|
||||
const { ds } = getTestcontext();
|
||||
const interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '${test}'], {});
|
||||
|
||||
expect(interpolated[2]).toBe('/[a-Z]*.html');
|
||||
});
|
||||
|
||||
it('should not escape an array of regexes but join them as a regex', () => {
|
||||
const templateSrv = initTemplateSrv(['/[a-Z]*.html', '/foo.html'], true);
|
||||
const { ds } = getTestcontext({ templateSrv });
|
||||
const interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '[[test]]'], {});
|
||||
replace = () => '(/[a-Z]*.html|/foo.html)';
|
||||
const { ds } = getTestcontext();
|
||||
const interpolated = ds.interpolateFilters(['resource.label.zone', '=~', '${test}'], {});
|
||||
|
||||
expect(interpolated[2]).toBe('(/[a-Z]*.html|/foo.html)');
|
||||
});
|
||||
@ -177,9 +140,9 @@ describe('CloudMonitoringDataSource', () => {
|
||||
describe('when interpolating a template variable for group bys', () => {
|
||||
describe('and is single value variable', () => {
|
||||
it('should replace the variable with the value', () => {
|
||||
const templateSrv = initTemplateSrv('groupby1');
|
||||
const { ds } = getTestcontext({ templateSrv });
|
||||
const interpolated = ds.interpolateGroupBys(['[[test]]'], {});
|
||||
replace = () => 'groupby1';
|
||||
const { ds } = getTestcontext();
|
||||
const interpolated = ds.interpolateGroupBys(['${test}'], {});
|
||||
|
||||
expect(interpolated.length).toBe(1);
|
||||
expect(interpolated[0]).toBe('groupby1');
|
||||
@ -188,9 +151,9 @@ describe('CloudMonitoringDataSource', () => {
|
||||
|
||||
describe('and is multi value variable', () => {
|
||||
it('should replace the variable with an array of group bys', () => {
|
||||
const templateSrv = initTemplateSrv(['groupby1', 'groupby2'], true);
|
||||
const { ds } = getTestcontext({ templateSrv });
|
||||
const interpolated = ds.interpolateGroupBys(['[[test]]'], {});
|
||||
replace = () => 'groupby1,groupby2';
|
||||
const { ds } = getTestcontext();
|
||||
const interpolated = ds.interpolateGroupBys(['${test}'], {});
|
||||
|
||||
expect(interpolated.length).toBe(2);
|
||||
expect(interpolated[0]).toBe('groupby1');
|
||||
@ -199,17 +162,3 @@ describe('CloudMonitoringDataSource', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function initTemplateSrv(values: string | string[], multi = false) {
|
||||
const templateSrv = new TemplateSrv();
|
||||
const test: CustomVariableModel = {
|
||||
...initialCustomVariableModelState,
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
current: { value: values, text: Array.isArray(values) ? values.toString() : values, selected: true },
|
||||
options: [{ value: values, text: Array.isArray(values) ? values.toString() : values, selected: false }],
|
||||
multi,
|
||||
};
|
||||
templateSrv.init([test]);
|
||||
return templateSrv;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user