mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-30 01:50:26 -06:00
* feat: added traceoperator component and styles * chore: minor style improvments * feat: added conditions for traceoperator * chore: minor UI fixes * chore: type changes * chore: added initialvalue for trace operators * chore: Added changes to prepare request payload * chore: fixed minor styles + minor ux fix * feat: added span selector * chore: added ui changes in the editor * chore: removed traceoperations and reused queryoperations * chore: minor changes in queryaddon and aggregation for support * chore: added traceoperators in alerts * chore: minor pr review change * chore: linter fix * fix: fixed minor ts issues * fix: added limit support in traceoperator * chore: minor fix in traceoperator styles * chore: linting fix + icon changes * chore: updated type * chore: lint fixes * feat: added changes for showing querynames in alerts * feat: added trace operator grammer + antlr files * feat: added traceoperator context util * chore: added traceoperator validation function * feat: added traceoperator editor * feat: added queryname boost + operator constants * fix: pr reviews * chore: minor ui fix * fix: updated grammer files * test: added test for traceoperatorcontext * chore: removed check for multiple queries in traceexplorer * test: minor test fix * test: fixed breaking mapQueryDataFromApi test * chore: fixed logic to show trace operator * chore: updated docs link * chore: minor ui issue fix * chore: changed trace operator query name * chore: removed using spans from in trace opeartors * fix: added fix for order by in trace opeartor * feat: added changes related to saved in views in trace opeartor * chore: added changes to keep indirect descendent operator at bottom * chore: removed returnspansfrom field from traceoperator * chore: updated file names + regenerated grammer * chore: added beta tag in trace opeartor * chore: pr review fixes * Fix/tsc trace operator + tests (#8942) * fix: added tsc fixes for trace operator * chore: moved traceoperator utils * test: added test for traceopertor util * chore: tsc fix * fix: fixed tsc issue * Feat/trace operator dashboards (#8992) * chore: added callout message for multiple queries without trace operators * feat: added changes for supporting trace operators in dashboards * chore: minor changes for list panel
294 lines
8.0 KiB
TypeScript
294 lines
8.0 KiB
TypeScript
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
|
import { EQueryType } from 'types/common/dashboard';
|
|
import { DataSource } from 'types/common/queryBuilder';
|
|
|
|
import { getBarStepIntervalPoints, updateBarStepInterval } from '../utils';
|
|
|
|
describe('GridCardLayout Utils', () => {
|
|
describe('getBarStepIntervalPoints', () => {
|
|
it('should return 60 points for duration <= 1 hour', () => {
|
|
// 30 minutes in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 30 * 60 * 1000;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(60);
|
|
});
|
|
|
|
it('should return 60 points for exactly 1 hour', () => {
|
|
// 1 hour in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 60 * 60 * 1000;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(60);
|
|
});
|
|
|
|
it('should return 120 points for duration <= 3 hours', () => {
|
|
// 2 hours in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 2 * 60 * 60 * 1000;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(120);
|
|
});
|
|
|
|
it('should return 120 points for exactly 3 hours', () => {
|
|
// 3 hours in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 3 * 60 * 60 * 1000;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(120);
|
|
});
|
|
|
|
it('should return 180 points for duration <= 5 hours', () => {
|
|
// 4 hours in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 4 * 60 * 60 * 1000;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(180);
|
|
});
|
|
|
|
it('should return 180 points for exactly 5 hours', () => {
|
|
// 5 hours in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 5 * 60 * 60 * 1000;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(180);
|
|
});
|
|
|
|
it('should calculate dynamic interval for duration > 5 hours', () => {
|
|
// 10 hours in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 10 * 60 * 60 * 1000;
|
|
|
|
const result = getBarStepIntervalPoints(start, end);
|
|
|
|
// For 10 hours (600 minutes), interval should be ceil(600/80) = 8, rounded to 10, then * 60 = 600
|
|
expect(result).toBe(600);
|
|
});
|
|
|
|
it('should handle very long durations correctly', () => {
|
|
// 7 days in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 7 * 24 * 60 * 60 * 1000;
|
|
|
|
const result = getBarStepIntervalPoints(start, end);
|
|
|
|
// For 7 days (10080 minutes), interval should be ceil(10080/80) = 126, rounded to 130, then * 60 = 7800
|
|
expect(result).toBe(7800);
|
|
});
|
|
|
|
it('should round up to nearest multiple of 5 minutes', () => {
|
|
// 12 hours in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 12 * 60 * 60 * 1000;
|
|
|
|
const result = getBarStepIntervalPoints(start, end);
|
|
|
|
// For 12 hours (720 minutes), interval should be ceil(720/80) = 9, rounded to 10, then * 60 = 600
|
|
expect(result).toBe(600);
|
|
});
|
|
|
|
it('should handle edge case with very small duration', () => {
|
|
// 1 minute in milliseconds
|
|
const start = Date.now();
|
|
const end = start + 1 * 60 * 1000;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(60);
|
|
});
|
|
|
|
it('should handle zero duration', () => {
|
|
const start = Date.now();
|
|
const end = start;
|
|
|
|
expect(getBarStepIntervalPoints(start, end)).toBe(60);
|
|
});
|
|
});
|
|
|
|
describe('updateBarStepInterval', () => {
|
|
const mockQuery: Query = {
|
|
queryType: EQueryType.QUERY_BUILDER,
|
|
builder: {
|
|
queryData: [
|
|
{
|
|
stepInterval: null,
|
|
aggregateOperator: 'avg',
|
|
dataSource: DataSource.METRICS,
|
|
queryName: 'A',
|
|
aggregateAttribute: { key: 'cpu_usage', type: 'Gauge' },
|
|
timeAggregation: 'avg',
|
|
spaceAggregation: 'avg',
|
|
functions: [],
|
|
filters: { items: [], op: 'AND' },
|
|
expression: 'A',
|
|
disabled: false,
|
|
having: [],
|
|
groupBy: [],
|
|
orderBy: [],
|
|
limit: null,
|
|
offset: 0,
|
|
pageSize: 0,
|
|
reduceTo: 'avg',
|
|
legend: '',
|
|
},
|
|
],
|
|
queryFormulas: [],
|
|
queryTraceOperator: [],
|
|
},
|
|
clickhouse_sql: [],
|
|
promql: [],
|
|
id: 'test-query',
|
|
};
|
|
|
|
it('should update stepInterval based on time range', () => {
|
|
// 2 hours duration
|
|
const minTime = Date.now();
|
|
const maxTime = minTime + 2 * 60 * 60 * 1000;
|
|
|
|
const result = updateBarStepInterval(mockQuery, minTime, maxTime);
|
|
|
|
expect(result.builder.queryData[0].stepInterval).toBe(120);
|
|
});
|
|
|
|
it('should preserve other query properties', () => {
|
|
const minTime = Date.now();
|
|
const maxTime = minTime + 1 * 60 * 60 * 1000;
|
|
|
|
const result = updateBarStepInterval(mockQuery, minTime, maxTime);
|
|
|
|
expect(result.builder.queryData[0].aggregateOperator).toBe('avg');
|
|
expect(result.builder.queryData[0].queryName).toBe('A');
|
|
expect(result.builder.queryData[0].dataSource).toBe('metrics');
|
|
});
|
|
|
|
it('should handle multiple queryData items', () => {
|
|
const multiQueryMock: Query = {
|
|
...mockQuery,
|
|
builder: {
|
|
queryData: [
|
|
...mockQuery.builder.queryData,
|
|
{
|
|
...mockQuery.builder.queryData[0],
|
|
queryName: 'B',
|
|
stepInterval: 45,
|
|
},
|
|
],
|
|
queryFormulas: [],
|
|
queryTraceOperator: [],
|
|
},
|
|
};
|
|
|
|
const minTime = Date.now();
|
|
const maxTime = minTime + 4 * 60 * 60 * 1000;
|
|
|
|
const result = updateBarStepInterval(multiQueryMock, minTime, maxTime);
|
|
|
|
expect(result.builder.queryData).toHaveLength(2);
|
|
expect(result.builder.queryData[0].stepInterval).toBe(180);
|
|
expect(result.builder.queryData[1].stepInterval).toBe(45); // 45 is the stepInterval of the second query - custom value
|
|
});
|
|
|
|
it('should use calculated stepInterval when original is undefined', () => {
|
|
const queryWithUndefinedStep: Query = {
|
|
...mockQuery,
|
|
builder: {
|
|
queryData: [
|
|
{
|
|
...mockQuery.builder.queryData[0],
|
|
stepInterval: undefined as any,
|
|
},
|
|
],
|
|
queryFormulas: [],
|
|
queryTraceOperator: [],
|
|
},
|
|
};
|
|
|
|
const minTime = Date.now();
|
|
const maxTime = minTime + 1 * 60 * 60 * 1000;
|
|
|
|
const result = updateBarStepInterval(
|
|
queryWithUndefinedStep,
|
|
minTime,
|
|
maxTime,
|
|
);
|
|
|
|
expect(result.builder.queryData[0].stepInterval).toBe(60);
|
|
});
|
|
|
|
it('should fallback to 60 when calculated stepInterval is 0', () => {
|
|
const minTime = Date.now();
|
|
const maxTime = minTime; // Same time = 0 duration
|
|
|
|
const result = updateBarStepInterval(mockQuery, minTime, maxTime);
|
|
|
|
expect(result.builder.queryData[0].stepInterval).toBe(60);
|
|
});
|
|
|
|
it('should handle very large time ranges', () => {
|
|
const minTime = Date.now();
|
|
const maxTime = minTime + 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
|
|
const result = updateBarStepInterval(mockQuery, minTime, maxTime);
|
|
|
|
// Should calculate appropriate interval for 30 days
|
|
expect(result.builder.queryData[0].stepInterval).toBeGreaterThan(180);
|
|
});
|
|
|
|
it('should handle stepInterval as 0', () => {
|
|
const queryWithZeroStep: Query = {
|
|
...mockQuery,
|
|
builder: {
|
|
queryData: [
|
|
{
|
|
...mockQuery.builder.queryData[0],
|
|
stepInterval: 0,
|
|
},
|
|
],
|
|
queryFormulas: [],
|
|
queryTraceOperator: [],
|
|
},
|
|
};
|
|
|
|
const minTime = Date.now();
|
|
let maxTime = minTime + 1 * 60 * 60 * 1000;
|
|
|
|
const result = updateBarStepInterval(queryWithZeroStep, minTime, maxTime);
|
|
|
|
expect(result.builder.queryData[0].stepInterval).toBe(60);
|
|
|
|
maxTime = minTime + 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
|
|
const result1 = updateBarStepInterval(queryWithZeroStep, minTime, maxTime);
|
|
|
|
expect(result1.builder.queryData[0].stepInterval).toBe(32400);
|
|
});
|
|
|
|
it('should respect user entered inputs', () => {
|
|
const queryWithUserStep: Query = {
|
|
...mockQuery,
|
|
builder: {
|
|
queryData: [
|
|
{
|
|
...mockQuery.builder.queryData[0],
|
|
stepInterval: 120,
|
|
},
|
|
],
|
|
queryFormulas: [],
|
|
queryTraceOperator: [],
|
|
},
|
|
};
|
|
|
|
const minTime = Date.now();
|
|
let maxTime = minTime + 1 * 60 * 60 * 1000;
|
|
|
|
const result = updateBarStepInterval(queryWithUserStep, minTime, maxTime);
|
|
|
|
expect(result.builder.queryData[0].stepInterval).toBe(120); // not 60
|
|
|
|
maxTime = minTime + 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
|
|
const result1 = updateBarStepInterval(queryWithUserStep, minTime, maxTime);
|
|
|
|
expect(result1.builder.queryData[0].stepInterval).toBe(120); // not 32400
|
|
});
|
|
});
|
|
});
|