diff --git a/scripts/utils/wifi_monitor_daemon.py b/scripts/utils/wifi_monitor_daemon.py index 30962acc..ea5efb69 100755 --- a/scripts/utils/wifi_monitor_daemon.py +++ b/scripts/utils/wifi_monitor_daemon.py @@ -132,7 +132,7 @@ class WiFiMonitorDaemon: # AP-enable trigger clean and avoid false-positive AP enables from # transient packet loss on otherwise working WiFi. if updated_status.connected and not updated_status.ap_mode_active: - if not self.wifi_manager._check_internet_connectivity(): + if not self.wifi_manager.check_internet_connectivity(): self._consecutive_internet_failures += 1 logger.warning( f"Internet unreachable despite nmcli connection " @@ -140,10 +140,18 @@ class WiFiMonitorDaemon: ) if self._consecutive_internet_failures >= self._nm_restart_threshold: logger.warning("Restarting NetworkManager to recover internet connectivity") - import subprocess as _sp - _sp.run(["sudo", "systemctl", "restart", "NetworkManager"], - capture_output=True, timeout=20) - self._consecutive_internet_failures = 0 + try: + subprocess.run( + ["/usr/bin/systemctl", "restart", "NetworkManager"], + capture_output=True, timeout=20, check=True + ) + self._consecutive_internet_failures = 0 + except subprocess.CalledProcessError as e: + logger.error(f"NetworkManager restart failed (rc={e.returncode}); " + "keeping failure counter unchanged") + except Exception as e: + logger.error(f"NetworkManager restart error: {e}; " + "keeping failure counter unchanged") else: self._consecutive_internet_failures = 0 else: diff --git a/src/wifi_manager.py b/src/wifi_manager.py index 94696861..e31bd5fb 100644 --- a/src/wifi_manager.py +++ b/src/wifi_manager.py @@ -948,6 +948,10 @@ class WiFiManager: logger.debug("Internet connectivity check failed (both ping and HTTP)") return False + def check_internet_connectivity(self, timeout: int = 5) -> bool: + """Public wrapper around _check_internet_connectivity for use by the daemon.""" + return self._check_internet_connectivity(timeout=timeout) + def _has_ap_clients(self) -> bool: """ Return True if at least one client is associated with the AP. diff --git a/test/test_wifi_manager_ap.py b/test/test_wifi_manager_ap.py index 9bad4cc3..88e4b309 100644 --- a/test/test_wifi_manager_ap.py +++ b/test/test_wifi_manager_ap.py @@ -129,7 +129,15 @@ def test_nmcli_ap_profile_has_no_security_params(manager: WiFiManager) -> None: assert "psk" not in add_str, "AP profile must not include a PSK/password" assert "wpa" not in add_str.lower(), "AP profile must not reference WPA" assert "802-11-wireless.mode" in add_str, "AP profile must declare wireless mode" - assert "ap" in add_calls[0], "Wireless mode value must be 'ap'" + # Verify the value for 802-11-wireless.mode is exactly "ap" — check the element + # that immediately follows the key in the command list, not a loose substring match. + cmd = add_calls[0] + try: + mode_idx = cmd.index("802-11-wireless.mode") + assert cmd[mode_idx + 1] == "ap", \ + f"802-11-wireless.mode value must be exactly 'ap', got {cmd[mode_idx + 1]!r}" + except ValueError: + pytest.fail("802-11-wireless.mode not found as a list element in nmcli command") # ---------------------------------------------------------------------------