test(scrapers/krt): вернуть в прогон проверку многоблочной страницы (#2778) #2781
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2781
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "test/2777-krt-multisite-no-dump"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Refs #2778 (issue остаётся открытой — в ней запрошен PDF-образец для оставшихся 6 тестов)
Диагноз: 2 из 8 — выразимое, 6 из 8 — невыразимое
Секция «Образцы, которых нет в git» в
skip_allowlist.txtсодержала 8 записей и лечилась, по замыслу, одинаково: «закоммитить образцы». Разбор показал, что это два разных случая.Где искали образцы (обоих нет)
<repo>/.playwright-mcp//Users/antonдо 6 уровней.playwright-mcp, ни в одном нетekb-docs/find / -xdevekb-docs)ekb_krt_sites= 15 строк ·ekb_ppt_tep= 0 строкЛожный след, который стоит назвать.
ekb_krt_sites.raw_blockна проде заполнен во всех 15 строках (30 КБ) и выглядит как готовая замена дампу. Это не так:raw_block=block_text[:4000](ekb_krt_registry.py:338) — уже очищенный от тегов текст. Вход парсера из него не восстановить; проверено выгрузкой (0 совпадений<strong>/<h2>).KRT ×2 — выразимо без дампа → починено
Три вопроса:
_BABUSHKINA_BLOCKс комментарием «не требует локального дампа»).TestMultiSiteCountFromDump→TestMultiSitePage: страница из трёх блоков в двух годовых секциях, собранная из фрагментов, уже лежащих в файле, обёрнутых в<div>.Что проверяется теперь и не проверялось раньше:
site_nameвсё равно обязан быть уникальным (номер сам по себе ключом не является);1-2/21.7-14и «Брусника» остаются у своей площадки;_extract_krt_sectionчерезfind_parent(контейнер<div>) — одиночные блоки её не касаются вовсе.Осознанная потеря, названная вслух (в комментарии у теста и в #2778): утверждение «на живой странице ЕКБ ≥14 площадок» синтетической страницей не заменяется. На проде
ekb_krt_sites= 15, то есть по факту разбирается всё — но автоматической проверки этого больше нет.PPT ×6 — невыразимо → задокументировано
Эти 6 проверяют извлечение таблиц из НАСТОЯЩЕГО PDF через pdfplumber. Соседний класс
TestParsePptTepуже мокает pdfplumber целиком — синтетика тут просто дублировала бы его. Нужен файл; запрошен у Anton в #2778, там же — что оживёт, куда класть и почему нет блокеров (официальный градостроительный документ: без персональных данных, вне авторского права по ст. 1259 п. 6 ГК РФ).Попутная находка в #2778: у парсера ППТ нет и прод-питания. Единственный seed в
ekb_ppt_tep_sync.py:42—"# VERIFY URL: ...", таск его пропускает с WARNING, отсюдаekb_ppt_tep = 0на проде. Тот же файл (или рабочий URL) закрывает обе дыры сразу — и тесты, и acceptance #1136.Сторож пропусков
Две строки убраны из
tests/skip_allowlist.txt— иначе сторож ждал бы пропуска, которого больше нет. Комментарий секции переписан: сколько записей было, что с ними стало, какой файл нужен и от кого.Верификация — прогон, а не конфиг
Было: в
test_ekb_krt_registry.py2 пропуска. Стало: ноль, и 4 исполняемых теста вместо 2 неисполняемых. Все 6 оставшихся пропусков названы в логе (-rs) и учтены сторожем (exit 0).`TestMultiSiteCountFromDump` читал `.playwright-mcp/ekb-docs/krt_page_raw.html` и пропускался всегда: файла нет ни в репозитории, ни на дисках (шесть каталогов `.playwright-mcp` — ни в одном нет `ekb-docs/`), ни на прод-VPS (`find / -xdev` по имени и по каталогу — пусто). Восстановить из БД тоже нельзя, хотя выглядит будто можно: на проде `ekb_krt_sites` = 15 строк с непустым `raw_block`, но там лежит НЕ HTML — `raw_block=block_text[:4000]` (ekb_krt_registry.py:338), то есть уже очищенный от тегов текст. Вход парсера из него не собрать. Зато свойство, ради которого тесты писались, от дампа не зависит: страница собирается из блоков, которые УЖЕ лежат в этом тест-файле (`_BRUSNIKA_BLOCK` + `_BABUSHKINA_BLOCK` + третий, «нежилой»), обёрнутых в один `<div>`. Проверяется: • три блока в двух годовых секциях → три площадки; • нумерация на реальной странице начинается заново каждый год, поэтому «2.» встречается дважды — и site_name обязан остаться уникальным; • границы блоков не текут: договор 1-2/21.7-14 и «Брусника» остаются у своей площадки, не прилипая к соседям; • вид КРТ читается поблочно (третий — «нежилой застройки»). Плюс это первый тест, который проходит через ветку `_extract_krt_section` с `find_parent` (контейнер `<div>`); одиночные блоки её не касаются вовсе. ЧЕГО ЗАМЕНА НЕ ПРОВЕРЯЕТ — сказано вслух в комментарии у теста и в #2778: утверждение «на живой странице ≥14 площадок» синтетикой не заменяется. Оно вернётся, когда в репозитории появится образец страницы. Сторож пропусков: две строки убраны из tests/skip_allowlist.txt — иначе он ждал бы пропуска, которого больше нет. Оставшиеся 6 (PDF-образец ППТ) переписаны с указанием, какой файл нужен, от кого и что оживёт: #2778. Верификация: tests/services/scrapers/ — 292 passed, 6 skipped, exit 0. Все 6 пропусков названы в логе (`-rs`) и учтены сторожем. В самом test_ekb_krt_registry.py пропусков больше нет: 31 passed. Refs #2778Первый прогон
CI / backend-tests(run 6961) был красным не из-за этого PR. Диффа тут два файла —test_ekb_krt_registry.pyиskip_allowlist.txt, — а упалоtests/services/test_weather_cache.py:283.Разобрал, потому что «наверное флейк, перезапусти» — плохой ответ. Оказалось не флейк: тест требует гарантии, которой в коде нет.
Тест поднимает 16 потоков и утверждает «Single-flight под lock'ом — РОВНО один реальный вызов».
weather_cache.py:283-287в комментарии говорит обратное: сетевой вызов сделан вне lock'а сознательно (#1370), «cold-start на ОДИН ключ может породить несколько параллельных запросов… что приемлемо». Локально 5 прогонов подряд зелёные — при GIL и мгновенном моке первый поток обычно успевает сложить результат раньше остальных; на нагруженном раннере не успевает.Заведено отдельно: #2783 (там же развилка — чинить тест под фактический контракт или делать настоящий per-key single-flight). Сюда не тащу: другой подсистемы и требует решения, а не правки.
Прогон перезапущен (rerun через API этой версии Forgejo не поддерживается — 404, поэтому close/reopen): runs 6974/6975.