summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_security_regressions.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-04 02:20:57 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-04 02:20:57 +0200
commitd11e571c5b6c24b586ef5b8fb2cfcf6a6bfa6d6d (patch)
treefe3c4fbce3db02a8b84a15c413735622a51eefb0 /packages/meshbay-node/tests/test_security_regressions.py
parent7a4b905ddb64bdc92b7f9acf2ccde9bd84d7a6f3 (diff)
downloadmeshbay-d11e571c5b6c24b586ef5b8fb2cfcf6a6bfa6d6d.tar.gz
test(node): make the suite pass on Windows
- `.read_text()` on source files now `encoding="utf-8"` — cp1252 chokes on the em dashes / box-drawing chars those files contain. - test node.toml templates embed paths via `Path.as_posix()`: a raw Windows path in a basic TOML string is a parse error (`\U`, `\a`, ... are escapes). - new `test_platform.py` covers `meshbay_node.platform` by mocking `sys.platform` / `os.environ` — runs on both OSes. - `skipif(sys.platform == "win32")`, in `conftest.needs_subprocess` and inline, for the documented gaps: ffmpeg/ffprobe via asyncio subprocess (the win32 selector loop, forced for aiortc, cannot spawn one), the systemd `reload`/`restart-daemon` delegation (Windows path is W3), the keystore `st_mode == 600` assertion (NTFS ignores mode bits), and the symlink-escape test (needs Developer Mode). Windows: 781 passed, 25 skipped. No change on Linux. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/tests/test_security_regressions.py')
-rw-r--r--packages/meshbay-node/tests/test_security_regressions.py14
1 files changed, 7 insertions, 7 deletions
diff --git a/packages/meshbay-node/tests/test_security_regressions.py b/packages/meshbay-node/tests/test_security_regressions.py
index 10182d3..7f71da5 100644
--- a/packages/meshbay-node/tests/test_security_regressions.py
+++ b/packages/meshbay-node/tests/test_security_regressions.py
@@ -308,7 +308,7 @@ def test_chat_store_and_peers_are_per_group(tmp_path):
def test_daemon_sets_no_global_chat_store(tmp_path):
"""H1: the daemon must not hoist one group's chat store onto the transport."""
source = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "daemon.py").read_text()
+ / "src" / "meshbay_node" / "daemon.py").read_text(encoding="utf-8")
assert '_ctx["chat_store"]' not in source, (
"daemon must not assign a transport-wide chat_store — it leaks chat "
"across groups (H1)"
@@ -336,7 +336,7 @@ def test_no_member_can_hand_the_node_key_material(tmp_path):
)
source = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "transport" / "webrtc_server.py").read_text()
+ / "src" / "meshbay_node" / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
assert "_do_gek_bundle_store" not in source
assert "_admin_exec_bundle_store" not in source
@@ -370,7 +370,7 @@ def test_gek_auto_activation_is_gone():
node a GEK of their choosing. Nothing arriving over MNP may set a live GEK.
"""
source = (Path(__file__).parent.parent / "src" / "meshbay_node"
- / "transport" / "webrtc_server.py").read_text()
+ / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
assert "_try_activate_gek" not in source
assert 'unwrap_gek_aes' not in source, (
"the MNP path must not unwrap a GEK — activation is local-admin only"
@@ -485,7 +485,7 @@ def test_swarm_registration_skips_private_groups():
dormant leak into a live one.
"""
source = (Path(__file__).parent.parent / "src" / "meshbay_node"
- / "daemon.py").read_text()
+ / "daemon.py").read_text(encoding="utf-8")
assert 'visibility' in source and '_register_swarm' in source
# Both registration sites must gate on public visibility.
for marker in ['gctx.get("visibility") == "public"',
@@ -509,7 +509,7 @@ def test_keystore_records_argon2_params_for_migration(tmp_path):
path = tmp_path / "keystore.enc"
created = create_keystore(path=path, password="correct horse battery")
- envelope = json.loads(path.read_text())
+ envelope = json.loads(path.read_text(encoding="utf-8"))
assert envelope["argon2"]["memory_cost"] >= 262144
reopened = load_keystore(path=path, password="correct horse battery")
@@ -575,7 +575,7 @@ def test_peer_errors_do_not_leak_internals():
that purpose. The check targets the generic `except Exception as e` path.
"""
source = (Path(__file__).parent.parent / "src" / "meshbay_node"
- / "transport" / "webrtc_server.py").read_text()
+ / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
assert '"detail": str(e)' not in source, (
"generic exception text relayed to peer — use a fixed message"
)
@@ -616,7 +616,7 @@ def test_stream_segment_is_not_synchronous():
assert inspect.iscoroutinefunction(WebRTCPeerSession._do_stream_segment_async)
source = (Path(__file__).parent.parent / "src" / "meshbay_node"
- / "transport" / "webrtc_server.py").read_text()
+ / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
tree = ast.parse(source)
blocking = [
node for node in ast.walk(tree)