PageRenderTime 36ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/components/test_history.py

https://gitlab.com/mkerfoot/home-assistant
Python | 202 lines | 134 code | 41 blank | 27 comment | 13 complexity | 32373bb146bd1f4930b4e7b8a1ff674c MD5 | raw file
  1. """
  2. tests.components.test_history
  3. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. Tests the history component.
  5. """
  6. # pylint: disable=protected-access,too-many-public-methods
  7. from datetime import timedelta
  8. import os
  9. import unittest
  10. from unittest.mock import patch, sentinel
  11. import homeassistant.core as ha
  12. import homeassistant.util.dt as dt_util
  13. from homeassistant.components import history, recorder
  14. from tests.common import (
  15. mock_http_component, mock_state_change_event, get_test_home_assistant)
  16. class TestComponentHistory(unittest.TestCase):
  17. """ Tests homeassistant.components.history module. """
  18. def setUp(self): # pylint: disable=invalid-name
  19. """ Init needed objects. """
  20. self.hass = get_test_home_assistant(1)
  21. def tearDown(self): # pylint: disable=invalid-name
  22. """ Stop down stuff we started. """
  23. self.hass.stop()
  24. db_path = self.hass.config.path(recorder.DB_FILE)
  25. if os.path.isfile(db_path):
  26. os.remove(db_path)
  27. def init_recorder(self):
  28. recorder.setup(self.hass, {})
  29. self.hass.start()
  30. self.wait_recording_done()
  31. def wait_recording_done(self):
  32. """ Block till recording is done. """
  33. self.hass.pool.block_till_done()
  34. recorder._INSTANCE.block_till_done()
  35. def test_setup(self):
  36. """ Test setup method of history. """
  37. mock_http_component(self.hass)
  38. self.assertTrue(history.setup(self.hass, {}))
  39. def test_last_5_states(self):
  40. """ Test retrieving the last 5 states. """
  41. self.init_recorder()
  42. states = []
  43. entity_id = 'test.last_5_states'
  44. for i in range(7):
  45. self.hass.states.set(entity_id, "State {}".format(i))
  46. self.wait_recording_done()
  47. if i > 1:
  48. states.append(self.hass.states.get(entity_id))
  49. self.assertEqual(
  50. list(reversed(states)), history.last_5_states(entity_id))
  51. def test_get_states(self):
  52. """ Test getting states at a specific point in time. """
  53. self.init_recorder()
  54. states = []
  55. now = dt_util.utcnow()
  56. with patch('homeassistant.components.recorder.dt_util.utcnow',
  57. return_value=now):
  58. for i in range(5):
  59. state = ha.State(
  60. 'test.point_in_time_{}'.format(i % 5),
  61. "State {}".format(i),
  62. {'attribute_test': i})
  63. mock_state_change_event(self.hass, state)
  64. states.append(state)
  65. self.wait_recording_done()
  66. future = now + timedelta(seconds=1)
  67. with patch('homeassistant.components.recorder.dt_util.utcnow',
  68. return_value=future):
  69. for i in range(5):
  70. state = ha.State(
  71. 'test.point_in_time_{}'.format(i % 5),
  72. "State {}".format(i),
  73. {'attribute_test': i})
  74. mock_state_change_event(self.hass, state)
  75. self.wait_recording_done()
  76. # Get states returns everything before POINT
  77. self.assertEqual(states,
  78. sorted(history.get_states(future),
  79. key=lambda state: state.entity_id))
  80. # Test get_state here because we have a DB setup
  81. self.assertEqual(
  82. states[0], history.get_state(future, states[0].entity_id))
  83. def test_state_changes_during_period(self):
  84. self.init_recorder()
  85. entity_id = 'media_player.test'
  86. def set_state(state):
  87. self.hass.states.set(entity_id, state)
  88. self.wait_recording_done()
  89. return self.hass.states.get(entity_id)
  90. start = dt_util.utcnow()
  91. point = start + timedelta(seconds=1)
  92. end = point + timedelta(seconds=1)
  93. with patch('homeassistant.components.recorder.dt_util.utcnow',
  94. return_value=start):
  95. set_state('idle')
  96. set_state('YouTube')
  97. with patch('homeassistant.components.recorder.dt_util.utcnow',
  98. return_value=point):
  99. states = [
  100. set_state('idle'),
  101. set_state('Netflix'),
  102. set_state('Plex'),
  103. set_state('YouTube'),
  104. ]
  105. with patch('homeassistant.components.recorder.dt_util.utcnow',
  106. return_value=end):
  107. set_state('Netflix')
  108. set_state('Plex')
  109. hist = history.state_changes_during_period(start, end, entity_id)
  110. self.assertEqual(states, hist[entity_id])
  111. def test_get_significant_states(self):
  112. """test that only significant states are returned with
  113. get_significant_states.
  114. We inject a bunch of state updates from media player and
  115. thermostat. We should get back every thermostat change that
  116. includes an attribute change, but only the state updates for
  117. media player (attribute changes are not significant and not returned).
  118. """
  119. self.init_recorder()
  120. mp = 'media_player.test'
  121. therm = 'thermostat.test'
  122. def set_state(entity_id, state, **kwargs):
  123. self.hass.states.set(entity_id, state, **kwargs)
  124. self.wait_recording_done()
  125. return self.hass.states.get(entity_id)
  126. zero = dt_util.utcnow()
  127. one = zero + timedelta(seconds=1)
  128. two = one + timedelta(seconds=1)
  129. three = two + timedelta(seconds=1)
  130. four = three + timedelta(seconds=1)
  131. states = {therm: [], mp: []}
  132. with patch('homeassistant.components.recorder.dt_util.utcnow',
  133. return_value=one):
  134. states[mp].append(
  135. set_state(mp, 'idle',
  136. attributes={'media_title': str(sentinel.mt1)}))
  137. states[mp].append(
  138. set_state(mp, 'YouTube',
  139. attributes={'media_title': str(sentinel.mt2)}))
  140. states[therm].append(
  141. set_state(therm, 20, attributes={'current_temperature': 19.5}))
  142. with patch('homeassistant.components.recorder.dt_util.utcnow',
  143. return_value=two):
  144. # this state will be skipped only different in time
  145. set_state(mp, 'YouTube',
  146. attributes={'media_title': str(sentinel.mt3)})
  147. states[therm].append(
  148. set_state(therm, 21, attributes={'current_temperature': 19.8}))
  149. with patch('homeassistant.components.recorder.dt_util.utcnow',
  150. return_value=three):
  151. states[mp].append(
  152. set_state(mp, 'Netflix',
  153. attributes={'media_title': str(sentinel.mt4)}))
  154. # attributes changed even though state is the same
  155. states[therm].append(
  156. set_state(therm, 21, attributes={'current_temperature': 20}))
  157. hist = history.get_significant_states(zero, four)
  158. self.assertEqual(states, hist)