Merge pull request #1262 from balloob/chore/tests-cleanup

More testing cleanup
This commit is contained in:
Paulus Schoutsen 2016-02-14 23:37:10 -08:00
commit cdc93ab670
10 changed files with 56 additions and 62 deletions

View File

@ -103,12 +103,7 @@ class HomeAssistant(object):
def stop(self): def stop(self):
"""Stop Home Assistant and shuts down all threads.""" """Stop Home Assistant and shuts down all threads."""
_LOGGER.info("Stopping") _LOGGER.info("Stopping")
self.bus.fire(EVENT_HOMEASSISTANT_STOP) self.bus.fire(EVENT_HOMEASSISTANT_STOP)
# Wait till all responses to homeassistant_stop are done
self.pool.block_till_done()
self.pool.stop() self.pool.stop()

View File

@ -148,14 +148,11 @@ class HomeAssistant(ha.HomeAssistant):
self.bus.fire(ha.EVENT_HOMEASSISTANT_STOP, self.bus.fire(ha.EVENT_HOMEASSISTANT_STOP,
origin=ha.EventOrigin.remote) origin=ha.EventOrigin.remote)
self.pool.stop()
# Disconnect master event forwarding # Disconnect master event forwarding
disconnect_remote_events(self.remote_api, self.config.api) disconnect_remote_events(self.remote_api, self.config.api)
# Wait till all responses to homeassistant_stop are done
self.pool.block_till_done()
self.pool.stop()
class EventBus(ha.EventBus): class EventBus(ha.EventBus):
""" EventBus implementation that forwards fire_event to remote API. """ """ EventBus implementation that forwards fire_event to remote API. """

View File

@ -284,7 +284,7 @@ class Throttle(object):
class ThreadPool(object): class ThreadPool(object):
""" A priority queue-based thread pool. """ """A priority queue-based thread pool."""
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
def __init__(self, job_handler, worker_count=0, busy_callback=None): def __init__(self, job_handler, worker_count=0, busy_callback=None):
@ -311,7 +311,7 @@ class ThreadPool(object):
self.add_worker() self.add_worker()
def add_worker(self): def add_worker(self):
""" Adds a worker to the thread pool. Resets warning limit. """ """Add worker to the thread pool and reset warning limit."""
with self._lock: with self._lock:
if not self.running: if not self.running:
raise RuntimeError("ThreadPool not running") raise RuntimeError("ThreadPool not running")
@ -324,7 +324,7 @@ class ThreadPool(object):
self.busy_warning_limit = self.worker_count * 3 self.busy_warning_limit = self.worker_count * 3
def remove_worker(self): def remove_worker(self):
""" Removes a worker from the thread pool. Resets warning limit. """ """Remove worker from the thread pool and reset warning limit."""
with self._lock: with self._lock:
if not self.running: if not self.running:
raise RuntimeError("ThreadPool not running") raise RuntimeError("ThreadPool not running")
@ -354,18 +354,19 @@ class ThreadPool(object):
self._work_queue.qsize()) self._work_queue.qsize())
def block_till_done(self): def block_till_done(self):
""" Blocks till all work is done. """ """Block till current work is done."""
self._work_queue.join() self._work_queue.join()
# import traceback
# traceback.print_stack()
def stop(self): def stop(self):
""" Stops all the threads. """ """Finish all the jobs and stops all the threads."""
self.block_till_done()
with self._lock: with self._lock:
if not self.running: if not self.running:
return return
# Ensure all current jobs finish
self.block_till_done()
# Tell the workers to quit # Tell the workers to quit
for _ in range(self.worker_count): for _ in range(self.worker_count):
self.remove_worker() self.remove_worker()
@ -376,7 +377,7 @@ class ThreadPool(object):
self.block_till_done() self.block_till_done()
def _worker(self): def _worker(self):
""" Handles jobs for the thread pool. """ """Handle jobs for the thread pool."""
while True: while True:
# Get new item from work_queue # Get new item from work_queue
job = self._work_queue.get().item job = self._work_queue.get().item

View File

@ -6,6 +6,7 @@ Tests initialization.
""" """
import betamax import betamax
from homeassistant import util
from homeassistant.util import location from homeassistant.util import location
with betamax.Betamax.configure() as config: with betamax.Betamax.configure() as config:
@ -28,3 +29,4 @@ location.detect_location_info = lambda: location.LocationInfo(
) )
location.elevation = lambda latitude, longitude: 0 location.elevation = lambda latitude, longitude: 0
util.get_local_ip = lambda: '127.0.0.1'

View File

