test: update and add tests for all updated subsystems

This commit is contained in:
2026-06-16 03:37:00 +00:00
parent 6e814d2827
commit 7abe7700e9
10 changed files with 733 additions and 102 deletions
+145
View File
@@ -0,0 +1,145 @@
"""Tests that daemon.iface stays in sync with registered server routes.
Verifies a two-way contract:
1. Every iface constant has a matching handler registered.
2. Every registered handler has a matching iface constant.
Run with: pytest tests/test_iface_sync.py -v
"""
from collections import defaultdict
import pytest
@pytest.fixture(autouse=True)
def _load_handlers():
"""Load all handler modules so registry is populated."""
# Import server to get registry, then load handlers
from daemon import server
# Force route registration
server._register_routes()
@pytest.fixture()
def registry():
from daemon import server
return server.registry
@pytest.fixture()
def iface_module():
import daemon.iface as iface
return iface
def _get_iface_pairs(iface_module):
"""Extract all (method, path) pairs from iface module."""
iface = iface_module
return {
name: val
for name, val in iface.__dict__.items()
if isinstance(val, tuple) and len(val) == 2 and isinstance(val[0], str)
}
def _get_registered_routes(registry):
"""Extract all (METHOD, path) keys from the registry."""
return {(method.upper(), path) for (method, path) in registry._routes}
class TestIfaceSync:
"""Verify iface constants match registered routes."""
def test_iface_constants_non_empty(self, iface_module):
pairs = _get_iface_pairs(iface_module)
assert len(pairs) >= 50, f"Expected many iface constants, got {len(pairs)}"
def test_iface_constants_have_registered_handlers(self, registry, iface_module):
"""Every iface constant should map to a registered route."""
registered = _get_registered_routes(registry)
iface_pairs = _get_iface_pairs(iface_module)
# These 5 routes go through add_route() in create_app(), not @registry.register
add_route_paths = {
"/health",
"/status/all",
"/status/refresh",
"/ws",
"/batch",
}
missing = []
for name, (method, path) in iface_pairs.items():
key = (method.upper(), path)
if path not in add_route_paths and key not in registered:
missing.append(
(
name,
{
"method": method,
"path": path,
},
)
)
if missing:
detail = "\n".join(f" {name}: {pair}" for name, pair in missing)
pytest.fail(
f"{len(missing)} iface constant(s) have no matching handler:\n{detail}"
)
def test_registered_routes_have_iface_constants(self, registry, iface_module):
"""Every registered route should have a matching iface constant."""
registered = _get_registered_routes(registry)
iface_pairs = _get_iface_pairs(iface_module)
iface_keys = set(iface_pairs.values())
missing = registered - iface_keys
if missing:
detail = "\n".join(f" {method} {path}" for method, path in sorted(missing))
pytest.fail(
f"{len(missing)} registered route(s) have no matching iface constant:\n{detail}"
)
def test_no_duplicate_iface_constants(self, iface_module):
"""All iface constants should have unique (method, path) pairs."""
iface_pairs = _get_iface_pairs(iface_module)
seen = defaultdict(list)
for name, val in iface_pairs.items():
seen[val].append(name)
dupes = {pair: names for pair, names in seen.items() if len(names) > 1}
assert not dupes, "Duplicate iface constants:\n" + "".join(
f" {pair}: {names}\n" for pair, names in dupes.items()
)
class TestIfaceFormat:
"""Verify iface constants follow the expected format."""
def test_all_constants_are_tuples_of_str(self, iface_module):
iface_pairs = _get_iface_pairs(iface_module)
for name, val in iface_pairs.items():
assert isinstance(val, tuple), f"{name} should be a tuple"
assert len(val) == 2, f"{name} should have length 2"
assert isinstance(val[0], str), f"{name} method should be a string"
assert isinstance(val[1], str), f"{name} path should be a string"
def test_all_constants_have_uppercase_methods(self, iface_module):
iface_pairs = _get_iface_pairs(iface_module)
valid_methods = {"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"}
for name, val in iface_pairs.items():
assert val[0].upper() in valid_methods, (
f"{name} has invalid method: {val[0]}"
f"should be one of {valid_methods}"
)
def test_all_constants_have_leading_slash_path(self, iface_module):
iface_pairs = _get_iface_pairs(iface_module)
for name, val in iface_pairs.items():
assert val[1].startswith("/"), f"{name} path should start with /: {val[1]}"