mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-06-22 02:55:53 +02:00
Don't use a stale MC instance
This commit is contained in:
@@ -32,16 +32,19 @@ async def run_post_connect_setup(radio_manager) -> None:
|
||||
return
|
||||
radio_manager._setup_in_progress = True
|
||||
radio_manager._setup_complete = False
|
||||
mc = radio_manager.meshcore
|
||||
try:
|
||||
# Register event handlers (no radio I/O, just callback setup)
|
||||
register_event_handlers(mc)
|
||||
|
||||
# Hold the operation lock for all radio I/O during setup.
|
||||
# This prevents user-initiated operations (send message, etc.)
|
||||
# from interleaving commands on the serial link.
|
||||
await radio_manager._acquire_operation_lock("post_connect_setup", blocking=True)
|
||||
try:
|
||||
mc = radio_manager.meshcore
|
||||
if not mc:
|
||||
return
|
||||
|
||||
# Register event handlers against the locked, current transport.
|
||||
register_event_handlers(mc)
|
||||
|
||||
await export_and_store_private_key(mc)
|
||||
|
||||
# Sync radio clock with system time
|
||||
|
||||
@@ -2,7 +2,11 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from app.services.radio_lifecycle import prepare_connected_radio, reconnect_and_prepare_radio
|
||||
from app.services.radio_lifecycle import (
|
||||
prepare_connected_radio,
|
||||
reconnect_and_prepare_radio,
|
||||
run_post_connect_setup,
|
||||
)
|
||||
|
||||
|
||||
class TestPrepareConnectedRadio:
|
||||
@@ -82,3 +86,58 @@ class TestReconnectAndPrepareRadio:
|
||||
assert result is False
|
||||
radio_manager.post_connect_setup.assert_not_awaited()
|
||||
mock_broadcast.assert_not_called()
|
||||
|
||||
|
||||
class TestRunPostConnectSetup:
|
||||
@pytest.mark.asyncio
|
||||
async def test_uses_current_meshcore_after_waiting_for_operation_lock(self):
|
||||
initial_mc = MagicMock()
|
||||
initial_mc.commands.send_device_query = AsyncMock(return_value=None)
|
||||
initial_mc.commands.set_flood_scope = AsyncMock(return_value=None)
|
||||
initial_mc._reader = MagicMock()
|
||||
initial_mc._reader.handle_rx = AsyncMock()
|
||||
initial_mc.start_auto_message_fetching = AsyncMock()
|
||||
|
||||
replacement_mc = MagicMock()
|
||||
replacement_mc.commands.send_device_query = AsyncMock(return_value=None)
|
||||
replacement_mc.commands.set_flood_scope = AsyncMock(return_value=None)
|
||||
replacement_mc._reader = MagicMock()
|
||||
replacement_mc._reader.handle_rx = AsyncMock()
|
||||
replacement_mc.start_auto_message_fetching = AsyncMock()
|
||||
|
||||
radio_manager = MagicMock()
|
||||
radio_manager.meshcore = initial_mc
|
||||
radio_manager._setup_lock = None
|
||||
radio_manager._setup_in_progress = False
|
||||
radio_manager._setup_complete = False
|
||||
radio_manager.path_hash_mode = 0
|
||||
radio_manager.path_hash_mode_supported = False
|
||||
|
||||
async def _acquire(*args, **kwargs):
|
||||
radio_manager.meshcore = replacement_mc
|
||||
|
||||
radio_manager._acquire_operation_lock = AsyncMock(side_effect=_acquire)
|
||||
radio_manager._release_operation_lock = MagicMock()
|
||||
|
||||
with (
|
||||
patch("app.event_handlers.register_event_handlers") as mock_register_handlers,
|
||||
patch("app.keystore.export_and_store_private_key", new=AsyncMock()) as mock_export_key,
|
||||
patch("app.radio_sync.sync_radio_time", new=AsyncMock()) as mock_sync_time,
|
||||
patch(
|
||||
"app.repository.AppSettingsRepository.get",
|
||||
new=AsyncMock(return_value=MagicMock(flood_scope=None)),
|
||||
),
|
||||
patch("app.radio_sync.sync_and_offload_all", new=AsyncMock(return_value={"synced": 0})),
|
||||
patch("app.radio_sync.send_advertisement", new=AsyncMock(return_value=False)),
|
||||
patch("app.radio_sync.drain_pending_messages", new=AsyncMock(return_value=0)),
|
||||
patch("app.radio_sync.start_periodic_sync"),
|
||||
patch("app.radio_sync.start_periodic_advert"),
|
||||
patch("app.radio_sync.start_message_polling"),
|
||||
):
|
||||
await run_post_connect_setup(radio_manager)
|
||||
|
||||
mock_register_handlers.assert_called_once_with(replacement_mc)
|
||||
mock_export_key.assert_awaited_once_with(replacement_mc)
|
||||
mock_sync_time.assert_awaited_once_with(replacement_mc)
|
||||
replacement_mc.start_auto_message_fetching.assert_awaited_once()
|
||||
initial_mc.start_auto_message_fetching.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user