fix(tests+mutator): unbreak the docker-shadow test env + let mutator delete from active
Two related fixes that came out of running the W5 tests locally:
1. tests/__init__.py — empty file, makes 'tests/' a package so pytest
stops inserting it into sys.path. Without it, 'tests/docker/'
(the docker-image test category) shadowed the installed docker SDK
on every engine-touching test in the repo:
module 'docker' has no attribute 'DockerClient'
Pytest's default --import-mode=prepend was the culprit; making
tests/ a package is the cheapest fix and doesn't change
--import-mode for the whole tree.
2. delete_topology_decky / delete_topology_edge / delete_lan grow an
'enforce_pending: bool = True' kwarg. Default preserves the HTTP
CRUD guard (api_decky_crud / api_edge_crud / api_lan_crud get the
409 for free). apply_remove_decky / apply_detach_decky /
apply_remove_lan now pass enforce_pending=False — the mutator
queue is the live-editing surface and has its own active-topology
gating; the repo's pending-only guard was for design-time CRUD
that mustn't bypass it. Without this, apply_remove_decky was
silently broken on active topologies pre-W5; W5's new test
surfaced it on first run.
10/10 new W5 tests pass; 58/58 across mutator + topology suites.
This commit is contained in:
@@ -558,7 +558,11 @@ async def apply_remove_lan(
|
||||
f"{d['decky_config']['name']!r}; remove the decky first"
|
||||
)
|
||||
lan_name = lan["name"]
|
||||
await repo.delete_lan(lan["id"])
|
||||
# enforce_pending=False: the mutator queue is the live-editing
|
||||
# surface, gated on topology status by us before we got here. The
|
||||
# repo's pending-only guard is for HTTP CRUD callers that mustn't
|
||||
# bypass it.
|
||||
await repo.delete_lan(lan["id"], enforce_pending=False)
|
||||
|
||||
# Live materialisation symmetric to apply_add_lan: tear down the
|
||||
# docker bridge and re-render compose so a future redeploy doesn't
|
||||
@@ -757,7 +761,7 @@ async def apply_detach_decky(
|
||||
await repo.update_topology_decky(
|
||||
decky["uuid"], {"decky_config": new_cfg}
|
||||
)
|
||||
await repo.delete_topology_edge(edge["id"])
|
||||
await repo.delete_topology_edge(edge["id"], enforce_pending=False)
|
||||
# Live materialisation: SDK network.disconnect on the base
|
||||
# container. Service containers automatically lose visibility into
|
||||
# the LAN because they share the base's netns.
|
||||
@@ -778,7 +782,7 @@ async def apply_remove_decky(
|
||||
raise MutationError(f"decky {payload['decky']!r} not found")
|
||||
decky_name = decky["decky_config"]["name"]
|
||||
services_list = list(decky.get("services") or [])
|
||||
await repo.delete_topology_decky(decky["uuid"])
|
||||
await repo.delete_topology_decky(decky["uuid"], enforce_pending=False)
|
||||
# Live materialisation: stop + rm -f the decky's containers. We
|
||||
# capture decky_name + services BEFORE the delete so the helper
|
||||
# has the targets even though the row is gone.
|
||||
|
||||
Reference in New Issue
Block a user