mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix(gate): clear the xenon complexity failure + fixable test warnings
- transcript_retention.py: split select_prunable_transcripts into small helpers so the module averages complexity rank A (was B — failed make quality / xenon). - pyproject: move the markers table from [tool.coverage.run] (coverage warned 'Unrecognized option') to [tool.pytest.ini_options] where it belongs. - HTTP_422_UNPROCESSABLE_ENTITY -> HTTP_422_UNPROCESSABLE_CONTENT (old name deprecated) in the tasks/product/settings routes + the validation middleware. - conftest: drop pool_pre_ping on the per-test engine — pointless for a fresh per-test engine and it leaves an un-awaited asyncpg Connection._cancel coroutine that surfaced as a RuntimeWarning across ~30 integration tests.
This commit is contained in:
+6
-6
@@ -237,6 +237,12 @@ testpaths = ["tests"]
|
||||
python_files = ["test_*.py"]
|
||||
asyncio_default_fixture_loop_scope = "function"
|
||||
addopts = "--cov=roboco --cov-report=term-missing"
|
||||
markers = [
|
||||
"asyncio: mark tests as async",
|
||||
"slow: marks tests as slow",
|
||||
"integration: marks tests as integration tests",
|
||||
"unit: marks tests as unit tests",
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
# Coverage core. Python 3.12+ supports sys.monitoring; the legacy `pytrace`
|
||||
@@ -286,12 +292,6 @@ omit = [
|
||||
# Auto-generated migrations.
|
||||
"alembic/*",
|
||||
]
|
||||
markers = [
|
||||
"asyncio: mark tests as async",
|
||||
"slow: marks tests as slow",
|
||||
"integration: marks tests as integration tests",
|
||||
"unit: marks tests as unit tests",
|
||||
]
|
||||
|
||||
# =============================================================================
|
||||
# Vulture Configuration
|
||||
|
||||
@@ -389,7 +389,7 @@ async def request_validation_handler(request: Request, exc: Exception) -> JSONRe
|
||||
if remediate is not None:
|
||||
content["remediate"] = remediate
|
||||
return JSONResponse(
|
||||
status_code=http_status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
status_code=http_status.HTTP_422_UNPROCESSABLE_CONTENT,
|
||||
content=content,
|
||||
)
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ async def create_product(
|
||||
detail="Duplicate cell: each team may map to at most one project.",
|
||||
) from e
|
||||
raise HTTPException(
|
||||
status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
status.HTTP_422_UNPROCESSABLE_CONTENT,
|
||||
detail="Invalid cell mapping: project_id does not reference a project.",
|
||||
) from e
|
||||
return product_to_response(product)
|
||||
@@ -131,7 +131,7 @@ async def update_product(
|
||||
detail="Duplicate cell: each team may map to at most one project.",
|
||||
) from e
|
||||
raise HTTPException(
|
||||
status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
status.HTTP_422_UNPROCESSABLE_CONTENT,
|
||||
detail="Invalid cell mapping: project_id does not reference a project.",
|
||||
) from e
|
||||
return product_to_response(product)
|
||||
|
||||
@@ -30,7 +30,7 @@ async def update_setting(
|
||||
await service.set(key, data.value)
|
||||
except SettingValidationError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc)
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)
|
||||
) from exc
|
||||
# Write route commits explicitly (get_db auto-commit is unreliable).
|
||||
await db.commit()
|
||||
|
||||
@@ -154,7 +154,7 @@ async def create_task(
|
||||
agent_row = await get_agent_by_slug(db, data.assigned_to)
|
||||
if agent_row is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
|
||||
detail={
|
||||
"error": {
|
||||
"code": "ASSIGNEE_NOT_FOUND",
|
||||
|
||||
@@ -37,6 +37,19 @@ def is_agent_owned_dir(dir_name: str, workspaces_root: str) -> bool:
|
||||
return bool(encoded_root) and dir_name.startswith(encoded_root)
|
||||
|
||||
|
||||
def _is_old_transcript(path: Path, cutoff_epoch: float) -> bool:
|
||||
"""True if ``path`` is a regular .jsonl file last modified before the cutoff."""
|
||||
try:
|
||||
return path.is_file() and path.stat().st_mtime < cutoff_epoch
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def _old_transcripts_in(directory: Path, cutoff_epoch: float) -> list[Path]:
|
||||
"""Old ``*.jsonl`` transcripts directly inside one agent-owned dir."""
|
||||
return [t for t in directory.glob("*.jsonl") if _is_old_transcript(t, cutoff_epoch)]
|
||||
|
||||
|
||||
def select_prunable_transcripts(
|
||||
projects_root: Path, workspaces_root: str, cutoff_epoch: float
|
||||
) -> list[Path]:
|
||||
@@ -50,12 +63,6 @@ def select_prunable_transcripts(
|
||||
return []
|
||||
prunable: list[Path] = []
|
||||
for child in sorted(projects_root.iterdir()):
|
||||
if not child.is_dir() or not is_agent_owned_dir(child.name, workspaces_root):
|
||||
continue
|
||||
for transcript in child.glob("*.jsonl"):
|
||||
try:
|
||||
if transcript.is_file() and transcript.stat().st_mtime < cutoff_epoch:
|
||||
prunable.append(transcript)
|
||||
except OSError:
|
||||
continue
|
||||
if child.is_dir() and is_agent_owned_dir(child.name, workspaces_root):
|
||||
prunable.extend(_old_transcripts_in(child, cutoff_epoch))
|
||||
return prunable
|
||||
|
||||
+4
-1
@@ -214,7 +214,10 @@ async def db_session(_test_database_url: str) -> AsyncIterator[AsyncSession]:
|
||||
Each test gets its own session and connection; teardown rolls back any
|
||||
uncommitted state and disposes the engine to keep connection counts low.
|
||||
"""
|
||||
engine = create_async_engine(_test_database_url, future=True, pool_pre_ping=True)
|
||||
# No pool_pre_ping: a fresh per-test engine can't have stale connections, and
|
||||
# pre-ping on asyncpg leaves an un-awaited Connection._cancel coroutine that
|
||||
# surfaces as a RuntimeWarning during GC.
|
||||
engine = create_async_engine(_test_database_url, future=True)
|
||||
factory = async_sessionmaker(
|
||||
bind=engine, class_=AsyncSession, expire_on_commit=False
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user