mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudMonitoring: Fixes broken variable queries that use group bys (#43914)
This commit is contained in:
parent
9fb8339f87
commit
715166baf3
@ -100,7 +100,10 @@ export default class CloudMonitoringMetricFindQuery {
|
||||
return [];
|
||||
}
|
||||
const refId = 'handleLabelValuesQuery';
|
||||
const labels = await this.datasource.getLabels(selectedMetricType, refId, projectName, [labelKey]);
|
||||
const labels = await this.datasource.getLabels(selectedMetricType, refId, projectName, {
|
||||
groupBys: [labelKey],
|
||||
crossSeriesReducer: 'REDUCE_MEAN',
|
||||
});
|
||||
const interpolatedKey = this.datasource.templateSrv.replace(labelKey);
|
||||
const values = labels.hasOwnProperty(interpolatedKey) ? labels[interpolatedKey] : [];
|
||||
return values.map(this.toFindQueryResult);
|
||||
|
@ -61,15 +61,15 @@ function Editor({
|
||||
variableOptionGroup,
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
const [state, setState] = useState<State>(defaultState);
|
||||
const { projectName, metricType, groupBys, editorMode } = query;
|
||||
const { projectName, metricType, groupBys, editorMode, crossSeriesReducer } = query;
|
||||
|
||||
useEffect(() => {
|
||||
if (projectName && metricType) {
|
||||
datasource
|
||||
.getLabels(metricType, refId, projectName, groupBys)
|
||||
.getLabels(metricType, refId, projectName, { groupBys, crossSeriesReducer })
|
||||
.then((labels) => setState((prevState) => ({ ...prevState, labels })));
|
||||
}
|
||||
}, [datasource, groupBys, metricType, projectName, refId]);
|
||||
}, [datasource, groupBys, metricType, projectName, refId, crossSeriesReducer]);
|
||||
|
||||
const onChange = useCallback(
|
||||
(metricQuery: MetricQuery | SLOQuery) => {
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
MetricDescriptor,
|
||||
QueryType,
|
||||
PostResponse,
|
||||
Aggregation,
|
||||
} from './types';
|
||||
import { CloudMonitoringVariableSupport } from './variables';
|
||||
|
||||
@ -136,7 +137,7 @@ export default class CloudMonitoringDatasource extends DataSourceWithBackend<
|
||||
};
|
||||
}
|
||||
|
||||
async getLabels(metricType: string, refId: string, projectName: string, groupBys?: string[]) {
|
||||
async getLabels(metricType: string, refId: string, projectName: string, aggregation?: Aggregation) {
|
||||
const options = {
|
||||
targets: [
|
||||
{
|
||||
@ -146,8 +147,8 @@ export default class CloudMonitoringDatasource extends DataSourceWithBackend<
|
||||
metricQuery: {
|
||||
projectName: this.templateSrv.replace(projectName),
|
||||
metricType: this.templateSrv.replace(metricType),
|
||||
groupBys: this.interpolateGroupBys(groupBys || [], {}),
|
||||
crossSeriesReducer: 'REDUCE_NONE',
|
||||
groupBys: this.interpolateGroupBys(aggregation?.groupBys || [], {}),
|
||||
crossSeriesReducer: aggregation?.crossSeriesReducer ?? 'REDUCE_NONE',
|
||||
view: 'HEADERS',
|
||||
},
|
||||
},
|
||||
|
@ -17,6 +17,8 @@ jest.mock('@grafana/runtime', () => ({
|
||||
|
||||
type Args = { response?: any; throws?: boolean; templateSrv?: TemplateSrv };
|
||||
|
||||
const fetchMock = jest.spyOn(backendSrv, 'fetch');
|
||||
|
||||
function getTestcontext({ response = {}, throws = false, templateSrv = new TemplateSrv() }: Args = {}) {
|
||||
jest.clearAllMocks();
|
||||
|
||||
@ -26,9 +28,12 @@ function getTestcontext({ response = {}, throws = false, templateSrv = new Templ
|
||||
},
|
||||
} as unknown) as DataSourceInstanceSettings<CloudMonitoringOptions>;
|
||||
|
||||
const timeSrv = {} as TimeSrv;
|
||||
|
||||
const fetchMock = jest.spyOn(backendSrv, 'fetch');
|
||||
const timeSrv = {
|
||||
timeRange: () => ({
|
||||
from: toUtc('2017-08-22T20:00:00Z'),
|
||||
to: toUtc('2017-08-22T23:59:00Z'),
|
||||
}),
|
||||
} as TimeSrv;
|
||||
|
||||
throws
|
||||
? fetchMock.mockImplementation(() => throwError(response))
|
||||
@ -82,6 +87,41 @@ 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].metricQuery).toMatchObject({
|
||||
crossSeriesReducer: 'REDUCE_NONE',
|
||||
groupBys: [],
|
||||
metricType: '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].metricQuery).toMatchObject({
|
||||
crossSeriesReducer: 'REDUCE_MEAN',
|
||||
groupBys: ['metadata.system_label.name'],
|
||||
metricType: 'sql',
|
||||
projectName: 'default-proj',
|
||||
view: 'HEADERS',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when interpolating a template variable for the filter', () => {
|
||||
describe('and is single value variable', () => {
|
||||
it('should replace the variable with the value', () => {
|
||||
|
@ -53,6 +53,11 @@ export interface VariableQueryData {
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
export interface Aggregation {
|
||||
crossSeriesReducer?: string;
|
||||
groupBys?: string[];
|
||||
}
|
||||
|
||||
export enum QueryType {
|
||||
METRICS = 'metrics',
|
||||
SLO = 'slo',
|
||||
|
Loading…
Reference in New Issue
Block a user