27 KiB
type, work_item_id, title, version, status, verdict, created_at, updated_at, authors, related, adr_refs
| type | work_item_id | title | version | status | verdict | created_at | updated_at | authors | related | adr_refs | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| test-report | ET-013 | Test Report: Перепады высот на z9-z11 — zoom-aware paint | 1 | blocked | BLOCKED | 2026-06-04 | 2026-06-04 |
|
|
|
Test Report — ET-013
TL;DR
make lint✅, прицельный прогон unit/integration ET-013 ✅ (23 passed, 7 skipped — skip ожидаемы: нет PNG-fixtures в sandbox).- Полный
make testпадает на этапе collection из-за внешней проблемы (ModuleNotFoundError: No module named 'lxml'в тестахtests/api/test_gps_tracks_download.py/_gpx_builder.py) — это наследие ET-011, не имеет отношения к ET-013. После исключения этих двух файлов: 191 passed, 46 skipped, 0 failed, регрессий ET-007/008/009/011/012 нет. - Код в ветке
feature/ET-013-z9-z11-z81:1 соответствует TRZ (REQ-F-01..F-21) и ADR-017 (подтверждено Review v2, APPROVED). - ❌ Pre-deploy gate AC-19 — FAIL (P1): на test-среде отсутствуют
тайлы
hillshade/9/*(а такжеhillshade/8/*). Проверка по координатам[37.6, 54.5](юг МО / Кашира — основная зона UI-тестов):hillshade/z9/309/348.png → 404. Тайлыhillshade/z10,hillshade/z11,tri/z8..z11присутствуют (200 OK). Это блокирует основную пользовательскую ценность ET-013: после деплоя на z=9 чекбокс «Тени рельефа» станет активным, но карта 404'нется на каждом hillshade-запросе, и пользователь увидит включённый слой без теней (хуже, чем до ET-013, где чекбокс был disabled с честным hint'ом «Зум 10+»). - UI Playwright (TC-UI-01..12) — NOT EXECUTED: раннер
/home/slin/tools/ui-test/run_tests.jsиplaywright/npxнедоступны в этом контейнере. Дополнительно: test-среда сейчас держит до-ET-013 код (if (zoom < 10),HILLSHADE_PAINTнет), поэтому даже при наличии раннера большинство TC дали бы PASS «по старому контракту» — нерелевантный сигнал. Визуальные TC должны выполниться после деплоя.
Вердикт: BLOCKED. Реализация ET-013 в коде корректна и готова, но деплой остановлен по TRZ REQ-F-20 §1: «При 404 — задача останавливается, тайлы z9 нужно догенерировать в рамках PH-6 follow-up». Следующий шаг — открыть PH-6 follow-up («generate hillshade tiles z8-z9 для CFO») и после генерации тайлов повторно прогнать pre-deploy probe + Playwright UI suite.
1. Окружение прогона
| Параметр | Значение |
|---|---|
| Ветка | feature/ET-013-z9-z11-z8 |
| HEAD | 397dc60 reviewer(ET): auto-commit from reviewer run_id=84 |
| Содержательные коммиты | 5be81f9 feat(terrain): zoom-aware paint для hillshade/TRI на z9-z11 (ET-013)099669d fix(terrain): расширить whitelist endpoint'а на tri (ET-013 review F-1) |
| Python | 3.12.13 |
| pytest | 8.3.3 |
| Ruff | через python -m ruff check src/api/ |
| Test-среда (HTTP) | https://openclaw.mva154.duckdns.org/enduro/ |
| Состояние test-среды | до-ET-013 (фронт ещё с if (zoom < 10), без HILLSHADE_PAINT/TRI_PAINT). Это ожидаемо: деплой ET-013 — следующий этап пайплайна. |
curl в sandbox |
отсутствует; HTTP-проверки выполнены через urllib.request (Python). |
Сетевая проверка /health:
GET /enduro/api/health → 200
{"status":"ok","db_path":"/app/data/centralfederal.sqlite","db_exists":true}
2. Шаг 1 — make lint
python -m ruff check src/api/
All checks passed!
Результат: ✅ PASS (часть AC-18).
3. Шаг 2 — make test (целевой gate)
3.1 Прицельный прогон ET-013
python -m pytest tests/unit/test_terrain_paint.py \
tests/integration/test_terrain_z9_tiles.py -v
collected 30 items
…
=================== 23 passed, 7 skipped, 1 warning in 0.46s ===================
| Suite | Кейсов | PASS | SKIP | Покрытие AC |
|---|---|---|---|---|
tests/unit/test_terrain_paint.py |
17 | 17 | 0 | AC-01, AC-04, AC-05, AC-15, AC-22 |
tests/integration/test_terrain_z9_tiles.py |
13 | 6 | 7 | AC-16 |
Что покрывают unit-тесты (выборка):
test_hillshade_paint_defined,test_hillshade_opacity_is_interpolate_by_zoom,test_hillshade_opacity_stops,test_hillshade_contrast_peak_z9,test_hillshade_resampling_nearest— структураHILLSHADE_PAINT, stops 9/10/11/12/14 → 0.65/0.60/0.55/0.50/0.40, contrast пик z9 ≥0.30 / z14 ≤0.10.test_tri_paint_defined,test_tri_opacity_z8_regression(«8, 0.70» ровно, защита AC-06),test_tri_opacity_peak_z9_z11(z10/z11 ≥ 0.80),test_tri_resampling_nearest.test_apply_terrain_layer_signature_uses_opacity_or_paint,test_apply_terrain_layer_normalizes_number_to_legacy_paint,test_apply_terrain_layer_uses_paint_variable— обратная совместимостьapplyTerrainLayer(AC-22).test_minzoom_threshold_lowered_to_9(if (zoom < 9)найден,< 10отсутствует),test_hint_text_updated_to_z9(«Зум 9+»),test_apply_terrain_layer_caller_count(ровно 2 вызова),test_hillshade_call_uses_paint_constant_and_minzoom_9,test_tri_call_uses_paint_constant_and_minzoom_5.
Что покрывают integration-тесты:
- PASS:
test_known_terrain_layer_accepted_by_whitelist[hypso|hillshade|tri](доказывает фикс F-1 review v1),test_unknown_terrain_layer_returns_404,test_missing_terrain_tile_returns_404,test_invalid_zoom_returns_404. - SKIP:
test_terrain_tile_available_z9_z10_z11[*]×6,test_terrain_tile_cache_control_immutable— требуют PNG-fixtures вdata/terrain/, которых нет в sandbox-репо. Skip — корректный механизм через_maybe_skip; AC-16 говорит «при отсутствии тайлов в CI — тесты skipped с reason», что в точности и наблюдается.
3.2 Полный регресс (pytest tests/)
Полный прогон падает на collection из-за внешней проблемы:
ERROR tests/api/test_gps_tracks_download.py
ERROR tests/api/test_gps_tracks_gpx_builder.py
from lxml import etree as lxml_et
E ModuleNotFoundError: No module named 'lxml'
!!! Interrupted: 2 errors during collection !!!
lxml не установлен в этом контейнере. Это наследие ET-011 / GPX
download, не связано с ET-013 (ветка не трогает gps_tracks/).
В CI-окружении проекта lxml устанавливается через
src/api/requirements.txt, и эти тесты зелёные.
Прогон без этих двух файлов:
python -m pytest tests/ \
--ignore=tests/api/test_gps_tracks_download.py \
--ignore=tests/api/test_gps_tracks_gpx_builder.py
…
========== 191 passed, 46 skipped, 4 deselected, 79 warnings in 3.47s ==========
4 deselected— perf/network маркеры (стандартный exclude).46 skipped— async-тестыgps_tracks(нет pytest-asyncio в sandbox) + integration без fixtures. Не относится к ET-013.- Регрессий ET-007 / ET-008 / ET-009 / ET-011 / ET-012 — НЕТ.
Результат: ✅ PASS (AC-15, AC-16 в части автоматики, AC-17, AC-18).
4. Шаг 3 — E2E (контракт API на test-среде)
4.1 IT-TILE-* «вживую» против test-среды
Поскольку sandbox без data fixtures даёт SKIP, я выполнил эквивалент
IT-TILE-* напрямую HTTP-запросом к test-среде. Координата
[37.6, 54.5] (юг МО / Кашира) — основная для UI-тестов (см.
04b-ui-test-cases.md §«Координаты»). Тайлы под TMS-схемой (как
объявлено в addSource(... scheme: 'tms' ...)):
| z | hillshade (x, y_tms) | hillshade status | tri (x, y_tms) | tri status |
|---|---|---|---|---|
| 8 | 8/154/174 |
❌ 404 | 8/154/174 |
✅ 200 |
| 9 | 9/309/348 |
❌ 404 | 9/309/348 |
✅ 200 |
| 10 | 10/618/697 |
✅ 200 | 10/618/697 |
✅ 200 |
| 11 | 11/1237/1395 |
✅ 200 | 11/1237/1395 |
✅ 200 |
| 14 | 14/9903/11162 |
✅ 200 | 14/9903/11162 |
❌ 404 ¹ |
¹ TRI z=14 404 — за пределами TRI-стека (TRI генерится до z11 в PH-6, регрессия известная, в скоупе ET-013 не трогается). Чекбокс TRI на z=14 включит источник с minzoom=5/maxzoom=15, но реально тайлы отдадутся только до z=11; визуально на z>11 — пусто. Это не новая регрессия ET-013, такое же поведение было до ET-013. Фиксирую как P3 для PH-6 follow-up.
Дополнительная проверка покрытия hillshade z=9 — wide grid 5×5 вокруг
центра (309, 348):
hillshade z=9 found: 0 tiles around (309,348)
hillshade z=10 found: 9 tiles around (618,697)
То есть на z=9 нет ни одного hillshade-тайла, не только «целевого»; данных просто нет в pipeline.
4.2 Заголовок Cache-Control
hillshade z=10 → Cache-Control: max-age=31536000
hillshade z=11 → Cache-Control: max-age=31536000
tri z=8 → Cache-Control: max-age=31536000
…
Только max-age=31536000; immutable-флаг отсутствует в ответах
nginx-перед-fastapi на test-среде. Это предсуществующая ситуация
(не введена ET-013): backend FastAPI отдаёт Cache-Control: max-age=…, immutable, но nginx-конфиг на test-среде стрипает immutable. На
бизнес-логику это не влияет (max-age=1y достаточен), но формальная
формулировка REQ-F-18 / IT-TILE-CACHE-HEADER «immutable сохраняется»
выполняется только на backend-уровне (см. integration-тест
test_terrain_tile_cache_control_immutable, корректно SKIPPED здесь).
Не блокер ET-013. Фиксирую как P3 (известная инфра-косметика,
не в скоупе).
4.3 /health стабилен
См. раздел 1. ✅
5. Шаг 4 — UI / Visual тесты
5.1 Состояние раннера
ls /home/slin/tools/ui-test/ → No such file or directory
which playwright / npx → not found
find / -name run_tests.js -type f → (нет результатов)
UI-test раннер, Playwright и npx в этом контейнере отсутствуют.
Запустить TC-UI-01..12 невозможно.
5.2 Состояние test-среды (до-ET-013)
GET https://openclaw.mva154.duckdns.org/enduro/app.js
HILLSHADE_PAINT in body: False
TRI_PAINT in body: False
'if (zoom < 9)' in body: False
'if (zoom < 10)' in body: True
На test-среде сейчас выкатан до-ET-013 код. Это ожидаемо:
деплой ET-013 — следующий этап пайплайна (deployer → 14-deploy-log.md).
Визуальную регрессию TC-UI-01..12 имеет смысл прогонять только
ПОСЛЕ деплоя.
5.3 План постдеплойного прогона (DEFERRED)
| TC | Тип | viewport | Зум | Что проверяем | Severity | Статус |
|---|---|---|---|---|---|---|
| TC-UI-01-Z9 | functional+visual | desktop | 9 | Чекбокс активен, hint скрыт, hillshade виден | P1 | DEFERRED ¹ |
| TC-UI-02-Z8-REGRESS | regression+visual | desktop | 8 | TRI выглядит как до ET-013 | P2 | DEFERRED |
| TC-UI-03-Z9-Q | visual (qual.) | desktop | 9 | Перепады читаются ≥ z=8 | P1 | DEFERRED ¹ |
| TC-UI-04-Z10-Q | visual (qual.) | desktop | 10 | Перепады читаются | P2 | DEFERRED |
| TC-UI-05-Z11-Q | visual (qual.) | desktop | 11 | Перепады читаются | P2 | DEFERRED |
| TC-UI-06-Z14-REGRESS | regression+visual | desktop | 14 | Hillshade не «перегрет» (opacity 0.40, contrast 0) | P2 | DEFERRED |
| TC-UI-07-Z9-MOBILE | visual | mobile | 9 | Чекбокс/hint работают, нет H-scroll | P1 | DEFERRED ¹ |
| TC-UI-08-Z10-SAT-Q | visual (qual.) | desktop | 10 | Hillshade поверх спутника не «глушит» | P2 | DEFERRED |
| TC-UI-09-Z10-DARK-Q | visual (qual.) | desktop | 10 | Hillshade на тёмной теме читается | P2 | DEFERRED |
| TC-UI-10-PERSIST | functional+visual | desktop | 10 | F5 не теряет состояние, оба слоя восстановлены | P2 | DEFERRED |
| TC-UI-11-NETWORK-Q | perf (network) | desktop | 8-11 | Σ traffic ≤ 135% baseline | P2 | DEFERRED |
| TC-UI-12-Z9-PAN | perf+visual | desktop | 9 | Pan без «белых дыр» в hillshade/TRI | P3 | DEFERRED |
¹ TC-UI-01, TC-UI-03, TC-UI-07 — заблокированы pre-deploy gate
(см. §4.1): даже после деплоя ET-013 эти три кейса дадут FAIL,
потому что /terrain/hillshade/9/* отдаёт 404 → MapLibre нарисует
hillshade-слой пустым (или с «белыми дырами»), что не соответствует
AC-03 «На карте видны тени рельефа».
DEFERRED = тест не запущен в текущем окружении и должен быть выполнен оператором/Playwright против test-среды после: (a) генерации hillshade z8-z9 тайлов (PH-6 follow-up); (b) деплоя ET-013.
Результаты приколоть к 14-deploy-log.md.
6. Матрица Acceptance Criteria → Test
| AC | Покрытие | Результат |
|---|---|---|
| AC-01 | test_minzoom_threshold_lowered_to_9, test_hint_text_updated_to_z9 |
✅ PASS |
| AC-02 | DevTools на test-среде | ⏳ DEFER → deploy log |
| AC-03 | TC-UI-01-Z9 + видимость hillshade-слоя | ❌ BLOCKED (нет тайлов z9) |
| AC-04 | test_hillshade_opacity_is_interpolate_by_zoom, …contrast_peak_z9, …resampling_nearest |
✅ PASS |
| AC-05 | test_tri_opacity_z8_regression, test_tri_opacity_peak_z9_z11, …resampling_nearest |
✅ PASS |
| AC-06 | test_tri_opacity_z8_regression (z8 = 0.70 ровно) + TC-UI-02-Z8-REGRESS |
✅ PASS (код) / ⏳ DEFER (visual) |
| AC-07 | TC-UI-03-Z9-Q | ❌ BLOCKED (нет тайлов z9) |
| AC-08 | TC-UI-04-Z10-Q | ⏳ DEFER → deploy log |
| AC-09 | TC-UI-05-Z11-Q | ⏳ DEFER → deploy log |
| AC-10 | TC-UI-06-Z14-REGRESS | ⏳ DEFER → deploy log |
| AC-11 | TC-UI-09-Z10-DARK-Q | ⏳ DEFER → deploy log |
| AC-12 | TC-UI-08-Z10-SAT-Q | ⏳ DEFER → deploy log |
| AC-13 | TC-UI-07-Z9-MOBILE | ❌ BLOCKED (нет тайлов z9) |
| AC-14 | TC-UI-10-PERSIST | ⏳ DEFER → deploy log |
| AC-15 | pytest tests/unit/test_terrain_paint.py — 17/17 |
✅ PASS |
| AC-16 | pytest tests/integration/test_terrain_z9_tiles.py — 6 pass / 7 skip (по плану) |
✅ PASS |
| AC-17 | Полный pytest tests/ (исключая lxml-зависимые) — 191 passed, 46 skipped |
✅ PASS |
| AC-18 | make lint (✅) + make test (✅ модуль ET-013; полный — внешняя lxml-проблема) |
✅ PASS |
| AC-19 | Pre-deploy curl -sI .../hillshade/{9,10,11}/X/Y.png — hillshade/9 отдаёт 404 |
❌ FAIL (P1) |
| AC-20 | Документация work item (см. §8) | ✅ PASS (12+ файлов) |
| AC-21 | TC-UI-11-NETWORK-Q (требует baseline + Playwright) | ⏳ DEFER → deploy log |
| AC-22 | test_apply_terrain_layer_normalizes_number_to_legacy_paint + …uses_paint_variable |
✅ PASS |
Итого: 10/22 AC закрыты автоматически зелёные · 1 AC FAIL (блокер P1) · 3 AC BLOCKED (зависят от AC-19) · 8 AC делегированы Deployer-агенту.
7. Findings
P0
Нет.
P1
P1-01 — Pre-deploy gate AC-19: hillshade z=9 тайлы отсутствуют
Где. Test-среда https://openclaw.mva154.duckdns.org/enduro/terrain/hillshade/9/*.png.
Симптом. Все запросы вида GET /terrain/hillshade/9/X/Y.png (и
hillshade/8/…) возвращают 404. Покрытие отсутствует на всю
изученную область юга МО / ЦФО (проверено grid'ом 5×5 вокруг
ожидаемой целевой плитки (309, 348) под TMS).
Почему блокер. После деплоя ET-013 фронт:
- понизит UI-минзум hillshade до 9 → чекбокс «Тени рельефа» станет активным на z=9;
- понизит
source.minzoomдо 9 → MapLibre начнёт запрашивать/terrain/hillshade/9/X/Y.png; - получит 404 → слой нарисуется пустым.
Пользователь увидит включённый слой без теней. Это хуже, чем до ET-013, где чекбокс был disabled с честным hint'ом «Зум 10+». Регрессия UX, явно противоречащая AC-03 / AC-07 / AC-13 / BRD-цели ET-013 («перепады читаются на z9-z11»).
Что делать. TRZ REQ-F-20 §1 и AC-19 однозначно говорят:
Если 404 — задача останавливается, тайлы z9 нужно догенерировать в рамках PH-6 follow-up.
Действия:
- Открыть PH-6 follow-up: «Generate hillshade tiles z8-z9 for CFO
coverage» (как минимум область, покрываемая текущим
data/terrain/hillshade/10..14/). - После генерации повторно прогнать probe из §4.1.
- После 200 OK на z=9 — повторный запуск Tester'а + переход на Deployer.
Severity = P1, не P0 только потому, что: (a) код ET-013 корректен и proven unit/integration-тестами; (b) рег-серверная UI-страница сейчас работает (тестовая среда держит до-ET-013, чекбокс правомерно disabled); (c) рабочий процесс PH-6 follow-up — стандартная процедура для такого класса проблем.
P2
Нет.
P3
P3-01 — TRI z=14 отдаёт 404 (предсуществующая регрессия PH-6, не в скоупе ET-013)
GET .../tri/14/X/Y.png → 404. ET-013 не трогает TRI pipeline,
но при включённом TRI и z>11 пользователь видит пустой слой. Покрыть
follow-up'ом «extend TRI tiles to z14».
P3-02 — Cache-Control immutable стрипается nginx-проксей на test
Backend FastAPI отдаёт max-age=31536000, immutable, на проде через
nginx остаётся только max-age=31536000. Формально REQ-F-18 нарушен
на edge-слое, но max-age=1y функционально достаточен. Не в скоупе
ET-013.
P3-03 — from __future__ import annotations в unit-тесте не используется
tests/unit/test_terrain_paint.py:15 — косметика (унаследовано из
review v2 F-5).
P3-04 — Комментарий в HILLSHADE_PAINT не учитывает MapLibre clamping ниже z9
src/web/app.js:2728-2733 — унаследовано из review v2 F-3. Не блокер;
актуально только если UI-минзум hillshade когда-нибудь понизят до z<9.
8. Документация work item (AC-20)
docs/work-items/ET-013/
00-business-request.md ✅
01-brd.md ✅
02-trz.md ✅
03-acceptance-criteria.md ✅
04-test-plan.yaml ✅
04b-ui-test-cases.md ✅
06-adr/ADR-017-zoom-aware-terrain-paint.md ✅
07-infra-requirements.md ✅
08-data-requirements.md ✅
10-tech-risks.md ✅
12-review.md ✅
13-test-report.md ← этот файл
14-deploy-log.md ⏳ ожидается после устранения P1-01
9. Вердикт
BLOCKED. Реализация ET-013 в коде корректна и готова к деплою:
make lintи прицельныйmake test(ET-013 модуль) — зелёные.- 23/23 PASS unit/integration ET-013 (7 SKIP — ожидаемые без data fixtures), 0 регрессий на 191 кейсе остальных тестов.
- Соответствие TRZ / ADR-017 — 1:1 (подтверждено Review v2).
- Контракт API на test-среде — стабилен.
Однако pre-deploy gate AC-19 не пройден (P1-01): на test-среде
отсутствуют hillshade/z9/* (и z8) тайлы. Деплой остановлен
согласно TRZ REQ-F-20 §1 и BRD-приоритету «UX-regression > frontend-fix
ready».
Что должно произойти дальше
- Открыть PH-6 follow-up: «Generate hillshade tiles z8..z9 for
CFO coverage area» (≈ область, покрытая
data/terrain/hillshade/10/, расширенная вверх по zoom-иерархии). - После генерации тайлов:
- повторный пробинг по §4.1 — все 6 ячеек (hillshade/tri × z=9..11) должны вернуть 200;
- повторный запуск Tester'а (изменения отчёта — в виде патча версии
v2 этого файла, без
back-to:devдля самого ET-013); - переход на Deployer.
- Deployer:
- накатить ветку
feature/ET-013-z9-z11-z8в test; - выполнить ручные шаги REQ-F-20 §2: открыть карту,
setZoom(9), включить hillshade, скриншот → визуальная приёмка AC-03..AC-05; - прогнать Playwright TC-UI-01..12 (или хотя бы P1: TC-UI-01, TC-UI-03, TC-UI-07);
- замерить network-объём (TC-UI-11/AC-21) против baseline;
- зафиксировать всё в
14-deploy-log.md.
- накатить ветку
- Если визуальная приёмка AC-07..AC-09 «перепады недостаточно выразительны» — корректировка stops в HILLSHADE_PAINT/TRI_PAINT (это калибровка, не баг — см. BRD §6 «известная итеративность калибровки»).
Что НЕ нужно делать
- Не back-to:dev для ET-013-frontend. Код ETM-013 правильный, тесты
зелёные, ревью пройдено. Изменения в
src/web/app.js/src/web/index.htmlне требуются. - Не закрывать ET-013 без устранения P1-01. Деплой без z9-тайлов даст регрессию UX (включённый, но пустой hillshade на z=9).