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.

76 lines
2.3KB

  1. package main
  2. import (
  3. "testing"
  4. "sdr-wideband-suite/internal/config"
  5. "sdr-wideband-suite/internal/detector"
  6. fftutil "sdr-wideband-suite/internal/fft"
  7. "sdr-wideband-suite/internal/pipeline"
  8. )
  9. func TestNewDSPRuntime(t *testing.T) {
  10. cfg := config.Default()
  11. det := detector.New(cfg.Detector, cfg.SampleRate, cfg.FFTSize)
  12. window := fftutil.Hann(cfg.FFTSize)
  13. rt := newDSPRuntime(cfg, det, window, &gpuStatus{})
  14. if rt == nil {
  15. t.Fatalf("runtime is nil")
  16. }
  17. if rt.plan == nil {
  18. t.Fatalf("fft plan is nil")
  19. }
  20. if rt.cfg.FFTSize != cfg.FFTSize {
  21. t.Fatalf("unexpected fft size: %d", rt.cfg.FFTSize)
  22. }
  23. }
  24. func TestScheduledCandidateSelectionUsesPolicy(t *testing.T) {
  25. cfg := config.Default()
  26. cfg.Resources.MaxRefinementJobs = 1
  27. cfg.Refinement.MinCandidateSNRDb = 6
  28. policy := pipeline.PolicyFromConfig(cfg)
  29. got := pipeline.ScheduleCandidates([]pipeline.Candidate{
  30. {ID: 1, SNRDb: 3, BandwidthHz: 1000},
  31. {ID: 2, SNRDb: 12, BandwidthHz: 5000},
  32. {ID: 3, SNRDb: 8, BandwidthHz: 7000},
  33. }, policy)
  34. if len(got) != 2 {
  35. t.Fatalf("expected 2 scheduled candidates after gating, got %d", len(got))
  36. }
  37. if got[0].Candidate.ID != 2 {
  38. t.Fatalf("expected highest priority candidate, got %d", got[0].Candidate.ID)
  39. }
  40. }
  41. func TestSurveillanceLevelsRespectStrategy(t *testing.T) {
  42. policy := pipeline.Policy{SurveillanceStrategy: "single-resolution"}
  43. primary := pipeline.AnalysisLevel{Name: "primary", SampleRate: 2000000, FFTSize: 2048}
  44. secondary := pipeline.AnalysisLevel{Name: "secondary", SampleRate: 1000000, FFTSize: 1024}
  45. presentation := pipeline.AnalysisLevel{Name: "presentation", SampleRate: 2000000, FFTSize: 2048}
  46. levels, _ := surveillanceLevels(policy, primary, secondary, presentation)
  47. if len(levels) != 1 {
  48. t.Fatalf("expected single level for single-resolution, got %d", len(levels))
  49. }
  50. policy.SurveillanceStrategy = "multi-res"
  51. levels, _ = surveillanceLevels(policy, primary, secondary, presentation)
  52. if len(levels) != 2 {
  53. t.Fatalf("expected secondary level for multi-res, got %d", len(levels))
  54. }
  55. }
  56. func TestWindowSpanBounds(t *testing.T) {
  57. windows := []pipeline.RefinementWindow{
  58. {SpanHz: 8000},
  59. {SpanHz: 16000},
  60. {SpanHz: 12000},
  61. }
  62. minSpan, maxSpan, ok := windowSpanBounds(windows)
  63. if !ok {
  64. t.Fatalf("expected spans to be found")
  65. }
  66. if minSpan != 8000 || maxSpan != 16000 {
  67. t.Fatalf("unexpected span bounds: min %.0f max %.0f", minSpan, maxSpan)
  68. }
  69. }