Loki: Fix fetching of values for label if no previous equality operator (#82251)

* Loki: Fix teching of values if no previoous equality operator

* Update to consider regex with match everything

* Update public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>

* Fix lint

---------

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
This commit is contained in:
Ivana Huckova 2024-02-15 13:02:26 +01:00 committed by GitHub
parent 951399ac39
commit 45c7393564
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 2 deletions

View File

@ -65,7 +65,72 @@ describe('LokiQueryBuilder', () => {
await waitFor(() => expect(screen.getByText('job')).toBeInTheDocument());
});
it('does refetch label values with the correct timerange', async () => {
it('uses fetchLabelValues preselected labels have no equality matcher', async () => {
const props = createDefaultProps();
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]);
props.datasource.languageProvider.fetchSeriesLabels = jest.fn();
props.datasource.languageProvider.fetchLabelValues = jest.fn().mockReturnValue(['a', 'b']);
const query: LokiVisualQuery = {
labels: [
{ op: '!=', label: 'cluster', value: 'cluster1' },
{ op: '=', label: 'job', value: 'grafana' },
],
operations: [],
};
render(<LokiQueryBuilder {...props} query={query} />);
const labels = screen.getByText(/Label filters/);
const selects = getAllByRole(getSelectParent(labels)!, 'combobox');
await userEvent.click(selects[5]);
expect(props.datasource.languageProvider.fetchLabelValues).toBeCalledWith('job', { timeRange: mockTimeRange });
expect(props.datasource.languageProvider.fetchSeriesLabels).not.toBeCalled();
});
it('uses fetchLabelValues preselected label have regex equality matcher with match everything value (.*)', async () => {
const props = createDefaultProps();
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]);
props.datasource.languageProvider.fetchSeriesLabels = jest.fn();
props.datasource.languageProvider.fetchLabelValues = jest.fn().mockReturnValue(['a', 'b']);
const query: LokiVisualQuery = {
labels: [
{ op: '=~', label: 'cluster', value: '.*' },
{ op: '=', label: 'job', value: 'grafana' },
],
operations: [],
};
render(<LokiQueryBuilder {...props} query={query} />);
const labels = screen.getByText(/Label filters/);
const selects = getAllByRole(getSelectParent(labels)!, 'combobox');
await userEvent.click(selects[5]);
expect(props.datasource.languageProvider.fetchLabelValues).toBeCalledWith('job', { timeRange: mockTimeRange });
expect(props.datasource.languageProvider.fetchSeriesLabels).not.toBeCalled();
});
it('uses fetchSeriesLabels preselected label have regex equality matcher', async () => {
const props = createDefaultProps();
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]);
props.datasource.languageProvider.fetchSeriesLabels = jest.fn().mockReturnValue({ job: ['a'], instance: ['b'] });
props.datasource.languageProvider.fetchLabelValues = jest.fn();
const query: LokiVisualQuery = {
labels: [
{ op: '=~', label: 'cluster', value: 'cluster1|cluster2' },
{ op: '=', label: 'job', value: 'grafana' },
],
operations: [],
};
render(<LokiQueryBuilder {...props} query={query} />);
const labels = screen.getByText(/Label filters/);
const selects = getAllByRole(getSelectParent(labels)!, 'combobox');
await userEvent.click(selects[5]);
expect(props.datasource.languageProvider.fetchSeriesLabels).toBeCalledWith('{cluster=~"cluster1|cluster2"}', {
timeRange: mockTimeRange,
});
expect(props.datasource.languageProvider.fetchLabelValues).not.toBeCalled();
});
it('does refetch label values with the correct time range', async () => {
const props = createDefaultProps();
props.datasource.getDataSamples = jest.fn().mockResolvedValue([]);
props.datasource.languageProvider.fetchSeriesLabels = jest

View File

@ -81,7 +81,11 @@ export const LokiQueryBuilder = React.memo<Props>(
let values;
const labelsToConsider = query.labels.filter((x) => x !== forLabel);
if (labelsToConsider.length === 0) {
// If we have no equality/regex operation with .*, we can't fetch series as it will throw an error, so we fetch label values
const hasEqualityOperation = labelsToConsider.find(
(filter) => filter.op === '=' || (filter.op === '=~' && new RegExp(filter.value).test('') === false)
);
if (labelsToConsider.length === 0 || !hasEqualityOperation) {
values = await datasource.languageProvider.fetchLabelValues(forLabel.label, { timeRange });
} else {
const expr = lokiQueryModeller.renderLabels(labelsToConsider);