From f91d214ba4337874c598d6a0b7a2645d9ce146c0 Mon Sep 17 00:00:00 2001 From: jan iversen Date: Mon, 23 Aug 2021 23:55:57 +0200 Subject: [PATCH] Break out mock of pymodbus return from mock_modbus to new fixture (#55063) * Remove unused mock_modbus. * Break out mock pymodbus return values. * Review comments. --- tests/components/modbus/conftest.py | 43 +++++++++++++------ tests/components/modbus/test_binary_sensor.py | 12 ++++-- tests/components/modbus/test_climate.py | 2 +- tests/components/modbus/test_cover.py | 4 +- tests/components/modbus/test_fan.py | 13 ++++-- tests/components/modbus/test_light.py | 13 ++++-- tests/components/modbus/test_sensor.py | 35 ++++++++++++--- tests/components/modbus/test_switch.py | 13 ++++-- 8 files changed, 98 insertions(+), 37 deletions(-) diff --git a/tests/components/modbus/conftest.py b/tests/components/modbus/conftest.py index 33ecf909a6f..7942a8193b3 100644 --- a/tests/components/modbus/conftest.py +++ b/tests/components/modbus/conftest.py @@ -67,6 +67,12 @@ def config_addon(): return None +@pytest.fixture +def do_exception(): + """Remove side_effect to pymodbus calls.""" + return False + + @pytest.fixture async def mock_modbus( hass, caplog, register_words, check_config_loaded, config_addon, do_config @@ -92,18 +98,6 @@ async def mock_modbus( with mock.patch( "homeassistant.components.modbus.modbus.ModbusTcpClient", return_value=mock_pb ): - if register_words is None: - exc = ModbusException("fail read_coils") - mock_pb.read_coils.side_effect = exc - mock_pb.read_discrete_inputs.side_effect = exc - mock_pb.read_input_registers.side_effect = exc - mock_pb.read_holding_registers.side_effect = exc - else: - read_result = ReadResult(register_words) - mock_pb.read_coils.return_value = read_result - mock_pb.read_discrete_inputs.return_value = read_result - mock_pb.read_input_registers.return_value = read_result - mock_pb.read_holding_registers.return_value = read_result now = dt_util.utcnow() with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now): result = await async_setup_component(hass, DOMAIN, config) @@ -113,7 +107,28 @@ async def mock_modbus( @pytest.fixture -async def mock_do_cycle(hass): +async def mock_pymodbus_exception(hass, do_exception, mock_modbus): + """Trigger update call with time_changed event.""" + if do_exception: + exc = ModbusException("fail read_coils") + mock_modbus.read_coils.side_effect = exc + mock_modbus.read_discrete_inputs.side_effect = exc + mock_modbus.read_input_registers.side_effect = exc + mock_modbus.read_holding_registers.side_effect = exc + + +@pytest.fixture +async def mock_pymodbus_return(hass, register_words, mock_modbus): + """Trigger update call with time_changed event.""" + read_result = ReadResult(register_words) + mock_modbus.read_coils.return_value = read_result + mock_modbus.read_discrete_inputs.return_value = read_result + mock_modbus.read_input_registers.return_value = read_result + mock_modbus.read_holding_registers.return_value = read_result + + +@pytest.fixture +async def mock_do_cycle(hass, mock_pymodbus_exception, mock_pymodbus_return): """Trigger update call with time_changed event.""" now = dt_util.utcnow() + timedelta(seconds=90) with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now): @@ -129,7 +144,7 @@ async def mock_test_state(hass, request): @pytest.fixture -async def mock_ha(hass): +async def mock_ha(hass, mock_pymodbus_return): """Load homeassistant to allow service calls.""" assert await async_setup_component(hass, "homeassistant", {}) await hass.async_block_till_done() diff --git a/tests/components/modbus/test_binary_sensor.py b/tests/components/modbus/test_binary_sensor.py index a4442eb3609..5de03287592 100644 --- a/tests/components/modbus/test_binary_sensor.py +++ b/tests/components/modbus/test_binary_sensor.py @@ -80,35 +80,41 @@ async def test_config_binary_sensor(hass, mock_modbus): ], ) @pytest.mark.parametrize( - "register_words,expected", + "register_words,do_exception,expected", [ ( [0xFF], + False, STATE_ON, ), ( [0x01], + False, STATE_ON, ), ( [0x00], + False, STATE_OFF, ), ( [0x80], + False, STATE_OFF, ), ( [0xFE], + False, STATE_OFF, ), ( - None, + [0x00], + True, STATE_UNAVAILABLE, ), ], ) -async def test_all_binary_sensor(hass, expected, mock_modbus, mock_do_cycle): +async def test_all_binary_sensor(hass, expected, mock_do_cycle): """Run test for given config.""" assert hass.states.get(ENTITY_ID).state == expected diff --git a/tests/components/modbus/test_climate.py b/tests/components/modbus/test_climate.py index f3d50317782..187c049b069 100644 --- a/tests/components/modbus/test_climate.py +++ b/tests/components/modbus/test_climate.py @@ -86,7 +86,7 @@ async def test_config_climate(hass, mock_modbus): ), ], ) -async def test_temperature_climate(hass, expected, mock_modbus, mock_do_cycle): +async def test_temperature_climate(hass, expected, mock_do_cycle): """Run test for given config.""" assert hass.states.get(ENTITY_ID).state == expected diff --git a/tests/components/modbus/test_cover.py b/tests/components/modbus/test_cover.py index 0b639bc0858..9c5b08d59b6 100644 --- a/tests/components/modbus/test_cover.py +++ b/tests/components/modbus/test_cover.py @@ -106,7 +106,7 @@ async def test_config_cover(hass, mock_modbus): ), ], ) -async def test_coil_cover(hass, expected, mock_modbus, mock_do_cycle): +async def test_coil_cover(hass, expected, mock_do_cycle): """Run test for given config.""" assert hass.states.get(ENTITY_ID).state == expected @@ -150,7 +150,7 @@ async def test_coil_cover(hass, expected, mock_modbus, mock_do_cycle): ), ], ) -async def test_register_cover(hass, expected, mock_modbus, mock_do_cycle): +async def test_register_cover(hass, expected, mock_do_cycle): """Run test for given config.""" assert hass.states.get(ENTITY_ID).state == expected diff --git a/tests/components/modbus/test_fan.py b/tests/components/modbus/test_fan.py index 77cb650a184..b2793d15bff 100644 --- a/tests/components/modbus/test_fan.py +++ b/tests/components/modbus/test_fan.py @@ -157,36 +157,41 @@ async def test_config_fan(hass, mock_modbus): ], ) @pytest.mark.parametrize( - "register_words,config_addon,expected", + "register_words,do_exception,config_addon,expected", [ ( [0x00], + False, {CONF_VERIFY: {}}, STATE_OFF, ), ( [0x01], + False, {CONF_VERIFY: {}}, STATE_ON, ), ( [0xFE], + False, {CONF_VERIFY: {}}, STATE_OFF, ), ( - None, + [0x00], + True, {CONF_VERIFY: {}}, STATE_UNAVAILABLE, ), ( - None, + [0x00], + True, None, STATE_OFF, ), ], ) -async def test_all_fan(hass, mock_modbus, mock_do_cycle, expected): +async def test_all_fan(hass, mock_do_cycle, expected): """Run test for given config.""" assert hass.states.get(ENTITY_ID).state == expected diff --git a/tests/components/modbus/test_light.py b/tests/components/modbus/test_light.py index 4d277d0267f..65d42dff987 100644 --- a/tests/components/modbus/test_light.py +++ b/tests/components/modbus/test_light.py @@ -157,36 +157,41 @@ async def test_config_light(hass, mock_modbus): ], ) @pytest.mark.parametrize( - "register_words,config_addon,expected", + "register_words,do_exception,config_addon,expected", [ ( [0x00], + False, {CONF_VERIFY: {}}, STATE_OFF, ), ( [0x01], + False, {CONF_VERIFY: {}}, STATE_ON, ), ( [0xFE], + False, {CONF_VERIFY: {}}, STATE_OFF, ), ( - None, + [0x00], + True, {CONF_VERIFY: {}}, STATE_UNAVAILABLE, ), ( - None, + [0x00], + True, None, STATE_OFF, ), ], ) -async def test_all_light(hass, mock_modbus, mock_do_cycle, expected): +async def test_all_light(hass, mock_do_cycle, expected): """Run test for given config.""" assert hass.states.get(ENTITY_ID).state == expected diff --git a/tests/components/modbus/test_sensor.py b/tests/components/modbus/test_sensor.py index 8de22f88eb6..a52f833be1c 100644 --- a/tests/components/modbus/test_sensor.py +++ b/tests/components/modbus/test_sensor.py @@ -247,7 +247,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl ], ) @pytest.mark.parametrize( - "config_addon,register_words,expected", + "config_addon,register_words,do_exception,expected", [ ( { @@ -258,11 +258,13 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0], + False, "0", ), ( {}, [0x8000], + False, "-32768", ), ( @@ -274,6 +276,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [7], + False, "20", ), ( @@ -285,6 +288,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [7], + False, "34", ), ( @@ -296,6 +300,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 4, }, [7], + False, "34.0000", ), ( @@ -307,6 +312,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [1], + False, "2", ), ( @@ -318,6 +324,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: "1", }, [9], + False, "18.5", ), ( @@ -329,6 +336,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 2, }, [1], + False, "2.40", ), ( @@ -340,6 +348,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 1, }, [2], + False, "-8.3", ), ( @@ -351,6 +360,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x89AB, 0xCDEF], + False, "-1985229329", ), ( @@ -362,6 +372,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x89AB, 0xCDEF], + False, str(0x89ABCDEF), ), ( @@ -373,6 +384,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x89AB, 0xCDEF, 0x0123, 0x4567], + False, "9920249030613615975", ), ( @@ -384,6 +396,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x0123, 0x4567, 0x89AB, 0xCDEF], + False, "163971058432973793", ), ( @@ -395,6 +408,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x0123, 0x4567, 0x89AB, 0xCDEF], + False, "163971058432973792", ), ( @@ -407,6 +421,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x89AB, 0xCDEF], + False, str(0x89ABCDEF), ), ( @@ -419,6 +434,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x89AB, 0xCDEF], + False, str(0x89ABCDEF), ), ( @@ -431,6 +447,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 5, }, [16286, 1617], + False, "1.23457", ), ( @@ -443,6 +460,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_PRECISION: 0, }, [0x3037, 0x2D30, 0x352D, 0x3230, 0x3230, 0x2031, 0x343A, 0x3335], + False, "07-05-2020 14:35", ), ( @@ -454,7 +472,8 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_OFFSET: 0, CONF_PRECISION: 0, }, - None, + [0x00], + True, STATE_UNAVAILABLE, ), ( @@ -466,7 +485,8 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_OFFSET: 0, CONF_PRECISION: 0, }, - None, + [0x00], + True, STATE_UNAVAILABLE, ), ( @@ -476,6 +496,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_SWAP: CONF_SWAP_NONE, }, [0x0102], + False, str(int(0x0102)), ), ( @@ -485,6 +506,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_SWAP: CONF_SWAP_BYTE, }, [0x0201], + False, str(int(0x0102)), ), ( @@ -494,6 +516,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_SWAP: CONF_SWAP_BYTE, }, [0x0102, 0x0304], + False, str(int(0x02010403)), ), ( @@ -503,6 +526,7 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_SWAP: CONF_SWAP_WORD, }, [0x0102, 0x0304], + False, str(int(0x03040102)), ), ( @@ -512,11 +536,12 @@ async def test_config_wrong_struct_sensor(hass, error_message, mock_modbus, capl CONF_SWAP: CONF_SWAP_WORD_BYTE, }, [0x0102, 0x0304], + False, str(int(0x04030201)), ), ], ) -async def test_all_sensor(hass, mock_modbus, mock_do_cycle, expected): +async def test_all_sensor(hass, mock_do_cycle, expected): """Run test for sensor.""" assert hass.states.get(ENTITY_ID).state == expected @@ -570,7 +595,7 @@ async def test_all_sensor(hass, mock_modbus, mock_do_cycle, expected): ), ], ) -async def test_struct_sensor(hass, mock_modbus, mock_do_cycle, expected): +async def test_struct_sensor(hass, mock_do_cycle, expected): """Run test for sensor struct.""" assert hass.states.get(ENTITY_ID).state == expected diff --git a/tests/components/modbus/test_switch.py b/tests/components/modbus/test_switch.py index 53907fe18e5..c14a7169ae0 100644 --- a/tests/components/modbus/test_switch.py +++ b/tests/components/modbus/test_switch.py @@ -171,36 +171,41 @@ async def test_config_switch(hass, mock_modbus): ], ) @pytest.mark.parametrize( - "register_words,config_addon,expected", + "register_words,do_exception,config_addon,expected", [ ( [0x00], + False, {CONF_VERIFY: {}}, STATE_OFF, ), ( [0x01], + False, {CONF_VERIFY: {}}, STATE_ON, ), ( [0xFE], + False, {CONF_VERIFY: {}}, STATE_OFF, ), ( - None, + [0x00], + True, {CONF_VERIFY: {}}, STATE_UNAVAILABLE, ), ( - None, + [0x00], + True, None, STATE_OFF, ), ], ) -async def test_all_switch(hass, mock_modbus, mock_do_cycle, expected): +async def test_all_switch(hass, mock_do_cycle, expected): """Run test for given config.""" assert hass.states.get(ENTITY_ID).state == expected