test(ptica): покрыть переиспользование сессии после close() в отдаче фотографий (#2464-C) #2930

Merged
bot-backend merged 1 commit from test/2464c-photos-session-reuse-after-close into main 2026-08-19 11:52:14 +00:00
Collaborator

Зачем

#2928 поставил db.close() выше по коду отдачи фотографии, а ниже сессия ещё раз работает с БД — UPDATE thumb_path + commit() в ветке генерации миниатюры из локального оригинала. Поведение штатное (close() возвращает соединение в пул, следующий execute берёт новое и открывает свою транзакцию), но проверял это только комментарий.

Проблема не в том, что код скорее всего верен, а в том, что ошибка тут не проявилась бы в эксплуатации. Замер на проде 19.08:

domrf_kn_photos: есть local_path, нет thumb_path      0
domrf_kn_photos: есть thumb_path                  1 889

Ноль строк на этой ветке. Все закешированные уже с миниатюрами, значит сегодня по ней не проходит ни один запрос — а первый же ленивый фетч новой фотографии пойдёт по коду, который не проверял никто.

Что проверяет тест

  1. Генерация миниатюры (медленная работа) идёт без открытой транзакции — то же свойство, что и для внешнего фетча.
  2. UPDATE после close() доезжает до БД.

Второе читается отдельным соединением, а не той же сессией. Через ту же сессию проверять нельзя: она видит собственную незакоммиченную транзакцию, и пропажа commit() прошла бы незамеченной — тест был бы зелёным по построению.

Доказательство, что у теста есть зубы

Тест не двусторонний в обычном смысле: он покрывает уже смерженный код, а не фиксирует новую правку, поэтому на origin/main он зелёный. Вместо этого — фальсификация: временно убрал db.commit() из photos.py:

>       assert stored == str(generated), "UPDATE после close() не закоммичен"
E       assert None == '/.../orig.webp'
1 failed, 3 passed          КОД ВОЗВРАТА = 1

Исходник восстановлен, git diff по photos.py пуст.

Прогон

pytest -k "photos or 2464"11 passed, 1 skipped, rc=0 (код возврата снят без конвейера — статус tail за него не отвечает).

Форматирование assert-сообщения в диффе — от pre-commit ruff 0.7.4, расходящегося с venv 0.15.12 (#2864), не моя правка.

Refs #2464

## Зачем #2928 поставил `db.close()` выше по коду отдачи фотографии, а **ниже** сессия ещё раз работает с БД — `UPDATE thumb_path` + `commit()` в ветке генерации миниатюры из локального оригинала. Поведение штатное (`close()` возвращает соединение в пул, следующий `execute` берёт новое и открывает свою транзакцию), но проверял это только комментарий. Проблема не в том, что код скорее всего верен, а в том, что **ошибка тут не проявилась бы в эксплуатации**. Замер на проде 19.08: ``` domrf_kn_photos: есть local_path, нет thumb_path 0 domrf_kn_photos: есть thumb_path 1 889 ``` Ноль строк на этой ветке. Все закешированные уже с миниатюрами, значит сегодня по ней не проходит ни один запрос — а первый же ленивый фетч новой фотографии пойдёт по коду, который не проверял никто. ## Что проверяет тест 1. Генерация миниатюры (медленная работа) идёт **без** открытой транзакции — то же свойство, что и для внешнего фетча. 2. `UPDATE` после `close()` **доезжает до БД**. Второе читается **отдельным соединением**, а не той же сессией. Через ту же сессию проверять нельзя: она видит собственную незакоммиченную транзакцию, и пропажа `commit()` прошла бы незамеченной — тест был бы зелёным по построению. ## Доказательство, что у теста есть зубы Тест не двусторонний в обычном смысле: он покрывает уже смерженный код, а не фиксирует новую правку, поэтому на `origin/main` он зелёный. Вместо этого — фальсификация: временно убрал `db.commit()` из `photos.py`: ``` > assert stored == str(generated), "UPDATE после close() не закоммичен" E assert None == '/.../orig.webp' 1 failed, 3 passed КОД ВОЗВРАТА = 1 ``` Исходник восстановлен, `git diff` по `photos.py` пуст. ## Прогон `pytest -k "photos or 2464"` → **11 passed, 1 skipped, rc=0** (код возврата снят без конвейера — статус `tail` за него не отвечает). Форматирование assert-сообщения в диффе — от pre-commit ruff 0.7.4, расходящегося с venv 0.15.12 (#2864), не моя правка. Refs #2464
bot-backend added 1 commit 2026-08-19 11:33:26 +00:00
test(ptica): покрыть переиспользование сессии после close() в отдаче фотографий (#2464-C)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m56s
CI / backend-tests (pull_request) Successful in 16m5s
63170ff2f5
#2928 поставил db.close() выше по коду, а ниже сессия ещё раз работает с БД:
UPDATE thumb_path + commit в ветке генерации миниатюры из локального оригинала.
Поведение штатное — close() возвращает соединение в пул, следующий execute берёт
новое, — но проверял это только комментарий.

На проде ветка сегодня не исполняется ни разу: замер 19.08 по domrf_kn_photos —
0 строк с непустым local_path и пустым thumb_path (все 1889 закешированных уже
с миниатюрами). Значит первый же ленивый фетч новой фотографии пойдёт по коду,
который не проверял никто, и обычная эксплуатация дефект бы не показала.

Проверка читает результат ОТДЕЛЬНЫМ соединением, а не той же сессией: сессия
видит собственную незакоммиченную транзакцию, и пропажа commit() прошла бы мимо.
Фальсификация: с убранным db.commit() тест краснеет (assert None == ...webp).

Форматирование assert-сообщения — от pre-commit ruff 0.7.4, не моё (#2864).
bot-backend merged commit 3c9505c8b0 into main 2026-08-19 11:52:14 +00:00
bot-backend deleted branch test/2464c-photos-session-reuse-after-close 2026-08-19 11:52:14 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2930
No description provided.