From cf5278b7e9f6f60f9abe36c438a73c6933387348 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 29 Apr 2015 23:21:31 -0700 Subject: [PATCH] Add tests for recorder component --- homeassistant/__init__.py | 14 +++++- homeassistant/components/recorder.py | 7 +++ tests/test_component_recorder.py | 70 ++++++++++++++++++++++++++++ tests/test_core.py | 6 ++- 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/test_component_recorder.py diff --git a/homeassistant/__init__.py b/homeassistant/__init__.py index 301a403193d0..2beb749ec6bb 100644 --- a/homeassistant/__init__.py +++ b/homeassistant/__init__.py @@ -376,6 +376,13 @@ class Event(object): return "".format(self.event_type, str(self.origin)[0]) + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.event_type == other.event_type and + self.data == other.data and + self.origin == other.origin and + self.time_fired == other.time_fired) + class EventBus(object): """ Class that allows different components to communicate via services @@ -398,6 +405,9 @@ class EventBus(object): def fire(self, event_type, event_data=None, origin=EventOrigin.local): """ Fire an event. """ + if not self._pool.running: + raise HomeAssistantError('Home Assistant has shut down.') + with self._lock: # Copy the list of the current listeners because some listeners # remove themselves as a listener while being executed which @@ -898,7 +908,9 @@ class Timer(threading.Thread): last_fired_on_second = now.second - self.hass.bus.fire(EVENT_TIME_CHANGED, {ATTR_NOW: now}) + # Event might have been set while sleeping + if not self._stop_event.isSet(): + self.hass.bus.fire(EVENT_TIME_CHANGED, {ATTR_NOW: now}) class Config(object): diff --git a/homeassistant/components/recorder.py b/homeassistant/components/recorder.py index 4f0a76cf18a0..717b6514bb44 100644 --- a/homeassistant/components/recorder.py +++ b/homeassistant/components/recorder.py @@ -189,9 +189,11 @@ class Recorder(threading.Thread): if event == self.quit_object: self._close_run() self._close_connection() + self.queue.task_done() return elif event.event_type == EVENT_TIME_CHANGED: + self.queue.task_done() continue elif event.event_type == EVENT_STATE_CHANGED: @@ -199,6 +201,7 @@ class Recorder(threading.Thread): event.data['entity_id'], event.data.get('new_state')) self.record_event(event) + self.queue.task_done() def event_listener(self, event): """ Listens for new events on the EventBus and puts them @@ -266,6 +269,10 @@ class Recorder(threading.Thread): "Error querying the database using: %s", sql_query) return [] + def block_till_done(self): + """ Blocks till all events processed. """ + self.queue.join() + def _setup_connection(self): """ Ensure database is ready to fly. """ db_path = self.hass.config.path(DB_FILE) diff --git a/tests/test_component_recorder.py b/tests/test_component_recorder.py new file mode 100644 index 000000000000..68c63b637d04 --- /dev/null +++ b/tests/test_component_recorder.py @@ -0,0 +1,70 @@ +""" +tests.test_component_recorder +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Tests Recorder component. +""" +# pylint: disable=too-many-public-methods,protected-access +import unittest +import os + +from homeassistant.const import MATCH_ALL +from homeassistant.components import recorder + +from helpers import get_test_home_assistant + + +class TestRecorder(unittest.TestCase): + """ Test the chromecast module. """ + + def setUp(self): # pylint: disable=invalid-name + self.hass = get_test_home_assistant() + recorder.setup(self.hass, {}) + self.hass.start() + recorder._INSTANCE.block_till_done() + + def tearDown(self): # pylint: disable=invalid-name + """ Stop down stuff we started. """ + self.hass.stop() + recorder._INSTANCE.block_till_done() + os.remove(self.hass.config.path(recorder.DB_FILE)) + + def test_saving_state(self): + """ Tests saving and restoring a state. """ + entity_id = 'test.recorder' + state = 'restoring_from_db' + attributes = {'test_attr': 5, 'test_attr_10': 'nice'} + + self.hass.states.set(entity_id, state, attributes) + + self.hass.pool.block_till_done() + recorder._INSTANCE.block_till_done() + + states = recorder.query_states('SELECT * FROM states') + + self.assertEqual(1, len(states)) + self.assertEqual(self.hass.states.get(entity_id), states[0]) + + def test_saving_event(self): + """ Tests saving and restoring an event. """ + event_type = 'EVENT_TEST' + event_data = {'test_attr': 5, 'test_attr_10': 'nice'} + + events = [] + + def event_listener(event): + """ Records events from eventbus. """ + if event.event_type == event_type: + events.append(event) + + self.hass.bus.listen(MATCH_ALL, event_listener) + + self.hass.bus.fire(event_type, event_data) + + self.hass.pool.block_till_done() + recorder._INSTANCE.block_till_done() + + db_events = recorder.query_events( + 'SELECT * FROM events WHERE event_type = ?', (event_type, )) + + self.assertEqual(events, db_events) diff --git a/tests/test_core.py b/tests/test_core.py index b450479f2d9c..58052fe43f09 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -30,7 +30,11 @@ class TestHomeAssistant(unittest.TestCase): def tearDown(self): # pylint: disable=invalid-name """ Stop down stuff we started. """ - self.hass.stop() + try: + self.hass.stop() + except ha.HomeAssistantError: + # Already stopped after the block till stopped test + pass def test_get_config_path(self): """ Test get_config_path method. """