Files
go-otel/internal/features/features_test.go
T
mats 8f5c267444
Build and Publish / Metadata (push) Successful in 2s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 1m3s
ml
2026-09-19 06:50:19 +00:00

57 lines
2.5 KiB
Go

package features
import (
"testing"
"time"
)
func TestBuildLabelsSpikeUsingOnlyEarlierSameTimeWindows(t *testing.T) {
base := time.Date(2026, 9, 15, 12, 0, 0, 0, time.UTC)
events := make([]Event, 0)
// The prior two daily windows have 10 events and one error each.
for day := 1; day <= 2; day++ {
for i := 0; i < 10; i++ {
events = append(events, Event{Timestamp: base.AddDate(0, 0, -day).Add(time.Duration(i) * time.Second), Service: "api", Kind: "span", IsError: i == 0, DurationMS: float64(i)})
}
}
// Current row is non-error telemetry. The following fifteen minutes have
// five errors out of ten events: 5x the 10% baseline and above the floor.
for i := 0; i < 10; i++ {
events = append(events, Event{Timestamp: base.Add(time.Duration(i) * time.Second), Service: "api", Release: "v2", Kind: "span", IsError: false, DurationMS: float64(i)})
}
for i := 0; i < 10; i++ {
events = append(events, Event{Timestamp: base.Add(5 * time.Minute).Add(time.Duration(i) * time.Second), Service: "api", Kind: "log", IsError: i < 5})
}
// The source export's explicit exclusive watermark proves that the rest of
// the future interval was observed even though it was quiet.
rows := Build(events, Config{Window: 5 * time.Minute, Step: 5 * time.Minute, Future: 15 * time.Minute, ObservedUntil: base.Add(20 * time.Minute), BaselineDays: 2, MinBaselineSamples: 2, SpikeMultiple: 3, MinFutureErrors: 5})
var row *Row
for i := range rows {
if rows[i].WindowStart.Equal(base) && rows[i].Service == "api" && rows[i].Release == "v2" {
row = &rows[i]
break
}
}
if row == nil {
t.Fatal("missing current api/v2 row")
}
if !row.LabelKnown || !row.Label {
t.Fatalf("expected a known positive label, got %+v", *row)
}
if row.BaselineErrorRate != .1 || row.FutureErrorRate != .5 || row.FutureErrorCount != 5 {
t.Fatalf("unexpected label inputs: %+v", *row)
}
if row.P50Duration != 4 || row.P95Duration != 8 || row.SpanCount != 10 {
t.Fatalf("unexpected fixed-width features: %+v", *row)
}
}
func TestBuildWithholdsLabelWithoutCompleteBaseline(t *testing.T) {
base := time.Date(2026, 9, 15, 12, 0, 0, 0, time.UTC)
events := []Event{{Timestamp: base, Service: "api", Kind: "log"}, {Timestamp: base.Add(20 * time.Minute), Service: "other", Kind: "log"}}
rows := Build(events, Config{Window: 5 * time.Minute, Step: 5 * time.Minute, Future: 15 * time.Minute, BaselineDays: 7, MinBaselineSamples: 7})
if len(rows) == 0 || rows[0].LabelKnown {
t.Fatalf("short history must not be labelled: %+v", rows)
}
}