package v4 import ( "testing" "github.com/stretchr/testify/assert" v3 "go.signoz.io/signoz/pkg/query-service/model/v3" ) func TestPrepareTimeseriesFilterQuery(t *testing.T) { testCases := []struct { name string builderQuery *v3.BuilderQuery expectedQueryContains string }{ { name: "test prepare time series with no filters and no group by", builderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, DataSource: v3.DataSourceMetrics, AggregateAttribute: v3.AttributeKey{ Key: "http_requests", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeUnspecified, IsColumn: true, IsJSON: false, }, Temporality: v3.Delta, Expression: "A", Disabled: false, // remaining struct fields are not needed here }, expectedQueryContains: "SELECT DISTINCT fingerprint FROM signoz_metrics.time_series_v2 WHERE metric_name = 'http_requests' AND temporality = 'Delta'", }, { name: "test prepare time series with no filters and group by", builderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, DataSource: v3.DataSourceMetrics, AggregateAttribute: v3.AttributeKey{ Key: "http_requests", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeUnspecified, IsColumn: true, IsJSON: false, }, Temporality: v3.Cumulative, GroupBy: []v3.AttributeKey{{ Key: "service_name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, }}, Expression: "A", Disabled: false, // remaining struct fields are not needed here }, expectedQueryContains: "SELECT DISTINCT JSONExtractString(labels, 'service_name') as service_name, fingerprint FROM signoz_metrics.time_series_v2 WHERE metric_name = 'http_requests' AND temporality = 'Cumulative'", }, { name: "test prepare time series with no filters and multiple group by", builderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, DataSource: v3.DataSourceMetrics, AggregateAttribute: v3.AttributeKey{ Key: "http_requests", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeUnspecified, IsColumn: true, IsJSON: false, }, Temporality: v3.Cumulative, GroupBy: []v3.AttributeKey{ { Key: "service_name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, }, { Key: "endpoint", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, }, }, Expression: "A", Disabled: false, // remaining struct fields are not needed here }, expectedQueryContains: "SELECT DISTINCT JSONExtractString(labels, 'service_name') as service_name, JSONExtractString(labels, 'endpoint') as endpoint, fingerprint FROM signoz_metrics.time_series_v2 WHERE metric_name = 'http_requests' AND temporality = 'Cumulative'", }, { name: "test prepare time series with filters and multiple group by", builderQuery: &v3.BuilderQuery{ QueryName: "A", StepInterval: 60, DataSource: v3.DataSourceMetrics, AggregateAttribute: v3.AttributeKey{ Key: "http_requests", DataType: v3.AttributeKeyDataTypeFloat64, Type: v3.AttributeKeyTypeUnspecified, IsColumn: true, IsJSON: false, }, Temporality: v3.Cumulative, Filters: &v3.FilterSet{ Operator: "AND", Items: []v3.FilterItem{ { Key: v3.AttributeKey{ Key: "service_name", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeString, }, Operator: v3.FilterOperatorNotEqual, Value: "payment_service", }, { Key: v3.AttributeKey{ Key: "endpoint", Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeString, }, Operator: v3.FilterOperatorIn, Value: []interface{}{"/paycallback", "/payme", "/paypal"}, }, }, }, GroupBy: []v3.AttributeKey{{ Key: "service_name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, }}, Expression: "A", Disabled: false, // remaining struct fields are not needed here }, expectedQueryContains: "SELECT DISTINCT JSONExtractString(labels, 'service_name') as service_name, fingerprint FROM signoz_metrics.time_series_v2 WHERE metric_name = 'http_requests' AND temporality = 'Cumulative' AND JSONExtractString(labels, 'service_name') != 'payment_service' AND JSONExtractString(labels, 'endpoint') IN ['/paycallback','/payme','/paypal']", }, } for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { query, err := PrepareTimeseriesFilterQuery(testCase.builderQuery) assert.Nil(t, err) assert.Contains(t, query, testCase.expectedQueryContains) }) } }