diff --git a/tests/components/test__init__.py b/tests/components/test__init__.py index 9bac7b06f..bc680cc9a 100644 --- a/tests/components/test__init__.py +++ b/tests/components/test__init__.py @@ -23,9 +23,10 @@ ) from tests.common import MockComponent, return_any +from tests.conftest import MockViseron -def test_setup_components(vis, caplog): +def test_setup_components(vis: MockViseron, caplog): """Test setup of core and default components.""" setup_components(vis, {"logger": {}}) for component in CORE_COMPONENTS: @@ -33,6 +34,7 @@ def test_setup_components(vis, caplog): for component in DEFAULT_COMPONENTS: assert component in vis.data[LOADED] + vis.shutdown() def test_setup_components_2(vis, caplog): diff --git a/tests/components/webserver/common.py b/tests/components/webserver/common.py index 1df4b5852..d402574bb 100644 --- a/tests/components/webserver/common.py +++ b/tests/components/webserver/common.py @@ -75,7 +75,7 @@ def setUp(self) -> None: "viseron.components.webserver.create_application" ): mocked_load_config.return_value = self.config - self.vis = setup_viseron() + self.vis = setup_viseron(start_background_scheduler=False) self.webserver: Webserver = self.vis.data[COMPONENT] return super().setUp() diff --git a/viseron/__init__.py b/viseron/__init__.py index 57575090f..46b34c0b2 100644 --- a/viseron/__init__.py +++ b/viseron/__init__.py @@ -190,7 +190,7 @@ def enable_logging() -> None: ) -def setup_viseron() -> Viseron: +def setup_viseron(start_background_scheduler=True) -> Viseron: """Set up and run Viseron.""" start = timer() enable_logging() @@ -198,7 +198,7 @@ def setup_viseron() -> Viseron: LOGGER.info("-------------------------------------------") LOGGER.info(f"Initializing Viseron {viseron_version if viseron_version else ''}") - vis = Viseron() + vis = Viseron(start_background_scheduler=start_background_scheduler) try: config = load_config() @@ -249,7 +249,7 @@ def setup_viseron() -> Viseron: class Viseron: """Viseron.""" - def __init__(self) -> None: + def __init__(self, start_background_scheduler=True) -> None: self.states = States(self) self.setup_threads: list[threading.Thread] = [] @@ -270,7 +270,8 @@ def __init__(self) -> None: self.data[REGISTERED_DOMAINS] = {} self.background_scheduler = BackgroundScheduler(timezone="UTC", daemon=True) - self.background_scheduler.start() + if start_background_scheduler: + self.background_scheduler.start() self._thread_watchdog = ThreadWatchDog(self) self._subprocess_watchdog = SubprocessWatchDog(self) self._process_watchdog = ProcessWatchDog(self) @@ -542,6 +543,7 @@ def shutdown(self) -> None: try: self.background_scheduler.shutdown(wait=False) + self.background_scheduler.remove_all_jobs() except SchedulerNotRunningError as err: LOGGER.warning(f"Failed to shutdown scheduler: {err}") @@ -555,6 +557,8 @@ def shutdown(self) -> None: self, data_stream, VISERON_SIGNAL_STOPPING ) + if data_stream: + data_stream.remove_all_subscriptions() LOGGER.info("Shutdown complete in %.1f seconds", timer() - start) def add_entity(self, component: str, entity: Entity): diff --git a/viseron/components/data_stream/__init__.py b/viseron/components/data_stream/__init__.py index fb9cfa58f..b2c2c621a 100644 --- a/viseron/components/data_stream/__init__.py +++ b/viseron/components/data_stream/__init__.py @@ -145,6 +145,12 @@ def unsubscribe_data(data_topic: str, unique_id: uuid.UUID) -> None: DataStream._subscribers[data_topic].pop(unique_id) + @staticmethod + def remove_all_subscriptions() -> None: + """Remove all subscriptions.""" + DataStream._subscribers.clear() + DataStream._wildcard_subscribers.clear() + def run_callbacks( self, callbacks: dict[uuid.UUID, DataSubscriber],