Pulse/internal/ai/learning/learning_memory_regression_test.go
2026-02-04 19:46:20 +00:00

73 lines
1.7 KiB
Go

package learning
import (
"fmt"
"runtime"
"runtime/debug"
"testing"
"time"
)
func TestLearningStoreMemoryStability(t *testing.T) {
if testing.Short() {
t.Skip("skipping memory regression in short mode")
}
store := NewLearningStore(LearningStoreConfig{
MaxRecords: 200,
RetentionDays: 1,
})
recordsPerCycle := 300
warmupCycles := 5
measureCycles := 15
recordFeedback := func(offset int) {
now := time.Now()
for i := 0; i < recordsPerCycle; i++ {
idx := offset + i
record := FeedbackRecord{
FindingID: fmt.Sprintf("finding-%d", idx),
FindingKey: fmt.Sprintf("key-%d", idx%10),
ResourceID: fmt.Sprintf("vm-%02d", idx%20),
Category: "performance",
Severity: "high",
Action: ActionAcknowledge,
Timestamp: now.Add(-time.Duration(idx%60) * time.Minute),
UserNote: "acknowledged",
}
if idx%3 == 0 {
record.Action = ActionDismissNotAnIssue
}
store.RecordFeedback(record)
}
store.Cleanup()
store.GetStatistics()
}
for i := 0; i < warmupCycles; i++ {
recordFeedback(i * recordsPerCycle)
}
runtime.GC()
debug.FreeOSMemory()
var baseline runtime.MemStats
runtime.ReadMemStats(&baseline)
for i := 0; i < measureCycles; i++ {
recordFeedback(100000 + i*recordsPerCycle)
}
runtime.GC()
debug.FreeOSMemory()
var after runtime.MemStats
runtime.ReadMemStats(&after)
if baseline.HeapAlloc > 0 {
allowed := baseline.HeapAlloc + 5*1024*1024
growthRatio := float64(after.HeapAlloc) / float64(baseline.HeapAlloc)
if after.HeapAlloc > allowed && growthRatio > 1.25 {
t.Fatalf("heap allocation grew too much: baseline=%d final=%d ratio=%.2f", baseline.HeapAlloc, after.HeapAlloc, growthRatio)
}
}
}