| @@ -53,7 +53,11 @@ func TestSurveillanceLevelsRespectStrategy(t *testing.T) { | |||
| if len(plan.Levels) != 1 { | |||
| t.Fatalf("expected single level for single-resolution, got %d", len(plan.Levels)) | |||
| } | |||
| if plan.Levels[0].Role != pipeline.RoleSurveillancePrimary { | |||
| t.Fatalf("expected primary role, got %q", plan.Levels[0].Role) | |||
| } | |||
| policy.SurveillanceStrategy = "multi-res" | |||
| policy.Intent = "wideband-surveillance" | |||
| plan = rt.buildSurveillancePlan(policy) | |||
| if len(plan.Levels) != 2 { | |||
| t.Fatalf("expected secondary level for multi-res, got %d", len(plan.Levels)) | |||
| @@ -61,6 +65,9 @@ func TestSurveillanceLevelsRespectStrategy(t *testing.T) { | |||
| if plan.Levels[1].Decimation != 2 { | |||
| t.Fatalf("expected decimation factor 2, got %d", plan.Levels[1].Decimation) | |||
| } | |||
| if plan.Levels[1].Role != pipeline.RoleSurveillanceDerived { | |||
| t.Fatalf("expected derived role, got %q", plan.Levels[1].Role) | |||
| } | |||
| } | |||
| func TestWindowSpanBounds(t *testing.T) { | |||
| @@ -0,0 +1,45 @@ | |||
| package pipeline | |||
| import "testing" | |||
| func TestLevelRoleClassification(t *testing.T) { | |||
| primary := AnalysisLevel{Name: "surveillance", Role: RoleSurveillancePrimary, Truth: "surveillance"} | |||
| derived := AnalysisLevel{Name: "surveillance-lowres", Role: RoleSurveillanceDerived, Truth: "surveillance"} | |||
| support := AnalysisLevel{Name: "surveillance-lowres", Role: RoleSurveillanceSupport, Truth: "surveillance"} | |||
| presentation := AnalysisLevel{Name: "presentation", Role: RolePresentation, Truth: "presentation"} | |||
| if !IsDetectionLevel(primary) || IsPresentationLevel(primary) || IsSupportLevel(primary) { | |||
| t.Fatalf("primary role classification failed: %+v", primary) | |||
| } | |||
| if !IsDetectionLevel(derived) || IsPresentationLevel(derived) || IsSupportLevel(derived) { | |||
| t.Fatalf("derived role classification failed: %+v", derived) | |||
| } | |||
| if IsDetectionLevel(support) || IsPresentationLevel(support) || !IsSupportLevel(support) { | |||
| t.Fatalf("support role classification failed: %+v", support) | |||
| } | |||
| if IsDetectionLevel(presentation) || !IsPresentationLevel(presentation) || IsSupportLevel(presentation) { | |||
| t.Fatalf("presentation role classification failed: %+v", presentation) | |||
| } | |||
| } | |||
| func TestCandidateEvidenceStateTracksSupportLevels(t *testing.T) { | |||
| candidate := Candidate{ | |||
| ID: 1, | |||
| Evidence: []LevelEvidence{ | |||
| {Level: AnalysisLevel{Name: "surveillance", Role: RoleSurveillancePrimary, Truth: "surveillance"}, Provenance: "primary"}, | |||
| {Level: AnalysisLevel{Name: "surveillance-lowres", Role: RoleSurveillanceDerived, Truth: "surveillance"}, Provenance: "derived"}, | |||
| {Level: AnalysisLevel{Name: "surveillance-support", Role: RoleSurveillanceSupport, Truth: "surveillance"}, Provenance: "support"}, | |||
| {Level: AnalysisLevel{Name: "presentation", Role: RolePresentation, Truth: "presentation"}, Provenance: "display"}, | |||
| }, | |||
| } | |||
| state := CandidateEvidenceStateFor(candidate) | |||
| if state.DetectionLevelCount != 2 || state.PrimaryLevelCount != 1 || state.DerivedLevelCount != 1 { | |||
| t.Fatalf("unexpected detection counts: %+v", state) | |||
| } | |||
| if state.SupportLevelCount != 1 || state.PresentationLevelCount != 1 { | |||
| t.Fatalf("unexpected support/presentation counts: %+v", state) | |||
| } | |||
| if !state.MultiLevelConfirmed || state.DerivedOnly { | |||
| t.Fatalf("unexpected confirmation flags: %+v", state) | |||
| } | |||
| } | |||
| @@ -185,7 +185,7 @@ func TestScheduleCandidatesDerivedOnlyPenalty(t *testing.T) { | |||
| SNRDb: 10, | |||
| BandwidthHz: 12000, | |||
| Evidence: []LevelEvidence{ | |||
| {Level: AnalysisLevel{Name: "surveillance", Role: "surveillance", Truth: "surveillance"}}, | |||
| {Level: AnalysisLevel{Name: "surveillance", Role: RoleSurveillancePrimary, Truth: "surveillance"}}, | |||
| }, | |||
| } | |||
| derived := Candidate{ | |||
| @@ -193,7 +193,7 @@ func TestScheduleCandidatesDerivedOnlyPenalty(t *testing.T) { | |||
| SNRDb: 10, | |||
| BandwidthHz: 12000, | |||
| Evidence: []LevelEvidence{ | |||
| {Level: AnalysisLevel{Name: "surveillance-lowres", Role: "surveillance-lowres", Truth: "surveillance"}}, | |||
| {Level: AnalysisLevel{Name: "surveillance-lowres", Role: RoleSurveillanceDerived, Truth: "surveillance"}}, | |||
| }, | |||
| } | |||
| plan := BuildRefinementPlan([]Candidate{derived, primary}, policy) | |||
| @@ -211,7 +211,7 @@ func TestScheduleCandidatesDerivedOnlyStrategyBias(t *testing.T) { | |||
| SNRDb: 9, | |||
| BandwidthHz: 12000, | |||
| Evidence: []LevelEvidence{ | |||
| {Level: AnalysisLevel{Name: "surveillance-lowres", Role: "surveillance-lowres", Truth: "surveillance"}}, | |||
| {Level: AnalysisLevel{Name: "surveillance-lowres", Role: RoleSurveillanceDerived, Truth: "surveillance"}}, | |||
| }, | |||
| } | |||
| singlePlan := BuildRefinementPlan([]Candidate{cand}, Policy{MinCandidateSNRDb: 0}) | |||
| @@ -0,0 +1,30 @@ | |||
| package pipeline | |||
| import "testing" | |||
| func TestSurveillanceDetectionPolicyAuto(t *testing.T) { | |||
| policy := Policy{ | |||
| Mode: "wideband-balanced", | |||
| Profile: "wideband-balanced", | |||
| Intent: "wideband-surveillance", | |||
| SurveillanceStrategy: "multi-resolution", | |||
| } | |||
| policy.SurveillanceDerivedDetection = "auto" | |||
| got := SurveillanceDetectionPolicyFromPolicy(policy) | |||
| if !got.DerivedDetectionEnabled { | |||
| t.Fatalf("expected auto policy to enable derived detection, got %+v", got) | |||
| } | |||
| policy.Profile = "archive" | |||
| policy.Intent = "archive-and-triage" | |||
| got = SurveillanceDetectionPolicyFromPolicy(policy) | |||
| if got.DerivedDetectionEnabled { | |||
| t.Fatalf("expected archive policy to disable derived detection, got %+v", got) | |||
| } | |||
| policy = Policy{SurveillanceStrategy: "single-resolution", SurveillanceDerivedDetection: "auto"} | |||
| got = SurveillanceDetectionPolicyFromPolicy(policy) | |||
| if got.DerivedDetectionEnabled { | |||
| t.Fatalf("expected single-resolution to disable derived detection, got %+v", got) | |||
| } | |||
| } | |||