Przeglądaj źródła

pipeline: add intent and family priority tests

master
Jan Svabenik 9 godzin temu
rodzic
commit
1f5d4ab370
3 zmienionych plików z 84 dodań i 0 usunięć
  1. +20
    -0
      internal/pipeline/arbitration_test.go
  2. +33
    -0
      internal/pipeline/decision_queue_test.go
  3. +31
    -0
      internal/pipeline/scheduler_test.go

+ 20
- 0
internal/pipeline/arbitration_test.go Wyświetl plik

@@ -30,6 +30,26 @@ func TestHoldPolicyDigitalBiasesDecode(t *testing.T) {
}
}

func TestHoldPolicyIntentOverrides(t *testing.T) {
policy := Policy{DecisionHoldMs: 1000, Intent: "archive-and-triage"}
hold := HoldPolicyFromPolicy(policy)
if hold.RecordMs <= hold.BaseMs {
t.Fatalf("expected archive intent to extend record hold, got %d vs %d", hold.RecordMs, hold.BaseMs)
}
if !containsReason(hold.Reasons, HoldReasonIntentArchive) {
t.Fatalf("expected intent archive reason, got %+v", hold.Reasons)
}

policy = Policy{DecisionHoldMs: 1000, Intent: "decode-digital"}
hold = HoldPolicyFromPolicy(policy)
if hold.DecodeMs <= hold.BaseMs {
t.Fatalf("expected decode intent to extend decode hold, got %d vs %d", hold.DecodeMs, hold.BaseMs)
}
if !containsReason(hold.Reasons, HoldReasonIntentDecode) {
t.Fatalf("expected intent decode reason, got %+v", hold.Reasons)
}
}

func TestAdmitRefinementPlanNoCandidatesReason(t *testing.T) {
res := AdmitRefinementPlan(RefinementPlan{}, Policy{}, time.Now(), &RefinementHold{Active: map[int64]time.Time{}})
if res.Admission.Reason != ReasonAdmissionNoCandidates {


+ 33
- 0
internal/pipeline/decision_queue_test.go Wyświetl plik

@@ -138,6 +138,39 @@ func TestDecisionQueueHighTierHoldProtected(t *testing.T) {
}
}

func TestDecisionQueueFamilyPriorityProtectsHold(t *testing.T) {
arbiter := NewArbiter()
policy := Policy{DecisionHoldMs: 500, SignalPriorities: []string{"digital"}}
budget := BudgetModel{Record: BudgetQueue{Max: 1}}
now := time.Now()

decisions := []SignalDecision{
{Candidate: Candidate{ID: 1, SNRDb: 5, Hint: "digital"}, ShouldRecord: true},
}
arbiter.ApplyDecisions(decisions, budget, now, policy)
if !decisions[0].ShouldRecord {
t.Fatalf("expected candidate 1 to be selected initially")
}

decisions = []SignalDecision{
{Candidate: Candidate{ID: 1, SNRDb: 5, Hint: "digital"}, ShouldRecord: true},
{Candidate: Candidate{ID: 2, SNRDb: 35, Hint: "voice"}, ShouldRecord: true},
}
arbiter.ApplyDecisions(decisions, budget, now.Add(100*time.Millisecond), policy)
if !decisions[0].ShouldRecord {
t.Fatalf("expected family-priority hold to keep candidate 1")
}
if decisions[1].ShouldRecord {
t.Fatalf("expected candidate 2 to remain deferred behind family hold")
}
if decisions[0].RecordAdmission == nil || decisions[0].RecordAdmission.FamilyRank != 1 {
t.Fatalf("expected family rank on admission, got %+v", decisions[0].RecordAdmission)
}
if decisions[0].RecordAdmission == nil || decisions[0].RecordAdmission.TierFloor != PriorityTierHigh {
t.Fatalf("expected tier floor on admission, got %+v", decisions[0].RecordAdmission)
}
}

func TestDecisionQueueOpportunisticDisplacement(t *testing.T) {
arbiter := NewArbiter()
policy := Policy{DecisionHoldMs: 500}


+ 31
- 0
internal/pipeline/scheduler_test.go Wyświetl plik

@@ -145,6 +145,28 @@ func TestScheduleCandidatesPriorityBoost(t *testing.T) {
}
}

func TestScheduleCandidatesFamilyTierFloor(t *testing.T) {
policy := Policy{MaxRefinementJobs: 2, MinCandidateSNRDb: 0, SignalPriorities: []string{"digital", "wfm"}}
cands := []Candidate{
{ID: 1, SNRDb: 1, Hint: "digital-burst"},
{ID: 2, SNRDb: 20, Hint: "voice"},
}
plan := BuildRefinementPlan(cands, policy)
item := findScheduled(plan.Ranked, 1)
if item == nil {
t.Fatalf("expected ranked candidate 1")
}
if item.Family != "digital" || item.FamilyRank != 1 {
t.Fatalf("expected digital family rank 1, got family=%s rank=%d", item.Family, item.FamilyRank)
}
if item.TierFloor != PriorityTierHigh {
t.Fatalf("expected tier floor high, got %s", item.TierFloor)
}
if priorityTierRank(item.Tier) < priorityTierRank(PriorityTierHigh) {
t.Fatalf("expected tier to be raised by family floor, got %s", item.Tier)
}
}

func TestScheduleCandidatesEvidenceBoost(t *testing.T) {
policy := Policy{MaxRefinementJobs: 2, MinCandidateSNRDb: 0}
single := Candidate{
@@ -386,3 +408,12 @@ func findWorkItem(items []RefinementWorkItem, id int64) *RefinementWorkItem {
}
return nil
}

func findScheduled(items []ScheduledCandidate, id int64) *ScheduledCandidate {
for i := range items {
if items[i].Candidate.ID == id {
return &items[i]
}
}
return nil
}

Ładowanie…
Anuluj
Zapisz