* Add support for Numato 32 port USB GPIO boards Included are a binary_sensor, sensor and switch component implementations. The binary_sensor interface pushes updates via registered callback functions, so no need to poll here. Unit tests are included to test against a Numato device mockup. * Refactor numato configuration due to PR finding * Resolve minor review findings * Bump numato-gpio requirement * Load numato platforms during domain setup According to review finding * Guard from platform setup without discovery_info According to review finding * Move numato API state into hass.data According to review finding. * Avoid side effects in numato entity constructors According to review finding * Keep only first line of numato module docstrings Removed reference to the documentation. Requested by reviewer. * Minor improvements inspired by review findings * Fix async tests Pytest fixture was returning from the yield too early executing teardown code during test execution. * Improve test coverage * Configure GPIO ports early Review finding * Move read_gpio callback to outside the loop Also continue on failed switch setup, resolve other minor review findings and correct some error messages * Bump numato-gpio requirement This fixes a crash during cleanup. When any device had a communication problem, its cleanup would raise an exception which was not handled, fell through to the caller and prevented the remaining devices from being cleaned up. * Call services directly Define local helper functions for better readability. Resolves a review finding. * Assert something in every test So not only coverage is satisfied but things are actually tested to be in the expected state. Resolves a review finding. * Clarify scope of notification tests Make unit test for hass NumatoAPI independent of Home Assistant (very basic test of notifications). Improve the regular operations test for notifications. * Test for hass.states after operating switches Resolves a review finding. * Check for wrong port directions * WIP: Split numato tests to multiple files test_hass_binary_sensor_notification still fails. * Remove pytest asyncio decorator Apears to be redundant. Resolves a review finding. * Call switch services directly. Resolves a review finding. * Remove obsolete inline pylint config Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> * Improve the numato_gpio module mockup Resolves a review finding. * Remove needless explicit conversions to str Resolves review findings. * Test setup of binary_sensor callbacks * Fix test_hass_binary_sensor_notification * Add forgotten await Review finding. Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
161 lines
6 KiB
Python
161 lines
6 KiB
Python
"""Tests for the numato integration."""
|
|
from numato_gpio import NumatoGpioError
|
|
import pytest
|
|
|
|
from homeassistant.components import numato
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from .common import NUMATO_CFG, mockup_raise, mockup_return
|
|
|
|
|
|
async def test_setup_no_devices(hass, numato_fixture, monkeypatch):
|
|
"""Test handling of an 'empty' discovery.
|
|
|
|
Platform setups are expected to return after handling errors locally
|
|
without raising.
|
|
"""
|
|
monkeypatch.setattr(numato_fixture, "discover", mockup_return)
|
|
assert await async_setup_component(hass, "numato", NUMATO_CFG)
|
|
assert len(numato_fixture.devices) == 0
|
|
|
|
|
|
async def test_fail_setup_raising_discovery(hass, numato_fixture, caplog, monkeypatch):
|
|
"""Test handling of an exception during discovery.
|
|
|
|
Setup shall return False.
|
|
"""
|
|
monkeypatch.setattr(numato_fixture, "discover", mockup_raise)
|
|
assert not await async_setup_component(hass, "numato", NUMATO_CFG)
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
async def test_hass_numato_api_wrong_port_directions(hass, numato_fixture):
|
|
"""Test handling of wrong port directions.
|
|
|
|
This won't happen in the current platform implementation but would raise
|
|
in case of an introduced bug in the platforms.
|
|
"""
|
|
numato_fixture.discover()
|
|
api = numato.NumatoAPI()
|
|
api.setup_output(0, 5)
|
|
api.setup_input(0, 2)
|
|
api.setup_input(0, 6)
|
|
with pytest.raises(NumatoGpioError):
|
|
api.read_adc_input(0, 5) # adc_read from output
|
|
api.read_input(0, 6) # read from output
|
|
api.write_output(0, 2, 1) # write to input
|
|
|
|
|
|
async def test_hass_numato_api_errors(hass, numato_fixture, monkeypatch):
|
|
"""Test whether Home Assistant numato API (re-)raises errors."""
|
|
numato_fixture.discover()
|
|
monkeypatch.setattr(numato_fixture.devices[0], "setup", mockup_raise)
|
|
monkeypatch.setattr(numato_fixture.devices[0], "adc_read", mockup_raise)
|
|
monkeypatch.setattr(numato_fixture.devices[0], "read", mockup_raise)
|
|
monkeypatch.setattr(numato_fixture.devices[0], "write", mockup_raise)
|
|
api = numato.NumatoAPI()
|
|
with pytest.raises(NumatoGpioError):
|
|
api.setup_input(0, 5)
|
|
api.read_adc_input(0, 1)
|
|
api.read_input(0, 2)
|
|
api.write_output(0, 2, 1)
|
|
|
|
|
|
async def test_invalid_port_number(hass, numato_fixture, config):
|
|
"""Test validation of ADC port number type."""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
port1_config = sensorports_cfg["1"]
|
|
sensorports_cfg["one"] = port1_config
|
|
del sensorports_cfg["1"]
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
await hass.async_block_till_done()
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_too_low_adc_port_number(hass, numato_fixture, config):
|
|
"""Test handling of failing component setup.
|
|
|
|
Tries setting up an ADC on a port below (0) the allowed range.
|
|
"""
|
|
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg.update({0: {"name": "toolow"}})
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_too_high_adc_port_number(hass, numato_fixture, config):
|
|
"""Test handling of failing component setup.
|
|
|
|
Tries setting up an ADC on a port above (8) the allowed range.
|
|
"""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg.update({8: {"name": "toohigh"}})
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_invalid_adc_range_value_type(hass, numato_fixture, config):
|
|
"""Test validation of ADC range config's types.
|
|
|
|
Replaces the source range beginning by a string.
|
|
"""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg["1"]["source_range"][0] = "zero"
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_invalid_adc_source_range_length(hass, numato_fixture, config):
|
|
"""Test validation of ADC range config's length.
|
|
|
|
Adds an element to the source range.
|
|
"""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg["1"]["source_range"].append(42)
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_invalid_adc_source_range_order(hass, numato_fixture, config):
|
|
"""Test validation of ADC range config's order.
|
|
|
|
Sets the source range to a decreasing [2, 1].
|
|
"""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg["1"]["source_range"] = [2, 1]
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_invalid_adc_destination_range_value_type(hass, numato_fixture, config):
|
|
"""Test validation of ADC range .
|
|
|
|
Replaces the destination range beginning by a string.
|
|
"""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg["1"]["destination_range"][0] = "zero"
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_invalid_adc_destination_range_length(hass, numato_fixture, config):
|
|
"""Test validation of ADC range config's length.
|
|
|
|
Adds an element to the destination range.
|
|
"""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg["1"]["destination_range"].append(42)
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|
|
|
|
|
|
async def test_invalid_adc_destination_range_order(hass, numato_fixture, config):
|
|
"""Test validation of ADC range config's order.
|
|
|
|
Sets the destination range to a decreasing [2, 1].
|
|
"""
|
|
sensorports_cfg = config["numato"]["devices"][0]["sensors"]["ports"]
|
|
sensorports_cfg["1"]["destination_range"] = [2, 1]
|
|
assert not await async_setup_component(hass, "numato", config)
|
|
assert not numato_fixture.devices
|