Async tests for device tracker mqtt (#18680)

This commit is contained in:
Adam Mills 2018-11-24 13:24:06 -05:00 committed by GitHub
parent 5e18d52302
commit d24ea7da90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 263 additions and 268 deletions

View File

@ -1,40 +1,32 @@
"""The tests for the MQTT device tracker platform.""" """The tests for the MQTT device tracker platform."""
import asyncio
import unittest
from unittest.mock import patch
import logging import logging
import os import os
from asynctest import patch
import pytest
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
from homeassistant.components import device_tracker from homeassistant.components import device_tracker
from homeassistant.const import CONF_PLATFORM from homeassistant.const import CONF_PLATFORM
from tests.common import ( from tests.common import (
get_test_home_assistant, mock_mqtt_component, fire_mqtt_message) async_mock_mqtt_component, async_fire_mqtt_message)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class TestComponentsDeviceTrackerMQTT(unittest.TestCase): @pytest.fixture(autouse=True)
"""Test MQTT device tracker platform.""" def setup_comp(hass):
"""Initialize components."""
hass.loop.run_until_complete(async_mock_mqtt_component(hass))
yaml_devices = hass.config.path(device_tracker.YAML_DEVICES)
yield
if os.path.isfile(yaml_devices):
os.remove(yaml_devices)
def setUp(self): # pylint: disable=invalid-name
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_mqtt_component(self.hass)
def tearDown(self): # pylint: disable=invalid-name async def test_ensure_device_tracker_platform_validation(hass):
"""Stop everything that was started."""
self.hass.stop()
try:
os.remove(self.hass.config.path(device_tracker.YAML_DEVICES))
except FileNotFoundError:
pass
def test_ensure_device_tracker_platform_validation(self):
"""Test if platform validation was done.""" """Test if platform validation was done."""
@asyncio.coroutine async def mock_setup_scanner(hass, config, see, discovery_info=None):
def mock_setup_scanner(hass, config, see, discovery_info=None):
"""Check that Qos was added by validation.""" """Check that Qos was added by validation."""
assert 'qos' in config assert 'qos' in config
@ -44,7 +36,7 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
dev_id = 'paulus' dev_id = 'paulus'
topic = '/location/paulus' topic = '/location/paulus'
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt', CONF_PLATFORM: 'mqtt',
'devices': {dev_id: topic} 'devices': {dev_id: topic}
@ -52,25 +44,27 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
}) })
assert mock_sp.call_count == 1 assert mock_sp.call_count == 1
def test_new_message(self):
async def test_new_message(hass):
"""Test new message.""" """Test new message."""
dev_id = 'paulus' dev_id = 'paulus'
entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id)
topic = '/location/paulus' topic = '/location/paulus'
location = 'work' location = 'work'
self.hass.config.components = set(['mqtt', 'zone']) hass.config.components = set(['mqtt', 'zone'])
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt', CONF_PLATFORM: 'mqtt',
'devices': {dev_id: topic} 'devices': {dev_id: topic}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
assert location == self.hass.states.get(entity_id).state assert location == hass.states.get(entity_id).state
def test_single_level_wildcard_topic(self):
async def test_single_level_wildcard_topic(hass):
"""Test single level wildcard topic.""" """Test single level wildcard topic."""
dev_id = 'paulus' dev_id = 'paulus'
entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id)
@ -78,18 +72,19 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
topic = '/location/room/paulus' topic = '/location/room/paulus'
location = 'work' location = 'work'
self.hass.config.components = set(['mqtt', 'zone']) hass.config.components = set(['mqtt', 'zone'])
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt', CONF_PLATFORM: 'mqtt',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
assert location == self.hass.states.get(entity_id).state assert location == hass.states.get(entity_id).state
def test_multi_level_wildcard_topic(self):
async def test_multi_level_wildcard_topic(hass):
"""Test multi level wildcard topic.""" """Test multi level wildcard topic."""
dev_id = 'paulus' dev_id = 'paulus'
entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id)
@ -97,18 +92,19 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
topic = '/location/room/paulus' topic = '/location/room/paulus'
location = 'work' location = 'work'
self.hass.config.components = set(['mqtt', 'zone']) hass.config.components = set(['mqtt', 'zone'])
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt', CONF_PLATFORM: 'mqtt',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
assert location == self.hass.states.get(entity_id).state assert location == hass.states.get(entity_id).state
def test_single_level_wildcard_topic_not_matching(self):
async def test_single_level_wildcard_topic_not_matching(hass):
"""Test not matching single level wildcard topic.""" """Test not matching single level wildcard topic."""
dev_id = 'paulus' dev_id = 'paulus'
entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id)
@ -116,18 +112,19 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
topic = '/location/paulus' topic = '/location/paulus'
location = 'work' location = 'work'
self.hass.config.components = set(['mqtt', 'zone']) hass.config.components = set(['mqtt', 'zone'])
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt', CONF_PLATFORM: 'mqtt',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
assert self.hass.states.get(entity_id) is None assert hass.states.get(entity_id) is None
def test_multi_level_wildcard_topic_not_matching(self):
async def test_multi_level_wildcard_topic_not_matching(hass):
"""Test not matching multi level wildcard topic.""" """Test not matching multi level wildcard topic."""
dev_id = 'paulus' dev_id = 'paulus'
entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id)
@ -135,13 +132,13 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
topic = '/somewhere/room/paulus' topic = '/somewhere/room/paulus'
location = 'work' location = 'work'
self.hass.config.components = set(['mqtt', 'zone']) hass.config.components = set(['mqtt', 'zone'])
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt', CONF_PLATFORM: 'mqtt',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
assert self.hass.states.get(entity_id) is None assert hass.states.get(entity_id) is None

