mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 14:50:00 -07:00
Fix weather satellite mode returning false success on SatDump startup failure
Add synchronous startup verification after Popen() — sleep 0.5s and poll the process before returning to the caller. If SatDump exits immediately (missing device, bad args), raise RuntimeError with the actual error message instead of returning status: 'started'. Keep a shorter (2s) async backup check for slower failures. Also fix --source_id handling: omit the flag entirely when no serial number is found instead of passing "0" which SatDump may reject. Change start() and start_from_file() to return (bool, str|None) tuples so error messages propagate through to the HTTP response. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -73,9 +73,10 @@ class TestWeatherSatDecoder:
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start(satellite='NOAA-18', device_index=0, gain=40.0)
|
||||
success, error_msg = decoder.start(satellite='NOAA-18', device_index=0, gain=40.0)
|
||||
|
||||
assert success is False
|
||||
assert error_msg is not None
|
||||
callback.assert_called()
|
||||
progress = callback.call_args[0][0]
|
||||
assert progress.status == 'error'
|
||||
@@ -88,7 +89,7 @@ class TestWeatherSatDecoder:
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start(satellite='FAKE-SAT', device_index=0, gain=40.0)
|
||||
success, error_msg = decoder.start(satellite='FAKE-SAT', device_index=0, gain=40.0)
|
||||
|
||||
assert success is False
|
||||
callback.assert_called()
|
||||
@@ -113,7 +114,7 @@ class TestWeatherSatDecoder:
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start(
|
||||
success, error_msg = decoder.start(
|
||||
satellite='NOAA-18',
|
||||
device_index=0,
|
||||
gain=40.0,
|
||||
@@ -121,6 +122,7 @@ class TestWeatherSatDecoder:
|
||||
)
|
||||
|
||||
assert success is True
|
||||
assert error_msg is None
|
||||
assert decoder.is_running is True
|
||||
assert decoder.current_satellite == 'NOAA-18'
|
||||
assert decoder.current_frequency == 137.9125
|
||||
@@ -143,9 +145,10 @@ class TestWeatherSatDecoder:
|
||||
decoder = WeatherSatDecoder()
|
||||
decoder._running = True
|
||||
|
||||
success = decoder.start(satellite='NOAA-18', device_index=0, gain=40.0)
|
||||
success, error_msg = decoder.start(satellite='NOAA-18', device_index=0, gain=40.0)
|
||||
|
||||
assert success is True
|
||||
assert error_msg is None
|
||||
mock_popen.assert_not_called()
|
||||
|
||||
@patch('subprocess.Popen')
|
||||
@@ -160,9 +163,10 @@ class TestWeatherSatDecoder:
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start(satellite='NOAA-18', device_index=0, gain=40.0)
|
||||
success, error_msg = decoder.start(satellite='NOAA-18', device_index=0, gain=40.0)
|
||||
|
||||
assert success is False
|
||||
assert error_msg is not None
|
||||
assert decoder.is_running is False
|
||||
callback.assert_called()
|
||||
progress = callback.call_args[0][0]
|
||||
@@ -175,12 +179,13 @@ class TestWeatherSatDecoder:
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start_from_file(
|
||||
success, error_msg = decoder.start_from_file(
|
||||
satellite='NOAA-18',
|
||||
input_file='data/test.wav',
|
||||
)
|
||||
|
||||
assert success is False
|
||||
assert error_msg is not None
|
||||
callback.assert_called()
|
||||
|
||||
@patch('subprocess.Popen')
|
||||
@@ -200,19 +205,21 @@ class TestWeatherSatDecoder:
|
||||
|
||||
mock_pty.return_value = (10, 11)
|
||||
mock_process = MagicMock()
|
||||
mock_process.poll.return_value = None # Process still running
|
||||
mock_popen.return_value = mock_process
|
||||
|
||||
decoder = WeatherSatDecoder()
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start_from_file(
|
||||
success, error_msg = decoder.start_from_file(
|
||||
satellite='NOAA-18',
|
||||
input_file='data/test.wav',
|
||||
sample_rate=1000000,
|
||||
)
|
||||
|
||||
assert success is True
|
||||
assert error_msg is None
|
||||
assert decoder.is_running is True
|
||||
assert decoder.current_satellite == 'NOAA-18'
|
||||
|
||||
@@ -236,7 +243,7 @@ class TestWeatherSatDecoder:
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start_from_file(
|
||||
success, error_msg = decoder.start_from_file(
|
||||
satellite='NOAA-18',
|
||||
input_file='/etc/passwd',
|
||||
)
|
||||
@@ -259,7 +266,7 @@ class TestWeatherSatDecoder:
|
||||
callback = MagicMock()
|
||||
decoder.set_callback(callback)
|
||||
|
||||
success = decoder.start_from_file(
|
||||
success, error_msg = decoder.start_from_file(
|
||||
satellite='NOAA-18',
|
||||
input_file='data/missing.wav',
|
||||
)
|
||||
@@ -426,12 +433,12 @@ class TestWeatherSatDecoder:
|
||||
|
||||
@patch('subprocess.run')
|
||||
def test_resolve_device_id_fallback(self, mock_run):
|
||||
"""_resolve_device_id() should fall back to index string."""
|
||||
"""_resolve_device_id() should return None when no serial found."""
|
||||
mock_run.side_effect = FileNotFoundError
|
||||
|
||||
serial = WeatherSatDecoder._resolve_device_id(0)
|
||||
|
||||
assert serial == '0'
|
||||
assert serial is None
|
||||
|
||||
def test_parse_product_name_rgb(self):
|
||||
"""_parse_product_name() should identify RGB composite."""
|
||||
|
||||
Reference in New Issue
Block a user