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.

185 line
4.9KB

  1. package runtime
  2. import (
  3. "testing"
  4. "sdr-wideband-suite/internal/config"
  5. )
  6. func TestApplyConfigUpdate(t *testing.T) {
  7. cfg := config.Default()
  8. mgr := New(cfg)
  9. center := 7.2e6
  10. sampleRate := 1_024_000
  11. fftSize := 4096
  12. threshold := -35.0
  13. bw := 1536
  14. cfarMode := "OS"
  15. cfarWrap := true
  16. cfarGuard := 2
  17. cfarTrain := 12
  18. cfarRank := 18
  19. cfarScale := 5.5
  20. mode := "wideband-balanced"
  21. survFPS := 12
  22. maxRefJobs := 24
  23. updated, err := mgr.ApplyConfig(ConfigUpdate{
  24. CenterHz: &center,
  25. SampleRate: &sampleRate,
  26. FFTSize: &fftSize,
  27. TunerBwKHz: &bw,
  28. Pipeline: &PipelineUpdate{Mode: &mode},
  29. Surveillance: &SurveillanceUpdate{FrameRate: &survFPS},
  30. Resources: &ResourcesUpdate{MaxRefinementJobs: &maxRefJobs},
  31. Detector: &DetectorUpdate{
  32. ThresholdDb: &threshold,
  33. CFARMode: &cfarMode,
  34. CFARWrapAround: &cfarWrap,
  35. CFARGuardCells: &cfarGuard,
  36. CFARTrainCells: &cfarTrain,
  37. CFARRank: &cfarRank,
  38. CFARScaleDb: &cfarScale,
  39. },
  40. })
  41. if err != nil {
  42. t.Fatalf("apply: %v", err)
  43. }
  44. if updated.CenterHz != center {
  45. t.Fatalf("center hz: %v", updated.CenterHz)
  46. }
  47. if updated.SampleRate != sampleRate {
  48. t.Fatalf("sample rate: %v", updated.SampleRate)
  49. }
  50. if updated.FFTSize != fftSize {
  51. t.Fatalf("fft size: %v", updated.FFTSize)
  52. }
  53. if updated.Surveillance.AnalysisFFTSize != fftSize {
  54. t.Fatalf("analysis fft size: %v", updated.Surveillance.AnalysisFFTSize)
  55. }
  56. if updated.Detector.ThresholdDb != threshold {
  57. t.Fatalf("threshold: %v", updated.Detector.ThresholdDb)
  58. }
  59. if updated.Detector.CFARMode != cfarMode {
  60. t.Fatalf("cfar mode: %v", updated.Detector.CFARMode)
  61. }
  62. if updated.Detector.CFARWrapAround != cfarWrap {
  63. t.Fatalf("cfar wrap: %v", updated.Detector.CFARWrapAround)
  64. }
  65. if updated.Detector.CFARGuardCells != cfarGuard {
  66. t.Fatalf("cfar guard: %v", updated.Detector.CFARGuardCells)
  67. }
  68. if updated.Detector.CFARTrainCells != cfarTrain {
  69. t.Fatalf("cfar train: %v", updated.Detector.CFARTrainCells)
  70. }
  71. if updated.Detector.CFARRank != cfarRank {
  72. t.Fatalf("cfar rank: %v", updated.Detector.CFARRank)
  73. }
  74. if updated.Detector.CFARScaleDb != cfarScale {
  75. t.Fatalf("cfar scale: %v", updated.Detector.CFARScaleDb)
  76. }
  77. if updated.TunerBwKHz != bw {
  78. t.Fatalf("tuner bw: %v", updated.TunerBwKHz)
  79. }
  80. if updated.Pipeline.Mode != mode {
  81. t.Fatalf("pipeline mode: %v", updated.Pipeline.Mode)
  82. }
  83. if updated.Surveillance.FrameRate != survFPS || updated.FrameRate != survFPS {
  84. t.Fatalf("surveillance frame rate: %v / %v", updated.Surveillance.FrameRate, updated.FrameRate)
  85. }
  86. if updated.Resources.MaxRefinementJobs != maxRefJobs {
  87. t.Fatalf("max refinement jobs: %v", updated.Resources.MaxRefinementJobs)
  88. }
  89. }
  90. func TestApplyConfigRejectsInvalid(t *testing.T) {
  91. cfg := config.Default()
  92. {
  93. mgr := New(cfg)
  94. bad := 0
  95. if _, err := mgr.ApplyConfig(ConfigUpdate{SampleRate: &bad}); err == nil {
  96. t.Fatalf("expected error")
  97. }
  98. snap := mgr.Snapshot()
  99. if snap.SampleRate != cfg.SampleRate {
  100. t.Fatalf("sample rate changed on error")
  101. }
  102. }
  103. {
  104. mgr := New(cfg)
  105. badAlpha := -0.5
  106. if _, err := mgr.ApplyConfig(ConfigUpdate{Detector: &DetectorUpdate{EmaAlpha: &badAlpha}}); err == nil {
  107. t.Fatalf("expected ema_alpha error")
  108. }
  109. if mgr.Snapshot().Detector.EmaAlpha != cfg.Detector.EmaAlpha {
  110. t.Fatalf("ema_alpha changed on error")
  111. }
  112. }
  113. {
  114. mgr := New(cfg)
  115. badAlpha := 1.5
  116. if _, err := mgr.ApplyConfig(ConfigUpdate{Detector: &DetectorUpdate{EmaAlpha: &badAlpha}}); err == nil {
  117. t.Fatalf("expected ema_alpha upper bound error")
  118. }
  119. if mgr.Snapshot().Detector.EmaAlpha != cfg.Detector.EmaAlpha {
  120. t.Fatalf("ema_alpha changed on error")
  121. }
  122. }
  123. {
  124. mgr := New(cfg)
  125. badHyst := -1.0
  126. if _, err := mgr.ApplyConfig(ConfigUpdate{Detector: &DetectorUpdate{HysteresisDb: &badHyst}}); err == nil {
  127. t.Fatalf("expected hysteresis_db error")
  128. }
  129. if mgr.Snapshot().Detector.HysteresisDb != cfg.Detector.HysteresisDb {
  130. t.Fatalf("hysteresis_db changed on error")
  131. }
  132. }
  133. {
  134. mgr := New(cfg)
  135. badStable := 0
  136. if _, err := mgr.ApplyConfig(ConfigUpdate{Detector: &DetectorUpdate{MinStableFrames: &badStable}}); err == nil {
  137. t.Fatalf("expected min_stable_frames error")
  138. }
  139. if mgr.Snapshot().Detector.MinStableFrames != cfg.Detector.MinStableFrames {
  140. t.Fatalf("min_stable_frames changed on error")
  141. }
  142. }
  143. {
  144. mgr := New(cfg)
  145. badGap := -10
  146. if _, err := mgr.ApplyConfig(ConfigUpdate{Detector: &DetectorUpdate{GapToleranceMs: &badGap}}); err == nil {
  147. t.Fatalf("expected gap_tolerance_ms error")
  148. }
  149. if mgr.Snapshot().Detector.GapToleranceMs != cfg.Detector.GapToleranceMs {
  150. t.Fatalf("gap_tolerance_ms changed on error")
  151. }
  152. }
  153. }
  154. func TestApplySettings(t *testing.T) {
  155. cfg := config.Default()
  156. mgr := New(cfg)
  157. agc := true
  158. dc := true
  159. iq := true
  160. updated, err := mgr.ApplySettings(SettingsUpdate{
  161. AGC: &agc,
  162. DCBlock: &dc,
  163. IQBalance: &iq,
  164. })
  165. if err != nil {
  166. t.Fatalf("apply settings: %v", err)
  167. }
  168. if !updated.AGC || !updated.DCBlock || !updated.IQBalance {
  169. t.Fatalf("settings not applied: %+v", updated)
  170. }
  171. }