mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Cloudwatch : Fixed reseting metric name when changing namespace in Metric Query (#44612)
* Added logic to reset metric name when changing namespace in Metric Query * Added tests for reseting or not metricName onChange namespace * Added tests for reseting or not metricName onChange namespace * Removed comment * Cleaned up tests * Refactored namespace to be updated in utils * Removed unecessary overrides for query and onQueryChange * Renamed tests + used some instead of find
This commit is contained in:
parent
fd14112dbd
commit
33a7269b4f
@ -0,0 +1,137 @@
|
||||
import React from 'react';
|
||||
import { selectOptionInTest } from '@grafana/ui';
|
||||
import { act, render, screen } from '@testing-library/react';
|
||||
import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType, SQLExpression } from '../../types';
|
||||
import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource';
|
||||
import { QueryEditorExpressionType, QueryEditorPropertyType } from '../../expressions';
|
||||
import SQLBuilderSelectRow from './SQLBuilderSelectRow';
|
||||
|
||||
const { datasource } = setupMockedDataSource();
|
||||
|
||||
const makeSQLQuery = (sql?: SQLExpression): CloudWatchMetricsQuery => ({
|
||||
queryMode: 'Metrics',
|
||||
refId: '',
|
||||
id: '',
|
||||
region: 'us-east-1',
|
||||
namespace: 'ec2',
|
||||
dimensions: { somekey: 'somevalue' },
|
||||
metricQueryType: MetricQueryType.Query,
|
||||
metricEditorMode: MetricEditorMode.Builder,
|
||||
sql: sql,
|
||||
});
|
||||
|
||||
const query = makeSQLQuery({
|
||||
select: {
|
||||
type: QueryEditorExpressionType.Function,
|
||||
name: 'AVERAGE',
|
||||
parameters: [
|
||||
{
|
||||
type: QueryEditorExpressionType.FunctionParameter,
|
||||
name: 'm1',
|
||||
},
|
||||
],
|
||||
},
|
||||
from: {
|
||||
type: QueryEditorExpressionType.Property,
|
||||
property: {
|
||||
type: QueryEditorPropertyType.String,
|
||||
name: 'n1',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const onQueryChange = jest.fn();
|
||||
const baseProps = {
|
||||
query,
|
||||
datasource,
|
||||
onQueryChange,
|
||||
};
|
||||
|
||||
const namespaces = [
|
||||
{ value: 'n1', label: 'n1', text: 'n1' },
|
||||
{ value: 'n2', label: 'n2', text: 'n2' },
|
||||
];
|
||||
const metrics = [
|
||||
{ value: 'm1', label: 'm1', text: 'm1' },
|
||||
{ value: 'm2', label: 'm2', text: 'm2' },
|
||||
];
|
||||
|
||||
describe('Cloudwatch SQLBuilderSelectRow', () => {
|
||||
beforeEach(() => {
|
||||
datasource.getNamespaces = jest.fn().mockResolvedValue(namespaces);
|
||||
datasource.getMetrics = jest.fn().mockResolvedValue([]);
|
||||
datasource.getDimensionKeys = jest.fn().mockResolvedValue([]);
|
||||
datasource.getDimensionValues = jest.fn().mockResolvedValue([]);
|
||||
onQueryChange.mockReset();
|
||||
});
|
||||
|
||||
it('Should not reset metricName when selecting a namespace if metric exist in new namespace', async () => {
|
||||
datasource.getMetrics = jest.fn().mockResolvedValue(metrics);
|
||||
|
||||
await act(async () => {
|
||||
render(<SQLBuilderSelectRow {...baseProps} />);
|
||||
});
|
||||
|
||||
expect(screen.getByText('n1')).toBeInTheDocument();
|
||||
expect(screen.getByText('m1')).toBeInTheDocument();
|
||||
const namespaceSelect = screen.getByLabelText('Namespace');
|
||||
await selectOptionInTest(namespaceSelect, 'n2');
|
||||
|
||||
const expectedQuery = makeSQLQuery({
|
||||
select: {
|
||||
type: QueryEditorExpressionType.Function,
|
||||
name: 'AVERAGE',
|
||||
parameters: [
|
||||
{
|
||||
type: QueryEditorExpressionType.FunctionParameter,
|
||||
name: 'm1',
|
||||
},
|
||||
],
|
||||
},
|
||||
from: {
|
||||
type: QueryEditorExpressionType.Property,
|
||||
property: {
|
||||
type: QueryEditorPropertyType.String,
|
||||
name: 'n2',
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(onQueryChange).toHaveBeenCalledTimes(1);
|
||||
expect(onQueryChange.mock.calls).toEqual([[{ ...expectedQuery, namespace: 'n2' }]]);
|
||||
});
|
||||
|
||||
it('Should reset metricName when selecting a namespace if metric does not exist in new namespace', async () => {
|
||||
datasource.getMetrics = jest.fn().mockImplementation((namespace: string, region: string) => {
|
||||
let mockMetrics =
|
||||
namespace === 'n1' && region === baseProps.query.region
|
||||
? metrics
|
||||
: [{ value: 'newNamespaceMetric', label: 'newNamespaceMetric', text: 'newNamespaceMetric' }];
|
||||
return Promise.resolve(mockMetrics);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(<SQLBuilderSelectRow {...baseProps} />);
|
||||
});
|
||||
|
||||
expect(screen.getByText('n1')).toBeInTheDocument();
|
||||
expect(screen.getByText('m1')).toBeInTheDocument();
|
||||
const namespaceSelect = screen.getByLabelText('Namespace');
|
||||
await selectOptionInTest(namespaceSelect, 'n2');
|
||||
|
||||
const expectedQuery = makeSQLQuery({
|
||||
select: {
|
||||
type: QueryEditorExpressionType.Function,
|
||||
name: 'AVERAGE',
|
||||
},
|
||||
from: {
|
||||
type: QueryEditorExpressionType.Property,
|
||||
property: {
|
||||
type: QueryEditorPropertyType.String,
|
||||
name: 'n2',
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(onQueryChange).toHaveBeenCalledTimes(1);
|
||||
expect(onQueryChange.mock.calls).toEqual([[{ ...expectedQuery, namespace: 'n2' }]]);
|
||||
});
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { toOption } from '@grafana/data';
|
||||
import { SelectableValue, toOption } from '@grafana/data';
|
||||
import { EditorField, EditorFieldGroup } from '@grafana/experimental';
|
||||
import { Select, Switch } from '@grafana/ui';
|
||||
import { STATISTICS } from '../../cloudwatch-sql/language';
|
||||
@ -12,6 +12,7 @@ import {
|
||||
getNamespaceFromExpression,
|
||||
getSchemaLabelKeys as getSchemaLabels,
|
||||
isUsingWithSchema,
|
||||
removeMetricName,
|
||||
setAggregation,
|
||||
setMetricName,
|
||||
setNamespace,
|
||||
@ -52,16 +53,32 @@ const SQLBuilderSelectRow: React.FC<SQLBuilderSelectRowProps> = ({ datasource, q
|
||||
[unusedDimensionKeys, schemaLabels]
|
||||
);
|
||||
|
||||
const onNamespaceChange = async (query: CloudWatchMetricsQuery) => {
|
||||
const validatedQuery = await validateMetricName(query);
|
||||
onQueryChange(validatedQuery);
|
||||
};
|
||||
|
||||
const validateMetricName = async (query: CloudWatchMetricsQuery) => {
|
||||
let { region, sql } = query;
|
||||
await datasource.getMetrics(query.namespace, region).then((result: Array<SelectableValue<string>>) => {
|
||||
if (!result.some((metric) => metric.value === metricName)) {
|
||||
sql = removeMetricName(query).sql;
|
||||
}
|
||||
});
|
||||
return { ...query, sql };
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EditorFieldGroup>
|
||||
<EditorField label="Namespace" width={16}>
|
||||
<Select
|
||||
aria-label="Namespace"
|
||||
value={namespace ? toOption(namespace) : null}
|
||||
inputId={`${query.refId}-cloudwatch-sql-namespace`}
|
||||
options={namespaceOptions}
|
||||
allowCustomValue
|
||||
onChange={({ value }) => value && onQueryChange(setNamespace(query, value))}
|
||||
onChange={({ value }) => value && onNamespaceChange(setNamespace(query, value))}
|
||||
menuShouldPortal
|
||||
/>
|
||||
</EditorField>
|
||||
|
@ -146,6 +146,8 @@ export function setSql(query: CloudWatchMetricsQuery, sql: SQLExpression): Cloud
|
||||
|
||||
export function setNamespace(query: CloudWatchMetricsQuery, namespace: string | undefined): CloudWatchMetricsQuery {
|
||||
const sql = query.sql ?? {};
|
||||
//updating `namespace` props for CloudWatchMetricsQuery
|
||||
query.namespace = namespace ? namespace : '';
|
||||
|
||||
if (namespace === undefined) {
|
||||
return setSql(query, {
|
||||
@ -230,6 +232,13 @@ export function setMetricName(query: CloudWatchMetricsQuery, metricName: string)
|
||||
});
|
||||
}
|
||||
|
||||
export function removeMetricName(query: CloudWatchMetricsQuery): CloudWatchMetricsQuery {
|
||||
const queryWithNoParams = { ...query };
|
||||
delete queryWithNoParams.sql?.select?.parameters;
|
||||
|
||||
return queryWithNoParams;
|
||||
}
|
||||
|
||||
export function setAggregation(query: CloudWatchMetricsQuery, aggregation: string): CloudWatchMetricsQuery {
|
||||
return setSql(query, {
|
||||
select: {
|
||||
|
Loading…
Reference in New Issue
Block a user