Wideband autonomous SDR analysis engine forked from sdr-visual-suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.8KB

  1. package pipeline
  2. import (
  3. "strings"
  4. "testing"
  5. "time"
  6. )
  7. func TestBudgetPreferenceAffectsEffectiveBudgets(t *testing.T) {
  8. archivePolicy := Policy{
  9. Profile: "archive",
  10. Intent: "archive-and-triage",
  11. MaxRecordingStreams: 10,
  12. MaxDecodeJobs: 10,
  13. MaxRefinementJobs: 6,
  14. }
  15. archiveBudget := BudgetModelFromPolicy(archivePolicy)
  16. if archiveBudget.Record.EffectiveMax <= archiveBudget.Decode.EffectiveMax {
  17. t.Fatalf("expected archive preference to favor record, got record=%.2f decode=%.2f", archiveBudget.Record.EffectiveMax, archiveBudget.Decode.EffectiveMax)
  18. }
  19. if len(archiveBudget.Preference.Reasons) == 0 {
  20. t.Fatalf("expected archive preference reasons to be populated")
  21. }
  22. digitalPolicy := Policy{
  23. Profile: "digital-hunting",
  24. Intent: "decode-digital",
  25. MaxRecordingStreams: 10,
  26. MaxDecodeJobs: 10,
  27. MaxRefinementJobs: 6,
  28. }
  29. digitalBudget := BudgetModelFromPolicy(digitalPolicy)
  30. if digitalBudget.Decode.EffectiveMax <= digitalBudget.Record.EffectiveMax {
  31. t.Fatalf("expected digital preference to favor decode, got record=%.2f decode=%.2f", digitalBudget.Record.EffectiveMax, digitalBudget.Decode.EffectiveMax)
  32. }
  33. }
  34. func TestPressureSummaryReflectsPreference(t *testing.T) {
  35. policy := Policy{
  36. Profile: "digital-hunting",
  37. Intent: "decode-digital",
  38. MaxRecordingStreams: 4,
  39. MaxDecodeJobs: 4,
  40. MaxRefinementJobs: 2,
  41. }
  42. budget := BudgetModelFromPolicy(policy)
  43. queue := DecisionQueueStats{
  44. RecordQueued: 4,
  45. DecodeQueued: 4,
  46. RecordSelected: 2,
  47. DecodeSelected: 2,
  48. RecordActive: 1,
  49. DecodeActive: 1,
  50. }
  51. pressure := BuildBudgetPressureSummary(budget, RefinementAdmission{}, queue)
  52. if pressure.Record.Pressure <= 0 || pressure.Decode.Pressure <= 0 {
  53. t.Fatalf("expected non-zero pressure ratios, got record=%.2f decode=%.2f", pressure.Record.Pressure, pressure.Decode.Pressure)
  54. }
  55. if pressure.Record.Pressure <= pressure.Decode.Pressure {
  56. t.Fatalf("expected record pressure to be higher than decode under digital preference, got record=%.2f decode=%.2f", pressure.Record.Pressure, pressure.Decode.Pressure)
  57. }
  58. }
  59. func TestRefinementPressureTagsAdmission(t *testing.T) {
  60. policy := Policy{Profile: "archive", MaxRefinementJobs: 1, MinCandidateSNRDb: 0}
  61. cands := []Candidate{
  62. {ID: 1, CenterHz: 100, SNRDb: 10},
  63. {ID: 2, CenterHz: 200, SNRDb: 9},
  64. }
  65. plan := BuildRefinementPlan(cands, policy)
  66. res := AdmitRefinementPlan(plan, policy, time.Now(), &RefinementHold{Active: map[int64]time.Time{}})
  67. if res.Admission.Pressure.Level == "" || res.Admission.Pressure.Level == "idle" {
  68. t.Fatalf("expected pressure level to be set, got %+v", res.Admission.Pressure)
  69. }
  70. if res.Admission.Reason == "" || !strings.Contains(res.Admission.Reason, "pressure:") {
  71. t.Fatalf("expected admission reason to include pressure tag, got %s", res.Admission.Reason)
  72. }
  73. }