2025-04-01 10:38:02 +09:00

166 lines
5.1 KiB
TypeScript

import { TestVariable } from '@grafana/scenes';
import { Dashboard } from '@grafana/schema';
import { variableAdapters } from 'app/features/variables/adapters';
import { createCustomVariableAdapter } from 'app/features/variables/custom/adapter';
import { createDataSourceVariableAdapter } from 'app/features/variables/datasource/adapter';
import { createQueryVariableAdapter } from 'app/features/variables/query/adapter';
import {
createDependencyEdges,
getVariableName,
createDependencyNodes,
createUsagesNetwork,
transformUsagesToNetwork,
} from './utils';
variableAdapters.setInit(() => [
createDataSourceVariableAdapter(),
createCustomVariableAdapter(),
createQueryVariableAdapter(),
]);
const dashboardMock: Dashboard = {
panels: [
{
datasource: {
type: 'prometheus',
uid: 'gdev-prometheus',
},
targets: [
{
datasource: {
type: 'prometheus',
uid: 'gdev-prometheus',
},
disableTextWrap: false,
editorMode: 'code',
expr: 'go_gc_duration_seconds{job=$query0)',
fullMetaSearch: false,
includeNullMetadata: true,
instant: false,
legendFormat: '__auto',
range: true,
refId: 'A',
useBackend: false,
},
{
datasource: {
type: 'prometheus',
uid: 'gdev-prometheus',
},
disableTextWrap: false,
editorMode: 'code',
expr: 'go_gc_duration_seconds{job=$query1)',
fullMetaSearch: false,
includeNullMetadata: true,
instant: false,
legendFormat: '__auto',
range: true,
refId: 'A',
useBackend: false,
},
],
title: 'Panel Title',
type: 'timeseries',
},
],
schemaVersion: 40,
};
describe('createDependencyNodes', () => {
it('should create node for each variable', () => {
const variables = [
new TestVariable({ name: 'A', query: 'A.*', value: '', text: '', options: [] }),
new TestVariable({ name: 'B', query: 'B.*', value: '', text: '', options: [] }),
new TestVariable({ name: 'C', query: 'C.*', value: '', text: '', options: [] }),
];
const graphNodes = createDependencyNodes(variables);
expect(graphNodes[0].id).toBe('A');
expect(graphNodes[1].id).toBe('B');
expect(graphNodes[2].id).toBe('C');
});
});
describe('createDependencyEdges', () => {
it('should create edges for variable dependencies', () => {
const variables = [
new TestVariable({ name: 'A', query: 'A.*', value: '', text: '', options: [] }),
new TestVariable({ name: 'B', query: '${A}.*', value: '', text: '', options: [] }),
new TestVariable({ name: 'C', query: '${B}.*', value: '', text: '', options: [] }),
];
const graphEdges = createDependencyEdges(variables);
expect(graphEdges).toContainEqual({ from: 'B', to: 'A' });
expect(graphEdges).toContainEqual({ from: 'C', to: 'B' });
});
});
describe('createUsagesNetwork', () => {
it('should create usage network for variables', () => {
const variables = [
new TestVariable({
type: 'query',
name: 'query0',
loading: false,
error: null,
}),
new TestVariable({
type: 'query',
name: 'query1',
loading: false,
error: null,
}),
];
const usagesNetwork = createUsagesNetwork(variables, dashboardMock);
expect(usagesNetwork).toHaveLength(2);
expect(usagesNetwork[0].variable.state.name).toBe('query0');
expect(usagesNetwork[1].variable.state.name).toBe('query1');
});
it('should not create usage network for variables that are not part of the dashboard', () => {
const variables = [
new TestVariable({
type: 'query',
name: 'query3',
loading: false,
error: null,
}),
];
const usagesNetwork = createUsagesNetwork(variables, dashboardMock);
expect(usagesNetwork).toHaveLength(0);
});
});
describe('transformUsagesToNetwork', () => {
it('should transform usages to network', () => {
const variables = [
new TestVariable({ name: 'A', query: 'A.*', value: '', text: '', options: [] }),
new TestVariable({ name: 'B', query: 'B.*', value: '', text: '', options: [] }),
];
const usages = [
{ variable: variables[0], tree: { key: 'value' } },
{ variable: variables[1], tree: { key: 'value' } },
];
const network = transformUsagesToNetwork(usages);
expect(network).toHaveLength(2);
expect(network[0].nodes).toContainEqual({ id: 'dashboard', label: 'dashboard' });
expect(network[0].edges).toHaveLength(2);
});
});
describe('getVariableName', () => {
it('should return undefined if no match is found', () => {
expect(getVariableName('no variable here')).toBeUndefined();
});
it('should return undefined if variable matches inherited object prop names', () => {
expect(getVariableName('${toString}')).toBeUndefined();
});
it('should return the variable name if it exists and does not match inherited object prop names', () => {
expect(getVariableName('${myVariable}')).toBe('myVariable');
});
});