diff --git a/homeassistant/util/__init__.py b/homeassistant/util/__init__.py index f22d34979d1..5c77fa37814 100644 --- a/homeassistant/util/__init__.py +++ b/homeassistant/util/__init__.py @@ -244,22 +244,22 @@ class Throttle(object): Wrapper that allows wrapped to be called only once per min_time. If we cannot acquire the lock, it is running so return None. """ - if lock.acquire(False): - try: - last_call = wrapper.last_call + if not lock.acquire(False): + return None + try: + last_call = wrapper.last_call - # Check if method is never called or no_throttle is given - force = not last_call or kwargs.pop('no_throttle', False) + # Check if method is never called or no_throttle is given + force = not last_call or kwargs.pop('no_throttle', False) - if force or datetime.now() - last_call > self.min_time: - - result = method(*args, **kwargs) - wrapper.last_call = datetime.now() - return result - else: - return None - finally: - lock.release() + if force or utcnow() - last_call > self.min_time: + result = method(*args, **kwargs) + wrapper.last_call = utcnow() + return result + else: + return None + finally: + lock.release() wrapper.last_call = None diff --git a/tests/common.py b/tests/common.py index 77840306423..830b21ed47c 100644 --- a/tests/common.py +++ b/tests/common.py @@ -38,8 +38,8 @@ def get_test_home_assistant(num_threads=None): hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 - # if not loader.PREPARED: - loader. prepare(hass) + if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: + loader.prepare(hass) return hass diff --git a/tests/components/test_demo.py b/tests/components/test_demo.py index 0abd546e4c4..970f51f3bb4 100644 --- a/tests/components/test_demo.py +++ b/tests/components/test_demo.py @@ -5,6 +5,7 @@ tests.test_component_demo Tests demo component. """ import unittest +from unittest.mock import patch import homeassistant.core as ha import homeassistant.components.demo as demo @@ -23,13 +24,15 @@ class TestDemo(unittest.TestCase): """ Stop down stuff we started. """ self.hass.stop() - def test_if_demo_state_shows_by_default(self): + @patch('homeassistant.components.sun.setup') + def test_if_demo_state_shows_by_default(self, mock_sun_setup): """ Test if demo state shows if we give no configuration. """ demo.setup(self.hass, {demo.DOMAIN: {}}) self.assertIsNotNone(self.hass.states.get('a.Demo_Mode')) - def test_hiding_demo_state(self): + @patch('homeassistant.components.sun.setup') + def test_hiding_demo_state(self, mock_sun_setup): """ Test if you can hide the demo card. """ demo.setup(self.hass, {demo.DOMAIN: {'hide_demo_state': 1}}) diff --git a/tests/components/test_history.py b/tests/components/test_history.py index 12d10c52744..fdd8270a661 100644 --- a/tests/components/test_history.py +++ b/tests/components/test_history.py @@ -8,6 +8,8 @@ Tests the history component. import time import os import unittest +from unittest.mock import patch +from datetime import timedelta import homeassistant.core as ha import homeassistant.util.dt as dt_util @@ -68,11 +70,7 @@ class TestComponentHistory(unittest.TestCase): self.init_recorder() states = [] - # Create 10 states for 5 different entities - # After the first 5, sleep a second and save the time - # history.get_states takes the latest states BEFORE point X - - for i in range(10): + for i in range(5): state = ha.State( 'test.point_in_time_{}'.format(i % 5), "State {}".format(i), @@ -80,19 +78,27 @@ class TestComponentHistory(unittest.TestCase): mock_state_change_event(self.hass, state) self.hass.pool.block_till_done() - recorder._INSTANCE.block_till_done() - if i < 5: - states.append(state) + states.append(state) - if i == 4: - time.sleep(1) - point = dt_util.utcnow() + recorder._INSTANCE.block_till_done() - self.assertEqual( - states, - sorted( - history.get_states(point), key=lambda state: state.entity_id)) + point = dt_util.utcnow() + timedelta(seconds=1) + + with patch('homeassistant.util.dt.utcnow', return_value=point): + for i in range(5): + state = ha.State( + 'test.point_in_time_{}'.format(i % 5), + "State {}".format(i), + {'attribute_test': i}) + + mock_state_change_event(self.hass, state) + self.hass.pool.block_till_done() + + # Get states returns everything before POINT + self.assertEqual(states, + sorted(history.get_states(point), + key=lambda state: state.entity_id)) # Test get_state here because we have a DB setup self.assertEqual( @@ -113,22 +119,20 @@ class TestComponentHistory(unittest.TestCase): set_state('YouTube') start = dt_util.utcnow() + point = start + timedelta(seconds=1) + end = point + timedelta(seconds=1) - time.sleep(1) + with patch('homeassistant.util.dt.utcnow', return_value=point): + states = [ + set_state('idle'), + set_state('Netflix'), + set_state('Plex'), + set_state('YouTube'), + ] - states = [ - set_state('idle'), - set_state('Netflix'), - set_state('Plex'), - set_state('YouTube'), - ] - - time.sleep(1) - - end = dt_util.utcnow() - - set_state('Netflix') - set_state('Plex') + with patch('homeassistant.util.dt.utcnow', return_value=end): + set_state('Netflix') + set_state('Plex') self.assertEqual( {entity_id: states}, diff --git a/tests/components/test_switch.py b/tests/components/test_switch.py index afa96290aa0..dc7129ca541 100644 --- a/tests/components/test_switch.py +++ b/tests/components/test_switch.py @@ -7,9 +7,9 @@ Tests switch component. # pylint: disable=too-many-public-methods,protected-access import unittest -import homeassistant.loader as loader +from homeassistant import loader +from homeassistant.components import switch from homeassistant.const import STATE_ON, STATE_OFF, CONF_PLATFORM -import homeassistant.components.switch as switch from tests.common import get_test_home_assistant diff --git a/tests/helpers/test_init.py b/tests/helpers/test_init.py index 1e3d8b98b1a..0e7c310d91f 100644 --- a/tests/helpers/test_init.py +++ b/tests/helpers/test_init.py @@ -7,13 +7,13 @@ Tests component helpers. # pylint: disable=protected-access,too-many-public-methods import unittest -from common import get_test_home_assistant - import homeassistant.core as ha import homeassistant.loader as loader from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ENTITY_ID from homeassistant.helpers import extract_entity_ids +from tests.common import get_test_home_assistant + class TestComponentsCore(unittest.TestCase): """ Tests homeassistant.components module. """ diff --git a/tests/test_config.py b/tests/test_config.py index c986d7551c6..65c93f9f333 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -15,7 +15,7 @@ from homeassistant.const import ( CONF_LATITUDE, CONF_LONGITUDE, CONF_TEMPERATURE_UNIT, CONF_NAME, CONF_TIME_ZONE) -from common import get_test_config_dir, mock_detect_location_info +from tests.common import get_test_config_dir, mock_detect_location_info CONFIG_DIR = get_test_config_dir() YAML_PATH = os.path.join(CONFIG_DIR, config_util.YAML_CONFIG_FILE) diff --git a/tests/test_core.py b/tests/test_core.py index 1aab679805a..30ef03ac1b4 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -8,10 +8,10 @@ Provides tests to verify that Home Assistant core works. # pylint: disable=too-few-public-methods import os import unittest -import unittest.mock as mock +from unittest.mock import patch import time import threading -from datetime import datetime +from datetime import datetime, timedelta import pytz @@ -55,29 +55,26 @@ class TestHomeAssistant(unittest.TestCase): self.hass.pool.block_till_done() self.assertEqual(1, len(calls)) + # @patch('homeassistant.core.time.sleep') def test_block_till_stoped(self): """ Test if we can block till stop service is called. """ - blocking_thread = threading.Thread(target=self.hass.block_till_stopped) + with patch('time.sleep'): + blocking_thread = threading.Thread( + target=self.hass.block_till_stopped) - self.assertFalse(blocking_thread.is_alive()) + self.assertFalse(blocking_thread.is_alive()) - blocking_thread.start() + blocking_thread.start() - # Threads are unpredictable, try 20 times if we're ready - wait_loops = 0 - while not blocking_thread.is_alive() and wait_loops < 20: - wait_loops += 1 - time.sleep(0.05) + self.assertTrue(blocking_thread.is_alive()) - self.assertTrue(blocking_thread.is_alive()) + self.hass.services.call(ha.DOMAIN, ha.SERVICE_HOMEASSISTANT_STOP) + self.hass.pool.block_till_done() - self.hass.services.call(ha.DOMAIN, ha.SERVICE_HOMEASSISTANT_STOP) - self.hass.pool.block_till_done() - - # Threads are unpredictable, try 20 times if we're ready - wait_loops = 0 - while blocking_thread.is_alive() and wait_loops < 20: - wait_loops += 1 + # Wait for thread to stop + for _ in range(20): + if not blocking_thread.is_alive(): + break time.sleep(0.05) self.assertFalse(blocking_thread.is_alive()) @@ -88,13 +85,9 @@ class TestHomeAssistant(unittest.TestCase): lambda event: calls.append(1)) def raise_keyboardinterrupt(length): - # We don't want to patch the sleep of the timer. - if length == 1: - raise KeyboardInterrupt + raise KeyboardInterrupt - self.hass.start() - - with mock.patch('time.sleep', raise_keyboardinterrupt): + with patch('homeassistant.core.time.sleep', raise_keyboardinterrupt): self.hass.block_till_stopped() self.assertEqual(1, len(calls)) @@ -400,9 +393,10 @@ class TestStateMachine(unittest.TestCase): def test_last_changed_not_updated_on_same_state(self): state = self.states.get('light.Bowl') - time.sleep(1) + future = dt_util.utcnow() + timedelta(hours=10) - self.states.set("light.Bowl", "on") + with patch('homeassistant.util.dt.utcnow', return_value=future): + self.states.set("light.Bowl", "on", {'attr': 'triggers_change'}) self.assertEqual(state.last_changed, self.states.get('light.Bowl').last_changed) diff --git a/tests/test_loader.py b/tests/test_loader.py index 67b8e8d11a6..124a5c87d16 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -10,7 +10,7 @@ import unittest import homeassistant.loader as loader import homeassistant.components.http as http -from common import get_test_home_assistant, MockModule +from tests.common import get_test_home_assistant, MockModule class TestLoader(unittest.TestCase): @@ -24,9 +24,9 @@ class TestLoader(unittest.TestCase): def test_set_component(self): """ Test if set_component works. """ - loader.set_component('switch.test', http) + loader.set_component('switch.test_set', http) - self.assertEqual(http, loader.get_component('switch.test')) + self.assertEqual(http, loader.get_component('switch.test_set')) def test_get_component(self): """ Test if get_component works. """ diff --git a/tests/util/test_init.py b/tests/util/test_init.py index 5a4fb44b2d4..8b5f115d03b 100644 --- a/tests/util/test_init.py +++ b/tests/util/test_init.py @@ -6,10 +6,11 @@ Tests Home Assistant util methods. """ # pylint: disable=too-many-public-methods import unittest -import time +from unittest.mock import patch from datetime import datetime, timedelta -import homeassistant.util as util +from homeassistant import util +import homeassistant.util.dt as dt_util class TestUtil(unittest.TestCase): @@ -169,21 +170,19 @@ class TestUtil(unittest.TestCase): def test_throttle(self): """ Test the add cooldown decorator. """ calls1 = [] + calls2 = [] - @util.Throttle(timedelta(milliseconds=500)) + @util.Throttle(timedelta(seconds=4)) def test_throttle1(): calls1.append(1) - calls2 = [] - - @util.Throttle( - timedelta(milliseconds=500), timedelta(milliseconds=250)) + @util.Throttle(timedelta(seconds=4), timedelta(seconds=2)) def test_throttle2(): calls2.append(1) - # Ensure init is ok - self.assertEqual(0, len(calls1)) - self.assertEqual(0, len(calls2)) + now = dt_util.utcnow() + plus3 = now + timedelta(seconds=3) + plus5 = plus3 + timedelta(seconds=2) # Call first time and ensure methods got called test_throttle1() @@ -206,25 +205,16 @@ class TestUtil(unittest.TestCase): self.assertEqual(2, len(calls1)) self.assertEqual(1, len(calls2)) - # Sleep past the no throttle interval for throttle2 - time.sleep(.3) - - test_throttle1() - test_throttle2() + with patch('homeassistant.util.utcnow', return_value=plus3): + test_throttle1() + test_throttle2() self.assertEqual(2, len(calls1)) self.assertEqual(1, len(calls2)) - test_throttle1(no_throttle=True) - test_throttle2(no_throttle=True) + with patch('homeassistant.util.utcnow', return_value=plus5): + test_throttle1() + test_throttle2() self.assertEqual(3, len(calls1)) self.assertEqual(2, len(calls2)) - - time.sleep(.5) - - test_throttle1() - test_throttle2() - - self.assertEqual(4, len(calls1)) - self.assertEqual(3, len(calls2))