Files
pulse/internal/ai/memory/ids_test.go
T
pulse-triage[bot] 1052f21419 Preserve reviewed maintenance with current upstream report and identity ownership
Additively integrate exact upstream 1a094646d7 while retaining starting reviewed 19a8358a49. Keep reviewed UUID incident/event IDs and upstream non-wrapping atomic sequences for other memory IDs. Compose upstream shared SMART/Unraid temperatures with reviewed pending context and observation-gap interruption; pin Unraid-only continuity and both grace paths. Retain all browser, completion and security validation limits until evidenced.

Change-source: pulse-maintainer
2026-10-08 00:57:22 +01:00

127 lines
3.8 KiB
Go

package memory
import (
"fmt"
"regexp"
"strings"
"sync"
"testing"
"time"
"github.com/rcourtman/pulse-go-rewrite/internal/alerts"
)
// TestSequencedIDsStayUniqueUnderConcurrentMinting mints from every
// package-level ID sequence on many goroutines at once. Under -race it proves
// the sequences are synchronized. The uniqueness check proves the suffix does
// not wrap: more than a thousand IDs from one generator land in the same
// wall-clock second, which the old counter%1000 suffix turned into duplicates.
func TestSequencedIDsStayUniqueUnderConcurrentMinting(t *testing.T) {
generators := []struct {
prefix string
mint func() string
uuid bool
}{
{"inc-", generateIncidentID, true},
{"inc-evt-", generateIncidentEventID, true},
{"rem-", generateRecordID, false},
{"mem-", generateMemoryID, false},
{"inc-mem-", generateIncidentMemoryID, false},
{"pat-mem-", generatePatternMemoryID, false},
}
const goroutines, perGoroutine = 16, 150
for _, gen := range generators {
t.Run(strings.TrimSuffix(gen.prefix, "-"), func(t *testing.T) {
shape := regexp.MustCompile("^" + regexp.QuoteMeta(gen.prefix) + `\d{14}-[1-9]\d*$`)
if gen.uuid {
shape = regexp.MustCompile("^" + regexp.QuoteMeta(gen.prefix) + `[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`)
}
minted := make([][]string, goroutines)
start := make(chan struct{})
var wg sync.WaitGroup
for g := range goroutines {
wg.Add(1)
go func() {
defer wg.Done()
<-start
batch := make([]string, perGoroutine)
for i := range batch {
batch[i] = gen.mint()
}
minted[g] = batch
}()
}
close(start)
wg.Wait()
seen := make(map[string]bool, goroutines*perGoroutine)
for _, batch := range minted {
for _, id := range batch {
if !shape.MatchString(id) {
t.Fatalf("ID %q does not match %s", id, shape)
}
if seen[id] {
t.Fatalf("duplicate ID %q among %d concurrent mints", id, goroutines*perGoroutine)
}
seen[id] = true
}
}
})
}
}
// TestIncidentStoresMintIDsConcurrentlyAcrossTenants mirrors multi-tenant
// monitoring: each tenant monitor owns its own IncidentStore, and their alert
// checks call RecordAlertFired from separate goroutines. Each store's mutex
// covers only its own state, so the shared ID sequence must be synchronized on
// its own. Run under -race.
func TestIncidentStoresMintIDsConcurrentlyAcrossTenants(t *testing.T) {
const tenants, checkersPerTenant, alertsPerChecker = 2, 4, 50
stores := make([]*IncidentStore, tenants)
for i := range stores {
stores[i] = NewIncidentStore(IncidentStoreConfig{MaxIncidents: checkersPerTenant * alertsPerChecker})
}
startedAt := time.Now().Add(-time.Minute)
start := make(chan struct{})
var wg sync.WaitGroup
for tenant, store := range stores {
for checker := range checkersPerTenant {
wg.Add(1)
go func() {
defer wg.Done()
<-start
for n := range alertsPerChecker {
store.RecordAlertFired(&alerts.Alert{
ID: fmt.Sprintf("tenant-%d-checker-%d-alert-%d", tenant, checker, n),
Type: "cpu",
Level: alerts.AlertLevelWarning,
ResourceID: fmt.Sprintf("tenant-%d-vm-%d-%d", tenant, checker, n),
ResourceName: "vm",
StartTime: startedAt,
})
}
}()
}
}
close(start)
wg.Wait()
seen := make(map[string]bool, tenants*checkersPerTenant*alertsPerChecker)
for tenant, store := range stores {
store.mu.RLock()
incidents := len(store.incidents)
for _, shell := range store.incidents {
if seen[shell.ID] {
t.Errorf("tenant %d incident ID %q was already minted", tenant, shell.ID)
}
seen[shell.ID] = true
}
store.mu.RUnlock()
if incidents != checkersPerTenant*alertsPerChecker {
t.Errorf("tenant %d recorded %d incidents, want %d", tenant, incidents, checkersPerTenant*alertsPerChecker)
}
}
}