core/tests/components/recorder/test_init.py

190 lines
6.2 KiB
Python
Raw Normal View History

2016-03-09 09:25:50 +00:00
"""The tests for the Recorder component."""
2015-04-30 06:21:31 +00:00
# pylint: disable=too-many-public-methods,protected-access
import unittest
import json
from datetime import datetime, timedelta
from unittest.mock import patch
2015-04-30 06:21:31 +00:00
from homeassistant.const import MATCH_ALL
from homeassistant.components import recorder
from tests.common import get_test_home_assistant
2015-04-30 06:21:31 +00:00
class TestRecorder(unittest.TestCase):
"""Test the recorder module."""
2015-04-30 06:21:31 +00:00
def setUp(self): # pylint: disable=invalid-name
2016-03-09 09:25:50 +00:00
"""Setup things to be run when tests are started."""
2015-04-30 06:21:31 +00:00
self.hass = get_test_home_assistant()
db_uri = 'sqlite://'
with patch('homeassistant.core.Config.path', return_value=db_uri):
recorder.setup(self.hass, config={
"recorder": {
"db_url": db_uri}})
2015-04-30 06:21:31 +00:00
self.hass.start()
recorder._INSTANCE.block_till_db_ready()
self.session = recorder.Session()
2015-04-30 06:21:31 +00:00
recorder._INSTANCE.block_till_done()
def tearDown(self): # pylint: disable=invalid-name
2016-03-09 09:25:50 +00:00
"""Stop everything that was started."""
2015-04-30 06:21:31 +00:00
self.hass.stop()
def _add_test_states(self):
2016-05-13 21:42:08 +00:00
"""Add multiple states to the db for testing."""
now = datetime.now()
five_days_ago = now - timedelta(days=5)
attributes = {'test_attr': 5, 'test_attr_10': 'nice'}
self.hass.pool.block_till_done()
recorder._INSTANCE.block_till_done()
for event_id in range(5):
if event_id < 3:
timestamp = five_days_ago
state = 'purgeme'
else:
timestamp = now
state = 'dontpurgeme'
self.session.add(recorder.get_model('States')(
entity_id='test.recorder2',
domain='sensor',
state=state,
attributes=json.dumps(attributes),
last_changed=timestamp,
last_updated=timestamp,
created=timestamp,
event_id=event_id + 1000
))
self.session.commit()
def _add_test_events(self):
2016-05-13 21:42:08 +00:00
"""Add a few events for testing."""
now = datetime.now()
five_days_ago = now - timedelta(days=5)
event_data = {'test_attr': 5, 'test_attr_10': 'nice'}
self.hass.pool.block_till_done()
recorder._INSTANCE.block_till_done()
for event_id in range(5):
if event_id < 2:
timestamp = five_days_ago
event_type = 'EVENT_TEST_PURGE'
else:
timestamp = now
event_type = 'EVENT_TEST'
self.session.add(recorder.get_model('Events')(
event_type=event_type,
event_data=json.dumps(event_data),
origin='LOCAL',
created=timestamp,
time_fired=timestamp,
))
2015-04-30 06:21:31 +00:00
def test_saving_state(self):
2016-03-09 09:25:50 +00:00
"""Test saving and restoring a state."""
2015-04-30 06:21:31 +00:00
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()
2016-07-11 07:46:56 +00:00
db_states = recorder.query('States')
states = recorder.execute(db_states)
assert db_states[0].event_id is not None
2015-04-30 06:21:31 +00:00
self.assertEqual(1, len(states))
self.assertEqual(self.hass.states.get(entity_id), states[0])
def test_saving_event(self):
2016-03-09 09:25:50 +00:00
"""Test saving and restoring an event."""
2015-04-30 06:21:31 +00:00
event_type = 'EVENT_TEST'
event_data = {'test_attr': 5, 'test_attr_10': 'nice'}
events = []
def event_listener(event):
2016-03-09 09:25:50 +00:00
"""Record events from eventbus."""
2015-04-30 06:21:31 +00:00
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.execute(
recorder.query('Events').filter_by(
event_type=event_type))
2015-04-30 06:21:31 +00:00
2016-04-16 07:55:35 +00:00
assert len(events) == 1
assert len(db_events) == 1
event = events[0]
db_event = db_events[0]
assert event.event_type == db_event.event_type
assert event.data == db_event.data
assert event.origin == db_event.origin
# Recorder uses SQLite and stores datetimes as integer unix timestamps
assert event.time_fired.replace(microsecond=0) == \
db_event.time_fired.replace(microsecond=0)
def test_purge_old_states(self):
2016-05-13 21:42:08 +00:00
"""Test deleting old states."""
self._add_test_states()
# make sure we start with 5 states
states = recorder.query('States')
self.assertEqual(states.count(), 5)
# run purge_old_data()
recorder._INSTANCE.purge_days = 4
recorder._INSTANCE._purge_old_data()
# we should only have 2 states left after purging
self.assertEqual(states.count(), 2)
def test_purge_old_events(self):
2016-05-13 21:43:22 +00:00
"""Test deleting old events."""
self._add_test_events()
events = recorder.query('Events').filter(
recorder.get_model('Events').event_type.like("EVENT_TEST%"))
self.assertEqual(events.count(), 5)
# run purge_old_data()
recorder._INSTANCE.purge_days = 4
recorder._INSTANCE._purge_old_data()
# now we should only have 3 events left
self.assertEqual(events.count(), 3)
def test_purge_disabled(self):
2016-05-13 21:42:08 +00:00
"""Test leaving purge_days disabled."""
self._add_test_states()
self._add_test_events()
# make sure we start with 5 states and events
states = recorder.query('States')
events = recorder.query('Events').filter(
recorder.get_model('Events').event_type.like("EVENT_TEST%"))
self.assertEqual(states.count(), 5)
self.assertEqual(events.count(), 5)
# run purge_old_data()
recorder._INSTANCE.purge_days = None
recorder._INSTANCE._purge_old_data()
# we should have all of our states still
self.assertEqual(states.count(), 5)
self.assertEqual(events.count(), 5)