diff --git a/public/app/plugins/datasource/prometheus/result_transformer.test.ts b/public/app/plugins/datasource/prometheus/result_transformer.test.ts index 15c7a52e251..01aaed0aa2f 100644 --- a/public/app/plugins/datasource/prometheus/result_transformer.test.ts +++ b/public/app/plugins/datasource/prometheus/result_transformer.test.ts @@ -379,4 +379,47 @@ describe('Prometheus Result Transformer', () => { expect(result[0].fields[1].values.toArray()).toEqual([null, null, 10, null, 10]); }); }); + + describe('When infinity values are returned', () => { + describe('When resultType is scalar', () => { + const response = { + status: 'success', + data: { + resultType: 'scalar', + result: [1443454528, '+Inf'], + }, + }; + + it('should correctly parse values', () => { + const result: DataFrame[] = transform({ data: response } as any, { ...options, target: { format: 'table' } }); + expect(result[0].fields[1].values.toArray()).toEqual([Number.POSITIVE_INFINITY]); + }); + }); + + describe('When resultType is vector', () => { + const response = { + status: 'success', + data: { + resultType: 'vector', + result: [ + { + metric: { __name__: 'test', job: 'testjob' }, + value: [1443454528, '+Inf'], + }, + { + metric: { __name__: 'test', job: 'testjob' }, + value: [1443454528, '-Inf'], + }, + ], + }, + }; + + describe('When format is table', () => { + it('should correctly parse values', () => { + const result: DataFrame[] = transform({ data: response } as any, { ...options, target: { format: 'table' } }); + expect(result[0].fields[3].values.toArray()).toEqual([Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]); + }); + }); + }); + }); }); diff --git a/public/app/plugins/datasource/prometheus/result_transformer.ts b/public/app/plugins/datasource/prometheus/result_transformer.ts index 8c5fe866de9..dd93ff8587f 100644 --- a/public/app/plugins/datasource/prometheus/result_transformer.ts +++ b/public/app/plugins/datasource/prometheus/result_transformer.ts @@ -22,6 +22,9 @@ import { TransformOptions, } from './types'; +const POSITIVE_INFINITY_SAMPLE_VALUE = '+Inf'; +const NEGATIVE_INFINITY_SAMPLE_VALUE = '-Inf'; + export function transform( response: FetchResponse, transformOptions: { @@ -116,7 +119,7 @@ function transformToDataFrame(data: MatrixOrVectorResult, options: TransformOpti const dps: PromValue[] = []; for (const value of data.values) { - let dpValue: number | null = parseFloat(value[1]); + let dpValue: number | null = parseSampleValue(value[1]); if (isNaN(dpValue)) { dpValue = null; @@ -180,12 +183,12 @@ function transformMetricDataToTable(md: MatrixOrVectorResult[], options: Transfo d.values.forEach(val => { timeField.values.add(val[0] * 1000); metricFields.forEach(metricField => metricField.values.add(getLabelValue(d.metric, metricField.name))); - valueField.values.add(parseFloat(val[1])); + valueField.values.add(parseSampleValue(val[1])); }); } else { timeField.values.add(d.value[0] * 1000); metricFields.forEach(metricField => metricField.values.add(getLabelValue(d.metric, metricField.name))); - valueField.values.add(parseFloat(d.value[1])); + valueField.values.add(parseSampleValue(d.value[1])); } }); @@ -200,7 +203,7 @@ function transformMetricDataToTable(md: MatrixOrVectorResult[], options: Transfo function getLabelValue(metric: PromMetric, label: string): string | number { if (metric.hasOwnProperty(label)) { if (label === 'le') { - return parseHistogramLabel(metric[label]); + return parseSampleValue(metric[label]); } return metric[label]; } @@ -225,7 +228,7 @@ function getValueField( name: valueName, type: FieldType.number, config: {}, - values: new ArrayVector(data.map(val => (parseValue ? parseFloat(val[1]) : val[1]))), + values: new ArrayVector(data.map(val => (parseValue ? parseSampleValue(val[1]) : val[1]))), }; } @@ -289,8 +292,8 @@ function sortSeriesByLabel(s1: DataFrame, s2: DataFrame): number { try { // fail if not integer. might happen with bad queries - le1 = parseHistogramLabel(s1.name ?? ''); - le2 = parseHistogramLabel(s2.name ?? ''); + le1 = parseSampleValue(s1.name ?? ''); + le2 = parseSampleValue(s2.name ?? ''); } catch (err) { console.error(err); return 0; @@ -307,9 +310,13 @@ function sortSeriesByLabel(s1: DataFrame, s2: DataFrame): number { return 0; } -function parseHistogramLabel(le: string): number { - if (le === '+Inf') { - return +Infinity; +function parseSampleValue(value: string): number { + switch (value) { + case POSITIVE_INFINITY_SAMPLE_VALUE: + return Number.POSITIVE_INFINITY; + case NEGATIVE_INFINITY_SAMPLE_VALUE: + return Number.NEGATIVE_INFINITY; + default: + return parseFloat(value); } - return Number(le); }