hass-core/tests/components/numato/test_init.py
clssn 15b1a9ecea
Add numato integration (#33816)
* 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>
2020-04-30 14:23:30 +02:00

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