package querier import ( "testing" qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5" "github.com/stretchr/testify/assert" ) // TestAdjustTimeRangeForShift tests the time range adjustment logic func TestAdjustTimeRangeForShift(t *testing.T) { tests := []struct { name string spec qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation] timeRange qbtypes.TimeRange requestType qbtypes.RequestType expectedFromMS uint64 expectedToMS uint64 }{ { name: "no shift", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{}, }, timeRange: qbtypes.TimeRange{ From: 1000000, To: 2000000, }, requestType: qbtypes.RequestTypeTimeSeries, expectedFromMS: 1000000, expectedToMS: 2000000, }, { name: "shift by 60 seconds using timeShift function", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: "60"}, }, }, }, }, timeRange: qbtypes.TimeRange{ From: 1000000, To: 2000000, }, requestType: qbtypes.RequestTypeTimeSeries, expectedFromMS: 940000, // 1000000 - 60000 expectedToMS: 1940000, // 2000000 - 60000 }, { name: "shift by negative 30 seconds (future shift)", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: "-30"}, }, }, }, }, timeRange: qbtypes.TimeRange{ From: 1000000, To: 2000000, }, requestType: qbtypes.RequestTypeTimeSeries, expectedFromMS: 1030000, // 1000000 - (-30000) expectedToMS: 2030000, // 2000000 - (-30000) }, { name: "no shift for raw request type even with timeShift function", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: "3600"}, }, }, }, }, timeRange: qbtypes.TimeRange{ From: 1000000, To: 2000000, }, requestType: qbtypes.RequestTypeRaw, expectedFromMS: 1000000, // No shift for raw queries expectedToMS: 2000000, }, { name: "shift applied for scalar request type with timeShift function", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: "3600"}, }, }, }, }, timeRange: qbtypes.TimeRange{ From: 10000000, To: 20000000, }, requestType: qbtypes.RequestTypeScalar, expectedFromMS: 6400000, // 10000000 - 3600000 expectedToMS: 16400000, // 20000000 - 3600000 }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := adjustTimeRangeForShift(tt.spec, tt.timeRange, tt.requestType) assert.Equal(t, tt.expectedFromMS, result.From, "fromMS mismatch") assert.Equal(t, tt.expectedToMS, result.To, "toMS mismatch") }) } } // TestExtractShiftFromBuilderQuery tests the shift extraction logic func TestExtractShiftFromBuilderQuery(t *testing.T) { tests := []struct { name string spec qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation] expectedShiftBy int64 }{ { name: "extract from timeShift function with float64", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: float64(3600)}, }, }, }, }, expectedShiftBy: 3600, }, { name: "extract from timeShift function with int64", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: int64(3600)}, }, }, }, }, expectedShiftBy: 3600, }, { name: "extract from timeShift function with string", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: "3600"}, }, }, }, }, expectedShiftBy: 3600, }, { name: "no timeShift function", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameAbsolute, }, }, }, expectedShiftBy: 0, }, { name: "invalid timeShift value", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: "invalid"}, }, }, }, }, expectedShiftBy: 0, }, { name: "multiple functions with timeShift", spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{ Functions: []qbtypes.Function{ { Name: qbtypes.FunctionNameAbsolute, }, { Name: qbtypes.FunctionNameTimeShift, Args: []qbtypes.FunctionArg{ {Value: "1800"}, }, }, { Name: qbtypes.FunctionNameClampMax, Args: []qbtypes.FunctionArg{ {Value: "100"}, }, }, }, }, expectedShiftBy: 1800, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { shiftBy := extractShiftFromBuilderQuery(tt.spec) assert.Equal(t, tt.expectedShiftBy, shiftBy) }) } }