mirror of
https://github.com/home-assistant/core.git
synced 2026-03-14 06:52:04 +01:00
Compare commits
1 Commits
python-3.1
...
hassio-ntp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
351ac662c5 |
2
.github/workflows/builder.yml
vendored
2
.github/workflows/builder.yml
vendored
@@ -14,7 +14,7 @@ env:
|
||||
UV_HTTP_TIMEOUT: 60
|
||||
UV_SYSTEM_PYTHON: "true"
|
||||
# Base image version from https://github.com/home-assistant/docker
|
||||
BASE_IMAGE_VERSION: "2026.02.0"
|
||||
BASE_IMAGE_VERSION: "2026.01.0"
|
||||
ARCHITECTURES: '["amd64", "aarch64"]'
|
||||
|
||||
permissions: {}
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.14.3
|
||||
3.14.2
|
||||
|
||||
@@ -88,6 +88,7 @@ ISSUE_KEYS_FOR_REPAIRS = {
|
||||
"issue_system_disk_lifetime",
|
||||
ISSUE_KEY_SYSTEM_FREE_SPACE,
|
||||
ISSUE_KEY_ADDON_PWNED,
|
||||
"issue_system_ntp_sync_failed",
|
||||
}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "NTP sync failed - system time was corrected"
|
||||
},
|
||||
"issue_system_reboot_required": {
|
||||
"fix_flow": {
|
||||
"abort": {
|
||||
|
||||
@@ -961,8 +961,7 @@ class HomeAssistant:
|
||||
|
||||
async def async_block_till_done(self, wait_background_tasks: bool = False) -> None:
|
||||
"""Block until all pending work is done."""
|
||||
# Sleep twice to flush out any call_soon_threadsafe
|
||||
await asyncio.sleep(0)
|
||||
# To flush out any call_soon_threadsafe
|
||||
await asyncio.sleep(0)
|
||||
start_time: float | None = None
|
||||
current_task = asyncio.current_task()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -402,6 +402,156 @@ 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(
|
||||
# IssueType.NTP_SYNC_FAILED once aiohasupervisor >0.3.3 is released
|
||||
type="ntp_sync_failed",
|
||||
context=ContextType.SYSTEM,
|
||||
reference=None,
|
||||
uuid=(issue_uuid := uuid4()),
|
||||
),
|
||||
],
|
||||
suggestions_by_issue={
|
||||
issue_uuid: [
|
||||
Suggestion(
|
||||
# SuggestionType.ENABLE_NTP once aiohasupervisor >0.3.3 is released
|
||||
type="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(
|
||||
# IssueType.NTP_SYNC_FAILED once aiohasupervisor >0.3.3 is released
|
||||
type="ntp_sync_failed",
|
||||
context=ContextType.SYSTEM,
|
||||
reference=None,
|
||||
uuid=(issue_uuid := uuid4()),
|
||||
),
|
||||
],
|
||||
suggestions_by_issue={
|
||||
issue_uuid: [
|
||||
Suggestion(
|
||||
# SuggestionType.ENABLE_NTP once aiohasupervisor >0.3.3 is released
|
||||
type="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,
|
||||
|
||||
Reference in New Issue
Block a user