mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-06-04 11:25:52 +08:00
208 lines
6.4 KiB
Go
208 lines
6.4 KiB
Go
package queryBuilder
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
metricsv3 "go.signoz.io/signoz/pkg/query-service/app/metrics/v3"
|
|
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
|
|
)
|
|
|
|
func TestBuildQueryWithMultipleQueriesAndFormula(t *testing.T) {
|
|
t.Run("TestBuildQueryWithFilters", func(t *testing.T) {
|
|
q := &v3.QueryRangeParamsV3{
|
|
Start: 1650991982000,
|
|
End: 1651078382000,
|
|
Step: 60,
|
|
CompositeQuery: &v3.CompositeQuery{
|
|
BuilderQueries: map[string]*v3.BuilderQuery{
|
|
"A": {
|
|
QueryName: "A",
|
|
DataSource: v3.DataSourceMetrics,
|
|
AggregateAttribute: v3.AttributeKey{Key: "name"},
|
|
Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{
|
|
{Key: v3.AttributeKey{Key: "in"}, Value: []interface{}{"a", "b", "c"}, Operator: v3.FilterOperatorIn},
|
|
}},
|
|
AggregateOperator: v3.AggregateOperatorRateMax,
|
|
Expression: "A",
|
|
},
|
|
"B": {
|
|
QueryName: "B",
|
|
AggregateAttribute: v3.AttributeKey{Key: "name2"},
|
|
DataSource: v3.DataSourceMetrics,
|
|
AggregateOperator: v3.AggregateOperatorRateAvg,
|
|
Expression: "B",
|
|
},
|
|
"C": {
|
|
QueryName: "C",
|
|
Expression: "A/B",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
qbOptions := QueryBuilderOptions{
|
|
BuildMetricQuery: metricsv3.PrepareMetricQuery,
|
|
}
|
|
qb := NewQueryBuilder(qbOptions)
|
|
|
|
queries, err := qb.PrepareQueries(q)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Contains(t, queries["C"], "SELECT A.ts as ts, A.value / B.value")
|
|
require.Contains(t, queries["C"], "WHERE metric_name = 'name' AND JSONExtractString(labels, 'in') IN ['a','b','c']")
|
|
require.Contains(t, queries["C"], "runningDifference(value)/runningDifference(ts)")
|
|
})
|
|
}
|
|
|
|
func TestBuildQueryWithIncorrectQueryRef(t *testing.T) {
|
|
t.Run("TestBuildQueryWithFilters", func(t *testing.T) {
|
|
q := &v3.QueryRangeParamsV3{
|
|
Start: 1650991982000,
|
|
End: 1651078382000,
|
|
Step: 60,
|
|
CompositeQuery: &v3.CompositeQuery{
|
|
BuilderQueries: map[string]*v3.BuilderQuery{
|
|
"A": {
|
|
QueryName: "A",
|
|
DataSource: v3.DataSourceMetrics,
|
|
AggregateAttribute: v3.AttributeKey{Key: "name"},
|
|
Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{
|
|
{Key: v3.AttributeKey{Key: "in"}, Value: []interface{}{"a", "b", "c"}, Operator: v3.FilterOperatorIn},
|
|
}},
|
|
AggregateOperator: v3.AggregateOperatorRateMax,
|
|
Expression: "A",
|
|
},
|
|
"C": {
|
|
QueryName: "C",
|
|
Expression: "A*2",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
qbOptions := QueryBuilderOptions{
|
|
BuildMetricQuery: metricsv3.PrepareMetricQuery,
|
|
}
|
|
qb := NewQueryBuilder(qbOptions)
|
|
|
|
_, err := qb.PrepareQueries(q)
|
|
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
func TestBuildQueryWithThreeOrMoreQueriesRefAndFormula(t *testing.T) {
|
|
t.Run("TestBuildQueryWithFilters", func(t *testing.T) {
|
|
q := &v3.QueryRangeParamsV3{
|
|
Start: 1650991982000,
|
|
End: 1651078382000,
|
|
Step: 60,
|
|
CompositeQuery: &v3.CompositeQuery{
|
|
BuilderQueries: map[string]*v3.BuilderQuery{
|
|
"A": {
|
|
QueryName: "A",
|
|
DataSource: v3.DataSourceMetrics,
|
|
AggregateAttribute: v3.AttributeKey{Key: "name"},
|
|
Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{
|
|
{Key: v3.AttributeKey{Key: "in"}, Value: []interface{}{"a", "b", "c"}, Operator: v3.FilterOperatorIn},
|
|
}},
|
|
AggregateOperator: v3.AggregateOperatorRateMax,
|
|
Expression: "A",
|
|
Disabled: true,
|
|
},
|
|
"B": {
|
|
QueryName: "B",
|
|
AggregateAttribute: v3.AttributeKey{Key: "name2"},
|
|
DataSource: v3.DataSourceMetrics,
|
|
|
|
AggregateOperator: v3.AggregateOperatorRateMax,
|
|
Expression: "B",
|
|
Disabled: true,
|
|
},
|
|
"C": {
|
|
QueryName: "C",
|
|
AggregateAttribute: v3.AttributeKey{Key: "name3"},
|
|
DataSource: v3.DataSourceMetrics,
|
|
|
|
AggregateOperator: v3.AggregateOperatorSumRate,
|
|
Expression: "C",
|
|
Disabled: true,
|
|
},
|
|
"F1": {
|
|
QueryName: "F1",
|
|
Expression: "A/B",
|
|
},
|
|
"F2": {
|
|
QueryName: "F2",
|
|
Expression: "A/(B+C)",
|
|
},
|
|
"F3": {
|
|
QueryName: "F3",
|
|
Expression: "A*A",
|
|
},
|
|
"F4": {
|
|
QueryName: "F4",
|
|
Expression: "A*B*C",
|
|
},
|
|
"F5": {
|
|
QueryName: "F5",
|
|
Expression: "((A - B) / B) * 100",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
qbOptions := QueryBuilderOptions{
|
|
BuildMetricQuery: metricsv3.PrepareMetricQuery,
|
|
}
|
|
qb := NewQueryBuilder(qbOptions)
|
|
|
|
queries, err := qb.PrepareQueries(q)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Contains(t, queries["F1"], "SELECT A.ts as ts, A.value / B.value")
|
|
require.Equal(t, 1, strings.Count(queries["F1"], " ON "))
|
|
|
|
require.Contains(t, queries["F2"], "SELECT A.ts as ts, A.value / (B.value + C.value)")
|
|
require.Equal(t, 2, strings.Count(queries["F2"], " ON "))
|
|
|
|
// Working with same query multiple times should not join on itself
|
|
require.NotContains(t, queries["F3"], " ON ")
|
|
|
|
require.Contains(t, queries["F4"], "SELECT A.ts as ts, A.value * B.value * C.value")
|
|
require.Equal(t, 2, strings.Count(queries["F4"], " ON "))
|
|
|
|
require.Contains(t, queries["F5"], "SELECT A.ts as ts, ((A.value - B.value) / B.value) * 100")
|
|
require.Equal(t, 1, strings.Count(queries["F5"], " ON "))
|
|
|
|
for _, query := range q.CompositeQuery.BuilderQueries {
|
|
if query.Disabled {
|
|
require.NotContains(t, queries, query.QueryName)
|
|
}
|
|
}
|
|
|
|
// res := PrepareBuilderMetricQueries(q, "table")
|
|
// So(res.Err, ShouldBeNil)
|
|
// queries := res.Queries
|
|
// So(len(queries), ShouldEqual, 5)
|
|
// So(queries["F1"], ShouldContainSubstring, "SELECT A.ts as ts, A.value / B.value")
|
|
// So(strings.Count(queries["F1"], " ON "), ShouldEqual, 1)
|
|
|
|
// So(queries["F2"], ShouldContainSubstring, "SELECT A.ts as ts, A.value / (B.value + C.value)")
|
|
// So(strings.Count(queries["F2"], " ON "), ShouldEqual, 2)
|
|
|
|
// // Working with same query multiple times should not join on itself
|
|
// So(queries["F3"], ShouldNotContainSubstring, " ON ")
|
|
|
|
// So(queries["F4"], ShouldContainSubstring, "SELECT A.ts as ts, A.value * B.value * C.value")
|
|
// // Number of times JOIN ON appears is N-1 where N is number of unique queries
|
|
// So(strings.Count(queries["F4"], " ON "), ShouldEqual, 2)
|
|
|
|
// So(queries["F5"], ShouldContainSubstring, "SELECT A.ts as ts, ((A.value - B.value) / B.value) * 100")
|
|
// So(strings.Count(queries["F5"], " ON "), ShouldEqual, 1)
|
|
})
|
|
}
|