mirror of
https://github.com/grafana/grafana.git
synced 2025-09-25 18:03:50 +08:00

* Prometheus: Show variable options * Remove lint error * Fix test for CodeQL * Update public/app/plugins/datasource/prometheus/datasource.ts Co-authored-by: Torkel Ödegaard <torkel@grafana.org> * Update public/app/plugins/datasource/loki/datasource.ts Co-authored-by: Torkel Ödegaard <torkel@grafana.org> Co-authored-by: Torkel Ödegaard <torkel@grafana.org>
169 lines
5.3 KiB
TypeScript
169 lines
5.3 KiB
TypeScript
import React from 'react';
|
|
import { render, screen, getByRole, getByText } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { PromQueryBuilder } from './PromQueryBuilder';
|
|
import { PrometheusDatasource } from '../../datasource';
|
|
import { EmptyLanguageProviderMock } from '../../language_provider.mock';
|
|
import PromQlLanguageProvider from '../../language_provider';
|
|
import { PromVisualQuery } from '../types';
|
|
import { getLabelSelects } from '../testUtils';
|
|
|
|
const defaultQuery: PromVisualQuery = {
|
|
metric: 'random_metric',
|
|
labels: [],
|
|
operations: [],
|
|
};
|
|
|
|
const bugQuery: PromVisualQuery = {
|
|
metric: 'random_metric',
|
|
labels: [{ label: 'instance', op: '=', value: 'localhost:9090' }],
|
|
operations: [
|
|
{
|
|
id: 'rate',
|
|
params: ['auto'],
|
|
},
|
|
{
|
|
id: '__sum_by',
|
|
params: ['instance', 'job'],
|
|
},
|
|
],
|
|
binaryQueries: [
|
|
{
|
|
operator: '/',
|
|
query: {
|
|
metric: 'metric2',
|
|
labels: [{ label: 'foo', op: '=', value: 'bar' }],
|
|
operations: [
|
|
{
|
|
id: '__sum_by',
|
|
params: ['app'],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
};
|
|
|
|
describe('PromQueryBuilder', () => {
|
|
it('shows empty just with metric selected', async () => {
|
|
setup();
|
|
// One should be select another query preview
|
|
expect(screen.getAllByText('random_metric').length).toBe(2);
|
|
// Add label
|
|
expect(screen.getByLabelText('Add')).toBeInTheDocument();
|
|
expect(screen.getByLabelText('Add operation')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders all the query sections', async () => {
|
|
setup(bugQuery);
|
|
expect(screen.getByText('random_metric')).toBeInTheDocument();
|
|
expect(screen.getByText('localhost:9090')).toBeInTheDocument();
|
|
expect(screen.getByText('Rate')).toBeInTheDocument();
|
|
const sumBys = screen.getAllByTestId('operation-wrapper-for-__sum_by');
|
|
expect(getByText(sumBys[0], 'instance')).toBeInTheDocument();
|
|
expect(getByText(sumBys[0], 'job')).toBeInTheDocument();
|
|
|
|
expect(getByText(sumBys[1], 'app')).toBeInTheDocument();
|
|
expect(screen.getByText('Binary operations')).toBeInTheDocument();
|
|
expect(screen.getByText('Operator')).toBeInTheDocument();
|
|
expect(screen.getByText('Vector matches')).toBeInTheDocument();
|
|
expect(screen.getByLabelText('selector').textContent).toBe(
|
|
'sum by(instance, job) (rate(random_metric{instance="localhost:9090"}[$__rate_interval])) / sum by(app) (metric2{foo="bar"})'
|
|
);
|
|
});
|
|
|
|
it('tries to load metrics without labels', async () => {
|
|
const { languageProvider } = setup();
|
|
openMetricSelect();
|
|
expect(languageProvider.getLabelValues).toBeCalledWith('__name__');
|
|
});
|
|
|
|
it('tries to load metrics with labels', async () => {
|
|
const { languageProvider } = setup({
|
|
...defaultQuery,
|
|
labels: [{ label: 'label_name', op: '=', value: 'label_value' }],
|
|
});
|
|
openMetricSelect();
|
|
expect(languageProvider.getSeries).toBeCalledWith('{label_name="label_value"}', true);
|
|
});
|
|
|
|
it('tries to load variables in metric field', async () => {
|
|
const { datasource } = setup();
|
|
datasource.getVariables = jest.fn().mockReturnValue([]);
|
|
openMetricSelect();
|
|
expect(datasource.getVariables).toBeCalled();
|
|
});
|
|
|
|
it('tries to load labels when metric selected', async () => {
|
|
const { languageProvider } = setup();
|
|
openLabelNameSelect();
|
|
expect(languageProvider.fetchSeriesLabels).toBeCalledWith('{__name__="random_metric"}');
|
|
});
|
|
|
|
it('tries to load variables in label field', async () => {
|
|
const { datasource } = setup();
|
|
datasource.getVariables = jest.fn().mockReturnValue([]);
|
|
openLabelNameSelect();
|
|
expect(datasource.getVariables).toBeCalled();
|
|
});
|
|
|
|
it('tries to load labels when metric selected and other labels are already present', async () => {
|
|
const { languageProvider } = setup({
|
|
...defaultQuery,
|
|
labels: [
|
|
{ label: 'label_name', op: '=', value: 'label_value' },
|
|
{ label: 'foo', op: '=', value: 'bar' },
|
|
],
|
|
});
|
|
openLabelNameSelect(1);
|
|
expect(languageProvider.fetchSeriesLabels).toBeCalledWith('{label_name="label_value", __name__="random_metric"}');
|
|
});
|
|
|
|
it('tries to load labels when metric is not selected', async () => {
|
|
const { languageProvider } = setup({
|
|
...defaultQuery,
|
|
metric: '',
|
|
});
|
|
openLabelNameSelect();
|
|
expect(languageProvider.fetchLabels).toBeCalled();
|
|
});
|
|
});
|
|
|
|
function setup(query: PromVisualQuery = defaultQuery) {
|
|
const languageProvider = new EmptyLanguageProviderMock() as unknown as PromQlLanguageProvider;
|
|
const datasource = new PrometheusDatasource(
|
|
{
|
|
url: '',
|
|
jsonData: {},
|
|
meta: {} as any,
|
|
} as any,
|
|
undefined,
|
|
undefined,
|
|
languageProvider
|
|
);
|
|
const props = {
|
|
datasource,
|
|
onRunQuery: () => {},
|
|
onChange: () => {},
|
|
};
|
|
|
|
render(<PromQueryBuilder {...props} query={query} />);
|
|
return { languageProvider, datasource };
|
|
}
|
|
|
|
function getMetricSelect() {
|
|
const metricSelect = screen.getAllByText('random_metric')[0].parentElement!;
|
|
// We need to return specifically input element otherwise clicks don't seem to work
|
|
return getByRole(metricSelect, 'combobox');
|
|
}
|
|
|
|
function openMetricSelect() {
|
|
const select = getMetricSelect();
|
|
userEvent.click(select);
|
|
}
|
|
|
|
function openLabelNameSelect(index = 0) {
|
|
const { name } = getLabelSelects(index);
|
|
userEvent.click(name);
|
|
}
|