From 171a36984feff5247786b32958b52673e13cc8f0 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Fri, 4 Sep 2026 17:49:24 +0200 Subject: test(node): pin the fresh-install-before-provisioning safety property Two properties discussed but not yet pinned by a test, both load-bearing for service mode: 1. A bare `meshbay-node` with no config yet -- exactly what the W3 Startup .vbs and the service-mode Scheduled Task both run unattended, on the very first boot after a fresh install, quite possibly before the user has ever opened the client -- must fail closed, fast, and without a trace. Measured by hand first (under a second, zero bytes written against a real empty %LOCALAPPDATA%); this pins it as a test so it can't regress silently. load_config() already returns an empty Config on a missing path rather than raising, so main() reaches its own "hub.username not set" exit before ever touching NodeDaemon() or asyncio.run() -- nothing here has to mock the daemon startup. 2. node:start (main.js) must call provisionNode() before it ever checks for the service task or spawns -- reversed, the wizard's first Start on a fresh service-mode install would run/query the daemon before node.toml exists for it to read. Source-read, same technique as test_desktop_shell.py: the only evidence available without a live Electron run. Node suite 845 pass / 25 skip. Co-Authored-By: Claude Sonnet 5 --- packages/meshbay-node/tests/test_cli_dispatch.py | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'packages/meshbay-node/tests/test_cli_dispatch.py') diff --git a/packages/meshbay-node/tests/test_cli_dispatch.py b/packages/meshbay-node/tests/test_cli_dispatch.py index caf672d..f58c020 100644 --- a/packages/meshbay-node/tests/test_cli_dispatch.py +++ b/packages/meshbay-node/tests/test_cli_dispatch.py @@ -190,3 +190,37 @@ def test_lifecycle_commands_report_systemctl_failure( daemon_mod.main() assert exc.value.code == 1 assert "not loaded" in capsys.readouterr().out + + +def test_a_bare_invocation_with_no_config_yet_exits_cleanly(monkeypatch, tmp_path, capsys): + """ + A bare `meshbay-node` — no subcommand, nothing dispatches, falls through to + "start the daemon" at the bottom of main() — is exactly what the Windows W3 + Startup .vbs and the service-mode Scheduled Task both run unattended. On a + fresh install neither has ever provisioned anything, so this is the first + thing that runs on the very first boot, quite possibly before the user has + ever opened the client. + + This must fail closed, fast, and without a trace: no exception (nothing + catches one — the .vbs and the Scheduled Task are both headless, so an + uncaught crash is invisible and, run on every boot, an inert but permanent + fixture in the Task Scheduler history and Windows' own Application log). + Confirmed by hand first: measured under a second and zero bytes written + to disk against a real, empty %LOCALAPPDATA%. + + load_config() already returns an empty Config when the path does not + exist rather than raising — this pins that main() then notices the empty + hub.username and exits before ever reaching NodeDaemon()/asyncio.run(), + so nothing here has to mock the daemon startup at all. + """ + missing_config = tmp_path / "does-not-exist" / "node.toml" + monkeypatch.setattr(daemon_mod, "DEFAULT_CONFIG_PATH", missing_config) + monkeypatch.setattr(sys, "argv", ["meshbay-node"]) + + with pytest.raises(SystemExit) as exc: + daemon_mod.main() + + assert exc.value.code == 1 + assert "meshbay-node init" in capsys.readouterr().out + assert not missing_config.parent.exists(), ( + "a fresh, unprovisioned start must not create anything on disk") -- cgit v1.2.3