Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions homeassistant/components/hassio/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"issue_system_disk_lifetime",
ISSUE_KEY_SYSTEM_FREE_SPACE,
ISSUE_KEY_ADDON_PWNED,
"issue_system_ntp_sync_failed",
}

_LOGGER = logging.getLogger(__name__)
Expand Down
13 changes: 13 additions & 0 deletions homeassistant/components/hassio/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@
},
"title": "Multiple data disks detected"
},
"issue_system_ntp_sync_failed": {
"fix_flow": {
"abort": {
"apply_suggestion_fail": "Could not re-enable NTP. Check the Supervisor logs for more details."
},
"step": {
"system_enable_ntp": {
"description": "NTP time servers were unreachable and the system clock was found to be more than 1 hour off. The time has been corrected and the NTP service was temporarily disabled to allow this adjustment.\n\nCheck the **Host logs** to investigate why NTP servers could not be reached. Once resolved, select **Submit** to re-enable the NTP service."
Comment thread
sairon marked this conversation as resolved.
Outdated
}
}
},
"title": "NTP sync failed - system time was corrected"
Comment thread
sairon marked this conversation as resolved.
Outdated
},
"issue_system_reboot_required": {
"fix_flow": {
"abort": {
Expand Down
55 changes: 55 additions & 0 deletions tests/components/hassio/test_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,61 @@ async def test_supervisor_issues_detached_addon_missing(
)


@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issues_ntp_sync_failed(
hass: HomeAssistant,
supervisor_client: AsyncMock,
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test supervisor issue for NTP sync failed."""
mock_resolution_info(supervisor_client)

result = await async_setup_component(hass, "hassio", {})
assert result

client = await hass_ws_client(hass)

await client.send_json(
{
"id": 1,
"type": "supervisor/event",
"data": {
"event": "issue_changed",
"data": {
"uuid": (issue_uuid := uuid4().hex),
"type": "ntp_sync_failed",
"context": "system",
"reference": None,
"suggestions": [
{
"uuid": uuid4().hex,
"type": "enable_ntp",
"context": "system",
"reference": None,
}
],
},
},
}
)
msg = await client.receive_json()
assert msg["success"]
await hass.async_block_till_done()

await client.send_json({"id": 2, "type": "repairs/list_issues"})
msg = await client.receive_json()
assert msg["success"]
assert len(msg["result"]["issues"]) == 1
assert_issue_repair_in_list(
msg["result"]["issues"],
uuid=issue_uuid,
context="system",
type_="ntp_sync_failed",
fixable=True,
placeholders=None,
)


@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issues_disk_lifetime(
hass: HomeAssistant,
Expand Down
146 changes: 146 additions & 0 deletions tests/components/hassio/test_repairs.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,152 @@ async def test_supervisor_issue_repair_flow_skip_confirmation(
supervisor_client.resolution.apply_suggestion.assert_called_once_with(sugg_uuid)


@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issue_ntp_sync_failed_repair_flow(
hass: HomeAssistant,
supervisor_client: AsyncMock,
hass_client: ClientSessionGenerator,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test fix flow for NTP sync failed supervisor issue."""
mock_resolution_info(
supervisor_client,
issues=[
Issue(
type=IssueType.NTP_SYNC_FAILED,
context=ContextType.SYSTEM,
reference=None,
uuid=(issue_uuid := uuid4()),
),
],
suggestions_by_issue={
issue_uuid: [
Suggestion(
type=SuggestionType.ENABLE_NTP,
context=ContextType.SYSTEM,
reference=None,
uuid=(sugg_uuid := uuid4()),
auto=False,
),
]
},
)

assert await async_setup_component(hass, "hassio", {})

repair_issue = issue_registry.async_get_issue(
domain="hassio", issue_id=issue_uuid.hex
)
assert repair_issue

client = await hass_client()

resp = await client.post(
"/api/repairs/issues/fix",
json={"handler": "hassio", "issue_id": repair_issue.issue_id},
)

assert resp.status == HTTPStatus.OK
data = await resp.json()

flow_id = data["flow_id"]
assert data == {
"type": "form",
"flow_id": flow_id,
"handler": "hassio",
"step_id": "system_enable_ntp",
"data_schema": [],
"errors": None,
"description_placeholders": None,
"last_step": True,
"preview": None,
}

resp = await client.post(f"/api/repairs/issues/fix/{flow_id}")

assert resp.status == HTTPStatus.OK
data = await resp.json()

flow_id = data["flow_id"]
assert data == {
"type": "create_entry",
"flow_id": flow_id,
"handler": "hassio",
"description": None,
"description_placeholders": None,
}

assert not issue_registry.async_get_issue(domain="hassio", issue_id=issue_uuid.hex)
supervisor_client.resolution.apply_suggestion.assert_called_once_with(sugg_uuid)


@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issue_ntp_sync_failed_repair_flow_error(
hass: HomeAssistant,
supervisor_client: AsyncMock,
hass_client: ClientSessionGenerator,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test fix flow aborts when NTP re-enable fails."""
mock_resolution_info(
supervisor_client,
issues=[
Issue(
type=IssueType.NTP_SYNC_FAILED,
context=ContextType.SYSTEM,
reference=None,
uuid=(issue_uuid := uuid4()),
),
],
suggestions_by_issue={
issue_uuid: [
Suggestion(
type=SuggestionType.ENABLE_NTP,
context=ContextType.SYSTEM,
reference=None,
uuid=uuid4(),
auto=False,
),
]
},
suggestion_result=SupervisorError("boom"),
)

assert await async_setup_component(hass, "hassio", {})

repair_issue = issue_registry.async_get_issue(
domain="hassio", issue_id=issue_uuid.hex
)
assert repair_issue

client = await hass_client()

resp = await client.post(
"/api/repairs/issues/fix",
json={"handler": "hassio", "issue_id": repair_issue.issue_id},
)

assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data["flow_id"]

resp = await client.post(f"/api/repairs/issues/fix/{flow_id}")

assert resp.status == HTTPStatus.OK
data = await resp.json()

flow_id = data["flow_id"]
assert data == {
"type": "abort",
"flow_id": flow_id,
"handler": "hassio",
"reason": "apply_suggestion_fail",
"description_placeholders": None,
}

assert issue_registry.async_get_issue(domain="hassio", issue_id=issue_uuid.hex)


@pytest.mark.usefixtures("all_setup_requests")
async def test_mount_failed_repair_flow_error(
hass: HomeAssistant,
Expand Down
Loading