Files
grafana/packages/grafana-prometheus/src/query_hints.test.ts
Brendan O'Handley f85470d652 Prometheus: Use the frontend package in Prometheus and remove feature toggle (#86080)
* add history links for monaco completion provider folder

* add history links for monaco query field folder

* add history links for components folder

* add history links for configuration folder

* add history links for dashboard json folder

* add history links for gcopypaste folder

* add history link for variableMigration

* add history link for querybuilder/components/metrics-modal folder

* add history link for querybuilder/components/promqail folder

* add history links for querybuilder/components folder

* add history links for querybuilder/hooks folder

* add history links for querybuilder/shared folder

* add history links for querybuilder folder

* add history links for querycache folder

* add history links for src folder

* use frontend package and custom auth in module.ts

* remove files and fix import issues

* remove usePrometheusFrontendPackage

* remove extra files

* update betterer

* remove extra files after rebase

* fix betterer for rebase

* fix e2e flakiness
2024-04-15 16:45:23 -05:00

194 lines
5.3 KiB
TypeScript

// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/query_hints.test.ts
import { PrometheusDatasource } from './datasource';
import { getQueryHints, SUM_HINT_THRESHOLD_COUNT } from './query_hints';
describe('getQueryHints()', () => {
it('returns no hints for no series', () => {
expect(getQueryHints('', [])).toEqual([]);
});
it('returns no hints for empty series', () => {
expect(getQueryHints('', [{ datapoints: [] }])).toEqual([]);
});
it('returns a rate hint for a counter metric', () => {
const series = [
{
datapoints: [
[23, 1000],
[24, 1001],
],
},
];
const hints = getQueryHints('metric_total', series);
expect(hints!.length).toBe(1);
expect(hints![0]).toMatchObject({
label: 'Selected metric looks like a counter.',
fix: {
action: {
type: 'ADD_RATE',
query: 'metric_total',
},
},
});
});
it('returns a certain rate hint for a counter metric', () => {
const series = [
{
datapoints: [
[23, 1000],
[24, 1001],
],
},
];
const mock: unknown = { languageProvider: { metricsMetadata: { foo: { type: 'counter' } } } };
const datasource = mock as PrometheusDatasource;
let hints = getQueryHints('foo', series, datasource);
expect(hints!.length).toBe(1);
expect(hints![0]).toMatchObject({
label: 'Selected metric is a counter.',
fix: {
action: {
type: 'ADD_RATE',
query: 'foo',
},
},
});
// Test substring match not triggering hint
hints = getQueryHints('foo_foo', series, datasource);
expect(hints).toEqual([]);
});
it('returns no rate hint for a counter metric that already has a rate', () => {
const series = [
{
datapoints: [
[23, 1000],
[24, 1001],
],
},
];
const hints = getQueryHints('rate(metric_total[1m])', series);
expect(hints).toEqual([]);
});
it('returns no rate hint for a counter metric that already has an increase', () => {
const series = [
{
datapoints: [
[23, 1000],
[24, 1001],
],
},
];
const hints = getQueryHints('increase(metric_total[1m])', series);
expect(hints).toEqual([]);
});
it('returns a rate hint with action for a counter metric with labels', () => {
const series = [
{
datapoints: [
[23, 1000],
[24, 1001],
],
},
];
const hints = getQueryHints('metric_total{job="grafana"}', series);
expect(hints!.length).toBe(1);
expect(hints![0].label).toContain('Selected metric looks like a counter');
expect(hints![0].fix).toBeDefined();
});
it('returns a rate hint w/o action for a complex counter metric', () => {
const series = [
{
datapoints: [
[23, 1000],
[24, 1001],
],
},
];
const hints = getQueryHints('sum(metric_total)', series);
expect(hints!.length).toBe(1);
expect(hints![0].label).toContain('rate()');
expect(hints![0].fix).toBeUndefined();
});
it('returns a histogram hint for a bucket series', () => {
const series = [{ datapoints: [[23, 1000]] }];
const hints = getQueryHints('metric_bucket', series);
expect(hints!.length).toBe(1);
expect(hints![0]).toMatchObject({
label: 'Selected metric has buckets.',
fix: {
action: {
type: 'ADD_HISTOGRAM_QUANTILE',
query: 'metric_bucket',
},
},
});
});
it('returns a histogram hint with action for a bucket with labels', () => {
const series = [
{
datapoints: [
[23, 1000],
[24, 1001],
],
},
];
const hints = getQueryHints('metric_bucket{job="grafana"}', series);
expect(hints!.length).toBe(1);
expect(hints![0].label).toContain('Selected metric has buckets.');
expect(hints![0].fix).toBeDefined();
});
it('returns a sum hint when many time series results are returned for a simple metric', () => {
const seriesCount = SUM_HINT_THRESHOLD_COUNT;
const series = Array.from({ length: seriesCount }, (_) => ({
datapoints: [
[0, 0],
[0, 0],
],
}));
const hints = getQueryHints('metric', series);
expect(hints!.length).toBe(1);
expect(hints![0]).toMatchObject({
type: 'ADD_SUM',
label: 'Many time series results returned.',
fix: {
label: 'Consider aggregating with sum().',
action: {
type: 'ADD_SUM',
query: 'metric',
preventSubmit: true,
},
},
});
});
it('should not return rate hint for a recorded query', () => {
const seriesCount = SUM_HINT_THRESHOLD_COUNT;
const series = Array.from({ length: seriesCount }, (_) => ({
datapoints: [
[0, 0],
[0, 0],
],
}));
let hints = getQueryHints('node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate', series);
expect(hints!.length).toBe(0);
hints = getQueryHints('node_namespace_pod_container:container_cpu_usage_seconds_total', series);
expect(hints!.length).toBe(0);
hints = getQueryHints('container_cpu_usage_seconds_total:irate_total', series);
expect(hints!.length).toBe(0);
});
});