From 33182e7df9e1bfaed6e2320872add0ae20e2d221 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Thu, 17 Sep 2026 15:28:19 +0500 Subject: [PATCH] =?UTF-8?q?CI=20=D0=9F=D0=A2=D0=98=D0=A6=D0=90:=20Postgres?= =?UTF-8?q?=20=D1=81=20PostGIS,=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BC=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B0=20gap-fill=20=D0=B2=20CI=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D1=8F=D0=B5=D1=82=D1=81=D1=8F,=20?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=20=D0=BF=D1=80=D0=BE=D0=BF=D1=83=D1=81?= =?UTF-8?q?=D0=BA=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20(#2962)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit На голове b74b02ea CI / backend-tests был красным (run 11737): 5125 passed, но все 5 тестов test_2962_competitors_gapfill_bridge.py пропустились с причиной «нет расширения postgis», а в skip_allowlist.txt их не было — гейт вернул rc=1. В CI ПТИЦЫ plain postgres:16, а SQL конкурентов без PostGIS не исполнить (ST_DWithin по geography). - ci.yml: образ postgis/postgis:16-3.4 (тот же, что в ci-tradein.yml); образ сам создаёт расширение в POSTGRES_DB. - тест: при CI/GITHUB_ACTIONS skipif выключен — если PostGIS из CI пропадёт, тест упадёт с настоящей причиной, а не пропустится молча. - skip_allowlist.txt: пропуск объявлен только для машины без базы. Co-Authored-By: Claude Opus 5 --- .forgejo/workflows/ci.yml | 17 +++++++++-------- .../test_2962_competitors_gapfill_bridge.py | 10 ++++++++-- backend/tests/skip_allowlist.txt | 13 +++++++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index b599c368..d619a1ef 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -260,10 +260,12 @@ jobs: # #295 weighted AVG) self-skip'ался connectivity-probe'ом — в CI эти проверки # не бежали ни разу с момента написания. # - # plain postgres:16, БЕЗ PostGIS: тесты tests/sql/ строят себе временные - # таблицы (CREATE TEMP TABLE) и не трогают ни geometry, ни реальную схему — - # проверено локально, 16 passed за 1.3с. Поэтому и bootstrap схемы здесь не - # нужен, в отличие от tradein-лэйна. + # postgis/postgis:16-3.4, схема НЕ собирается: тесты строят себе временные + # таблицы (CREATE TEMP TABLE), которые затеняют боевые, и гоняют настоящий SQL + # модулей. PostGIS нужен с #2962: SQL конкурентов ищет «тот же ЖК» через + # ST_DWithin по geography, без расширения его не исполнить. На plain + # postgres:16 тест #2962 молча пропускался, то есть мост gap-fill в CI не + # проверялся вовсе. Образ сам создаёт расширение в POSTGRES_DB. # # TEST_DATABASE_URL НАМЕРЕННО НЕ задаётся: на него завязан tests/integration/ # (phantom-column gate), которому нужна КОПИЯ ПРОДОВОЙ схемы через pg_dump по @@ -294,15 +296,14 @@ jobs: # ВРЕМЕННЫЙ сервер фазы initdb (listen_addresses=''), после которой БД # ещё перезапускается. Проба по TCP зеленеет только на настоящем сервере. # - # plain postgres:16, БЕЗ PostGIS: тесты tests/sql/ строят себе временные - # таблицы и не трогают ни geometry, ни реальную схему — bootstrap схемы - # здесь не нужен вовсе, в отличие от tradein-лэйна. + # postgis, а не plain postgres (#2962) — см. комментарий у job'а. Bootstrap + # схемы здесь не нужен вовсе, в отличие от tradein-лэйна. run: | set -u docker rm -fv "$CI_PG" >/dev/null 2>&1 || true docker run -d --name "$CI_PG" \ -e POSTGRES_DB=gendesign_ci -e POSTGRES_USER=gendesign -e POSTGRES_PASSWORD=gendesign \ - postgres:16 + postgis/postgis:16-3.4 ready="" for _ in $(seq 1 45); do diff --git a/backend/tests/services/site_finder/test_2962_competitors_gapfill_bridge.py b/backend/tests/services/site_finder/test_2962_competitors_gapfill_bridge.py index 17ec59e2..20996211 100644 --- a/backend/tests/services/site_finder/test_2962_competitors_gapfill_bridge.py +++ b/backend/tests/services/site_finder/test_2962_competitors_gapfill_bridge.py @@ -8,7 +8,10 @@ Тест герметичный и прогоняет НАСТОЯЩИЕ `_COMPETITORS_SQL` и `_OBJECTIVE_PRICE_FALLBACK_SQL`: временные таблицы затеняют боевые в пределах сессии. -Нужен Postgres с PostGIS, иначе skip. +Нужен Postgres с PostGIS (ST_DWithin по geography). В CI он есть +(.forgejo/workflows/ci.yml, образ postgis/postgis), и там тест не пропускается +никогда: без PostGIS он падает с настоящей причиной. Пропуск разрешён только вне CI, +на машине без базы, и объявлен в skip_allowlist.txt. """ from __future__ import annotations @@ -43,7 +46,10 @@ def _postgis_reachable() -> tuple[bool, str]: _DB_OK, _DB_ERR = _postgis_reachable() -pytestmark = pytest.mark.skipif(not _DB_OK, reason=f"Postgres/PostGIS недоступен: {_DB_ERR}") +_IN_CI = bool(os.environ.get("GITHUB_ACTIONS") or os.environ.get("CI")) +pytestmark = pytest.mark.skipif( + not _DB_OK and not _IN_CI, reason=f"Postgres/PostGIS недоступен: {_DB_ERR}" +) _SCHEMA = [ """CREATE TEMP TABLE domrf_kn_objects ( diff --git a/backend/tests/skip_allowlist.txt b/backend/tests/skip_allowlist.txt index e77642d9..bcde3d05 100644 --- a/backend/tests/skip_allowlist.txt +++ b/backend/tests/skip_allowlist.txt @@ -144,6 +144,19 @@ tests/sql/test_2464_area_bin_unknown.py::test_lot_without_area_is_not_counted_as tests/sql/test_2464_area_bin_unknown.py::test_unknown_area_gets_its_own_bucket tests/sql/test_2464_area_bin_unknown.py::test_total_lots_preserved tests/sql/test_2464_area_bin_unknown.py::test_normal_buckets_unchanged + +# ── #2962: мост gap-fill конкурентов (complex_sources → project_name) ───────── +# Нужен Postgres С PostGIS: тесты затеняют боевые таблицы временными и гоняют +# НАСТОЯЩИЕ _COMPETITORS_SQL и _OBJECTIVE_PRICE_FALLBACK_SQL, а там ST_DWithin по +# geography. В CI ИДУТ (ci.yml поднимает postgis/postgis:16-3.4) и пропуститься +# там НЕ МОГУТ: при CI=true skipif выключен, без PostGIS тест падает. Записи нужны +# только для машины без базы. +tests/services/site_finder/test_2962_competitors_gapfill_bridge.py::test_gapfill_velocity_counts_only_own_project +tests/services/site_finder/test_2962_competitors_gapfill_bridge.py::test_gapfill_price_is_median_of_own_lots +tests/services/site_finder/test_2962_competitors_gapfill_bridge.py::test_wrong_fuzzy_link_gives_no_numbers +tests/services/site_finder/test_2962_competitors_gapfill_bridge.py::test_punctuation_difference_still_matches +tests/services/site_finder/test_2962_competitors_gapfill_bridge.py::test_explicit_mapping_unchanged + # ── #2464: backfill act_date (миграция 191) ────────────────────────────────── # Нужен живой Postgres: тесты создают ВРЕМЕННУЮ копию land_reservation в прод-форме # (9+2 строки с датой Генплана + контрольные посторонние) и прогоняют ТЕЛО миграции