This commit is contained in:
2026-08-07 08:33:41 +02:00
parent d088eb0a47
commit 246241fcda
419 changed files with 11924 additions and 203 deletions
+72
View File
@@ -0,0 +1,72 @@
package engine
import (
"context"
"errors"
"testing"
"time"
"github.com/local/glpi-neural-brain/internal/config"
"github.com/local/glpi-neural-brain/internal/model"
)
func TestResearchIntentDedupeReusesWithinNamespace(t *testing.T) {
e := &Engine{Cfg: config.Config{ResearchDedupeThreshold: .8, ResearchDedupeTTL: time.Hour}, researchDedupe: map[string]*researchDedupeEntry{}}
owner, _, err := e.beginResearchIntent(context.Background(), "evidence", "Azure MFA ransomware prevention")
if err != nil || !owner.owner {
t.Fatalf("expected owner lease, lease=%+v err=%v", owner, err)
}
e.completeResearchIntent(owner, []model.ResearchResult{{URL: "https://example.com/azure-mfa", Title: "Azure MFA"}}, nil)
reusedLease, reused, err := e.beginResearchIntent(context.Background(), "evidence", "Azure MFA ransomware prevention")
if err != nil {
t.Fatal(err)
}
if reusedLease.owner || len(reused) != 1 {
t.Fatalf("expected cached evidence reuse, lease=%+v results=%+v", reusedLease, reused)
}
relationLease, relationReuse, err := e.beginResearchIntent(context.Background(), "relation", "Azure MFA ransomware prevention")
if err != nil {
t.Fatal(err)
}
if !relationLease.owner || len(relationReuse) != 0 {
t.Fatalf("dedupe namespaces must not cross, lease=%+v results=%+v", relationLease, relationReuse)
}
e.completeResearchIntent(relationLease, nil, nil)
}
func TestResearchIntentWaiterRetriesAfterOwnerFailure(t *testing.T) {
e := &Engine{Cfg: config.Config{ResearchDedupeThreshold: .8, ResearchDedupeTTL: time.Hour}, researchDedupe: map[string]*researchDedupeEntry{}}
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
owner, _, err := e.beginResearchIntent(ctx, "evidence", "forensic evidence preservation")
if err != nil || !owner.owner {
t.Fatalf("expected owner lease, lease=%+v err=%v", owner, err)
}
type result struct {
lease researchIntentLease
err error
}
waiter := make(chan result, 1)
go func() {
lease, _, err := e.beginResearchIntent(ctx, "evidence", "forensic evidence preservation")
waiter <- result{lease: lease, err: err}
}()
// Give the duplicate enough time to enter the in-flight wait path.
time.Sleep(20 * time.Millisecond)
e.completeResearchIntent(owner, nil, errors.New("temporary search failure"))
got := <-waiter
if got.err != nil {
t.Fatalf("waiter should retry instead of inheriting owner failure: %v", got.err)
}
if !got.lease.owner {
t.Fatalf("waiter should become the new owner after failed owner, lease=%+v", got.lease)
}
e.completeResearchIntent(got.lease, nil, nil)
}