Files
grafana/pkg/tsdb/tempo/search_test.go
GarethandAndre Pereira e28f67fb4c Tempo: migrate search queries to the backend (#109800)
* migrate search queries to the backend

* set duration unit to ms

* remove error log for debugging

* support nested frames and improve url handling

* formatting in search.go

* space

* run make update-workspace

* remove un-necessary fmt.Sprintf

* add support for span table format

* update fn names and re-order

* support raw format

* revert go.mod and go.sum

* remove frontend logic

* remove any types from typescript

* fix golint

* add tests

* fix golangci-lint

* refactor and implement suggestions

* fix tests

* update data frame type

* remove console log

* fix

* use fallthough to traceql type

* use tempo backend for traceql queries

* update tests

* fix golangci-lint

* Correct types for Fields, allow nulls

* add feature toggle definition

* put backend logic behind feature toggle

* Change toggle default to false

* Remove console.log. Fix crash from missing table type

* fix tests

* fix backend tests

---------

Co-authored-by: Andre Pereira <adrapereira@gmail.com>
2025-09-17 12:02:08 +08:00

114 lines
4.5 KiB
Go

package tempo
import (
"context"
"testing"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/tsdb/tempo/kinds/dataquery"
"github.com/grafana/tempo/pkg/tempopb"
v1 "github.com/grafana/tempo/pkg/tempopb/common/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCreateSearchRequest(t *testing.T) {
datasource := &DatasourceInfo{URL: "http://localhost:3200"}
var qstring = "{service.name=\"svc\"}"
var limit int64 = 10
var spss int64 = 3
query := &dataquery.TempoQuery{Query: &qstring, Limit: &limit, Spss: &spss}
req, err := createSearchRequest(context.Background(), datasource, query, 100, 200)
require.NoError(t, err)
assert.Equal(t, `{service.name="svc"}`, req.URL.Query().Get("q"))
assert.Equal(t, "10", req.URL.Query().Get("limit"))
assert.Equal(t, "3", req.URL.Query().Get("spss"))
assert.Equal(t, "100", req.URL.Query().Get("start"))
assert.Equal(t, "200", req.URL.Query().Get("end"))
}
func TestTransformTraceSearchResponse(t *testing.T) {
pCtx := backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{UID: "u", Name: "n"}}
resp := &tempopb.SearchResponse{Traces: []*tempopb.TraceSearchMetadata{{
TraceID: "test-trace-id-x",
RootServiceName: "test-service-name",
RootTraceName: "test-root-trace-name",
StartTimeUnixNano: 2000000,
DurationMs: 5,
SpanSet: &tempopb.SpanSet{Spans: []*tempopb.Span{{SpanID: "span1", Name: "op", StartTimeUnixNano: 1000000, DurationNanos: 1000}}},
}, {
TraceID: "test-trace-id-y",
RootServiceName: "test-service-name",
RootTraceName: "test-root-trace-name",
StartTimeUnixNano: 1000000,
DurationMs: 10,
SpanSet: &tempopb.SpanSet{Spans: []*tempopb.Span{{SpanID: "span1", Name: "op", StartTimeUnixNano: 1000000, DurationNanos: 1000}}},
}}}
frames, err := transformTraceSearchResponse(pCtx, resp)
require.NoError(t, err)
require.Len(t, frames, 1)
assert.Equal(t, 2, frames[0].Rows())
assert.Equal(t, "test-trace-id-x", frames[0].Fields[0].At(0))
assert.Equal(t, "test-trace-id-y", frames[0].Fields[0].At(1))
assert.Equal(t, time.Unix(0, 2000000), frames[0].Fields[1].At(0))
assert.Equal(t, "test-service-name", frames[0].Fields[2].At(0))
assert.Equal(t, "test-root-trace-name", frames[0].Fields[3].At(0))
assert.Equal(t, 5.0, *(frames[0].Fields[4].At(0).(*float64)))
assert.NotEmpty(t, frames[0].Fields[5].At(0))
}
func TestTransformSpanSearchResponse(t *testing.T) {
pCtx := backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{UID: "u", Name: "n"}}
resp := &tempopb.SearchResponse{Traces: []*tempopb.TraceSearchMetadata{{
TraceID: "test-trace-id",
RootServiceName: "test-service-name",
RootTraceName: "test-root-trace-name",
StartTimeUnixNano: 1000,
SpanSets: []*tempopb.SpanSet{{
Attributes: []*v1.KeyValue{{Key: "service.name", Value: &v1.AnyValue{Value: &v1.AnyValue_StringValue{StringValue: "test-service-name"}}}},
Spans: []*tempopb.Span{{
SpanID: "test-span-id",
Name: "test-span-name",
StartTimeUnixNano: 2000,
DurationNanos: 3000,
Attributes: []*v1.KeyValue{{Key: "http.method", Value: &v1.AnyValue{Value: &v1.AnyValue_StringValue{StringValue: "GET"}}}},
}},
}},
}}}
frames, err := transformSpanSearchResponse(pCtx, resp)
require.NoError(t, err)
require.Len(t, frames, 1)
assert.Equal(t, 1, frames[0].Rows())
assert.Equal(t, "test-trace-id", frames[0].Fields[0].At(0))
assert.Equal(t, "test-service-name", frames[0].Fields[1].At(0))
assert.Equal(t, "test-root-trace-name", frames[0].Fields[2].At(0))
assert.Equal(t, "test-span-id", frames[0].Fields[3].At(0))
assert.Equal(t, time.Unix(0, 2000), frames[0].Fields[4].At(0))
assert.Equal(t, "test-span-name", frames[0].Fields[5].At(0))
assert.Equal(t, "GET", *(frames[0].Fields[6].At(0).(*string)))
assert.Equal(t, "test-service-name", *(frames[0].Fields[7].At(0).(*string)))
assert.Equal(t, 3000.0, frames[0].Fields[8].At(0))
}
func TestTransformRawSearchResponse(t *testing.T) {
resp := &tempopb.SearchResponse{Traces: []*tempopb.TraceSearchMetadata{{
TraceID: "test-trace-id-raw",
}}}
frames, err := transformRawSearchResponse(resp)
require.NoError(t, err)
require.Len(t, frames, 1)
require.Equal(t, 1, frames[0].Fields[0].Len())
raw := frames[0].Fields[0].At(0).(string)
expected := "{\n \"traces\": [\n {\n \"traceID\": \"test-trace-id-raw\"\n }\n ]\n}"
assert.Equal(t, expected, raw)
}