@ -28,9 +28,7 @@ def _url(data={}):
return "{}{}locative?{}".format(HTTP_BASE_URL, const.URL_API, data) return "{}{}locative?{}".format(HTTP_BASE_URL, const.URL_API, data)
@patch('homeassistant.components.http.util.get_local_ip', def setUpModule(): # pylint: disable=invalid-name
return_value='127.0.0.1')
def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name
""" Initalizes a Home Assistant server. """ """ Initalizes a Home Assistant server. """
global hass global hass
@ -66,6 +64,9 @@ def tearDownModule(): # pylint: disable=invalid-name
class TestLocative(unittest.TestCase): class TestLocative(unittest.TestCase):
""" Test Locative """ """ Test Locative """
def tearDown(self):
hass.pool.block_till_done()
def test_missing_data(self, update_config): def test_missing_data(self, update_config):
data = { data = {
'latitude': 1.0, 'latitude': 1.0,

View File

@ -172,12 +172,12 @@ class TestLightMQTT(unittest.TestCase):
self.assertIsNone(state.attributes.get('brightness')) self.assertIsNone(state.attributes.get('brightness'))
self.assertIsNone(state.attributes.get('rgb_color')) self.assertIsNone(state.attributes.get('rgb_color'))
fire_mqtt_message(self.hass, 'test_light_rgb/rgb/status',
'{"hello": [1, 2, 3]}')
fire_mqtt_message(self.hass, 'test_light_rgb/status', fire_mqtt_message(self.hass, 'test_light_rgb/status',
'{"hello": "ON"}') '{"hello": "ON"}')
fire_mqtt_message(self.hass, 'test_light_rgb/brightness/status', fire_mqtt_message(self.hass, 'test_light_rgb/brightness/status',
'{"hello": "50"}') '{"hello": "50"}')
fire_mqtt_message(self.hass, 'test_light_rgb/rgb/status',
'{"hello": [1, 2, 3]}')
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')

View File

@ -7,7 +7,6 @@ Tests Home Assistant Alexa component does what it should do.
# pylint: disable=protected-access,too-many-public-methods # pylint: disable=protected-access,too-many-public-methods
import unittest import unittest
import json import json
from unittest.mock import patch
import requests import requests
@ -29,9 +28,7 @@ hass = None
calls = [] calls = []
@patch('homeassistant.components.http.util.get_local_ip', def setUpModule(): # pylint: disable=invalid-name
return_value='127.0.0.1')
def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name
""" Initalize a Home Assistant server for testing this module. """ """ Initalize a Home Assistant server for testing this module. """
global hass global hass
@ -105,6 +102,9 @@ def _req(data={}):
class TestAlexa(unittest.TestCase): class TestAlexa(unittest.TestCase):
""" Test Alexa. """ """ Test Alexa. """
def tearDown(self):
hass.pool.block_till_done()
def test_launch_request(self): def test_launch_request(self):
data = { data = {
'version': '1.0', 'version': '1.0',

View File

@ -32,9 +32,7 @@ def _url(path=""):
return HTTP_BASE_URL + path return HTTP_BASE_URL + path
@patch('homeassistant.components.http.util.get_local_ip', def setUpModule(): # pylint: disable=invalid-name
return_value='127.0.0.1')
def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name
""" Initializes a Home Assistant server. """ """ Initializes a Home Assistant server. """
global hass global hass
@ -61,6 +59,9 @@ def tearDownModule(): # pylint: disable=invalid-name
class TestAPI(unittest.TestCase): class TestAPI(unittest.TestCase):
""" Test the API. """ """ Test the API. """
def tearDown(self):
hass.pool.block_till_done()
# TODO move back to http component and test with use_auth. # TODO move back to http component and test with use_auth.
def test_access_denied_without_password(self): def test_access_denied_without_password(self):
req = requests.get(_url(const.URL_API)) req = requests.get(_url(const.URL_API))

View File

@ -7,7 +7,6 @@ Tests Home Assistant HTTP component does what it should do.
# pylint: disable=protected-access,too-many-public-methods # pylint: disable=protected-access,too-many-public-methods
import re import re
import unittest import unittest
from unittest.mock import patch
import requests import requests
@ -30,9 +29,7 @@ def _url(path=""):
return HTTP_BASE_URL + path return HTTP_BASE_URL + path
@patch('homeassistant.components.http.util.get_local_ip', def setUpModule(): # pylint: disable=invalid-name
return_value='127.0.0.1')
def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name
""" Initalizes a Home Assistant server. """ """ Initalizes a Home Assistant server. """
global hass global hass
@ -59,6 +56,9 @@ def tearDownModule(): # pylint: disable=invalid-name
class TestFrontend(unittest.TestCase): class TestFrontend(unittest.TestCase):
""" Test the frontend. """ """ Test the frontend. """
def tearDown(self):
hass.pool.block_till_done()
def test_frontend_and_static(self): def test_frontend_and_static(self):
""" Tests if we can get the frontend. """ """ Tests if we can get the frontend. """
req = requests.get(_url("")) req = requests.get(_url(""))

View File

@ -6,7 +6,6 @@ Tests Home Assistant remote methods and classes.
""" """
# pylint: disable=protected-access,too-many-public-methods # pylint: disable=protected-access,too-many-public-methods
import unittest import unittest
from unittest.mock import patch
import homeassistant.core as ha import homeassistant.core as ha
import homeassistant.bootstrap as bootstrap import homeassistant.bootstrap as bootstrap
@ -24,7 +23,8 @@ HTTP_BASE_URL = "http://127.0.0.1:{}".format(MASTER_PORT)
HA_HEADERS = {HTTP_HEADER_HA_AUTH: API_PASSWORD} HA_HEADERS = {HTTP_HEADER_HA_AUTH: API_PASSWORD}
hass, slave, master_api, broken_api = None, None, None, None broken_api = remote.API('127.0.0.1', BROKEN_PORT)
hass, slave, master_api = None, None, None
def _url(path=""): def _url(path=""):
@ -32,11 +32,9 @@ def _url(path=""):
return HTTP_BASE_URL + path return HTTP_BASE_URL + path
@patch('homeassistant.components.http.util.get_local_ip', def setUpModule(): # pylint: disable=invalid-name
return_value='127.0.0.1')
def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name
""" Initalizes a Home Assistant server and Slave instance. """ """ Initalizes a Home Assistant server and Slave instance. """
global hass, slave, master_api, broken_api global hass, slave, master_api
hass = get_test_home_assistant() hass = get_test_home_assistant()
@ -63,14 +61,9 @@ def setUpModule(mock_get_local_ip): # pylint: disable=invalid-name
slave.start() slave.start()
# Setup API pointing at nothing
broken_api = remote.API("127.0.0.1", "", BROKEN_PORT)
def tearDownModule(): # pylint: disable=invalid-name def tearDownModule(): # pylint: disable=invalid-name
""" Stops the Home Assistant server and slave. """ """ Stops the Home Assistant server and slave. """
global hass, slave
slave.stop() slave.stop()
hass.stop() hass.stop()
@ -78,6 +71,10 @@ def tearDownModule(): # pylint: disable=invalid-name
class TestRemoteMethods(unittest.TestCase): class TestRemoteMethods(unittest.TestCase):
""" Test the homeassistant.remote module. """ """ Test the homeassistant.remote module. """
def tearDown(self):
slave.pool.block_till_done()
hass.pool.block_till_done()
def test_validate_api(self): def test_validate_api(self):
""" Test Python API validate_api. """ """ Test Python API validate_api. """
self.assertEqual(remote.APIStatus.OK, remote.validate_api(master_api)) self.assertEqual(remote.APIStatus.OK, remote.validate_api(master_api))
@ -198,10 +195,24 @@ class TestRemoteMethods(unittest.TestCase):
# Should not raise an exception # Should not raise an exception
remote.call_service(broken_api, "test_domain", "test_service") remote.call_service(broken_api, "test_domain", "test_service")
def test_json_encoder(self):
""" Test the JSON Encoder. """
ha_json_enc = remote.JSONEncoder()
state = hass.states.get('test.test')
self.assertEqual(state.as_dict(), ha_json_enc.default(state))
# Default method raises TypeError if non HA object
self.assertRaises(TypeError, ha_json_enc.default, 1)
class TestRemoteClasses(unittest.TestCase): class TestRemoteClasses(unittest.TestCase):
""" Test the homeassistant.remote module. """ """ Test the homeassistant.remote module. """
def tearDown(self):
slave.pool.block_till_done()
hass.pool.block_till_done()
def test_home_assistant_init(self): def test_home_assistant_init(self):
""" Test HomeAssistant init. """ """ Test HomeAssistant init. """
# Wrong password # Wrong password
@ -216,12 +227,8 @@ class TestRemoteClasses(unittest.TestCase):
def test_statemachine_init(self): def test_statemachine_init(self):
""" Tests if remote.StateMachine copies all states on init. """ """ Tests if remote.StateMachine copies all states on init. """
self.assertEqual(len(hass.states.all()), self.assertEqual(sorted(hass.states.all()),
len(slave.states.all())) sorted(slave.states.all()))
for state in hass.states.all():
self.assertEqual(
state, slave.states.get(state.entity_id))
def test_statemachine_set(self): def test_statemachine_set(self):
""" Tests if setting the state on a slave is recorded. """ """ Tests if setting the state on a slave is recorded. """
@ -276,13 +283,3 @@ class TestRemoteClasses(unittest.TestCase):
hass.pool.block_till_done() hass.pool.block_till_done()
self.assertEqual(1, len(test_value)) self.assertEqual(1, len(test_value))
def test_json_encoder(self):
""" Test the JSON Encoder. """
ha_json_enc = remote.JSONEncoder()
state = hass.states.get('test.test')
self.assertEqual(state.as_dict(), ha_json_enc.default(state))
# Default method raises TypeError if non HA object
self.assertRaises(TypeError, ha_json_enc.default, 1)