Files
traces/tempodb/encoding/vparquet5/block_findtracebyid_test.go
Joe Elliottandzeekay e94374166e [Tempo 3.0] Remove compactor and v2 block encoding code (#6273)
* o7 compactor

Signed-off-by: Joe Elliott <[email protected]>

* wip: o7 v2

Signed-off-by: Joe Elliott <[email protected]>

* test cleanup

Signed-off-by: Joe Elliott <[email protected]>

* remove compactor from jsonnet

Signed-off-by: Joe Elliott <[email protected]>

* changelog

Signed-off-by: Joe Elliott <[email protected]>

* gen manifest

Signed-off-by: Joe Elliott <[email protected]>

* config cleanup

Signed-off-by: Joe Elliott <[email protected]>

* docs

Signed-off-by: Joe Elliott <[email protected]>

* jsonnet

Signed-off-by: Joe Elliott <[email protected]>

* remove encoding

Signed-off-by: Joe Elliott <[email protected]>

* remove data encoding

Signed-off-by: Joe Elliott <[email protected]>

* lint and cleanup

Signed-off-by: Joe Elliott <[email protected]>

* unflake TestWorker\?

Signed-off-by: Joe Elliott <[email protected]>

---------

Signed-off-by: Joe Elliott <[email protected]>
2026-02-22 00:55:18 -08:00

200 lines
4.8 KiB
Go

package vparquet5
import (
"bytes"
"context"
"os"
"sort"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
tempo_io "github.com/grafana/tempo/pkg/io"
"github.com/grafana/tempo/pkg/util/test"
"github.com/grafana/tempo/tempodb/backend"
"github.com/grafana/tempo/tempodb/backend/local"
"github.com/grafana/tempo/tempodb/encoding/common"
)
func TestBackendBlockFindTraceByID(t *testing.T) {
rawR, rawW, _, err := local.New(&local.Config{
Path: t.TempDir(),
})
require.NoError(t, err)
r := backend.NewReader(rawR)
w := backend.NewWriter(rawW)
ctx := context.Background()
cfg := &common.BlockConfig{
BloomFP: 0.01,
BloomShardSizeBytes: 100 * 1024,
}
// Test data - sorted by trace ID
// Find trace by ID uses the column and page bounds,
// which by default only stores 16 bytes, which is the first
// half of the trace ID (which is stored as 32 hex text)
// Therefore it is important that the test data here has
// full-length trace IDs.
var traces []*Trace
for i := 0; i < 16; i++ {
bar := "bar"
traces = append(traces, &Trace{
TraceID: test.ValidTraceID(nil),
ResourceSpans: []ResourceSpans{
{
Resource: Resource{
ServiceName: "s",
},
ScopeSpans: []ScopeSpans{
{
SpanCount: 1,
Spans: []Span{
{
Name: "hello",
Attrs: []Attribute{
attr("foo", bar),
},
SpanID: []byte{},
ParentSpanID: []byte{},
},
},
},
},
},
},
})
}
// Sort
sort.Slice(traces, func(i, j int) bool {
return bytes.Compare(traces[i].TraceID, traces[j].TraceID) == -1
})
meta := backend.NewBlockMeta("fake", uuid.New(), VersionString)
meta.TotalObjects = int64(len(traces))
s := newStreamingBlock(ctx, cfg, meta, r, w, tempo_io.NewBufferedWriter)
// Write test data, occasionally flushing (cutting new row group)
rowGroupSize := 5
for _, tr := range traces {
err := s.Add(tr, 0, 0)
require.NoError(t, err)
if s.CurrentBufferedObjects() >= rowGroupSize {
_, err = s.Flush()
require.NoError(t, err)
}
}
_, err = s.Complete()
require.NoError(t, err)
b := newBackendBlock(s.meta, r)
// Now find and verify all test traces
for _, tr := range traces {
wantProto := ParquetTraceToTempopbTrace(meta, tr)
gotProto, err := b.FindTraceByID(ctx, tr.TraceID, common.DefaultSearchOptions())
require.NoError(t, err)
require.Equal(t, wantProto, gotProto.Trace)
}
}
func TestBackendBlockFindTraceByID_TestData(t *testing.T) {
rawR, _, _, err := local.New(&local.Config{
Path: "./test-data",
})
require.NoError(t, err)
r := backend.NewReader(rawR)
ctx := context.Background()
blocks, _, err := r.Blocks(ctx, "single-tenant")
require.NoError(t, err)
assert.Len(t, blocks, 1)
meta, err := r.BlockMeta(ctx, blocks[0], "single-tenant")
require.NoError(t, err)
b := newBackendBlock(meta, r)
iter, err := b.rawIter(context.Background(), newRowPool(10))
require.NoError(t, err)
sch, _, _ := SchemaWithDynamicChanges(meta.DedicatedColumns)
for {
_, row, err := iter.Next(context.Background())
require.NoError(t, err)
if row == nil {
break
}
tr := &Trace{}
err = sch.Reconstruct(tr, row)
require.NoError(t, err)
protoTr, err := b.FindTraceByID(ctx, tr.TraceID, common.DefaultSearchOptions())
require.NoError(t, err)
require.NotNil(t, protoTr)
}
}
func TestBackendBlockTraceRoundtrip(t *testing.T) {
testCases := []struct {
name string
tr *Trace
dc backend.DedicatedColumns
}{
{
name: "fullypopulated",
tr: fullyPopulatedTestTrace(test.ValidTraceID(nil)),
dc: test.MakeDedicatedColumns(),
},
{
name: "mixed array/non-array",
tr: func() *Trace { tr, _ := mixedArrayTestTrace(); return tr }(),
dc: func() backend.DedicatedColumns { _, dc := mixedArrayTestTrace(); return dc }(),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var (
ctx = t.Context()
block = makeBackendBlockWithTracesWithDedicatedColumns(t, []*Trace{tc.tr}, tc.dc)
wantProto = ParquetTraceToTempopbTrace(block.meta, tc.tr)
)
gotProto, err := block.FindTraceByID(ctx, tc.tr.TraceID, common.DefaultSearchOptions())
require.NoError(t, err)
require.Equal(t, wantProto, gotProto.Trace)
})
}
}
func BenchmarkFindTraceByID(b *testing.B) {
ctx := context.TODO()
traceID := []byte{}
block := blockForBenchmarks(b)
// index := genIndex(b, block)
// writeBlockMeta(ctx, ww, meta, &common.ShardedBloomFilter{}, index)
for _, tc := range []string{"0", EnvVarIndexEnabledValue} {
b.Run(EnvVarIndexName+"="+tc, func(b *testing.B) {
os.Setenv(EnvVarIndexName, tc)
b.ResetTimer()
for i := 0; i < b.N; i++ {
tr, err := block.FindTraceByID(ctx, traceID, common.DefaultSearchOptions())
require.NoError(b, err)
require.NotNil(b, tr)
}
})
}
}