Skip to content

fix(tests): close ADK backend test databases (GC-timing unraisable warning) - #1502

Closed
axisrow wants to merge 2 commits into
mainfrom
fix/close-adk-test-db
Closed

axisrow wants to merge 2 commits into
mainfrom
fix/close-adk-test-db

Conversation

@axisrow

@axisrow axisrow commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Проблема

_make_backend в tests/test_adk_backend.py создаёт Database(':memory:'), и никто его не закрывает: сырой sqlite3.Connection доедается GC в случайный момент более позднего теста, а filterwarnings=error превращает PytestUnraisableExceptionWarning в падение, приписанное тому тесту, который в этот момент работал.

Проявилось дважды в песочнице mutmut (там другой тайминг GC): статс-сбор умирал на test_adk_backend при 1713 зелёных тестах; в обычном прогоне репозитория тест зелёный — потому баг и был невидим.

Фикс

  • Autouse-фикстура закрывает все созданные _make_backend-ом базы (реестр _created_dbs).
  • Три синхронных контракт-теста переведены в async def (модуль anyio), иначе async-фикстура к ним неприменима.

Верификация

  • pytest tests/test_adk_backend.py — 20 passed, 1 skipped (было 18 passed + 3 errors до конверсии).
  • Красное доказательство: полный прогон в песочнице mutmut падал на test_chat_stream_emits_text_then_done с этим самым unraisable-warning (лог живой верификации PR-кноба mutmut); после фикса — прогон статс-фазы проходит (см. следующий прогон в описании PR fix(tooling): mutmut sandbox copies conftest+scripts; document flat-src incompatibility #1501-цепочки).

Refs: boxed/mutmut#593 (кноб strip_src_prefix), PR #1501 (конфиг песочницы mutmut).

🤖 Generated with Claude Code

axisrow and others added 2 commits October 7, 2026 13:14
…arning

_make_backend created Database(':memory:') and nothing closed it: the raw
sqlite3.Connection was finalized by the GC at an arbitrary later test, and
filterwarnings=error turned that PytestUnraisableExceptionWarning into a
failure attributed to whichever test was running (observed twice in mutmut's
sandbox — stats collection died at test_adk_backend with 1713 tests green;
GC timing there differs from the normal suite run, where the test passes).

The autouse fixture closes every created Database; the three sync contract
tests become async (module is anyio-based) so the async fixture can apply.

Co-Authored-By: Claude Code <noreply@anthropic.com>
…ents

/simplify follow-up: test_codex_backend._make_backend had the identical
leaked-Database pattern (altitude finding) — same registry + autouse close,
sync contract test converted (async autouse fixture). Comments trimmed to
the mechanism; the investigation story lives in the commit history.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@axisrow

axisrow commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

Закрыт как ошибочный диагноз (проверено ревью): регистрируемые базы в adk/codex тестах никогда не открывают соединение — закрывать было нечего; реальный источник unraisable — незакрытые file-backed базы в test_cli_photo_loader/extended. Честный фикс: #1505 (cli_init_patch закрывает базы по завершении теста, покрывая все 13 файлов с фикстурой). Но-оп-механика в main не попала.

@axisrow axisrow closed this Oct 7, 2026
axisrow added a commit that referenced this pull request Oct 8, 2026
… net) (#1505)

* fix(tests): close cli_init_patch databases at test teardown — real unraisable-source hygiene

Post-merge review of #1502 proved its mechanism a no-op: the Databases created
in test_adk_backend/test_codex_backend never open a connection (lazy
DatabaseConnection, backends never read self._db), so closing them could not
prevent the GC-unraisable flakes; the real leak sites are file-backed
Databases in test_cli_photo_loader.py (19x asyncio.run(initialize()), zero
close()) and test_cli_extended.py.

Fix at the shared altitude: cli_init_patch registers the handed-in Database
in a per-test registry and an autouse finalizer closes them after the test —
after teardown nothing can legally use them (closing inside the context
manager broke 12 tests that touch db after the with-block), and a failed
close logs a warning instead of failing the suite.

Note: 12 test_cli_agent_commands failures on this machine are pre-existing on
clean main and are a different family — unclosed local async-generator fakes
GC-finalized mid-run (_fake_stream), not sqlite; filed separately.

Co-Authored-By: Claude Code <noreply@anthropic.com>

* fix(tests): leak net closes db before pop; failed close surfaces as teardown error

Review of #1505: pop-before-close made a failed close unrecoverable, and the
swallowed log line hid the exact flake class the net targets. Close first,
pop after — the next teardown retries, and a close failure is a pytest
teardown error, not a silent warning. Drop the dead BLE001 noqa and the
logging import. Add the only exerciser of the close branch: a deliberately
leaked db is verified closed via a module-scope witness fixture.

Co-Authored-By: Claude Code <noreply@anthropic.com>

---------

Co-authored-by: axisrow <axisrow@users.noreply.github.com>
Co-authored-by: Claude Code <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant