From 0d1f7c8782f3cc7ad9cdd20c5257fdc087362f61 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 2 Jul 2018 20:04:36 +0200 Subject: [PATCH] Fix bar width issue in aligned prometheus queries (#12483) * Fix bar width issue in aligned prometheus queries This was broken because null values were filled in with unaligned times. * use aligned times for result transformation * add tests An earlier version of this fix aligned the times again in the transformer, but I think it's safe to only deal with aligned times in the response. * Fixed prometheus heatmap tranformer test The interval needs to be 1 to prevent step alignment. --- public/app/core/specs/time_series.jest.ts | 14 ++++ .../datasource/prometheus/datasource.ts | 4 +- .../prometheus/specs/datasource.jest.ts | 2 +- .../specs/result_transformer.jest.ts | 78 +++++++++++++++++++ 4 files changed, 95 insertions(+), 3 deletions(-) diff --git a/public/app/core/specs/time_series.jest.ts b/public/app/core/specs/time_series.jest.ts index f5245476218..bf50d807e03 100644 --- a/public/app/core/specs/time_series.jest.ts +++ b/public/app/core/specs/time_series.jest.ts @@ -119,6 +119,20 @@ describe('TimeSeries', function() { series.getFlotPairs('null'); expect(series.stats.avg).toBe(null); }); + + it('calculates timeStep', function() { + series = new TimeSeries({ + datapoints: [[null, 1], [null, 2], [null, 3]], + }); + series.getFlotPairs('null'); + expect(series.stats.timeStep).toBe(1); + + series = new TimeSeries({ + datapoints: [[0, 1530529290], [0, 1530529305], [0, 1530529320]], + }); + series.getFlotPairs('null'); + expect(series.stats.timeStep).toBe(15); + }); }); describe('When checking if ms resolution is needed', function() { diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 46431a08ab1..d7d33264c99 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -162,8 +162,8 @@ export class PrometheusDatasource { format: activeTargets[index].format, step: queries[index].step, legendFormat: activeTargets[index].legendFormat, - start: start, - end: end, + start: queries[index].start, + end: queries[index].end, query: queries[index].expr, responseListLength: responseList.length, responseIndex: index, diff --git a/public/app/plugins/datasource/prometheus/specs/datasource.jest.ts b/public/app/plugins/datasource/prometheus/specs/datasource.jest.ts index 0157322da58..219b990e5dd 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource.jest.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource.jest.ts @@ -68,7 +68,7 @@ describe('PrometheusDatasource', () => { ctx.query = { range: { from: moment(1443454528000), to: moment(1443454528000) }, targets: [{ expr: 'test{job="testjob"}', format: 'heatmap', legendFormat: '{{le}}' }], - interval: '60s', + interval: '1s', }; }); diff --git a/public/app/plugins/datasource/prometheus/specs/result_transformer.jest.ts b/public/app/plugins/datasource/prometheus/specs/result_transformer.jest.ts index 56a05d5aedb..b94cca79059 100644 --- a/public/app/plugins/datasource/prometheus/specs/result_transformer.jest.ts +++ b/public/app/plugins/datasource/prometheus/specs/result_transformer.jest.ts @@ -127,4 +127,82 @@ describe('Prometheus Result Transformer', () => { ]); }); }); + + describe('When resultFormat is time series', () => { + it('should transform matrix into timeseries', () => { + const response = { + status: 'success', + data: { + resultType: 'matrix', + result: [ + { + metric: { __name__: 'test', job: 'testjob' }, + values: [[0, '10'], [1, '10'], [2, '0']], + }, + ], + }, + }; + let result = []; + let options = { + format: 'timeseries', + start: 0, + end: 2, + }; + + ctx.resultTransformer.transform(result, { data: response }, options); + expect(result).toEqual([{ target: 'test{job="testjob"}', datapoints: [[10, 0], [10, 1000], [0, 2000]] }]); + }); + + it('should fill timeseries with null values', () => { + const response = { + status: 'success', + data: { + resultType: 'matrix', + result: [ + { + metric: { __name__: 'test', job: 'testjob' }, + values: [[1, '10'], [2, '0']], + }, + ], + }, + }; + let result = []; + let options = { + format: 'timeseries', + step: 1, + start: 0, + end: 2, + }; + + ctx.resultTransformer.transform(result, { data: response }, options); + expect(result).toEqual([{ target: 'test{job="testjob"}', datapoints: [[null, 0], [10, 1000], [0, 2000]] }]); + }); + + it('should align null values with step', () => { + const response = { + status: 'success', + data: { + resultType: 'matrix', + result: [ + { + metric: { __name__: 'test', job: 'testjob' }, + values: [[4, '10'], [8, '10']], + }, + ], + }, + }; + let result = []; + let options = { + format: 'timeseries', + step: 2, + start: 0, + end: 8, + }; + + ctx.resultTransformer.transform(result, { data: response }, options); + expect(result).toEqual([ + { target: 'test{job="testjob"}', datapoints: [[null, 0], [null, 2000], [10, 4000], [null, 6000], [10, 8000]] }, + ]); + }); + }); });