Plugins: InfluxDB variable interpolation fix for influxdbBackendMigration feature flag (#51624) (#51834)

(cherry picked from commit 9941e06e22)

Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>
This commit is contained in:
Grot (@grafanabot)
2022-07-07 17:22:00 +02:00
committed by GitHub
co-authored by ismail simsek
parent 62e0a2c561
commit a35e7f0bf5
2 changed files with 47 additions and 20 deletions
@@ -5,6 +5,7 @@ import { v4 as uuidv4 } from 'uuid';
import { import {
AnnotationEvent, AnnotationEvent,
AnnotationQueryRequest,
ArrayVector, ArrayVector,
DataFrame, DataFrame,
DataQueryError, DataQueryError,
@@ -21,7 +22,6 @@ import {
TIME_SERIES_TIME_FIELD_NAME, TIME_SERIES_TIME_FIELD_NAME,
TIME_SERIES_VALUE_FIELD_NAME, TIME_SERIES_VALUE_FIELD_NAME,
TimeSeries, TimeSeries,
AnnotationQueryRequest,
} from '@grafana/data'; } from '@grafana/data';
import { import {
BackendDataSourceResponse, BackendDataSourceResponse,
@@ -240,7 +240,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
if (this.isFlux) { if (this.isFlux) {
return { return {
...query, ...query,
query: this.templateSrv.replace(query.query ?? '', rest), // The raw query text query: this.templateSrv.replace(query.query ?? '', rest, 'regex'), // The raw query text
}; };
} }
@@ -368,7 +368,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
const target: InfluxQuery = { const target: InfluxQuery = {
refId: 'metricFindQuery', refId: 'metricFindQuery',
datasource: this.getRef(), datasource: this.getRef(),
query: this.templateSrv.replace(options.annotation.query ?? ''), query: this.templateSrv.replace(options.annotation.query ?? '', undefined, 'regex'),
rawQuery: true, rawQuery: true,
}; };
@@ -426,7 +426,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
return { return {
...query, ...query,
datasource: this.getRef(), datasource: this.getRef(),
query: this.templateSrv.replace(query.query ?? '', scopedVars), // The raw query text query: this.templateSrv.replace(query.query ?? '', scopedVars, 'regex'), // The raw query text
}; };
} }
@@ -475,7 +475,7 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
return { return {
...expandedQuery, ...expandedQuery,
query: this.templateSrv.replace(query.query ?? '', rest), // The raw query text query: this.templateSrv.replace(query.query ?? '', rest, 'regex'), // The raw query text
alias: this.templateSrv.replace(query.alias ?? '', scopedVars), alias: this.templateSrv.replace(query.alias ?? '', scopedVars),
limit: this.templateSrv.replace(query.limit?.toString() ?? '', scopedVars, 'regex'), limit: this.templateSrv.replace(query.limit?.toString() ?? '', scopedVars, 'regex'),
measurement: this.templateSrv.replace(query.measurement ?? '', scopedVars, 'regex'), measurement: this.templateSrv.replace(query.measurement ?? '', scopedVars, 'regex'),
@@ -1,6 +1,7 @@
import { lastValueFrom, of } from 'rxjs'; import { lastValueFrom, of } from 'rxjs';
import { TemplateSrvStub } from 'test/specs/helpers'; import { TemplateSrvStub } from 'test/specs/helpers';
import { ScopedVars } from '@grafana/data/src';
import { FetchResponse } from '@grafana/runtime'; import { FetchResponse } from '@grafana/runtime';
import config from 'app/core/config'; import config from 'app/core/config';
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
@@ -177,15 +178,31 @@ describe('InfluxDataSource', () => {
}); });
describe('Variables should be interpolated correctly', () => { describe('Variables should be interpolated correctly', () => {
const templateSrv: any = { replace: jest.fn() };
const instanceSettings: any = {}; const instanceSettings: any = {};
const ds = new InfluxDatasource(instanceSettings, templateSrv);
const text = 'interpolationText'; const text = 'interpolationText';
templateSrv.replace.mockReturnValue(text); const text2 = 'interpolationText2';
const textWithoutFormatRegex = 'interpolationText,interpolationText2';
const textWithFormatRegex = 'interpolationText|interpolationText2';
const variableMap: Record<string, string> = {
$interpolationVar: text,
$interpolationVar2: text2,
};
const templateSrv: any = {
replace: jest.fn((target?: string, scopedVars?: ScopedVars, format?: string | Function): string => {
if (!format) {
return variableMap[target!] || '';
}
if (format === 'regex') {
return textWithFormatRegex;
}
return textWithoutFormatRegex;
}),
};
const ds = new InfluxDatasource(instanceSettings, templateSrv);
const fluxQuery = { const fluxQuery = {
refId: 'x', refId: 'x',
query: '$interpolationVar', query: '$interpolationVar,$interpolationVar2',
}; };
const influxQuery = { const influxQuery = {
@@ -200,7 +217,7 @@ describe('InfluxDataSource', () => {
{ {
key: 'cpu', key: 'cpu',
operator: '=~', operator: '=~',
value: '/^$interpolationVar$/', value: '/^$interpolationVar,$interpolationVar2$/',
}, },
], ],
groupBy: [ groupBy: [
@@ -221,20 +238,20 @@ describe('InfluxDataSource', () => {
function fluxChecks(query: any) { function fluxChecks(query: any) {
expect(templateSrv.replace).toBeCalledTimes(1); expect(templateSrv.replace).toBeCalledTimes(1);
expect(query).toBe(text); expect(query).toBe(textWithFormatRegex);
} }
function influxChecks(query: any) { function influxChecks(query: any) {
expect(templateSrv.replace).toBeCalledTimes(10); expect(templateSrv.replace).toBeCalledTimes(10);
expect(query.alias).toBe(text); expect(query.alias).toBe(text);
expect(query.measurement).toBe(text); expect(query.measurement).toBe(textWithFormatRegex);
expect(query.policy).toBe(text); expect(query.policy).toBe(textWithFormatRegex);
expect(query.limit).toBe(text); expect(query.limit).toBe(textWithFormatRegex);
expect(query.slimit).toBe(text); expect(query.slimit).toBe(textWithFormatRegex);
expect(query.tz).toBe(text); expect(query.tz).toBe(text);
expect(query.tags![0].value).toBe(text); expect(query.tags![0].value).toBe(textWithFormatRegex);
expect(query.groupBy![0].params![0]).toBe(text); expect(query.groupBy![0].params![0]).toBe(textWithFormatRegex);
expect(query.select![0][0].params![0]).toBe(text); expect(query.select![0][0].params![0]).toBe(textWithFormatRegex);
} }
describe('when interpolating query variables for dashboard->explore', () => { describe('when interpolating query variables for dashboard->explore', () => {
@@ -242,6 +259,7 @@ describe('InfluxDataSource', () => {
ds.isFlux = true; ds.isFlux = true;
const queries = ds.interpolateVariablesInQueries([fluxQuery], { const queries = ds.interpolateVariablesInQueries([fluxQuery], {
interpolationVar: { text: text, value: text }, interpolationVar: { text: text, value: text },
interpolationVar2: { text: text2, value: text2 },
}); });
fluxChecks(queries[0].query); fluxChecks(queries[0].query);
}); });
@@ -250,6 +268,7 @@ describe('InfluxDataSource', () => {
ds.isFlux = false; ds.isFlux = false;
const queries = ds.interpolateVariablesInQueries([influxQuery], { const queries = ds.interpolateVariablesInQueries([influxQuery], {
interpolationVar: { text: text, value: text }, interpolationVar: { text: text, value: text },
interpolationVar2: { text: text2, value: text2 },
}); });
influxChecks(queries[0]); influxChecks(queries[0]);
}); });
@@ -258,7 +277,12 @@ describe('InfluxDataSource', () => {
describe('when interpolating template variables', () => { describe('when interpolating template variables', () => {
it('should apply all template variables with Flux mode', () => { it('should apply all template variables with Flux mode', () => {
ds.isFlux = true; ds.isFlux = true;
const query = ds.applyTemplateVariables(fluxQuery, { interpolationVar: { text: text, value: text } }); const query = ds.applyTemplateVariables(fluxQuery, {
interpolationVar: {
text: text,
value: text,
},
});
fluxChecks(query.query); fluxChecks(query.query);
}); });
@@ -266,7 +290,10 @@ describe('InfluxDataSource', () => {
ds.isFlux = false; ds.isFlux = false;
ds.access = 'proxy'; ds.access = 'proxy';
config.featureToggles.influxdbBackendMigration = true; config.featureToggles.influxdbBackendMigration = true;
const query = ds.applyTemplateVariables(influxQuery, { interpolationVar: { text: text, value: text } }); const query = ds.applyTemplateVariables(influxQuery, {
interpolationVar: { text: text, value: text },
interpolationVar2: { text: 'interpolationText2', value: 'interpolationText2' },
});
influxChecks(query); influxChecks(query);
}); });
}); });