From 48cf7a4af92bddc3e27ed50923c77344e885c436 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sun, 26 Feb 2017 23:31:46 +0100 Subject: [PATCH] Move ffmpeg to dispatcher from hass.data entity store. (#6211) * Move ffmpeg to dispatcher from hass.data entity store. * fix lint * address paulus comments * add more unittest for better coverage --- .../components/binary_sensor/ffmpeg_motion.py | 17 +- .../components/binary_sensor/ffmpeg_noise.py | 15 +- homeassistant/components/ffmpeg.py | 144 +++++------ tests/components/binary_sensor/test_ffmpeg.py | 55 ++++- tests/components/test_ffmpeg.py | 227 +++++++++--------- 5 files changed, 252 insertions(+), 206 deletions(-) diff --git a/homeassistant/components/binary_sensor/ffmpeg_motion.py b/homeassistant/components/binary_sensor/ffmpeg_motion.py index 8c822c56361..3dd3f351227 100644 --- a/homeassistant/components/binary_sensor/ffmpeg_motion.py +++ b/homeassistant/components/binary_sensor/ffmpeg_motion.py @@ -57,16 +57,13 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): # generate sensor object entity = FFmpegMotion(hass, manager, config) - - # add to system - manager.async_register_device(entity) yield from async_add_devices([entity]) class FFmpegBinarySensor(FFmpegBase, BinarySensorDevice): """A binary sensor which use ffmpeg for noise detection.""" - def __init__(self, hass, config): + def __init__(self, config): """Constructor for binary sensor noise detection.""" super().__init__(config.get(CONF_INITIAL_STATE)) @@ -98,15 +95,19 @@ class FFmpegMotion(FFmpegBinarySensor): """Initialize ffmpeg motion binary sensor.""" from haffmpeg import SensorMotion - super().__init__(hass, config) + super().__init__(config) self.ffmpeg = SensorMotion( manager.binary, hass.loop, self._async_callback) - def async_start_ffmpeg(self): + @asyncio.coroutine + def _async_start_ffmpeg(self, entity_ids): """Start a FFmpeg instance. - This method must be run in the event loop and returns a coroutine. + This method is a coroutine. """ + if entity_ids is not None and self.entity_id not in entity_ids: + return + # init config self.ffmpeg.set_options( time_reset=self._config.get(CONF_RESET), @@ -116,7 +117,7 @@ class FFmpegMotion(FFmpegBinarySensor): ) # run - return self.ffmpeg.open_sensor( + yield from self.ffmpeg.open_sensor( input_source=self._config.get(CONF_INPUT), extra_cmd=self._config.get(CONF_EXTRA_ARGUMENTS), ) diff --git a/homeassistant/components/binary_sensor/ffmpeg_noise.py b/homeassistant/components/binary_sensor/ffmpeg_noise.py index 8db4691d743..af5c64186f6 100644 --- a/homeassistant/components/binary_sensor/ffmpeg_noise.py +++ b/homeassistant/components/binary_sensor/ffmpeg_noise.py @@ -54,9 +54,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): # generate sensor object entity = FFmpegNoise(hass, manager, config) - - # add to system - manager.async_register_device(entity) yield from async_add_devices([entity]) @@ -67,15 +64,19 @@ class FFmpegNoise(FFmpegBinarySensor): """Initialize ffmpeg noise binary sensor.""" from haffmpeg import SensorNoise - super().__init__(hass, config) + super().__init__(config) self.ffmpeg = SensorNoise( manager.binary, hass.loop, self._async_callback) - def async_start_ffmpeg(self): + @asyncio.coroutine + def _async_start_ffmpeg(self, entity_ids): """Start a FFmpeg instance. - This method must be run in the event loop and returns a coroutine. + This method is a coroutine. """ + if entity_ids is not None and self.entity_id not in entity_ids: + return + # init config self.ffmpeg.set_options( time_duration=self._config.get(CONF_DURATION), @@ -84,7 +85,7 @@ class FFmpegNoise(FFmpegBinarySensor): ) # run - return self.ffmpeg.open_sensor( + yield from self.ffmpeg.open_sensor( input_source=self._config.get(CONF_INPUT), output_dest=self._config.get(CONF_OUTPUT), extra_cmd=self._config.get(CONF_EXTRA_ARGUMENTS), diff --git a/homeassistant/components/ffmpeg.py b/homeassistant/components/ffmpeg.py index c98354662e2..5b012ffad4a 100644 --- a/homeassistant/components/ffmpeg.py +++ b/homeassistant/components/ffmpeg.py @@ -14,6 +14,8 @@ from homeassistant.core import callback from homeassistant.const import ( ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) from homeassistant.config import load_yaml_config_file +from homeassistant.helpers.dispatcher import ( + async_dispatcher_send, async_dispatcher_connect) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity @@ -26,6 +28,10 @@ SERVICE_START = 'start' SERVICE_STOP = 'stop' SERVICE_RESTART = 'restart' +SIGNAL_FFMPEG_START = 'ffmpeg.start' +SIGNAL_FFMPEG_STOP = 'ffmpeg.stop' +SIGNAL_FFMPEG_RESTART = 'ffmpeg.restart' + DATA_FFMPEG = 'ffmpeg' CONF_INITIAL_STATE = 'initial_state' @@ -50,22 +56,25 @@ SERVICE_FFMPEG_SCHEMA = vol.Schema({ }) -def start(hass, entity_id=None): +@callback +def async_start(hass, entity_id=None): """Start a ffmpeg process on entity.""" data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} - hass.services.call(DOMAIN, SERVICE_START, data) + hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_START, data)) -def stop(hass, entity_id=None): +@callback +def async_stop(hass, entity_id=None): """Stop a ffmpeg process on entity.""" data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} - hass.services.call(DOMAIN, SERVICE_STOP, data) + hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_STOP, data)) -def restart(hass, entity_id=None): +@callback +def async_restart(hass, entity_id=None): """Restart a ffmpeg process on entity.""" data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} - hass.services.call(DOMAIN, SERVICE_RESTART, data) + hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_RESTART, data)) @asyncio.coroutine @@ -89,30 +98,12 @@ def async_setup(hass, config): """Handle service ffmpeg process.""" entity_ids = service.data.get(ATTR_ENTITY_ID) - if entity_ids: - devices = [device for device in manager.entities - if device.entity_id in entity_ids] + if service.service == SERVICE_START: + async_dispatcher_send(hass, SIGNAL_FFMPEG_START, entity_ids) + elif service.service == SERVICE_STOP: + async_dispatcher_send(hass, SIGNAL_FFMPEG_STOP, entity_ids) else: - devices = manager.entities - - tasks = [] - for device in devices: - if service.service == SERVICE_START: - tasks.append(device.async_start_ffmpeg()) - elif service.service == SERVICE_STOP: - tasks.append(device.async_stop_ffmpeg()) - else: - tasks.append(device.async_restart_ffmpeg()) - - if tasks: - yield from asyncio.wait(tasks, loop=hass.loop) - - tasks.clear() - for device in devices: - tasks.append(device.async_update_ha_state()) - - if tasks: - yield from asyncio.wait(tasks, loop=hass.loop) + async_dispatcher_send(hass, SIGNAL_FFMPEG_RESTART, entity_ids) hass.services.async_register( DOMAIN, SERVICE_START, async_service_handle, @@ -140,42 +131,12 @@ class FFmpegManager(object): self._cache = {} self._bin = ffmpeg_bin self._run_test = run_test - self._entities = [] @property def binary(self): """Return ffmpeg binary from config.""" return self._bin - @property - def entities(self): - """Return ffmpeg entities for services.""" - return self._entities - - @callback - def async_register_device(self, device): - """Register a ffmpeg process/device.""" - self._entities.append(device) - - @asyncio.coroutine - def async_shutdown(event): - """Stop ffmpeg process.""" - yield from device.async_stop_ffmpeg() - - self.hass.bus.async_listen_once( - EVENT_HOMEASSISTANT_STOP, async_shutdown) - - # start on startup - if device.initial_state: - @asyncio.coroutine - def async_start(event): - """Start ffmpeg process.""" - yield from device.async_start_ffmpeg() - yield from device.async_update_ha_state() - - self.hass.bus.async_listen_once( - EVENT_HOMEASSISTANT_START, async_start) - @asyncio.coroutine def async_run_test(self, input_source): """Run test on this input. TRUE is deactivate or run correct. @@ -208,6 +169,22 @@ class FFmpegBase(Entity): self.ffmpeg = None self.initial_state = initial_state + @asyncio.coroutine + def async_added_to_hass(self): + """Register dispatcher & events. + + This method is a coroutine. + """ + async_dispatcher_connect( + self.hass, SIGNAL_FFMPEG_START, self._async_start_ffmpeg) + async_dispatcher_connect( + self.hass, SIGNAL_FFMPEG_STOP, self._async_stop_ffmpeg) + async_dispatcher_connect( + self.hass, SIGNAL_FFMPEG_RESTART, self._async_restart_ffmpeg) + + # register start/stop + self._async_register_events() + @property def available(self): """Return True if entity is available.""" @@ -218,22 +195,53 @@ class FFmpegBase(Entity): """Return True if entity has to be polled for state.""" return False - def async_start_ffmpeg(self): + @asyncio.coroutine + def _async_start_ffmpeg(self, entity_ids): """Start a ffmpeg process. - This method must be run in the event loop and returns a coroutine. + This method is a coroutine. """ raise NotImplementedError() - def async_stop_ffmpeg(self): + @asyncio.coroutine + def _async_stop_ffmpeg(self, entity_ids): """Stop a ffmpeg process. - This method must be run in the event loop and returns a coroutine. + This method is a coroutine. """ - return self.ffmpeg.close() + if entity_ids is None or self.entity_id in entity_ids: + yield from self.ffmpeg.close() @asyncio.coroutine - def async_restart_ffmpeg(self): - """Stop a ffmpeg process.""" - yield from self.async_stop_ffmpeg() - yield from self.async_start_ffmpeg() + def _async_restart_ffmpeg(self, entity_ids): + """Stop a ffmpeg process. + + This method is a coroutine. + """ + if entity_ids is None or self.entity_id in entity_ids: + yield from self._async_stop_ffmpeg(None) + yield from self._async_start_ffmpeg(None) + + @callback + def _async_register_events(self): + """Register a ffmpeg process/device.""" + @asyncio.coroutine + def async_shutdown_handle(event): + """Stop ffmpeg process.""" + yield from self._async_stop_ffmpeg(None) + + self.hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_STOP, async_shutdown_handle) + + # start on startup + if not self.initial_state: + return + + @asyncio.coroutine + def async_start_handle(event): + """Start ffmpeg process.""" + yield from self._async_start_ffmpeg(None) + self.hass.async_add_job(self.async_update_ha_state()) + + self.hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_START, async_start_handle) diff --git a/tests/components/binary_sensor/test_ffmpeg.py b/tests/components/binary_sensor/test_ffmpeg.py index d2b999d1255..ffeba1870a6 100644 --- a/tests/components/binary_sensor/test_ffmpeg.py +++ b/tests/components/binary_sensor/test_ffmpeg.py @@ -2,7 +2,6 @@ from unittest.mock import patch from homeassistant.bootstrap import setup_component -from homeassistant.util.async import run_callback_threadsafe from tests.common import ( get_test_home_assistant, assert_setup_component, mock_coro) @@ -35,7 +34,7 @@ class TestFFmpegNoiseSetup(object): setup_component(self.hass, 'binary_sensor', self.config) assert self.hass.data['ffmpeg'].binary == 'ffmpeg' - assert len(self.hass.data['ffmpeg'].entities) == 1 + assert self.hass.states.get('binary_sensor.ffmpeg_noise') is not None @patch('haffmpeg.SensorNoise.open_sensor', return_value=mock_coro()) def test_setup_component_start(self, mock_start): @@ -44,15 +43,32 @@ class TestFFmpegNoiseSetup(object): setup_component(self.hass, 'binary_sensor', self.config) assert self.hass.data['ffmpeg'].binary == 'ffmpeg' - assert len(self.hass.data['ffmpeg'].entities) == 1 + assert self.hass.states.get('binary_sensor.ffmpeg_noise') is not None - entity = self.hass.data['ffmpeg'].entities[0] self.hass.start() assert mock_start.called + entity = self.hass.states.get('binary_sensor.ffmpeg_noise') + assert entity.state == 'unavailable' + + @patch('haffmpeg.SensorNoise') + def test_setup_component_start_callback(self, mock_ffmpeg): + """Setup ffmpeg component.""" + with assert_setup_component(1, 'binary_sensor'): + setup_component(self.hass, 'binary_sensor', self.config) + + assert self.hass.data['ffmpeg'].binary == 'ffmpeg' + assert self.hass.states.get('binary_sensor.ffmpeg_noise') is not None + + self.hass.start() + + entity = self.hass.states.get('binary_sensor.ffmpeg_noise') assert entity.state == 'off' - run_callback_threadsafe( - self.hass.loop, entity._async_callback, True).result() + + mock_ffmpeg.call_args[0][2](True) + self.hass.block_till_done() + + entity = self.hass.states.get('binary_sensor.ffmpeg_noise') assert entity.state == 'on' @@ -83,7 +99,7 @@ class TestFFmpegMotionSetup(object): setup_component(self.hass, 'binary_sensor', self.config) assert self.hass.data['ffmpeg'].binary == 'ffmpeg' - assert len(self.hass.data['ffmpeg'].entities) == 1 + assert self.hass.states.get('binary_sensor.ffmpeg_motion') is not None @patch('haffmpeg.SensorMotion.open_sensor', return_value=mock_coro()) def test_setup_component_start(self, mock_start): @@ -92,13 +108,30 @@ class TestFFmpegMotionSetup(object): setup_component(self.hass, 'binary_sensor', self.config) assert self.hass.data['ffmpeg'].binary == 'ffmpeg' - assert len(self.hass.data['ffmpeg'].entities) == 1 + assert self.hass.states.get('binary_sensor.ffmpeg_motion') is not None - entity = self.hass.data['ffmpeg'].entities[0] self.hass.start() assert mock_start.called + entity = self.hass.states.get('binary_sensor.ffmpeg_motion') + assert entity.state == 'unavailable' + + @patch('haffmpeg.SensorMotion') + def test_setup_component_start_callback(self, mock_ffmpeg): + """Setup ffmpeg component.""" + with assert_setup_component(1, 'binary_sensor'): + setup_component(self.hass, 'binary_sensor', self.config) + + assert self.hass.data['ffmpeg'].binary == 'ffmpeg' + assert self.hass.states.get('binary_sensor.ffmpeg_motion') is not None + + self.hass.start() + + entity = self.hass.states.get('binary_sensor.ffmpeg_motion') assert entity.state == 'off' - run_callback_threadsafe( - self.hass.loop, entity._async_callback, True).result() + + mock_ffmpeg.call_args[0][2](True) + self.hass.block_till_done() + + entity = self.hass.states.get('binary_sensor.ffmpeg_motion') assert entity.state == 'on' diff --git a/tests/components/test_ffmpeg.py b/tests/components/test_ffmpeg.py index abc69a627de..0af90ad7836 100644 --- a/tests/components/test_ffmpeg.py +++ b/tests/components/test_ffmpeg.py @@ -3,9 +3,7 @@ import asyncio from unittest.mock import patch, MagicMock import homeassistant.components.ffmpeg as ffmpeg -from homeassistant.bootstrap import setup_component -from homeassistant.util.async import ( - run_callback_threadsafe, run_coroutine_threadsafe) +from homeassistant.bootstrap import setup_component, async_setup_component from tests.common import ( get_test_home_assistant, assert_setup_component, mock_coro) @@ -14,30 +12,30 @@ from tests.common import ( class MockFFmpegDev(ffmpeg.FFmpegBase): """FFmpeg device mock.""" - def __init__(self, initial_state=True, entity_id='test.ffmpeg_device'): + def __init__(self, hass, initial_state=True, + entity_id='test.ffmpeg_device'): """Initialize mock.""" super().__init__(initial_state) + self.hass = hass self.entity_id = entity_id self.ffmpeg = MagicMock self.called_stop = False self.called_start = False self.called_restart = False + self.called_entities = None @asyncio.coroutine - def async_start_ffmpeg(self): + def _async_start_ffmpeg(self, entity_ids): """Mock start.""" self.called_start = True + self.called_entities = entity_ids @asyncio.coroutine - def async_stop_ffmpeg(self): + def _async_stop_ffmpeg(self, entity_ids): """Mock stop.""" self.called_stop = True - - @asyncio.coroutine - def async_restart_ffmpeg(self): - """Mock restart.""" - self.called_restart = True + self.called_entities = entity_ids class TestFFmpegSetup(object): @@ -67,160 +65,165 @@ class TestFFmpegSetup(object): assert self.hass.services.has_service(ffmpeg.DOMAIN, 'stop') assert self.hass.services.has_service(ffmpeg.DOMAIN, 'restart') - def test_setup_component_test_register(self): - """Setup ffmpeg component test register.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - self.hass.bus.async_listen_once = MagicMock() - ffmpeg_dev = MockFFmpegDev() +@asyncio.coroutine +def test_setup_component_test_register(hass): + """Setup ffmpeg component test register.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] + hass.bus.async_listen_once = MagicMock() + ffmpeg_dev = MockFFmpegDev(hass) + yield from ffmpeg_dev.async_added_to_hass() - run_callback_threadsafe( - self.hass.loop, manager.async_register_device, ffmpeg_dev).result() + assert hass.bus.async_listen_once.called + assert hass.bus.async_listen_once.call_count == 2 - assert self.hass.bus.async_listen_once.called - assert self.hass.bus.async_listen_once.call_count == 2 - assert len(manager.entities) == 1 - assert manager.entities[0] == ffmpeg_dev - def test_setup_component_test_register_no_startup(self): - """Setup ffmpeg component test register without startup.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) +@asyncio.coroutine +def test_setup_component_test_register_no_startup(hass): + """Setup ffmpeg component test register without startup.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - self.hass.bus.async_listen_once = MagicMock() - ffmpeg_dev = MockFFmpegDev(False) + hass.bus.async_listen_once = MagicMock() + ffmpeg_dev = MockFFmpegDev(hass, False) + yield from ffmpeg_dev.async_added_to_hass() - manager = self.hass.data[ffmpeg.DATA_FFMPEG] + assert hass.bus.async_listen_once.called + assert hass.bus.async_listen_once.call_count == 1 - run_callback_threadsafe( - self.hass.loop, manager.async_register_device, ffmpeg_dev).result() - assert self.hass.bus.async_listen_once.called - assert self.hass.bus.async_listen_once.call_count == 1 - assert len(manager.entities) == 1 - assert manager.entities[0] == ffmpeg_dev +@asyncio.coroutine +def test_setup_component_test_servcie_start(hass): + """Setup ffmpeg component test service start.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - def test_setup_component_test_servcie_start(self): - """Setup ffmpeg component test service start.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) + ffmpeg_dev = MockFFmpegDev(hass, False) + yield from ffmpeg_dev.async_added_to_hass() - ffmpeg_dev = MockFFmpegDev(False) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] + ffmpeg.async_start(hass) + yield from hass.async_block_till_done() - run_callback_threadsafe( - self.hass.loop, manager.async_register_device, ffmpeg_dev).result() + assert ffmpeg_dev.called_start - ffmpeg.start(self.hass) - self.hass.block_till_done() - assert ffmpeg_dev.called_start +@asyncio.coroutine +def test_setup_component_test_servcie_stop(hass): + """Setup ffmpeg component test service stop.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - def test_setup_component_test_servcie_stop(self): - """Setup ffmpeg component test service stop.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) + ffmpeg_dev = MockFFmpegDev(hass, False) + yield from ffmpeg_dev.async_added_to_hass() - ffmpeg_dev = MockFFmpegDev(False) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] + ffmpeg.async_stop(hass) + yield from hass.async_block_till_done() - run_callback_threadsafe( - self.hass.loop, manager.async_register_device, ffmpeg_dev).result() + assert ffmpeg_dev.called_stop - ffmpeg.stop(self.hass) - self.hass.block_till_done() - assert ffmpeg_dev.called_stop +@asyncio.coroutine +def test_setup_component_test_servcie_restart(hass): + """Setup ffmpeg component test service restart.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - def test_setup_component_test_servcie_restart(self): - """Setup ffmpeg component test service restart.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) + ffmpeg_dev = MockFFmpegDev(hass, False) + yield from ffmpeg_dev.async_added_to_hass() - ffmpeg_dev = MockFFmpegDev(False) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] + ffmpeg.async_restart(hass) + yield from hass.async_block_till_done() - run_callback_threadsafe( - self.hass.loop, manager.async_register_device, ffmpeg_dev).result() + assert ffmpeg_dev.called_stop + assert ffmpeg_dev.called_start - ffmpeg.restart(self.hass) - self.hass.block_till_done() - assert ffmpeg_dev.called_restart +@asyncio.coroutine +def test_setup_component_test_servcie_start_with_entity(hass): + """Setup ffmpeg component test service start.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - def test_setup_component_test_servcie_start_with_entity(self): - """Setup ffmpeg component test service start.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) + ffmpeg_dev = MockFFmpegDev(hass, False) + yield from ffmpeg_dev.async_added_to_hass() - ffmpeg_dev = MockFFmpegDev(False) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] + ffmpeg.async_start(hass, 'test.ffmpeg_device') + yield from hass.async_block_till_done() - run_callback_threadsafe( - self.hass.loop, manager.async_register_device, ffmpeg_dev).result() + assert ffmpeg_dev.called_start + assert ffmpeg_dev.called_entities == ['test.ffmpeg_device'] - ffmpeg.start(self.hass, 'test.ffmpeg_device') - self.hass.block_till_done() - assert ffmpeg_dev.called_start - - def test_setup_component_test_run_test_false(self): - """Setup ffmpeg component test run_test false.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: { +@asyncio.coroutine +def test_setup_component_test_run_test_false(hass): + """Setup ffmpeg component test run_test false.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: { 'run_test': False, }}) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] + manager = hass.data[ffmpeg.DATA_FFMPEG] + with patch('haffmpeg.Test.run_test', return_value=mock_coro(False)): + yield from manager.async_run_test("blabalblabla") - assert run_coroutine_threadsafe( - manager.async_run_test("blabalblabla"), self.hass.loop).result() - assert len(manager._cache) == 0 + assert len(manager._cache) == 0 - @patch('haffmpeg.Test.run_test', - return_value=mock_coro(True)) - def test_setup_component_test_run_test(self, mock_test): - """Setup ffmpeg component test run_test.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] +@asyncio.coroutine +def test_setup_component_test_run_test(hass): + """Setup ffmpeg component test run_test.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) + + manager = hass.data[ffmpeg.DATA_FFMPEG] + + with patch('haffmpeg.Test.run_test', return_value=mock_coro(True)) \ + as mock_test: + yield from manager.async_run_test("blabalblabla") - assert run_coroutine_threadsafe( - manager.async_run_test("blabalblabla"), self.hass.loop).result() assert mock_test.called assert mock_test.call_count == 1 assert len(manager._cache) == 1 assert manager._cache['blabalblabla'] - assert run_coroutine_threadsafe( - manager.async_run_test("blabalblabla"), self.hass.loop).result() + yield from manager.async_run_test("blabalblabla") + assert mock_test.called assert mock_test.call_count == 1 assert len(manager._cache) == 1 assert manager._cache['blabalblabla'] - @patch('haffmpeg.Test.run_test', - return_value=mock_coro(False)) - def test_setup_component_test_run_test_test_fail(self, mock_test): - """Setup ffmpeg component test run_test.""" - with assert_setup_component(2): - setup_component(self.hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) - manager = self.hass.data[ffmpeg.DATA_FFMPEG] +@asyncio.coroutine +def test_setup_component_test_run_test_test_fail(hass): + """Setup ffmpeg component test run_test.""" + with assert_setup_component(2): + yield from async_setup_component( + hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}}) + + manager = hass.data[ffmpeg.DATA_FFMPEG] + + with patch('haffmpeg.Test.run_test', return_value=mock_coro(False)) \ + as mock_test: + yield from manager.async_run_test("blabalblabla") - assert not run_coroutine_threadsafe( - manager.async_run_test("blabalblabla"), self.hass.loop).result() assert mock_test.called assert mock_test.call_count == 1 assert len(manager._cache) == 1 assert not manager._cache['blabalblabla'] - assert not run_coroutine_threadsafe( - manager.async_run_test("blabalblabla"), self.hass.loop).result() + yield from manager.async_run_test("blabalblabla") + assert mock_test.called assert mock_test.call_count == 1 assert len(manager._cache) == 1