test(runtime): establish isolated validation and comparison gates

This commit is contained in:
Alexandre Teixeira
2026-09-26 13:13:07 +01:00
parent 0e07d9a675
commit ea847e6c0b
2 changed files with 16 additions and 4 deletions
+8
View File
@@ -15,6 +15,14 @@ reference; that file is the standard the refactor works toward.
## Running focused subsets (taxonomy markers) ## Running focused subsets (taxonomy markers)
The shared static-server fixture defaults to loopback port 7011 and refuses an
occupied port rather than reusing another checkout's server. For focused tests
that do not load that fixed browser URL, use `ODYSSEUS_TEST_STATIC_PORT=0` to
allocate an ephemeral port. This permits direct subprocess/isolation tests on a
host already serving the application without stopping or changing that service.
Browser tests that hard-code port 7011 still need that port in their own isolated
network namespace; do not run them against an unrelated live server.
`tests/conftest.py` tags every test at collection time with two markers derived `tests/conftest.py` tags every test at collection time with two markers derived
from its filename by `tests/_taxonomy.py`: an `area_*` marker (e.g. from its filename by `tests/_taxonomy.py`: an `area_*` marker (e.g.
`area_security`) and a finer `sub_*` marker (e.g. `sub_owner_scope`). This adds `area_security`) and a finer `sub_*` marker (e.g. `sub_owner_scope`). This adds
+8 -4
View File
@@ -98,21 +98,25 @@ def pytest_collection_modifyitems(config, items):
@pytest.fixture(scope="session", autouse=True) @pytest.fixture(scope="session", autouse=True)
def _serve_test_static(): def _serve_test_static():
"""Ensure static assets are available on loopback port 7011 for browser integration tests.""" """Serve this worktree's assets; non-browser runs can request an ephemeral port."""
import socket import socket
import threading import threading
import http.server import http.server
import socketserver import socketserver
from pathlib import Path from pathlib import Path
port = int(os.environ.get("ODYSSEUS_TEST_STATIC_PORT", "7011"))
if not 0 <= port <= 65535:
raise ValueError("ODYSSEUS_TEST_STATIC_PORT must be between 0 and 65535")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try: try:
is_bound = (sock.connect_ex(("127.0.0.1", 7011)) == 0) is_bound = (sock.connect_ex(("127.0.0.1", port)) == 0) if port else False
finally: finally:
sock.close() sock.close()
if is_bound: if is_bound:
raise RuntimeError("port 7011 is already in use; browser tests require this worktree's static server") raise RuntimeError(f"port {port} is already in use; browser tests require this worktree's static server")
root_dir = Path(__file__).resolve().parent.parent root_dir = Path(__file__).resolve().parent.parent
@@ -133,7 +137,7 @@ def _serve_test_static():
class _Server(socketserver.TCPServer): class _Server(socketserver.TCPServer):
allow_reuse_address = True allow_reuse_address = True
server = _Server(("127.0.0.1", 7011), _Handler) server = _Server(("127.0.0.1", port), _Handler)
thread = threading.Thread(target=server.serve_forever, daemon=True) thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start() thread.start()
try: try: