Compare commits
7 Commits
limiting-a
...
dashboard-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6fd19b363 | ||
|
|
e50a773fa9 | ||
|
|
351178ef34 | ||
|
|
ae98aaad2d | ||
|
|
23d808af08 | ||
|
|
c991ee6239 | ||
|
|
f098518faa |
@@ -0,0 +1,241 @@
|
||||
import {
|
||||
buildDependencies,
|
||||
buildDependencyGraph,
|
||||
buildParentDependencyGraph,
|
||||
checkAPIInvocation,
|
||||
onUpdateVariableNode,
|
||||
VariableGraph,
|
||||
} from '../util';
|
||||
import {
|
||||
buildDependenciesMock,
|
||||
buildGraphMock,
|
||||
checkAPIInvocationMock,
|
||||
onUpdateVariableNodeMock,
|
||||
} from './mock';
|
||||
|
||||
describe('dashboardVariables - utilities and processors', () => {
|
||||
describe('onUpdateVariableNode', () => {
|
||||
const { graph, topologicalOrder } = onUpdateVariableNodeMock;
|
||||
const testCases = [
|
||||
{
|
||||
scenario: 'root element',
|
||||
nodeToUpdate: 'deployment_environment',
|
||||
expected: [
|
||||
'deployment_environment',
|
||||
'service_name',
|
||||
'endpoint',
|
||||
'http_status_code',
|
||||
],
|
||||
},
|
||||
{
|
||||
scenario: 'middle child',
|
||||
nodeToUpdate: 'k8s_node_name',
|
||||
expected: ['k8s_node_name', 'k8s_namespace_name'],
|
||||
},
|
||||
{
|
||||
scenario: 'leaf element',
|
||||
nodeToUpdate: 'http_status_code',
|
||||
expected: ['http_status_code'],
|
||||
},
|
||||
{
|
||||
scenario: 'node not in graph',
|
||||
nodeToUpdate: 'unknown',
|
||||
expected: [],
|
||||
},
|
||||
{
|
||||
scenario: 'node not in topological order',
|
||||
nodeToUpdate: 'unknown',
|
||||
expected: [],
|
||||
},
|
||||
];
|
||||
|
||||
test.each(testCases)(
|
||||
'should update variable node when $scenario',
|
||||
({ nodeToUpdate, expected }) => {
|
||||
const updatedVariables: string[] = [];
|
||||
const callback = (node: string): void => {
|
||||
updatedVariables.push(node);
|
||||
};
|
||||
|
||||
onUpdateVariableNode(nodeToUpdate, graph, topologicalOrder, callback);
|
||||
|
||||
expect(updatedVariables).toEqual(expected);
|
||||
},
|
||||
);
|
||||
|
||||
it('should return empty array when topological order is empty', () => {
|
||||
const updatedVariables: string[] = [];
|
||||
onUpdateVariableNode('http_status_code', graph, [], (node) =>
|
||||
updatedVariables.push(node),
|
||||
);
|
||||
expect(updatedVariables).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkAPIInvocation', () => {
|
||||
const {
|
||||
variablesToGetUpdated,
|
||||
variableData,
|
||||
parentDependencyGraph,
|
||||
} = checkAPIInvocationMock;
|
||||
|
||||
const mockRootElement = {
|
||||
name: 'deployment_environment',
|
||||
key: '036a47cd-9ffc-47de-9f27-0329198964a8',
|
||||
id: '036a47cd-9ffc-47de-9f27-0329198964a8',
|
||||
modificationUUID: '5f71b591-f583-497c-839d-6a1590c3f60f',
|
||||
selectedValue: 'production',
|
||||
type: 'QUERY',
|
||||
// ... other properties omitted for brevity
|
||||
} as any;
|
||||
|
||||
describe('edge cases', () => {
|
||||
it('should return false when variableData is empty', () => {
|
||||
expect(
|
||||
checkAPIInvocation(
|
||||
variablesToGetUpdated,
|
||||
variableData,
|
||||
parentDependencyGraph,
|
||||
),
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true when parentDependencyGraph is empty', () => {
|
||||
expect(
|
||||
checkAPIInvocation(variablesToGetUpdated, variableData, {}),
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('variable sequences', () => {
|
||||
it('should return true for valid sequence', () => {
|
||||
expect(
|
||||
checkAPIInvocation(
|
||||
['k8s_node_name', 'k8s_namespace_name'],
|
||||
variableData,
|
||||
parentDependencyGraph,
|
||||
),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false for invalid sequence', () => {
|
||||
expect(
|
||||
checkAPIInvocation(
|
||||
['k8s_cluster_name', 'k8s_node_name', 'k8s_namespace_name'],
|
||||
variableData,
|
||||
parentDependencyGraph,
|
||||
),
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return false when variableData is not in sequence', () => {
|
||||
expect(
|
||||
checkAPIInvocation(
|
||||
['deployment_environment', 'service_name', 'endpoint'],
|
||||
variableData,
|
||||
parentDependencyGraph,
|
||||
),
|
||||
).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('root element behavior', () => {
|
||||
it('should return true for valid root element sequence', () => {
|
||||
expect(
|
||||
checkAPIInvocation(
|
||||
[
|
||||
'deployment_environment',
|
||||
'service_name',
|
||||
'endpoint',
|
||||
'http_status_code',
|
||||
],
|
||||
mockRootElement,
|
||||
parentDependencyGraph,
|
||||
),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return true for empty variablesToGetUpdated array', () => {
|
||||
expect(
|
||||
checkAPIInvocation([], mockRootElement, parentDependencyGraph),
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Graph Building Utilities', () => {
|
||||
const { graph } = buildGraphMock;
|
||||
const { variables } = buildDependenciesMock;
|
||||
|
||||
describe('buildParentDependencyGraph', () => {
|
||||
it('should build parent dependency graph with correct relationships', () => {
|
||||
const expected = {
|
||||
deployment_environment: [],
|
||||
service_name: ['deployment_environment'],
|
||||
endpoint: ['deployment_environment', 'service_name'],
|
||||
http_status_code: ['endpoint'],
|
||||
k8s_cluster_name: [],
|
||||
k8s_node_name: ['k8s_cluster_name'],
|
||||
k8s_namespace_name: ['k8s_cluster_name', 'k8s_node_name'],
|
||||
environment: [],
|
||||
};
|
||||
|
||||
expect(buildParentDependencyGraph(graph)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle empty graph', () => {
|
||||
expect(buildParentDependencyGraph({})).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildDependencyGraph', () => {
|
||||
it('should build complete dependency graph with correct structure and order', () => {
|
||||
const expected = {
|
||||
graph: {
|
||||
deployment_environment: ['service_name', 'endpoint'],
|
||||
service_name: ['endpoint'],
|
||||
endpoint: ['http_status_code'],
|
||||
http_status_code: [],
|
||||
k8s_cluster_name: ['k8s_node_name', 'k8s_namespace_name'],
|
||||
k8s_node_name: ['k8s_namespace_name'],
|
||||
k8s_namespace_name: [],
|
||||
environment: [],
|
||||
},
|
||||
order: [
|
||||
'deployment_environment',
|
||||
'k8s_cluster_name',
|
||||
'environment',
|
||||
'service_name',
|
||||
'k8s_node_name',
|
||||
'endpoint',
|
||||
'k8s_namespace_name',
|
||||
'http_status_code',
|
||||
],
|
||||
};
|
||||
|
||||
expect(buildDependencyGraph(graph)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildDependencies', () => {
|
||||
it('should build dependency map from variables array', () => {
|
||||
const expected: VariableGraph = {
|
||||
deployment_environment: ['service_name', 'endpoint'],
|
||||
service_name: ['endpoint'],
|
||||
endpoint: ['http_status_code'],
|
||||
http_status_code: [],
|
||||
k8s_cluster_name: ['k8s_node_name', 'k8s_namespace_name'],
|
||||
k8s_node_name: ['k8s_namespace_name'],
|
||||
k8s_namespace_name: [],
|
||||
environment: [],
|
||||
};
|
||||
|
||||
expect(buildDependencies(variables)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle empty variables array', () => {
|
||||
expect(buildDependencies([])).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,251 @@
|
||||
/* eslint-disable sonarjs/no-duplicate-string */
|
||||
export const checkAPIInvocationMock = {
|
||||
variablesToGetUpdated: [],
|
||||
variableData: {
|
||||
name: 'k8s_node_name',
|
||||
key: '4d71d385-beaf-4434-8dbf-c62be68049fc',
|
||||
allSelected: false,
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: '4d71d385-beaf-4434-8dbf-c62be68049fc',
|
||||
modificationUUID: '77233d3c-96d7-4ccb-aa9d-11b04d563068',
|
||||
multiSelect: false,
|
||||
order: 6,
|
||||
queryValue:
|
||||
"SELECT JSONExtractString(labels, 'k8s_node_name') AS k8s_node_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'k8s_node_cpu_time' AND JSONExtractString(labels, 'k8s_cluster_name') = {{.k8s_cluster_name}}\nGROUP BY k8s_node_name",
|
||||
selectedValue: 'gke-signoz-saas-si-consumer-bsc-e2sd4-a6d430fa-gvm2',
|
||||
showALLOption: false,
|
||||
sort: 'DISABLED',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
},
|
||||
parentDependencyGraph: {
|
||||
deployment_environment: [],
|
||||
service_name: ['deployment_environment'],
|
||||
endpoint: ['deployment_environment', 'service_name'],
|
||||
http_status_code: ['endpoint'],
|
||||
k8s_cluster_name: [],
|
||||
environment: [],
|
||||
k8s_node_name: ['k8s_cluster_name'],
|
||||
k8s_namespace_name: ['k8s_cluster_name', 'k8s_node_name'],
|
||||
},
|
||||
} as any;
|
||||
|
||||
export const onUpdateVariableNodeMock = {
|
||||
nodeToUpdate: 'deployment_environment',
|
||||
graph: {
|
||||
deployment_environment: ['service_name', 'endpoint'],
|
||||
service_name: ['endpoint'],
|
||||
endpoint: ['http_status_code'],
|
||||
http_status_code: [],
|
||||
k8s_cluster_name: ['k8s_node_name', 'k8s_namespace_name'],
|
||||
environment: [],
|
||||
k8s_node_name: ['k8s_namespace_name'],
|
||||
k8s_namespace_name: [],
|
||||
},
|
||||
topologicalOrder: [
|
||||
'deployment_environment',
|
||||
'k8s_cluster_name',
|
||||
'environment',
|
||||
'service_name',
|
||||
'k8s_node_name',
|
||||
'endpoint',
|
||||
'k8s_namespace_name',
|
||||
'http_status_code',
|
||||
],
|
||||
callback: jest.fn(),
|
||||
};
|
||||
|
||||
export const buildGraphMock = {
|
||||
graph: {
|
||||
deployment_environment: ['service_name', 'endpoint'],
|
||||
service_name: ['endpoint'],
|
||||
endpoint: ['http_status_code'],
|
||||
http_status_code: [],
|
||||
k8s_cluster_name: ['k8s_node_name', 'k8s_namespace_name'],
|
||||
environment: [],
|
||||
k8s_node_name: ['k8s_namespace_name'],
|
||||
k8s_namespace_name: [],
|
||||
},
|
||||
};
|
||||
|
||||
export const buildDependenciesMock = {
|
||||
variables: [
|
||||
{
|
||||
key: '036a47cd-9ffc-47de-9f27-0329198964a8',
|
||||
name: 'deployment_environment',
|
||||
allSelected: false,
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: '036a47cd-9ffc-47de-9f27-0329198964a8',
|
||||
modificationUUID: '5f71b591-f583-497c-839d-6a1590c3f60f',
|
||||
multiSelect: false,
|
||||
order: 0,
|
||||
queryValue:
|
||||
"SELECT DISTINCT JSONExtractString(labels, 'deployment_environment') AS deployment_environment\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'signoz_calls_total'",
|
||||
selectedValue: 'production',
|
||||
showALLOption: false,
|
||||
sort: 'DISABLED',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
},
|
||||
{
|
||||
key: 'eed5c917-1860-4c7e-bf6d-a05b97bafbc9',
|
||||
name: 'service_name',
|
||||
allSelected: true,
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: 'eed5c917-1860-4c7e-bf6d-a05b97bafbc9',
|
||||
modificationUUID: '85db928b-ac9b-4e9f-b274-791112102fdf',
|
||||
multiSelect: true,
|
||||
order: 1,
|
||||
queryValue:
|
||||
"SELECT DISTINCT JSONExtractString(labels, 'service_name') FROM signoz_metrics.distributed_time_series_v4_1day\n WHERE metric_name = 'signoz_calls_total' and JSONExtractString(labels, 'deployment_environment') = {{.deployment_environment}}",
|
||||
selectedValue: ['otelgateway'],
|
||||
showALLOption: true,
|
||||
sort: 'ASC',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
},
|
||||
{
|
||||
key: '4022d3c1-e845-4952-8984-78f25f575c7a',
|
||||
name: 'endpoint',
|
||||
allSelected: true,
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: '4022d3c1-e845-4952-8984-78f25f575c7a',
|
||||
modificationUUID: 'c0107fa1-ebb7-4dd3-aa9d-6ba08ecc594d',
|
||||
multiSelect: true,
|
||||
order: 2,
|
||||
queryValue:
|
||||
"SELECT DISTINCT JSONExtractString(labels, 'operation') FROM signoz_metrics.distributed_time_series_v4_1day\n WHERE metric_name = 'signoz_calls_total' AND JSONExtractString(labels, 'service_name') IN {{.service_name}} and JSONExtractString(labels, 'deployment_environment') = {{.deployment_environment}}",
|
||||
selectedValue: [
|
||||
'//v1/traces',
|
||||
'/logs/heroku',
|
||||
'/logs/json',
|
||||
'/logs/vector',
|
||||
'/v1/logs',
|
||||
'/v1/metrics',
|
||||
'/v1/traces',
|
||||
'SELECT',
|
||||
'exporter/signozkafka/logs',
|
||||
'exporter/signozkafka/metrics',
|
||||
'exporter/signozkafka/traces',
|
||||
'extension/signozkeyauth/Authenticate',
|
||||
'get',
|
||||
'hmget',
|
||||
'opentelemetry.proto.collector.logs.v1.LogsService/Export',
|
||||
'opentelemetry.proto.collector.metrics.v1.MetricsService/Export',
|
||||
'opentelemetry.proto.collector.trace.v1.TraceService/Export',
|
||||
'processor/signozlimiter/LogsProcessed',
|
||||
'processor/signozlimiter/MetricsProcessed',
|
||||
'processor/signozlimiter/TracesProcessed',
|
||||
'receiver/otlp/LogsReceived',
|
||||
'receiver/otlp/MetricsReceived',
|
||||
'receiver/otlp/TraceDataReceived',
|
||||
'receiver/signozhttplog/heroku/LogsReceived',
|
||||
'receiver/signozhttplog/json/LogsReceived',
|
||||
'receiver/signozhttplog/vector/LogsReceived',
|
||||
'redis.dial',
|
||||
'redis.pipeline eval',
|
||||
'sadd',
|
||||
'set',
|
||||
'sismember',
|
||||
],
|
||||
showALLOption: true,
|
||||
sort: 'ASC',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
},
|
||||
{
|
||||
key: '5e8a3cd9-3cd9-42df-a76c-79471a0f75bd',
|
||||
name: 'http_status_code',
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: '5e8a3cd9-3cd9-42df-a76c-79471a0f75bd',
|
||||
modificationUUID: '9a4021cc-a80a-4f15-8899-78892b763ca7',
|
||||
multiSelect: true,
|
||||
order: 3,
|
||||
queryValue:
|
||||
"SELECT DISTINCT JSONExtractString(labels, 'http_status_code') FROM signoz_metrics.distributed_time_series_v4_1day\n WHERE metric_name = 'signoz_calls_total' AND JSONExtractString(labels, 'operation') IN {{.endpoint}}",
|
||||
showALLOption: true,
|
||||
sort: 'ASC',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
selectedValue: ['', '200', '301', '400', '401', '405', '415', '429'],
|
||||
allSelected: true,
|
||||
},
|
||||
{
|
||||
key: '48e9aa64-05ca-41c2-a1bd-6c8aeca659f1',
|
||||
name: 'k8s_cluster_name',
|
||||
allSelected: false,
|
||||
customValue: 'test-1,\ntest-2,\ntest-3',
|
||||
description: '',
|
||||
id: '48e9aa64-05ca-41c2-a1bd-6c8aeca659f1',
|
||||
modificationUUID: '44722322-368c-4613-bb7f-d0b12867d57a',
|
||||
multiSelect: false,
|
||||
order: 4,
|
||||
queryValue:
|
||||
"SELECT JSONExtractString(labels, 'k8s_cluster_name') AS k8s_cluster_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'k8s_node_cpu_time'\nGROUP BY k8s_cluster_name",
|
||||
selectedValue: 'saasmonitor-cluster',
|
||||
showALLOption: false,
|
||||
sort: 'DISABLED',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
},
|
||||
{
|
||||
key: '3ea18ba2-30cf-4220-b03b-720b5eaf35f8',
|
||||
name: 'environment',
|
||||
allSelected: false,
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: '3ea18ba2-30cf-4220-b03b-720b5eaf35f8',
|
||||
modificationUUID: '9f76cb06-1b9f-460f-a174-0b210bb3cf93',
|
||||
multiSelect: false,
|
||||
order: 5,
|
||||
queryValue:
|
||||
"SELECT DISTINCT JSONExtractString(labels, 'deployment_environment') AS environment\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'signoz_calls_total'",
|
||||
selectedValue: 'production',
|
||||
showALLOption: false,
|
||||
sort: 'DISABLED',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
},
|
||||
{
|
||||
key: '4d71d385-beaf-4434-8dbf-c62be68049fc',
|
||||
name: 'k8s_node_name',
|
||||
allSelected: false,
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: '4d71d385-beaf-4434-8dbf-c62be68049fc',
|
||||
modificationUUID: '77233d3c-96d7-4ccb-aa9d-11b04d563068',
|
||||
multiSelect: false,
|
||||
order: 6,
|
||||
queryValue:
|
||||
"SELECT JSONExtractString(labels, 'k8s_node_name') AS k8s_node_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'k8s_node_cpu_time' AND JSONExtractString(labels, 'k8s_cluster_name') = {{.k8s_cluster_name}}\nGROUP BY k8s_node_name",
|
||||
selectedValue: 'gke-signoz-saas-si-consumer-bsc-e2sd4-a6d430fa-gvm2',
|
||||
showALLOption: false,
|
||||
sort: 'DISABLED',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
},
|
||||
{
|
||||
key: '937ecbae-b24b-4d6d-8cc4-5d5b8d53569b',
|
||||
name: 'k8s_namespace_name',
|
||||
customValue: '',
|
||||
description: '',
|
||||
id: '937ecbae-b24b-4d6d-8cc4-5d5b8d53569b',
|
||||
modificationUUID: '8ad2442d-8b4d-4c64-848e-af847d1d0eec',
|
||||
multiSelect: false,
|
||||
order: 7,
|
||||
queryValue:
|
||||
"SELECT JSONExtractString(labels, 'k8s_namespace_name') AS k8s_namespace_name\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'k8s_pod_cpu_time' AND JSONExtractString(labels, 'k8s_cluster_name') = {{.k8s_cluster_name}} AND JSONExtractString(labels, 'k8s_node_name') IN {{.k8s_node_name}}\nGROUP BY k8s_namespace_name",
|
||||
showALLOption: false,
|
||||
sort: 'DISABLED',
|
||||
textboxValue: '',
|
||||
type: 'QUERY',
|
||||
selectedValue: 'saasmonitor',
|
||||
allSelected: false,
|
||||
},
|
||||
] as any,
|
||||
};
|
||||
@@ -46,6 +46,7 @@ export type VariableGraph = Record<string, string[]>;
|
||||
export const buildDependencies = (
|
||||
variables: IDashboardVariable[],
|
||||
): VariableGraph => {
|
||||
console.log('buildDependencies', variables);
|
||||
const graph: VariableGraph = {};
|
||||
|
||||
// Initialize empty arrays for all variables first
|
||||
|
||||
Reference in New Issue
Block a user