View File

@ -1,17 +1,15 @@
"""The tests for the JSON MQTT device tracker platform.""" """The tests for the JSON MQTT device tracker platform."""
import asyncio
import json import json
import unittest from asynctest import patch
from unittest.mock import patch
import logging import logging
import os import os
import pytest
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
from homeassistant.components import device_tracker from homeassistant.components import device_tracker
from homeassistant.const import CONF_PLATFORM from homeassistant.const import CONF_PLATFORM
from tests.common import ( from tests.common import async_mock_mqtt_component, async_fire_mqtt_message
get_test_home_assistant, mock_mqtt_component, fire_mqtt_message)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -25,26 +23,19 @@ LOCATION_MESSAGE_INCOMPLETE = {
'longitude': 2.0} 'longitude': 2.0}
class TestComponentsDeviceTrackerJSONMQTT(unittest.TestCase): @pytest.fixture(autouse=True)
"""Test JSON MQTT device tracker platform.""" def setup_comp(hass):
"""Initialize components."""
hass.loop.run_until_complete(async_mock_mqtt_component(hass))
yaml_devices = hass.config.path(device_tracker.YAML_DEVICES)
yield
if os.path.isfile(yaml_devices):
os.remove(yaml_devices)
def setUp(self): # pylint: disable=invalid-name
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_mqtt_component(self.hass)
def tearDown(self): # pylint: disable=invalid-name async def test_ensure_device_tracker_platform_validation(hass):
"""Stop everything that was started."""
self.hass.stop()
try:
os.remove(self.hass.config.path(device_tracker.YAML_DEVICES))
except FileNotFoundError:
pass
def test_ensure_device_tracker_platform_validation(self):
"""Test if platform validation was done.""" """Test if platform validation was done."""
@asyncio.coroutine async def mock_setup_scanner(hass, config, see, discovery_info=None):
def mock_setup_scanner(hass, config, see, discovery_info=None):
"""Check that Qos was added by validation.""" """Check that Qos was added by validation."""
assert 'qos' in config assert 'qos' in config
@ -54,7 +45,7 @@ class TestComponentsDeviceTrackerJSONMQTT(unittest.TestCase):
dev_id = 'paulus' dev_id = 'paulus'
topic = 'location/paulus' topic = 'location/paulus'
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: topic} 'devices': {dev_id: topic}
@ -62,104 +53,110 @@ class TestComponentsDeviceTrackerJSONMQTT(unittest.TestCase):
}) })
assert mock_sp.call_count == 1 assert mock_sp.call_count == 1
def test_json_message(self):
async def test_json_message(hass):
"""Test json location message.""" """Test json location message."""
dev_id = 'zanzito' dev_id = 'zanzito'
topic = 'location/zanzito' topic = 'location/zanzito'
location = json.dumps(LOCATION_MESSAGE) location = json.dumps(LOCATION_MESSAGE)
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: topic} 'devices': {dev_id: topic}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
state = self.hass.states.get('device_tracker.zanzito') state = hass.states.get('device_tracker.zanzito')
assert state.attributes.get('latitude') == 2.0 assert state.attributes.get('latitude') == 2.0
assert state.attributes.get('longitude') == 1.0 assert state.attributes.get('longitude') == 1.0
def test_non_json_message(self):
async def test_non_json_message(hass, caplog):
"""Test receiving a non JSON message.""" """Test receiving a non JSON message."""
dev_id = 'zanzito' dev_id = 'zanzito'
topic = 'location/zanzito' topic = 'location/zanzito'
location = 'home' location = 'home'
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: topic} 'devices': {dev_id: topic}
} }
}) })
with self.assertLogs(level='ERROR') as test_handle: caplog.set_level(logging.ERROR)
fire_mqtt_message(self.hass, topic, location) caplog.clear()
self.hass.block_till_done() async_fire_mqtt_message(hass, topic, location)
assert "ERROR:homeassistant.components.device_tracker.mqtt_json:" \ await hass.async_block_till_done()
"Error parsing JSON payload: home" in \ assert "Error parsing JSON payload: home" in \
test_handle.output[0] caplog.text
def test_incomplete_message(self):
async def test_incomplete_message(hass, caplog):
"""Test receiving an incomplete message.""" """Test receiving an incomplete message."""
dev_id = 'zanzito' dev_id = 'zanzito'
topic = 'location/zanzito' topic = 'location/zanzito'
location = json.dumps(LOCATION_MESSAGE_INCOMPLETE) location = json.dumps(LOCATION_MESSAGE_INCOMPLETE)
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: topic} 'devices': {dev_id: topic}
} }
}) })
with self.assertLogs(level='ERROR') as test_handle: caplog.set_level(logging.ERROR)
fire_mqtt_message(self.hass, topic, location) caplog.clear()
self.hass.block_till_done() async_fire_mqtt_message(hass, topic, location)
assert "ERROR:homeassistant.components.device_tracker.mqtt_json:" \ await hass.async_block_till_done()
"Skipping update for following data because of missing " \ assert "Skipping update for following data because of missing " \
"or malformatted data: {\"longitude\": 2.0}" in \ "or malformatted data: {\"longitude\": 2.0}" in \
test_handle.output[0] caplog.text
def test_single_level_wildcard_topic(self):
async def test_single_level_wildcard_topic(hass):
"""Test single level wildcard topic.""" """Test single level wildcard topic."""
dev_id = 'zanzito' dev_id = 'zanzito'
subscription = 'location/+/zanzito' subscription = 'location/+/zanzito'
topic = 'location/room/zanzito' topic = 'location/room/zanzito'
location = json.dumps(LOCATION_MESSAGE) location = json.dumps(LOCATION_MESSAGE)
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
state = self.hass.states.get('device_tracker.zanzito') state = hass.states.get('device_tracker.zanzito')
assert state.attributes.get('latitude') == 2.0 assert state.attributes.get('latitude') == 2.0
assert state.attributes.get('longitude') == 1.0 assert state.attributes.get('longitude') == 1.0
def test_multi_level_wildcard_topic(self):
async def test_multi_level_wildcard_topic(hass):
"""Test multi level wildcard topic.""" """Test multi level wildcard topic."""
dev_id = 'zanzito' dev_id = 'zanzito'
subscription = 'location/#' subscription = 'location/#'
topic = 'location/zanzito' topic = 'location/zanzito'
location = json.dumps(LOCATION_MESSAGE) location = json.dumps(LOCATION_MESSAGE)
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
state = self.hass.states.get('device_tracker.zanzito') state = hass.states.get('device_tracker.zanzito')
assert state.attributes.get('latitude') == 2.0 assert state.attributes.get('latitude') == 2.0
assert state.attributes.get('longitude') == 1.0 assert state.attributes.get('longitude') == 1.0
def test_single_level_wildcard_topic_not_matching(self):
async def test_single_level_wildcard_topic_not_matching(hass):
"""Test not matching single level wildcard topic.""" """Test not matching single level wildcard topic."""
dev_id = 'zanzito' dev_id = 'zanzito'
entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id)
@ -167,17 +164,18 @@ class TestComponentsDeviceTrackerJSONMQTT(unittest.TestCase):
topic = 'location/zanzito' topic = 'location/zanzito'
location = json.dumps(LOCATION_MESSAGE) location = json.dumps(LOCATION_MESSAGE)
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
assert self.hass.states.get(entity_id) is None assert hass.states.get(entity_id) is None
def test_multi_level_wildcard_topic_not_matching(self):
async def test_multi_level_wildcard_topic_not_matching(hass):
"""Test not matching multi level wildcard topic.""" """Test not matching multi level wildcard topic."""
dev_id = 'zanzito' dev_id = 'zanzito'
entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id)
@ -185,12 +183,12 @@ class TestComponentsDeviceTrackerJSONMQTT(unittest.TestCase):
topic = 'somewhere/zanzito' topic = 'somewhere/zanzito'
location = json.dumps(LOCATION_MESSAGE) location = json.dumps(LOCATION_MESSAGE)
assert setup_component(self.hass, device_tracker.DOMAIN, { assert await async_setup_component(hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt_json', CONF_PLATFORM: 'mqtt_json',
'devices': {dev_id: subscription} 'devices': {dev_id: subscription}
} }
}) })
fire_mqtt_message(self.hass, topic, location) async_fire_mqtt_message(hass, topic, location)
self.hass.block_till_done() await hass.async_block_till_done()
assert self.hass.states.get(entity_id) is None assert hass.states.get(entity_id) is None