From 8fe02612b6a6d3d90e9914f1758d0b1dc26d6701 Mon Sep 17 00:00:00 2001 From: Beto Muniz Date: Thu, 3 Nov 2022 09:34:34 -0300 Subject: [PATCH] Graphite: Allow metric name to use true/false as name (#57996) --- .../app/plugins/datasource/graphite/parser.ts | 2 +- .../datasource/graphite/specs/parser.test.ts | 22 +++++++++++++++++++ .../datasource/graphite/specs/store.test.ts | 16 ++------------ .../datasource/graphite/state/helpers.ts | 15 ++++++++----- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/public/app/plugins/datasource/graphite/parser.ts b/public/app/plugins/datasource/graphite/parser.ts index 8eee34554e1..b0ff68ef140 100644 --- a/public/app/plugins/datasource/graphite/parser.ts +++ b/public/app/plugins/datasource/graphite/parser.ts @@ -68,7 +68,7 @@ export class Parser { return curly; } - if (this.match('identifier') || this.match('number')) { + if (this.match('identifier') || this.match('number') || this.match('bool')) { // hack to handle float numbers in metric segments const parts = this.consumeToken().value.split('.'); if (parts.length === 2) { diff --git a/public/app/plugins/datasource/graphite/specs/parser.test.ts b/public/app/plugins/datasource/graphite/specs/parser.test.ts index 25cabd5d20c..05f4fc108d6 100644 --- a/public/app/plugins/datasource/graphite/specs/parser.test.ts +++ b/public/app/plugins/datasource/graphite/specs/parser.test.ts @@ -21,6 +21,28 @@ describe('when parsing', () => { expect(rootNode.segments[3].value).toBe('5'); }); + it('simple metric expression with "true" boolean in segments', () => { + const parser = new Parser('metric.15_20.5.true'); + const rootNode = parser.getAst(); + + expect(rootNode.type).toBe('metric'); + expect(rootNode.segments.length).toBe(4); + expect(rootNode.segments[1].value).toBe('15_20'); + expect(rootNode.segments[2].value).toBe('5'); + expect(rootNode.segments[3].value).toBe('true'); + }); + + it('simple metric expression with "false" boolean in segments', () => { + const parser = new Parser('metric.false.15_20.5'); + const rootNode = parser.getAst(); + + expect(rootNode.type).toBe('metric'); + expect(rootNode.segments.length).toBe(4); + expect(rootNode.segments[1].value).toBe('false'); + expect(rootNode.segments[2].value).toBe('15_20'); + expect(rootNode.segments[3].value).toBe('5'); + }); + it('simple metric expression with curly braces', () => { const parser = new Parser('metric.se1-{count, max}'); const rootNode = parser.getAst(); diff --git a/public/app/plugins/datasource/graphite/specs/store.test.ts b/public/app/plugins/datasource/graphite/specs/store.test.ts index 262e606e741..4c3919340dc 100644 --- a/public/app/plugins/datasource/graphite/specs/store.test.ts +++ b/public/app/plugins/datasource/graphite/specs/store.test.ts @@ -94,12 +94,6 @@ describe('Graphite actions', () => { expect(ctx.datasource.metricFindQuery.mock.calls[lastCallIndex][0]).toBe('test.prod.*'); }); - it('should delete last segment if no metrics are found', () => { - expect(ctx.state.segments[0].value).toBe('test'); - expect(ctx.state.segments[1].value).toBe('prod'); - expect(ctx.state.segments[2].value).toBe('select metric'); - }); - it('should parse expression and build function model', () => { expect(ctx.state.queryModel.functions.length).toBe(2); }); @@ -116,12 +110,6 @@ describe('Graphite actions', () => { expect(ctx.datasource.metricFindQuery.mock.calls[lastCallIndex][0]).toBe('test.test.*'); }); - it('should delete last segment if no metrics are found', () => { - expect(ctx.state.segments[0].value).toBe('test'); - expect(ctx.state.segments[1].value).toBe('test'); - expect(ctx.state.segments[2].value).toBe('select metric'); - }); - it('should parse expression and build function model', () => { expect(ctx.state.queryModel.functions.length).toBe(2); }); @@ -166,7 +154,7 @@ describe('Graphite actions', () => { }); it('should add 2 segments', () => { - expect(ctx.state.segments.length).toBe(2); + expect(ctx.state.segments.length).toBe(3); }); it('should add function param', () => { @@ -197,7 +185,7 @@ describe('Graphite actions', () => { }); it('should add segments', () => { - expect(ctx.state.segments.length).toBe(3); + expect(ctx.state.segments.length).toBe(4); }); it('should have correct func params', () => { diff --git a/public/app/plugins/datasource/graphite/state/helpers.ts b/public/app/plugins/datasource/graphite/state/helpers.ts index 0f58be18135..8a174d7fa4a 100644 --- a/public/app/plugins/datasource/graphite/state/helpers.ts +++ b/public/app/plugins/datasource/graphite/state/helpers.ts @@ -1,4 +1,4 @@ -import { clone } from 'lodash'; +import { clone, some } from 'lodash'; import { createErrorNotification } from '../../../../core/copy/appNotification'; import { notifyApp } from '../../../../core/reducers/appNotification'; @@ -69,7 +69,8 @@ export async function checkOtherSegments( return; } - const path = state.queryModel.getSegmentPathUpTo(fromIndex + 1); + const currentFromIndex = fromIndex + 1; + const path = state.queryModel.getSegmentPathUpTo(currentFromIndex); if (path === '') { return; } @@ -78,15 +79,17 @@ export async function checkOtherSegments( const segments = await state.datasource.metricFindQuery(path); if (segments.length === 0) { if (path !== '' && modifyLastSegment) { - state.queryModel.segments = state.queryModel.segments.splice(0, fromIndex); - state.segments = state.segments.splice(0, fromIndex); - addSelectMetricSegment(state); + state.queryModel.segments = state.queryModel.segments.splice(0, currentFromIndex); + state.segments = state.segments.splice(0, currentFromIndex); + if (!some(state.segments, { fake: true })) { + addSelectMetricSegment(state); + } } } else if (segments[0].expandable) { if (state.segments.length === fromIndex) { addSelectMetricSegment(state); } else { - await checkOtherSegments(state, fromIndex + 1); + await checkOtherSegments(state, currentFromIndex); } } } catch (err) {