tempo/tempodb/encoding/vparquet4/block_findtracebyid_test.go
Joe Elliott c1f6280dd1 Do less Nexting (#4753)
* this is garbage

Signed-off-by: Joe Elliott <number101010@gmail.com>

* filtery stuff

Signed-off-by: Joe Elliott <number101010@gmail.com>

* fix

Signed-off-by: Joe Elliott <number101010@gmail.com>

* max def everywhere

Signed-off-by: Joe Elliott <number101010@gmail.com>

* clean up benches

Signed-off-by: Joe Elliott <number101010@gmail.com>

* clean up

Signed-off-by: Joe Elliott <number101010@gmail.com>

* remove vendor chagnes

Signed-off-by: Joe Elliott <number101010@gmail.com>

* changelog

Signed-off-by: Joe Elliott <number101010@gmail.com>

* add details about bench env vars

Signed-off-by: Joe Elliott <number101010@gmail.com>

---------

Signed-off-by: Joe Elliott <number101010@gmail.com>
2025-02-28 08:08:18 -05:00

168 lines
4.0 KiB
Go

package vparquet4
import (
"bytes"
"context"
"os"
"sort"
"testing"
"github.com/google/uuid"
"github.com/parquet-go/parquet-go"
"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{
{
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, backend.EncNone, "")
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)
require.Greater(t, gotProto.Metrics.InspectedBytes, uint64(60000)) // approximate value
}
}
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 := parquet.SchemaOf(new(Trace))
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 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)
}
})
}
}