Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions connectors/grafana-plugin/src/datasource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,43 @@ describe('DataSource', () => {
expect(result.groupBy?.step).toBe('1h');
});
});

describe('metricFindQuery', () => {
it('extracts and expands a standard variable query object', async () => {
const scopedVars: ScopedVars = { cluster: { text: 'cluster-a', value: 'cluster-a' } };
const sql =
"table:metrics_validation:SELECT DISTINCT instance FROM sys_cpu_cores WHERE cluster IN (${cluster:sqlstring})";
const expandedSql =
"table:metrics_validation:SELECT DISTINCT instance FROM sys_cpu_cores WHERE cluster IN ('cluster-a')";
const getVariablesResult = jest.spyOn(ds, 'getVariablesResult').mockResolvedValue([]);
mockReplace.mockReturnValue(expandedSql);

await ds.metricFindQuery({ query: sql, refId: 'StandardVariableQuery' }, { scopedVars });

expect(mockReplace).toHaveBeenCalledWith(sql, scopedVars);
expect(getVariablesResult).toHaveBeenCalledWith(expandedSql);
});

it('keeps legacy string variable queries compatible', async () => {
const sql = 'show child paths root.sg';
const getVariablesResult = jest.spyOn(ds, 'getVariablesResult').mockResolvedValue([]);
mockReplace.mockReturnValue(sql);

await ds.metricFindQuery(sql);

expect(mockReplace).toHaveBeenCalledWith(sql, undefined);
expect(getVariablesResult).toHaveBeenCalledWith(sql);
});

it('rejects variable query objects without a string query field', async () => {
const getVariablesResult = jest.spyOn(ds, 'getVariablesResult').mockResolvedValue([]);

await expect(ds.metricFindQuery({ refId: 'StandardVariableQuery' })).rejects.toThrow(
'Variable query must be a string or an object with a string query field'
);

expect(mockReplace).not.toHaveBeenCalled();
expect(getVariablesResult).not.toHaveBeenCalled();
});
});
});
24 changes: 22 additions & 2 deletions connectors/grafana-plugin/src/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ import { IoTDBOptions, IoTDBQuery } from './types';
import { toMetricFindValue } from './functions';
import { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime';

function variableQueryText(query: unknown): string | undefined {
if (typeof query === 'string') {
return query;
}

if (query && typeof query === 'object' && 'query' in query) {
const queryText = (query as { query?: unknown }).query;
if (typeof queryText === 'string') {
return queryText;
}
}

return undefined;
}

export class DataSource extends DataSourceWithBackend<IoTDBQuery, IoTDBOptions> {
username: string;
url: string;
Expand Down Expand Up @@ -138,8 +153,13 @@ export class DataSource extends DataSourceWithBackend<IoTDBQuery, IoTDBOptions>
}

metricFindQuery(query: any, options?: any): Promise<MetricFindValue[]> {
query = getTemplateSrv().replace(query, options.scopedVars);
return this.getVariablesResult(query);
const queryText = variableQueryText(query);
if (queryText === undefined) {
return Promise.reject(new Error('Variable query must be a string or an object with a string query field'));
}

const expandedQuery = getTemplateSrv().replace(queryText, options?.scopedVars);
return this.getVariablesResult(expandedQuery);
}

nodeQuery(query: any, options?: any): Promise<MetricFindValue[]> {
Expand Down
Loading