From efbcff05721e71f1fdfcc30b7ee1b44ca1670762 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Tue, 13 Oct 2026 00:30:39 +0200 Subject: test(node): run the connection processes on Windows, source and frozen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Connection processes and the larger UDP receive buffer were written and measured on Linux; nothing had run on Windows, and `meshbay-node.exe webrtc-worker` had never run from a frozen build on any system. - test_connection_processes.py failed on Windows (8 tests): the selector loop the suite uses there cannot start a process. A test marked `daemon_loop` now runs on the daemon's own loop, chosen through pytest-asyncio's loop factories. - The build starts both frozen executables as connection processes and carries a connection through each (smoke-connection-process.py). The daemon's own smoke test never signs in to a hub, which is when the processes start. - The warning for a receive buffer below what was asked named net.core.rmem_max on every system; it names it on Linux only. Windows grants the 4 MB. Measured on an installed build in service mode, docs/WINDOWS-PORT.md ยง5.12: two processes at startup and on a live change, a browser's handshake, chat, a 200 MB download over 8 connections across both processes, an upload, a video stream, and stop, restart and start leaving no process behind. Co-Authored-By: Claude Opus 5.5 --- packages/meshbay-node/tests/conftest.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'packages/meshbay-node/tests/conftest.py') diff --git a/packages/meshbay-node/tests/conftest.py b/packages/meshbay-node/tests/conftest.py index 32c9b3d..545528b 100644 --- a/packages/meshbay-node/tests/conftest.py +++ b/packages/meshbay-node/tests/conftest.py @@ -1,9 +1,11 @@ """Shared fixtures and helpers for node tests.""" +import asyncio import sys from pathlib import Path import pytest +import pytest_asyncio from meshbay_node.roots import RootSet # ffmpeg / ffprobe run via asyncio.create_subprocess_exec, which needs the @@ -17,6 +19,35 @@ needs_subprocess = pytest.mark.skipif( "SelectorEventLoop for aiortc", ) +# The other way round, for a test that starts processes and has no two aiortc +# ends in one process: on Windows it runs on the loop the daemon itself runs +# on. The loop is chosen per test through pytest-asyncio's loop factories; +# a version without them leaves the selector loop in place, where such a test +# cannot run. +_LOOP_FACTORIES = hasattr( + getattr(pytest_asyncio.plugin, "PytestAsyncioSpecs", None), "pytest_asyncio_loop_factories") +on_the_daemons_loop = [ + pytest.mark.daemon_loop, + pytest.mark.skipif( + sys.platform == "win32" and not _LOOP_FACTORIES, + reason="starts processes, which needs the ProactorEventLoop: asked for through " + "pytest-asyncio's loop factories, which this version does not have"), +] + + +def pytest_configure(config): + config.addinivalue_line( + "markers", "daemon_loop: on Windows, run on the event loop the daemon runs on") + + +@pytest.hookimpl(optionalhook=True) +def pytest_asyncio_loop_factories(config, item): + """The event loop of each async test here: the one it always had, except + for a test marked `daemon_loop` on Windows.""" + if sys.platform == "win32" and item.get_closest_marker("daemon_loop"): + return {"proactor": asyncio.ProactorEventLoop} + return {"default": asyncio.new_event_loop} + @pytest.fixture(autouse=True) def _no_log_file_in_the_developers_profile(monkeypatch): """A test that runs the daemon's entry point must not open its log file. -- cgit v1.2.3