Pulse/internal/license/conversion/quality_test.go
2026-03-18 16:06:30 +00:00

116 lines
2.9 KiB
Go

package conversion
import (
"sync"
"testing"
"time"
)
func TestPipelineHealthHealthy(t *testing.T) {
health := NewPipelineHealth()
health.RecordEvent(EventPaywallViewed)
health.RecordEvent(EventTrialStarted)
health.RecordEvent(EventUpgradeClicked)
health.RecordEvent(EventCheckoutCompleted)
status := health.CheckHealth()
if status.Status != "healthy" {
t.Fatalf("status = %q, want healthy", status.Status)
}
if status.EventsTotal != 4 {
t.Fatalf("events_total = %d, want 4", status.EventsTotal)
}
if len(status.EventsByType) != 4 {
t.Fatalf("len(events_by_type) = %d, want 4", len(status.EventsByType))
}
if status.StartedAt <= 0 {
t.Fatalf("started_at = %d, want > 0", status.StartedAt)
}
}
func TestPipelineHealthStaleNoEvents(t *testing.T) {
baseNow := time.Now()
currentNow := baseNow
health := NewPipelineHealth(
WithPipelineHealthNow(func() time.Time { return currentNow }),
WithPipelineHealthStaleThreshold(5*time.Minute),
)
currentNow = baseNow.Add(6 * time.Minute)
status := health.CheckHealth()
if status.Status != "stale" {
t.Fatalf("status = %q, want stale", status.Status)
}
if status.EventsTotal != 0 {
t.Fatalf("events_total = %d, want 0", status.EventsTotal)
}
}
func TestPipelineHealthDegradedCoverage(t *testing.T) {
health := NewPipelineHealth()
for i := 0; i < 5; i++ {
health.RecordEvent(EventPaywallViewed)
}
status := health.CheckHealth()
if status.Status != "degraded" {
t.Fatalf("status = %q, want degraded", status.Status)
}
if status.EventsByType[EventPaywallViewed] != 5 {
t.Fatalf("events_by_type[%q] = %d, want 5", EventPaywallViewed, status.EventsByType[EventPaywallViewed])
}
}
func TestPipelineHealthColdStartHealthy(t *testing.T) {
health := NewPipelineHealth()
status := health.CheckHealth()
if status.Status != "healthy" {
t.Fatalf("status = %q, want healthy", status.Status)
}
if status.EventsTotal != 0 {
t.Fatalf("events_total = %d, want 0", status.EventsTotal)
}
}
func TestPipelineHealthConcurrentAccess(t *testing.T) {
health := NewPipelineHealth()
eventTypes := append([]string(nil), knownConversionEventTypes...)
const goroutines = 16
const recordsPerGoroutine = 200
var wg sync.WaitGroup
wg.Add(goroutines)
for g := 0; g < goroutines; g++ {
go func(id int) {
defer wg.Done()
for i := 0; i < recordsPerGoroutine; i++ {
health.RecordEvent(eventTypes[(id+i)%len(eventTypes)])
_ = health.CheckHealth()
}
}(g)
}
wg.Wait()
status := health.CheckHealth()
wantTotal := int64(goroutines * recordsPerGoroutine)
if status.EventsTotal != wantTotal {
t.Fatalf("events_total = %d, want %d", status.EventsTotal, wantTotal)
}
var summed int64
for _, count := range status.EventsByType {
summed += count
}
if summed != wantTotal {
t.Fatalf("sum(events_by_type) = %d, want %d", summed, wantTotal)
}
if status.Status != "healthy" {
t.Fatalf("status = %q, want healthy", status.Status)
}
}