blob: eabd79c912c81402ea634d07b876c3b2261505f6 [file] [log] [blame]
// Licensed to Apache Software Foundation (ASF) under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Apache Software Foundation (ASF) licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package logical_test
import (
"context"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"github.com/apache/skywalking-banyandb/api/common"
apiv1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/v1"
apischema "github.com/apache/skywalking-banyandb/api/schema"
"github.com/apache/skywalking-banyandb/banyand/series"
"github.com/apache/skywalking-banyandb/pkg/pb"
"github.com/apache/skywalking-banyandb/pkg/query/logical"
)
func TestAnalyzer_SimpleTimeScan(t *testing.T) {
assert := require.New(t)
ana := logical.DefaultAnalyzer()
sT, eT := time.Now().Add(-3*time.Hour), time.Now()
criteria := pb.NewQueryRequestBuilder().
Limit(0).
Offset(0).
Metadata("default", "trace").
TimeRange(sT, eT).
Build()
metadata := &common.Metadata{
KindVersion: apischema.SeriesKindVersion,
Spec: criteria.GetMetadata(),
}
schema, err := ana.BuildTraceSchema(context.TODO(), *metadata)
assert.NoError(err)
plan, err := ana.Analyze(context.TODO(), criteria, metadata, schema)
assert.NoError(err)
assert.NotNil(plan)
correctPlan, err := logical.Limit(
logical.Offset(
logical.TableScan(sT.UnixNano(), eT.UnixNano(), metadata, series.TraceStateDefault),
0),
20).
Analyze(schema)
assert.NoError(err)
assert.NotNil(correctPlan)
cmp.Equal(plan, correctPlan)
}
func TestAnalyzer_ComplexQuery(t *testing.T) {
assert := require.New(t)
ana := logical.DefaultAnalyzer()
sT, eT := time.Now().Add(-3*time.Hour), time.Now()
criteria := pb.NewQueryRequestBuilder().
Limit(5).
Offset(10).
OrderBy("service_instance_id", apiv1.QueryOrder_SORT_DESC).
Metadata("default", "trace").
Projection("http.method", "service_id", "service_instance_id").
Fields("service_id", "=", "my_app", "http.method", "=", "GET").
TimeRange(sT, eT).
Build()
metadata := &common.Metadata{
KindVersion: apischema.SeriesKindVersion,
Spec: criteria.GetMetadata(),
}
schema, err := ana.BuildTraceSchema(context.TODO(), *metadata)
assert.NoError(err)
plan, err := ana.Analyze(context.TODO(), criteria, metadata, schema)
assert.NoError(err)
assert.NotNil(plan)
correctPlan, err := logical.Limit(
logical.Offset(
logical.OrderBy(logical.IndexScan(sT.UnixNano(), eT.UnixNano(), metadata,
[]logical.Expr{
logical.Eq(logical.NewFieldRef("service_instance_id"), logical.Str("my_app")),
logical.Eq(logical.NewFieldRef("http.method"), logical.Str("GET")),
},
series.TraceStateDefault),
"service_instance_id", apiv1.QueryOrder_SORT_DESC),
10),
5).
Analyze(schema)
assert.NoError(err)
assert.NotNil(correctPlan)
cmp.Equal(plan, correctPlan)
}
func TestAnalyzer_TraceIDQuery(t *testing.T) {
assert := require.New(t)
ana := logical.DefaultAnalyzer()
criteria := pb.NewQueryRequestBuilder().
Limit(5).
Offset(10).
Metadata("default", "trace").
Fields("trace_id", "=", "123").
Build()
metadata := &common.Metadata{
KindVersion: apischema.SeriesKindVersion,
Spec: criteria.GetMetadata(),
}
schema, err := ana.BuildTraceSchema(context.TODO(), *metadata)
assert.NoError(err)
plan, err := ana.Analyze(context.TODO(), criteria, metadata, schema)
assert.NoError(err)
assert.NotNil(plan)
correctPlan, err := logical.TraceIDFetch("123", metadata).Analyze(schema)
assert.NoError(err)
assert.NotNil(correctPlan)
cmp.Equal(plan, correctPlan)
}
func TestAnalyzer_Fields_FieldNotDefined(t *testing.T) {
assert := require.New(t)
ana := logical.DefaultAnalyzer()
criteria := pb.NewQueryRequestBuilder().
Limit(5).
Offset(10).
OrderBy("service_instance_id", apiv1.QueryOrder_SORT_DESC).
Metadata("default", "sw").
Projection("trace_id", "service_id").
Fields("duration", ">", 500).
TimeRange(time.Now().Add(-3*time.Hour), time.Now()).
Build()
metadata := &common.Metadata{
KindVersion: apischema.SeriesKindVersion,
Spec: criteria.GetMetadata(),
}
schema, err := ana.BuildTraceSchema(context.TODO(), *metadata)
assert.NoError(err)
_, err = ana.Analyze(context.TODO(), criteria, metadata, schema)
assert.ErrorIs(err, logical.ErrFieldNotDefined)
}
func TestAnalyzer_OrderBy_FieldNotDefined(t *testing.T) {
assert := require.New(t)
ana := logical.DefaultAnalyzer()
criteria := pb.NewQueryRequestBuilder().
Limit(5).
Offset(10).
OrderBy("duration", apiv1.QueryOrder_SORT_DESC).
Metadata("default", "trace").
Projection("trace_id", "service_id").
TimeRange(time.Now().Add(-3*time.Hour), time.Now()).
Build()
metadata := &common.Metadata{
KindVersion: apischema.SeriesKindVersion,
Spec: criteria.GetMetadata(),
}
schema, err := ana.BuildTraceSchema(context.TODO(), *metadata)
assert.NoError(err)
_, err = ana.Analyze(context.TODO(), criteria, metadata, schema)
assert.ErrorIs(err, logical.ErrFieldNotDefined)
}
func TestAnalyzer_Projection_FieldNotDefined(t *testing.T) {
assert := require.New(t)
ana := logical.DefaultAnalyzer()
criteria := pb.NewQueryRequestBuilder().
Limit(5).
Offset(10).
OrderBy("duration", apiv1.QueryOrder_SORT_DESC).
Metadata("default", "sw").
Projection("duration", "service_id", "unknown").
TimeRange(time.Now().Add(-3*time.Hour), time.Now()).
Build()
metadata := &common.Metadata{
KindVersion: apischema.SeriesKindVersion,
Spec: criteria.GetMetadata(),
}
schema, err := ana.BuildTraceSchema(context.TODO(), *metadata)
assert.NoError(err)
_, err = ana.Analyze(context.TODO(), criteria, metadata, schema)
assert.ErrorIs(err, logical.ErrFieldNotDefined)
}
func TestAnalyzer_Fields_IndexNotDefined(t *testing.T) {
assert := require.New(t)
ana := logical.DefaultAnalyzer()
criteria := pb.NewQueryRequestBuilder().
Limit(5).
Offset(10).
Metadata("default", "trace").
Projection("duration", "service_id").
TimeRange(time.Now().Add(-3*time.Hour), time.Now()).
Fields("service_name", "=", "app").
Build()
metadata := &common.Metadata{
KindVersion: apischema.SeriesKindVersion,
Spec: criteria.GetMetadata(),
}
schema, err := ana.BuildTraceSchema(context.TODO(), *metadata)
assert.NoError(err)
_, err = ana.Analyze(context.TODO(), criteria, metadata, schema)
assert.ErrorIs(err, logical.ErrIndexNotDefined)
}