mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 14:25:08 +00:00
- Vegas: a live-priority pause was only lifted from inside run_frame(), which returns before that check while paused, so the ticker never came back until a restart. run_iteration() now resumes it (the controller only calls it when nothing preempts Vegas); start()/stop() clear the pause state. Iteration length is timed with the monotonic clock. - Dim schedule: a per-day disabled day now updates the minute-gate cache, so brightness no longer flips back to dim within each minute. - On-demand: a second request no longer overwrites the rotation resume index with the first request's mode. - Render pipeline: reset() drops the prepared group and deferred queue, and a prefetch in flight across a reset discards its result. - Sync: stop() removes the status file (and the controller's cleanup now calls it), standalone removes a stale one at startup, and writes use a unique mkstemp temp file. - render_gate.swap_releases_gil() delegates to frame_timing. - Stale docstrings/comments corrected. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
"""DisplayController.cleanup() must tear down Vegas mode.
|
|
|
|
VegasModeCoordinator.cleanup() stops the scroll, resets the render pipeline and
|
|
stream manager and drops the adapter's content cache, but the controller never
|
|
called it, so none of that teardown ran at shutdown.
|
|
"""
|
|
|
|
import os
|
|
from unittest.mock import MagicMock
|
|
|
|
os.environ.setdefault("EMULATOR", "true")
|
|
|
|
from src.display_controller import DisplayController
|
|
|
|
|
|
def _controller(vegas_coordinator):
|
|
dc = object.__new__(DisplayController)
|
|
dc.plugin_manager = MagicMock()
|
|
dc.config_service = MagicMock()
|
|
dc._font_usage_publisher = None
|
|
dc.display_manager = MagicMock()
|
|
dc.vegas_coordinator = vegas_coordinator
|
|
return dc
|
|
|
|
|
|
def test_cleanup_tears_down_vegas():
|
|
vegas = MagicMock()
|
|
_controller(vegas).cleanup()
|
|
vegas.cleanup.assert_called_once_with()
|
|
|
|
|
|
def test_vegas_is_torn_down_before_the_display_manager():
|
|
# Stopping Vegas resets the display's scrolling state, so the display
|
|
# manager has to still be there when it runs.
|
|
order = []
|
|
vegas = MagicMock()
|
|
vegas.cleanup.side_effect = lambda: order.append('vegas')
|
|
dc = _controller(vegas)
|
|
dc.display_manager.cleanup.side_effect = lambda: order.append('display')
|
|
|
|
dc.cleanup()
|
|
|
|
assert order == ['vegas', 'display']
|
|
|
|
|
|
def test_cleanup_without_vegas_does_not_raise():
|
|
dc = _controller(None)
|
|
dc.cleanup()
|
|
dc.display_manager.cleanup.assert_called_once_with()
|
|
|
|
|
|
def test_cleanup_stops_display_sync_after_vegas():
|
|
# Stopping sync withdraws its status file; left behind, the web UI kept
|
|
# reporting a connected peer after the display service had stopped.
|
|
order = []
|
|
vegas = MagicMock()
|
|
vegas.cleanup.side_effect = lambda: order.append('vegas')
|
|
dc = _controller(vegas)
|
|
dc.sync_manager = MagicMock()
|
|
dc.sync_manager.stop.side_effect = lambda: order.append('sync')
|
|
|
|
dc.cleanup()
|
|
|
|
assert order == ['vegas', 'sync']
|
|
|
|
|
|
def test_a_failing_sync_stop_does_not_stop_the_rest():
|
|
dc = _controller(None)
|
|
dc.sync_manager = MagicMock()
|
|
dc.sync_manager.stop.side_effect = OSError('boom')
|
|
|
|
dc.cleanup()
|
|
|
|
dc.display_manager.cleanup.assert_called_once_with()
|
|
|
|
|
|
def test_a_failing_vegas_teardown_does_not_stop_the_rest():
|
|
vegas = MagicMock()
|
|
vegas.cleanup.side_effect = RuntimeError('boom')
|
|
dc = _controller(vegas)
|
|
|
|
dc.cleanup()
|
|
|
|
dc.display_manager.cleanup.assert_called_once_with()
|