From 256062fd997260793a41124201aeeb1d41a538b2 Mon Sep 17 00:00:00 2001 From: Ben Bangert Date: Sun, 18 Sep 2016 20:35:58 -0700 Subject: [PATCH] Fix test shutdown to ensure loop/threads are clean. (#3447) * Fix test shutdown to ensure loop/threads are clean. We now ensure the loop is closed, it has completed, and the executer has completed. This ensure all threads are freed up with any test calling hass.stop(). * Fix lint issue with run_loop --- homeassistant/core.py | 1 + tests/common.py | 16 ++++++++++++++-- tests/test_bootstrap.py | 3 +++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index 48702c15513..5ec94f69045 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -273,6 +273,7 @@ class HomeAssistant(object): self.bus.async_fire(EVENT_HOMEASSISTANT_STOP) yield from self.loop.run_in_executor(None, self.pool.block_till_done) yield from self.loop.run_in_executor(None, self.pool.stop) + self.executer.shutdown() self.state = CoreState.not_running self.loop.stop() diff --git a/tests/common.py b/tests/common.py index e75de06013e..ffc5d13b2be 100644 --- a/tests/common.py +++ b/tests/common.py @@ -55,10 +55,17 @@ def get_test_home_assistant(num_threads=None): loader.prepare(hass) # FIXME should not be a daemon. Means hass.stop() not called in teardown - threading.Thread(name="LoopThread", target=loop.run_forever, - daemon=True).start() + stop_event = threading.Event() + + def run_loop(): + loop.run_forever() + loop.close() + stop_event.set() + + threading.Thread(name="LoopThread", target=run_loop, daemon=True).start() orig_start = hass.start + orig_stop = hass.stop @asyncio.coroutine def fake_stop(): @@ -72,7 +79,12 @@ def get_test_home_assistant(num_threads=None): orig_start() hass.block_till_done() + def stop_hass(): + orig_stop() + stop_event.wait() + hass.start = start_hass + hass.stop = stop_hass return hass diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py index 8ad9d1cc409..b2a3136455a 100644 --- a/tests/test_bootstrap.py +++ b/tests/test_bootstrap.py @@ -29,6 +29,9 @@ class TestBootstrap: def teardown_method(self, method): """Clean up.""" + if method == self.test_from_config_file: + return + dt_util.DEFAULT_TIME_ZONE = ORIG_TIMEZONE self.hass.stop() loader._COMPONENT_CACHE = self.backup_cache