diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-05 14:48:08 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-05 14:48:08 +0200 |
| commit | c11dd22b593358ef7932deec53c8200f5f14ed8b (patch) | |
| tree | f7347edeedb14aef5dafeab6bc3f0263e15b1929 /packages/meshbay-node/tests/test_platform.py | |
| parent | 3fd1f1b456bacc3da2d38323a16b60345ac7105e (diff) | |
| download | meshbay-c11dd22b593358ef7932deec53c8200f5f14ed8b.tar.gz | |
fix(node): register the service-mode task with Register-ScheduledTask -LogonType S4U
schtasks.exe has no flag naming the logon type directly -- it only infers
S4U vs Interactive from whether /rp is present, and both readings broke
live on a blank-password account: /rp "" fails schtasks' own credential
validation, and omitting /rp registers "Interactive only", which never
launches the process at boot or on demand despite installing cleanly.
Register-ScheduledTask -LogonType S4U names the logon type explicitly, no
inference. Confirmed live: install, manual start, and unattended boot-time
start all now work.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/tests/test_platform.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_platform.py | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/packages/meshbay-node/tests/test_platform.py b/packages/meshbay-node/tests/test_platform.py index 91713be..92e74df 100644 --- a/packages/meshbay-node/tests/test_platform.py +++ b/packages/meshbay-node/tests/test_platform.py @@ -346,24 +346,57 @@ def test_service_install_removes_the_startup_launcher_first(win_startup, monkeyp monkeypatch.setattr(plat, "_current_user", lambda: "DOMAIN\\user") calls = [] monkeypatch.setattr( - plat, "_schtasks", - lambda *args: calls.append(args) or Mock(returncode=0, stdout="", stderr="")) + plat.subprocess, "run", + lambda argv, **kw: calls.append((argv, kw)) or Mock(returncode=0, stdout="", stderr="")) plat.service_install(exe=r"C:\x\meshbay-node.exe") assert not win_startup.exists() # removed as part of service_install - assert calls and calls[0][0] == "/create" + assert calls and calls[0][0][0] == "powershell" + env = calls[0][1]["env"] + assert env["MESHBAY_SVC_USER"] == "DOMAIN\\user" + assert env["MESHBAY_SVC_EXE"] == r"C:\x\meshbay-node.exe" + + +def test_service_install_uses_s4u_not_a_stored_password(monkeypatch): + """Register-ScheduledTask -LogonType S4U, not schtasks: schtasks only + infers the logon type from whether /rp is present, and both readings + broke live on a blank-password account (2026-09-05) -- /rp "" fails + credential validation, and omitting /rp registers "Interactive only", + which never runs at boot or on demand. See platform.py's service mode + comment for the full story.""" + monkeypatch.setattr(plat, "_current_user", lambda: "DOMAIN\\user") + calls = [] + monkeypatch.setattr( + plat.subprocess, "run", + lambda argv, **kw: calls.append((argv, kw)) or Mock(returncode=0, stdout="", stderr="")) + + plat.service_install(exe=r"C:\x\meshbay-node.exe") + + script = calls[0][0][-1] + assert "-LogonType S4U" in script + assert "New-ScheduledTaskTrigger -AtStartup" in script def test_service_install_tolerates_no_startup_launcher_present(win_startup, monkeypatch): assert not win_startup.exists() monkeypatch.setattr(plat, "_current_user", lambda: "DOMAIN\\user") - monkeypatch.setattr(plat, "_schtasks", - lambda *args: Mock(returncode=0, stdout="", stderr="")) + monkeypatch.setattr(plat.subprocess, "run", + lambda argv, **kw: Mock(returncode=0, stdout="", stderr="")) plat.service_install(exe=r"C:\x\meshbay-node.exe") # no error assert not win_startup.exists() +def test_service_install_raises_with_powershells_error_message(monkeypatch): + monkeypatch.setattr(plat, "_current_user", lambda: "DOMAIN\\user") + monkeypatch.setattr( + plat.subprocess, "run", + lambda argv, **kw: Mock(returncode=1, stdout="", stderr="Access is denied.")) + + with pytest.raises(RuntimeError, match="Access is denied"): + plat.service_install(exe=r"C:\x\meshbay-node.exe") + + # ── Packaged defaults ──────────────────────────────────────────────────────── def test_frozen_build_finds_default_env_beside_the_executable(monkeypatch, tmp_path): |