Compare commits

..
1 Commits
Author SHA1 Message Date
Gleb NikiforovandGitHub 4f03480afd Fix audio worker startup after enabling a disabled camera (#24806)
CI / AMD64 Build (push) Waiting to run
CI / AMD64 Smoke Test (push) Blocked by required conditions
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
* Fix audio worker startup after enabling a disabled camera

* Document audio lifecycle test helpers

* Focus audio startup coverage on the enabled update regression
2026-10-26 17:44:48 -05:00
4 changed files with 38 additions and 6 deletions
+1
View File
@@ -178,6 +178,7 @@ class AudioProcessor(FrigateProcess):
[
CameraConfigUpdateEnum.add,
CameraConfigUpdateEnum.audio,
CameraConfigUpdateEnum.enabled,
CameraConfigUpdateEnum.ffmpeg,
CameraConfigUpdateEnum.remove,
],
+37 -1
View File
@@ -1,4 +1,4 @@
"""Tests for audio maintainer spawning on runtime camera adds."""
"""Tests for audio maintainer spawning on runtime camera updates."""
import threading
import unittest
@@ -42,6 +42,42 @@ class TestAudioSpawnIfNeeded(unittest.TestCase):
processor.logger = MagicMock()
return processor
def test_initially_disabled_camera_spawns_after_enabled_update(self):
"""Consume an enabled update through the manager's real subscriber."""
config = _build_config()
config.cameras["front_door"].enabled = False
stop = MagicMock()
stop.wait.side_effect = [False, True]
processor = AudioProcessor(
config, {"front_door": MagicMock()}, MagicMock(), stop
)
processor.logger = MagicMock()
updates = iter([("config/cameras/front_door/enabled", True), (None, None)])
self.addCleanup(
setattr, threading.current_thread(), "name", threading.current_thread().name
)
with (
patch.object(processor, "pre_run_setup"),
patch("frigate.config.camera.updater.ConfigSubscriber") as transport,
patch("frigate.events.audio.AudioEventMaintainer") as maintainer,
):
def receive_update():
self.assertEqual(processor.audio_threads, {})
maintainer.assert_not_called()
return next(updates)
transport.return_value.check_for_update.side_effect = receive_update
maintainer.return_value.is_alive.return_value = False
processor.run()
self.assertEqual(
processor.audio_threads, {"front_door": maintainer.return_value}
)
maintainer.assert_called_once()
maintainer.return_value.start.assert_called_once()
def test_skips_camera_whose_metrics_have_not_been_created_yet(self):
"""The camera maintainer creates metrics on its own poll of the add
update, so the audio processor can see the camera first."""
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

-5
View File
@@ -7,11 +7,6 @@
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<style>
@media (prefers-color-scheme: dark) {
g { fill: #ffffff; }
}
</style>
<g transform="translate(0.000000,888.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M8228 8865 c-2 -2 -25 -6 -53 -9 -38 -5 -278 -56 -425 -91 -33 -7

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB