mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-08-21 21:57:26 +01:00
Per review: the generic wrapper existed for a time when suggestions were only applied by autofix and the one job was separating fixup failures from real bugs for Sentry. The suggestion API is in regular use now and the wrapper actively hurts it — well-defined errors from the underlying operations were caught and replaced with a generic message. Remove the exception type entirely and let the original errors reach the caller. The autofix loop and the bus-event fixup path treat any HassioError as an environmental/config failure: log and continue without Sentry capture (the raise site reports to Sentry where warranted); everything else is still captured. Direct raises in the data disk fixups become HassOSDataDiskError, the could-not-start check in the app start fixup becomes AppsError. ResolutionFixupJobError now derives from ResolutionError and JobException. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
110 lines
3.3 KiB
Python
110 lines
3.3 KiB
Python
"""Test fixup mount reload."""
|
|
|
|
import errno
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from supervisor.coresys import CoreSys
|
|
from supervisor.exceptions import MountActivationError
|
|
from supervisor.mounts.mount import Mount
|
|
from supervisor.resolution.const import ContextType, IssueType, SuggestionType
|
|
from supervisor.resolution.data import Issue
|
|
from supervisor.resolution.fixups.mount_execute_reload import FixupMountExecuteReload
|
|
|
|
from tests.dbus_service_mocks.base import DBusServiceMock
|
|
from tests.dbus_service_mocks.systemd import Systemd as SystemdService
|
|
|
|
|
|
async def test_fixup(
|
|
coresys: CoreSys,
|
|
all_dbus_services: dict[str, DBusServiceMock],
|
|
path_extern,
|
|
mount_propagation,
|
|
mock_is_mount,
|
|
):
|
|
"""Test fixup."""
|
|
systemd_service: SystemdService = all_dbus_services["systemd"]
|
|
systemd_service.ReloadOrRestartUnit.calls.clear()
|
|
|
|
mount_execute_reload = FixupMountExecuteReload(coresys)
|
|
|
|
assert mount_execute_reload.auto is False
|
|
|
|
await coresys.mounts.create_mount(
|
|
Mount.from_dict(
|
|
coresys,
|
|
{
|
|
"name": "test",
|
|
"usage": "backup",
|
|
"type": "cifs",
|
|
"server": "test.local",
|
|
"share": "test",
|
|
},
|
|
)
|
|
)
|
|
|
|
coresys.resolution.create_issue(
|
|
IssueType.MOUNT_FAILED,
|
|
ContextType.MOUNT,
|
|
reference="test",
|
|
suggestions=[SuggestionType.EXECUTE_RELOAD, SuggestionType.EXECUTE_REMOVE],
|
|
)
|
|
await mount_execute_reload()
|
|
|
|
assert coresys.resolution.issues == []
|
|
assert coresys.resolution.suggestions == []
|
|
assert "test" in coresys.mounts
|
|
# Mount is reachable (probe passes via mock_is_mount); the fixup
|
|
# clears the issue without needing to touch systemd. A user invoking
|
|
# the fixup on a still-broken mount would fail the probe, exercising
|
|
# the reload->restart path covered by test_fixup_error_after_reload.
|
|
assert systemd_service.ReloadOrRestartUnit.calls == []
|
|
|
|
|
|
async def test_fixup_error_after_reload(
|
|
coresys: CoreSys,
|
|
all_dbus_services: dict[str, DBusServiceMock],
|
|
mock_is_mount: MagicMock,
|
|
path_extern,
|
|
mount_propagation,
|
|
):
|
|
"""Test fixup."""
|
|
mount_execute_reload = FixupMountExecuteReload(coresys)
|
|
await coresys.mounts.create_mount(
|
|
Mount.from_dict(
|
|
coresys,
|
|
{
|
|
"name": "test",
|
|
"usage": "backup",
|
|
"type": "cifs",
|
|
"server": "test.local",
|
|
"share": "test",
|
|
},
|
|
)
|
|
)
|
|
|
|
coresys.resolution.create_issue(
|
|
IssueType.MOUNT_FAILED,
|
|
ContextType.MOUNT,
|
|
reference="test",
|
|
suggestions=[SuggestionType.EXECUTE_RELOAD, SuggestionType.EXECUTE_REMOVE],
|
|
)
|
|
# Probe (statvfs) fails — the mount stays unreachable through the
|
|
# reload -> restart cycle. The MountActivationError propagates to
|
|
# the caller so the issue cleanup is skipped.
|
|
with (
|
|
patch(
|
|
"supervisor.mounts.mount._probe_network_mount",
|
|
side_effect=OSError(errno.EHOSTDOWN, "Host is down"),
|
|
),
|
|
pytest.raises(MountActivationError),
|
|
):
|
|
await mount_execute_reload()
|
|
|
|
# Probe never succeeds, issue remains.
|
|
assert (
|
|
Issue(IssueType.MOUNT_FAILED, ContextType.MOUNT, reference="test")
|
|
in coresys.resolution.issues
|
|
)
|