mirror of
https://github.com/hanzoai/traces.git
synced 2026-10-30 18:20:41 +00:00
* wip: first batch of eliminating promLabels from traceql metrics * Finish adding helper methods and fix tests * Fix frontend, more tests * Fix test * cleanup * changelog * More cleanup * Use proto reserved to prevent reuse of promlabels instead of just commenting it out * Add e2e test for fixed type handling * lint * Cleanup prom_labels from instant series * Relabel as breaking change and update with notes on breaking changes and rollout consideration
251 lines
7.0 KiB
Go
251 lines
7.0 KiB
Go
package traceql
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/grafana/tempo/pkg/tempopb"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCompare(t *testing.T) {
|
|
// Test that the compare function correctly multiplies results based on sampling multiplier
|
|
// The multiplication happens in result() method: s.Values[i] *= multiplier
|
|
|
|
// Instant query
|
|
req := &tempopb.QueryRangeRequest{
|
|
Start: 1,
|
|
End: uint64(3 * time.Second),
|
|
Step: uint64(2 * time.Second),
|
|
Query: `{ } | compare({ .service="selected" })`,
|
|
}
|
|
|
|
// Test data with clear baseline vs selection distinction
|
|
spans := []Span{
|
|
// Baseline spans (service != "selected")
|
|
newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "baseline1").WithSpanString("environment", "prod"),
|
|
newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "baseline2").WithSpanString("environment", "dev"),
|
|
newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "baseline1").WithSpanString("environment", "prod"),
|
|
|
|
// Selection spans (service == "selected")
|
|
newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "prod"),
|
|
newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "dev"),
|
|
newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "dev"),
|
|
newMockSpan(nil).WithStartTime(uint64(3*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "prod"),
|
|
}
|
|
|
|
ss, _, err := runTraceQLMetric(req, spans)
|
|
require.NoError(t, err)
|
|
|
|
expected := []TimeSeries{
|
|
// Baseline values
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.service", Value: NewStaticString("baseline1")},
|
|
},
|
|
Values: []float64{2, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.service", Value: NewStaticString("baseline2")},
|
|
},
|
|
Values: []float64{1, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.environment", Value: NewStaticString("prod")},
|
|
},
|
|
Values: []float64{2, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.environment", Value: NewStaticString("dev")},
|
|
},
|
|
Values: []float64{1, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaselineTotal,
|
|
Label{Name: "span.service", Value: NewStaticString("nil")},
|
|
},
|
|
Values: []float64{3, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaselineTotal,
|
|
Label{Name: "span.environment", Value: NewStaticString("nil")},
|
|
},
|
|
Values: []float64{3, 0},
|
|
},
|
|
|
|
// Selection values
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelection,
|
|
Label{Name: "span.service", Value: NewStaticString("selected")},
|
|
},
|
|
Values: []float64{3, 1},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelection,
|
|
Label{Name: "span.environment", Value: NewStaticString("prod")},
|
|
},
|
|
Values: []float64{1, 1},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelection,
|
|
Label{Name: "span.environment", Value: NewStaticString("dev")},
|
|
},
|
|
Values: []float64{2, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelectionTotal,
|
|
Label{Name: "span.service", Value: NewStaticString("nil")},
|
|
},
|
|
Values: []float64{3, 1},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelectionTotal,
|
|
Label{Name: "span.environment", Value: NewStaticString("nil")},
|
|
},
|
|
Values: []float64{3, 1},
|
|
},
|
|
}
|
|
|
|
requireEqualSeriesSets(t, expected, ss)
|
|
}
|
|
|
|
func TestCompareScalesResults(t *testing.T) {
|
|
// Test that the compare function correctly multiplies results based on sampling multiplier
|
|
// The multiplication happens in result() method: s.Values[i] *= multiplier
|
|
|
|
// Instant query
|
|
req := &tempopb.QueryRangeRequest{
|
|
Start: 1,
|
|
End: uint64(3 * time.Second),
|
|
Step: uint64(2 * time.Second),
|
|
Query: `{ } | compare({ .service="selected" })`,
|
|
}
|
|
|
|
a := newMetricsCompare(newSpansetFilter(
|
|
newBinaryOperation(OpEqual,
|
|
NewAttribute("service"),
|
|
NewStaticString("selected"),
|
|
)), 10, 0, 0)
|
|
a.init(req, AggregateModeRaw)
|
|
|
|
// Test data with clear baseline vs selection distinction
|
|
spans := []Span{
|
|
// Baseline spans (service != "selected")
|
|
newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "baseline1").WithSpanString("environment", "prod"),
|
|
newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "baseline2").WithSpanString("environment", "dev"),
|
|
newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "baseline1").WithSpanString("environment", "prod"),
|
|
|
|
// Selection spans (service == "selected")
|
|
newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "prod"),
|
|
newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "dev"),
|
|
newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "dev"),
|
|
newMockSpan(nil).WithStartTime(uint64(3*time.Second)).WithSpanString("service", "selected").WithSpanString("environment", "prod"),
|
|
}
|
|
|
|
for _, span := range spans {
|
|
a.observe(span)
|
|
}
|
|
|
|
// Double all counts
|
|
ss := a.result(2.0)
|
|
|
|
expected := []TimeSeries{
|
|
// Baseline values
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.service", Value: NewStaticString("baseline1")},
|
|
},
|
|
Values: []float64{4, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.service", Value: NewStaticString("baseline2")},
|
|
},
|
|
Values: []float64{2, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.environment", Value: NewStaticString("prod")},
|
|
},
|
|
Values: []float64{4, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaseline,
|
|
Label{Name: "span.environment", Value: NewStaticString("dev")},
|
|
},
|
|
Values: []float64{2, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaselineTotal,
|
|
Label{Name: "span.service"},
|
|
},
|
|
Values: []float64{6, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeBaselineTotal,
|
|
Label{Name: "span.environment"},
|
|
},
|
|
Values: []float64{6, 0},
|
|
},
|
|
|
|
// Selection values
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelection,
|
|
Label{Name: "span.service", Value: NewStaticString("selected")},
|
|
},
|
|
Values: []float64{6, 2},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelection,
|
|
Label{Name: "span.environment", Value: NewStaticString("prod")},
|
|
},
|
|
Values: []float64{2, 2},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelection,
|
|
Label{Name: "span.environment", Value: NewStaticString("dev")},
|
|
},
|
|
Values: []float64{4, 0},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelectionTotal,
|
|
Label{Name: "span.service"},
|
|
},
|
|
Values: []float64{6, 2},
|
|
},
|
|
{
|
|
Labels: Labels{
|
|
internalLabelTypeSelectionTotal,
|
|
Label{Name: "span.environment"},
|
|
},
|
|
Values: []float64{6, 2},
|
|
},
|
|
}
|
|
|
|
requireEqualSeriesSets(t, expected, ss)
|
|
}
|