mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
[fix] MegaTask verification: migration 052 enum + async cell-map read
Two real bugs surfaced running the full gate against a containerized
Postgres (and the orchestrator boot log):
1. Migration 052 crashed a real orchestrator boot with
'type "team" already exists'. The generic sa.Enum(create_type=False)
does NOT set the postgres enum's create_type attribute, so op.create_table
(checkfirst=False) emitted a redundant CREATE TYPE against the pre-existing
team enum. Switched to postgresql.ENUM(create_type=False) — the postgres-
native enum whose create_type _check_for_name_in_memos actually reads, so
the CREATE TYPE is suppressed. Verified: 051->052 upgrade against a DB where
the team enum pre-existed (the exact path that crashed) now succeeds;
downgrade 052->051 drops the table and preserves the shared enum; fresh
upgrade head clean. (Migration 016 has the same latent sa.Enum pattern but
never re-runs in prod, so it's noted, not touched here.)
2. _ensure_branch_for_task read task.cell_projects (lazy=selectin to-many)
directly, tripping MissingGreenlet on a freshly-created/unqueried task —
which then poisoned the async session (PendingRollbackError). Replaced with
_task_has_cell_map: peeks InstanceState.unloaded (no IO) and reads the
already-loaded map, falling back to an awaited count query only when the
relationship is genuinely unloaded. Non-ORM stubs route to the plain
attribute. Fixes 2 integration tests; the 6 cell-map unit tests still pass.
Also: typed the self stub as Any in test_choreographer_subtask_project
(mypy tests/ wants Choreographer, not SimpleNamespace) — the codebase idiom.
Gate: ruff format/check clean; mypy roboco/ + tests/ clean; full pytest
10371 passed / 388 skipped against containerized pgvector:pg16; vulture clean.
Pre-existing xenon C-rank on reassign (from prior commit 19a474d3, not this
feature) still blocks make quality — surfaced separately.
This commit is contained in:
@@ -17,6 +17,7 @@ other tiers are unchanged product-root / single-project behavior.
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import pytest
|
||||
@@ -54,7 +55,7 @@ async def test_explicit_inputs_project_id_wins_over_cell_map() -> None:
|
||||
product_id=None,
|
||||
project_id=None,
|
||||
)
|
||||
self_stub = SimpleNamespace(product=None)
|
||||
self_stub: Any = SimpleNamespace(product=None)
|
||||
resolved = await Choreographer._resolve_subtask_project(
|
||||
self_stub, parent, _inputs(team=Team.BACKEND, project_id=explicit)
|
||||
)
|
||||
@@ -73,7 +74,7 @@ async def test_cell_map_resolves_project_for_matching_team() -> None:
|
||||
product_id=None,
|
||||
project_id=None,
|
||||
)
|
||||
self_stub = SimpleNamespace(product=None)
|
||||
self_stub: Any = SimpleNamespace(product=None)
|
||||
resolved = await Choreographer._resolve_subtask_project(
|
||||
self_stub, parent, _inputs(team=Team.BACKEND)
|
||||
)
|
||||
@@ -90,7 +91,7 @@ async def test_cell_map_missing_team_falls_through_to_parent_project() -> None:
|
||||
product_id=None,
|
||||
project_id=own,
|
||||
)
|
||||
self_stub = SimpleNamespace(product=None)
|
||||
self_stub: Any = SimpleNamespace(product=None)
|
||||
# Frontend subtask but the map only covers backend → fall to parent.project_id.
|
||||
resolved = await Choreographer._resolve_subtask_project(
|
||||
self_stub, parent, _inputs(team=Team.FRONTEND)
|
||||
@@ -109,7 +110,7 @@ async def test_cell_map_only_parent_with_no_match_raises_completeness() -> None:
|
||||
product_id=None,
|
||||
project_id=None,
|
||||
)
|
||||
self_stub = SimpleNamespace(product=None)
|
||||
self_stub: Any = SimpleNamespace(product=None)
|
||||
with pytest.raises(TaskCompletenessError) as exc:
|
||||
await Choreographer._resolve_subtask_project(
|
||||
self_stub, parent, _inputs(team=Team.FRONTEND)
|
||||
|
||||
Reference in New Issue
Block a user