1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2026-06-04 14:03:06 +01:00
Files
supervisor/tests/dbus/network/test_settings.py
T
Stefan Agner 9088810b49 Improve D-Bus error handling for NetworkManager (#4720)
* Improve D-Bus error handling for NetworkManager

There are quite some errors captured which are related by seemingly a
suddenly missing NetworkManager. Errors appear as:
23-11-21 17:42:50 ERROR (MainThread) [supervisor.dbus.network] Error while processing /org/freedesktop/NetworkManager/Devices/10: Remote peer disconnected
...
23-11-21 17:42:50 ERROR (MainThread) [supervisor.dbus.network] Error while processing /org/freedesktop/NetworkManager/Devices/35: The name is not activatable

Both errors seem to already happen at introspection time, however
the current code doesn't converts these errors to Supervisor issues.
This PR uses the already existing `DBus.from_dbus_error()`.

Furthermore this adds a new Exception `DBusNoReplyError` for the
`ErrorType.NO_REPLY` (or `org.freedesktop.DBus.Error.NoReply` in
D-Bus terms, which is the type of the first of the two issues above).

And finally it separates the `ErrorType.SERVICE_UNKNOWN` (or
`org.freedesktop.DBus.Error.ServiceUnknown` in D-Bus terms, which is
the second of the above issue) from `DBusInterfaceError` into a new
`DBusServiceUnkownError`.

This allows to handle errors more specifically.

To avoid too much churn, all instances where `DBusInterfaceError`
got handled, we are now also handling `DBusServiceUnkownError`.

The `DBusNoReplyError` and `DBusServiceUnkownError` appear when
the NetworkManager service stops or crashes. Instead of retrying
every interface we know, just give up if one of these issues appear.
This should significantly lower error messages users are seeing
and Sentry events.

* Remove unnecessary statement

* Fix pytests

* Make sure error strings are compared correctly

* Fix typo/remove unnecessary pylint exception

* Fix DBusError typing

* Add pytest for from_dbus_error

* Revert "Make sure error strings are compared correctly"

This reverts commit 10dc2e4c3887532921414b4291fe3987186db408.

* Add test cases

---------

Co-authored-by: Mike Degatano <michael.degatano@gmail.com>
2023-11-27 23:32:11 +01:00

67 lines
2.3 KiB
Python

"""Test Network Manager Connection Settings Profile Manager."""
from dbus_fast.aio.message_bus import MessageBus
import pytest
from supervisor.dbus.network.settings import NetworkManagerSettings
from supervisor.exceptions import DBusNotConnectedError
from tests.common import mock_dbus_services
from tests.dbus_service_mocks.network_connection_settings import SETTINGS_FIXTURE
from tests.dbus_service_mocks.network_settings import Settings as SettingsService
@pytest.fixture(name="settings_service")
async def fixture_settings_service(dbus_session_bus: MessageBus) -> SettingsService:
"""Mock Settings service."""
yield (
await mock_dbus_services(
{"network_settings": None, "network_connection_settings": None},
dbus_session_bus,
)
)["network_settings"]
async def test_add_connection(
settings_service: SettingsService, dbus_session_bus: MessageBus
):
"""Test adding settings connection."""
settings_service.AddConnection.calls.clear()
settings = NetworkManagerSettings()
with pytest.raises(DBusNotConnectedError):
await settings.add_connection(SETTINGS_FIXTURE)
await settings.connect(dbus_session_bus)
connection_settings = await settings.add_connection(SETTINGS_FIXTURE)
assert connection_settings.connection.uuid == "0c23631e-2118-355c-bbb0-8943229cb0d6"
assert connection_settings.ipv4.method == "auto"
assert settings_service.AddConnection.calls == [(SETTINGS_FIXTURE,)]
async def test_reload_connections(
settings_service: SettingsService, dbus_session_bus: MessageBus
):
"""Test reload connections."""
settings_service.ReloadConnections.calls.clear()
settings = NetworkManagerSettings()
with pytest.raises(DBusNotConnectedError):
await settings.reload_connections()
await settings.connect(dbus_session_bus)
assert await settings.reload_connections() is True
assert settings_service.ReloadConnections.calls == [tuple()]
async def test_dbus_network_settings_connect_error(
dbus_session_bus: MessageBus, caplog: pytest.LogCaptureFixture
):
"""Test connecting to network settings error."""
settings = NetworkManagerSettings()
await settings.connect(dbus_session_bus)
assert "No Network Manager Settings support on the host" in caplog.text