Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions tests/components/shelly/test_binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
MODEL_MOTION,
MODEL_PLUS_SMOKE,
)
from aioshelly.exceptions import DeviceConnectionError
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
Expand Down Expand Up @@ -332,6 +333,7 @@ async def test_rpc_sleeping_binary_sensor(
) -> None:
"""Test RPC online sleeping binary sensor."""
entity_id = f"{BINARY_SENSOR_DOMAIN}.test_name_cloud"
mock_rpc_device.initialize.side_effect = DeviceConnectionError

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect and changes the role of this test

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this test failing is thus a bug in the integration itself and requires a seperate PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the core issue is a race condition in

The tests are using await init_integration with sleep_period=xyz, and changing them to use sleep_period=None fixes most of the issues.

However, this most likely highlights a deeper issue in the integration that should be investigated by the code owners.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will take a look, the problem is that I don't have an environment to reproduce it, if we change the tests so they pass but they don't really validate what they need to than we better disable them with a note that they need to be fixed.

I suggest to finish #169293 first and get back to this one

monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
config_entry = await init_integration(hass, 2, sleep_period=1000)
Expand All @@ -344,6 +346,7 @@ async def test_rpc_sleeping_binary_sensor(
)

# Make device online
mock_rpc_device.initialize.side_effect = None
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down Expand Up @@ -373,6 +376,7 @@ async def test_rpc_sleeping_binary_sensor_with_channel_name(
) -> None:
"""Test RPC online sleeping binary sensor with channel name."""
entity_id = f"{BINARY_SENSOR_DOMAIN}.test_name_test_channel_name_smoke"
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
await init_integration(hass, 2, sleep_period=1000, model=MODEL_PLUS_SMOKE)
Expand All @@ -381,6 +385,7 @@ async def test_rpc_sleeping_binary_sensor_with_channel_name(
assert hass.states.get(entity_id) is None

# Make device online
mock_rpc_device.initialize.side_effect = None
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down
2 changes: 2 additions & 0 deletions tests/components/shelly/test_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,13 +493,15 @@ async def test_rpc_smoke_mute_alarm_button(
entity_id = f"{BUTTON_DOMAIN}.test_name_mute_alarm"
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
monkeypatch.setattr(mock_rpc_device, "config", {"smoke:0": {"id": 0, "name": None}})
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
await init_integration(hass, 2, sleep_period=1000, model=MODEL_PLUS_SMOKE)

# Sensor should be created when device is online
assert hass.states.get(entity_id) is None

# Make device online
mock_rpc_device.initialize.side_effect = None
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down
4 changes: 4 additions & 0 deletions tests/components/shelly/test_climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ async def test_block_set_mode_connection_error(
hass: HomeAssistant, mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test block device set mode connection error."""
monkeypatch.delattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "targetTemp")
monkeypatch.delattr(mock_block_device.blocks[GAS_VALVE_BLOCK_ID], "targetTemp")
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
monkeypatch.setattr(
mock_block_device,
Expand Down Expand Up @@ -507,6 +509,8 @@ async def test_block_set_mode_auth_error(
hass: HomeAssistant, mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test block device set mode authentication error."""
monkeypatch.delattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "targetTemp")
monkeypatch.delattr(mock_block_device.blocks[GAS_VALVE_BLOCK_ID], "targetTemp")
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
monkeypatch.setattr(
mock_block_device,
Expand Down
18 changes: 12 additions & 6 deletions tests/components/shelly/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2747,6 +2747,7 @@ async def test_zeroconf_sleeping_device_not_triggers_refresh(
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test zeroconf discovery does not triggers refresh for sleeping device."""
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
entry = MockConfigEntry(
Expand All @@ -2763,6 +2764,8 @@ async def test_zeroconf_sleeping_device_not_triggers_refresh(
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

mock_rpc_device.initialize.side_effect = None
mock_rpc_device.initialize.reset_mock()
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down Expand Up @@ -2799,6 +2802,7 @@ async def test_zeroconf_sleeping_device_attempts_configure(
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test zeroconf discovery configures a sleeping device outbound websocket."""
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setattr(mock_rpc_device, "initialized", False)
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
Expand All @@ -2815,9 +2819,9 @@ async def test_zeroconf_sleeping_device_attempts_configure(
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
mock_rpc_device.mock_disconnected()
await hass.async_block_till_done()

mock_rpc_device.initialize.side_effect = None
mock_rpc_device.initialize.reset_mock()
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down Expand Up @@ -2862,6 +2866,7 @@ async def test_zeroconf_sleeping_device_attempts_configure_ws_disabled(
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test zeroconf discovery configures a sleeping device outbound websocket when its disabled."""
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setattr(mock_rpc_device, "initialized", False)
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
Expand All @@ -2881,9 +2886,9 @@ async def test_zeroconf_sleeping_device_attempts_configure_ws_disabled(
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
mock_rpc_device.mock_disconnected()
await hass.async_block_till_done()

mock_rpc_device.initialize.side_effect = None
mock_rpc_device.initialize.reset_mock()
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down Expand Up @@ -2931,6 +2936,7 @@ async def test_zeroconf_sleeping_device_attempts_configure_no_url_available(
hass.config.internal_url = None
hass.config.external_url = None
hass.config.api = None
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setattr(mock_rpc_device, "initialized", False)
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
Expand All @@ -2947,9 +2953,9 @@ async def test_zeroconf_sleeping_device_attempts_configure_no_url_available(
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
mock_rpc_device.mock_disconnected()
await hass.async_block_till_done()

mock_rpc_device.initialize.side_effect = None
mock_rpc_device.initialize.reset_mock()
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down
7 changes: 2 additions & 5 deletions tests/components/shelly/test_coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1097,17 +1097,14 @@ async def test_rpc_sleeping_device_late_setup(
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
assert entry.data[CONF_SLEEP_PERIOD] == 1000
register_device(device_registry, entry)
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setattr(mock_rpc_device, "initialized", False)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

monkeypatch.setattr(mock_rpc_device, "initialized", True)
mock_rpc_device.initialize.side_effect = None
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)
monkeypatch.setattr(mock_rpc_device, "connected", True)
mock_rpc_device.mock_initialized()
await hass.async_block_till_done(wait_background_tasks=True)

assert hass.states.get("sensor.test_name_temperature")

Expand Down
6 changes: 5 additions & 1 deletion tests/components/shelly/test_device_trigger.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""The tests for Shelly device triggers."""

from unittest.mock import Mock
from unittest.mock import AsyncMock, Mock

from aioshelly.const import MODEL_BUTTON1
import pytest
Expand Down Expand Up @@ -402,6 +402,10 @@ async def test_rpc_no_runtime_data(
) -> None:
"""Test the device trigger for the RPC device when there is no runtime_data in the entry."""
entry = await init_integration(hass, 2)
monkeypatch.setattr(
"homeassistant.components.shelly.async_unload_entry",
AsyncMock(return_value=True),
)
monkeypatch.delattr(entry, "runtime_data")
device = dr.async_entries_for_config_entry(device_registry, entry.entry_id)[0]

Expand Down
2 changes: 2 additions & 0 deletions tests/components/shelly/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ async def test_rpc_sleeping_update(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Test RPC sleeping device update entity."""
mock_rpc_device.initialize.side_effect = DeviceConnectionError
monkeypatch.setattr(mock_rpc_device, "connected", False)
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
monkeypatch.setitem(mock_rpc_device.shelly, "ver", "1")
Expand All @@ -426,6 +427,7 @@ async def test_rpc_sleeping_update(
assert hass.states.get(entity_id) is None

# Make device online
mock_rpc_device.initialize.side_effect = None
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)

Expand Down
Loading