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.

186 lines
5.0KB

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