fix(homeassistant): detect the supervised launch through is_supervised_gateway_launch
gateway.restart already answers "was this gateway launched by a generated service" (HERMES_SUPERVISED_CHILD or launchd's XPC_SERVICE_NAME, so a plist that predates the marker still counts); the hint reuses it instead of a second env read. The negative branch (plain unreachable host without a supervisor) is now an unmarked test so the Linux lane keeps covering the function; the macOS-only test holds the positive branch.
This commit is contained in:
@@ -7,7 +7,6 @@ import asyncio
|
||||
import errno
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
@@ -21,6 +20,7 @@ except ImportError:
|
||||
AIOHTTP_AVAILABLE = False
|
||||
aiohttp = None # type: ignore[assignment]
|
||||
|
||||
from gateway.restart import is_supervised_gateway_launch
|
||||
from gateway.config import Platform, PlatformConfig
|
||||
from gateway.platforms.base import gateway_trust_env, BasePlatformAdapter, SendResult
|
||||
from gateway.platforms.event import MessageEvent, MessageType
|
||||
@@ -70,12 +70,12 @@ _TRIGGERED = ("cleared", "triggered") # binary_sensor wording, indexed by ``sta
|
||||
def _connect_error_detail(exc: BaseException) -> str:
|
||||
"""Annotate macOS Local Network Privacy denials so launchd HA failures are actionable (#71206).
|
||||
|
||||
Only a launchd-supervised gateway on macOS (``HERMES_SUPERVISED_CHILD`` is set by the generated plist)
|
||||
can be denied this way; the same errno elsewhere is a genuinely unreachable host.
|
||||
Only a supervised (launchd) gateway on macOS can be denied this way; the same errno from a
|
||||
Terminal-run gateway or on another OS is a genuinely unreachable host.
|
||||
"""
|
||||
text = str(exc)
|
||||
os_error = getattr(exc, "os_error", None) or exc.__cause__ or exc
|
||||
if (sys.platform == "darwin" and os.environ.get("HERMES_SUPERVISED_CHILD")
|
||||
if (sys.platform == "darwin" and is_supervised_gateway_launch()
|
||||
and getattr(os_error, "errno", None) == errno.EHOSTUNREACH):
|
||||
return (
|
||||
f"{text} — macOS Local Network Privacy is blocking this launchd gateway from the LAN. "
|
||||
|
||||
@@ -321,22 +321,25 @@ class TestWsUrlConstruction:
|
||||
|
||||
|
||||
class TestLocalNetworkConnectHint:
|
||||
@pytest.mark.macos_only
|
||||
def test_ehostunreach_under_launchd_names_the_remedy(self, monkeypatch):
|
||||
"""Only the launchd-supervised gateway can be denied by Local Network Privacy; the same errno from a
|
||||
Terminal-run gateway is a genuinely unreachable host and must not be blamed on macOS (#71206)."""
|
||||
def test_ehostunreach_outside_launchd_is_a_plain_unreachable_host(self, monkeypatch):
|
||||
"""The same errno from a Terminal-run gateway (or another OS) must not be blamed on macOS."""
|
||||
from plugins.platforms.homeassistant.adapter import _connect_error_detail
|
||||
|
||||
err = OSError(errno.EHOSTUNREACH, "No route to host")
|
||||
monkeypatch.delenv("HERMES_SUPERVISED_CHILD", raising=False)
|
||||
monkeypatch.delenv("XPC_SERVICE_NAME", raising=False)
|
||||
err = OSError(errno.EHOSTUNREACH, "No route to host")
|
||||
assert _connect_error_detail(err) == str(err)
|
||||
assert _connect_error_detail(RuntimeError("auth failed")) == "auth failed"
|
||||
|
||||
@pytest.mark.macos_only
|
||||
def test_ehostunreach_under_launchd_names_the_remedy(self, monkeypatch):
|
||||
"""Only the launchd-supervised gateway can be denied by Local Network Privacy (#71206)."""
|
||||
from plugins.platforms.homeassistant.adapter import _connect_error_detail
|
||||
|
||||
monkeypatch.setenv("HERMES_SUPERVISED_CHILD", "1")
|
||||
err = OSError(errno.EHOSTUNREACH, "No route to host")
|
||||
detail = _connect_error_detail(err)
|
||||
assert detail.startswith(str(err))
|
||||
assert "Local Network" in detail
|
||||
assert "hermes gateway install" in detail
|
||||
assert "71206" in detail
|
||||
# Unrelated failures stay untouched.
|
||||
assert _connect_error_detail(RuntimeError("auth failed")) == "auth failed"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user