| @@ -3,24 +3,28 @@ package main | |||||
| import "sdr-wideband-suite/internal/pipeline" | import "sdr-wideband-suite/internal/pipeline" | ||||
| type compactDecision struct { | type compactDecision struct { | ||||
| ID int64 `json:"id"` | |||||
| Class string `json:"class,omitempty"` | |||||
| Record bool `json:"record"` | |||||
| Decode bool `json:"decode"` | |||||
| Reason string `json:"reason,omitempty"` | |||||
| Candidate pipeline.Candidate `json:"candidate"` | |||||
| ID int64 `json:"id"` | |||||
| Class string `json:"class,omitempty"` | |||||
| Record bool `json:"record"` | |||||
| Decode bool `json:"decode"` | |||||
| Reason string `json:"reason,omitempty"` | |||||
| RecordAdmission *pipeline.PriorityAdmission `json:"record_admission,omitempty"` | |||||
| DecodeAdmission *pipeline.PriorityAdmission `json:"decode_admission,omitempty"` | |||||
| Candidate pipeline.Candidate `json:"candidate"` | |||||
| } | } | ||||
| func compactDecisions(decisions []pipeline.SignalDecision) []compactDecision { | func compactDecisions(decisions []pipeline.SignalDecision) []compactDecision { | ||||
| out := make([]compactDecision, 0, len(decisions)) | out := make([]compactDecision, 0, len(decisions)) | ||||
| for _, d := range decisions { | for _, d := range decisions { | ||||
| out = append(out, compactDecision{ | out = append(out, compactDecision{ | ||||
| ID: d.Candidate.ID, | |||||
| Class: d.Class, | |||||
| Record: d.ShouldRecord, | |||||
| Decode: d.ShouldAutoDecode, | |||||
| Reason: d.Reason, | |||||
| Candidate: d.Candidate, | |||||
| ID: d.Candidate.ID, | |||||
| Class: d.Class, | |||||
| Record: d.ShouldRecord, | |||||
| Decode: d.ShouldAutoDecode, | |||||
| Reason: d.Reason, | |||||
| RecordAdmission: d.RecordAdmission, | |||||
| DecodeAdmission: d.DecodeAdmission, | |||||
| Candidate: d.Candidate, | |||||
| }) | }) | ||||
| } | } | ||||
| return out | return out | ||||
| @@ -1,6 +1,7 @@ | |||||
| package pipeline | package pipeline | ||||
| import ( | import ( | ||||
| "strings" | |||||
| "testing" | "testing" | ||||
| "time" | "time" | ||||
| ) | ) | ||||
| @@ -25,7 +26,7 @@ func TestDecisionQueueDropsByBudget(t *testing.T) { | |||||
| allowed++ | allowed++ | ||||
| continue | continue | ||||
| } | } | ||||
| if d.Reason != DecisionReasonQueueRecord && d.Reason != DecisionReasonQueueDecode { | |||||
| if !strings.HasPrefix(d.Reason, DecisionReasonQueueRecord) && !strings.HasPrefix(d.Reason, DecisionReasonQueueDecode) { | |||||
| t.Fatalf("unexpected decision reason: %s", d.Reason) | t.Fatalf("unexpected decision reason: %s", d.Reason) | ||||
| } | } | ||||
| } | } | ||||
| @@ -56,6 +57,12 @@ func TestDecisionQueueEnforcesBudgets(t *testing.T) { | |||||
| if decisions[2].ShouldRecord { | if decisions[2].ShouldRecord { | ||||
| t.Fatalf("expected mid SNR decision to be budgeted off by record budget") | t.Fatalf("expected mid SNR decision to be budgeted off by record budget") | ||||
| } | } | ||||
| if decisions[1].RecordAdmission == nil || decisions[1].RecordAdmission.Class != AdmissionClassAdmit { | |||||
| t.Fatalf("expected admitted record admission, got %+v", decisions[1].RecordAdmission) | |||||
| } | |||||
| if decisions[0].RecordAdmission == nil || decisions[0].RecordAdmission.Class != AdmissionClassDefer { | |||||
| t.Fatalf("expected deferred record admission, got %+v", decisions[0].RecordAdmission) | |||||
| } | |||||
| } | } | ||||
| func TestDecisionQueueHoldKeepsSelection(t *testing.T) { | func TestDecisionQueueHoldKeepsSelection(t *testing.T) { | ||||
| @@ -84,4 +91,7 @@ func TestDecisionQueueHoldKeepsSelection(t *testing.T) { | |||||
| if decisions[0].ShouldRecord || decisions[0].ShouldAutoDecode { | if decisions[0].ShouldRecord || decisions[0].ShouldAutoDecode { | ||||
| t.Fatalf("expected candidate 1 to remain queued behind hold") | t.Fatalf("expected candidate 1 to remain queued behind hold") | ||||
| } | } | ||||
| if decisions[1].RecordAdmission == nil || decisions[1].RecordAdmission.Class != AdmissionClassHold { | |||||
| t.Fatalf("expected record admission hold class, got %+v", decisions[1].RecordAdmission) | |||||
| } | |||||
| } | } | ||||
| @@ -287,10 +287,16 @@ func TestAdmitRefinementPlanAppliesBudget(t *testing.T) { | |||||
| if item2 == nil || item2.Status != RefinementStatusAdmitted { | if item2 == nil || item2.Status != RefinementStatusAdmitted { | ||||
| t.Fatalf("expected candidate 2 admitted, got %+v", item2) | t.Fatalf("expected candidate 2 admitted, got %+v", item2) | ||||
| } | } | ||||
| if item2.Admission == nil || item2.Admission.Class != AdmissionClassAdmit || item2.Admission.Tier == "" { | |||||
| t.Fatalf("expected admission class/tier on admitted item, got %+v", item2.Admission) | |||||
| } | |||||
| item3 := findWorkItem(res.WorkItems, 3) | item3 := findWorkItem(res.WorkItems, 3) | ||||
| if item3 == nil || item3.Status != RefinementStatusSkipped { | if item3 == nil || item3.Status != RefinementStatusSkipped { | ||||
| t.Fatalf("expected candidate 3 skipped, got %+v", item3) | t.Fatalf("expected candidate 3 skipped, got %+v", item3) | ||||
| } | } | ||||
| if item3.Admission == nil || item3.Admission.Class != AdmissionClassDefer { | |||||
| t.Fatalf("expected deferred admission class on skipped item, got %+v", item3.Admission) | |||||
| } | |||||
| } | } | ||||
| func TestAdmitRefinementPlanDisplacedByHold(t *testing.T) { | func TestAdmitRefinementPlanDisplacedByHold(t *testing.T) { | ||||
| @@ -309,6 +315,9 @@ func TestAdmitRefinementPlanDisplacedByHold(t *testing.T) { | |||||
| if item2 == nil || item2.Status != RefinementStatusDisplaced { | if item2 == nil || item2.Status != RefinementStatusDisplaced { | ||||
| t.Fatalf("expected higher priority candidate displaced, got %+v", item2) | t.Fatalf("expected higher priority candidate displaced, got %+v", item2) | ||||
| } | } | ||||
| if item2.Admission == nil || item2.Admission.Class != AdmissionClassDisplace { | |||||
| t.Fatalf("expected displaced admission class, got %+v", item2.Admission) | |||||
| } | |||||
| } | } | ||||
| func TestRefinementStrategyUsesProfile(t *testing.T) { | func TestRefinementStrategyUsesProfile(t *testing.T) { | ||||