| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- import { getProcessedSeriesData, PanelQueryRunner } from './PanelQueryRunner';
- import { PanelData, DataQueryRequest } from '@grafana/ui/src/types';
- import moment from 'moment';
- describe('PanelQueryRunner', () => {
- it('converts timeseries to table skipping nulls', () => {
- const input1 = {
- target: 'Field Name',
- datapoints: [[100, 1], [200, 2]],
- };
- const input2 = {
- // without target
- target: '',
- datapoints: [[100, 1], [200, 2]],
- };
- const data = getProcessedSeriesData([null, input1, input2, null, null]);
- expect(data.length).toBe(2);
- expect(data[0].fields[0].name).toBe(input1.target);
- expect(data[0].rows).toBe(input1.datapoints);
- // Default name
- expect(data[1].fields[0].name).toEqual('Value');
- // Every colun should have a name and a type
- for (const table of data) {
- for (const column of table.fields) {
- expect(column.name).toBeDefined();
- expect(column.type).toBeDefined();
- }
- }
- });
- it('supports null values from query OK', () => {
- expect(getProcessedSeriesData([null, null, null, null])).toEqual([]);
- expect(getProcessedSeriesData(undefined)).toEqual([]);
- expect(getProcessedSeriesData((null as unknown) as any[])).toEqual([]);
- expect(getProcessedSeriesData([])).toEqual([]);
- });
- });
- interface ScenarioContext {
- setup: (fn: () => void) => void;
- maxDataPoints?: number | null;
- widthPixels: number;
- dsInterval?: string;
- minInterval?: string;
- events?: PanelData[];
- res?: PanelData;
- queryCalledWith?: DataQueryRequest;
- }
- type ScenarioFn = (ctx: ScenarioContext) => void;
- function describeQueryRunnerScenario(description: string, scenarioFn: ScenarioFn) {
- describe(description, () => {
- let setupFn = () => {};
- const ctx: ScenarioContext = {
- widthPixels: 200,
- setup: (fn: () => void) => {
- setupFn = fn;
- },
- };
- let runner: PanelQueryRunner;
- const response: any = {
- data: [{ target: 'hello', datapoints: [] }],
- };
- beforeEach(async () => {
- setupFn();
- const datasource: any = {
- interval: ctx.dsInterval,
- query: (options: DataQueryRequest) => {
- ctx.queryCalledWith = options;
- return Promise.resolve(response);
- },
- testDatasource: jest.fn(),
- };
- const args: any = {
- datasource,
- minInterval: ctx.minInterval,
- widthPixels: ctx.widthPixels,
- maxDataPoints: ctx.maxDataPoints,
- timeRange: {
- from: moment().subtract(1, 'days'),
- to: moment(),
- raw: { from: '1h', to: 'now' },
- },
- panelId: 0,
- queries: [{ refId: 'A', test: 1 }],
- };
- runner = new PanelQueryRunner();
- runner.subscribe({
- next: (data: PanelData) => {
- ctx.events.push(data);
- },
- });
- ctx.events = [];
- ctx.res = await runner.run(args);
- });
- scenarioFn(ctx);
- });
- }
- describe('PanelQueryRunner', () => {
- describeQueryRunnerScenario('with no maxDataPoints or minInterval', ctx => {
- ctx.setup(() => {
- ctx.maxDataPoints = null;
- ctx.widthPixels = 200;
- });
- it('should return data', async () => {
- expect(ctx.res.error).toBeUndefined();
- expect(ctx.res.series.length).toBe(1);
- });
- it('should use widthPixels as maxDataPoints', async () => {
- expect(ctx.queryCalledWith.maxDataPoints).toBe(200);
- });
- it('should calculate interval based on width', async () => {
- expect(ctx.queryCalledWith.interval).toBe('5m');
- });
- it('fast query should only publish 1 data events', async () => {
- expect(ctx.events.length).toBe(1);
- });
- });
- describeQueryRunnerScenario('with no panel min interval but datasource min interval', ctx => {
- ctx.setup(() => {
- ctx.widthPixels = 20000;
- ctx.dsInterval = '15s';
- });
- it('should limit interval to data source min interval', async () => {
- expect(ctx.queryCalledWith.interval).toBe('15s');
- });
- });
- describeQueryRunnerScenario('with panel min interval and data source min interval', ctx => {
- ctx.setup(() => {
- ctx.widthPixels = 20000;
- ctx.dsInterval = '15s';
- ctx.minInterval = '30s';
- });
- it('should limit interval to panel min interval', async () => {
- expect(ctx.queryCalledWith.interval).toBe('30s');
- });
- });
- describeQueryRunnerScenario('with maxDataPoints', ctx => {
- ctx.setup(() => {
- ctx.maxDataPoints = 10;
- });
- it('should pass maxDataPoints if specified', async () => {
- expect(ctx.queryCalledWith.maxDataPoints).toBe(10);
- });
- });
- });
|