Files
enduro-trails/docs/work-items/ET-013/13-test-report.md
claude-bot 316bb0d1a6
All checks were successful
CI / lint (push) Successful in 4s
CI / lint (pull_request) Successful in 4s
CI / test (push) Successful in 10s
CI / build (push) Successful in 2s
CI / test (pull_request) Successful in 9s
CI / build (pull_request) Successful in 2s
tester(ET): auto-commit from tester run_id=85
2026-06-04 10:10:25 +00:00

27 KiB
Raw Blame History

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
agent:tester
ET-007
PH-6.terrain
ADR-017

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-z8 1: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.pnghillshade/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.pnghillshade/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.

Действия:

  1. Открыть PH-6 follow-up: «Generate hillshade tiles z8-z9 for CFO coverage» (как минимум область, покрываемая текущим data/terrain/hillshade/10..14/).
  2. После генерации повторно прогнать probe из §4.1.
  3. После 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».

Что должно произойти дальше

  1. Открыть PH-6 follow-up: «Generate hillshade tiles z8..z9 for CFO coverage area» (≈ область, покрытая data/terrain/hillshade/10/, расширенная вверх по zoom-иерархии).
  2. После генерации тайлов:
    • повторный пробинг по §4.1 — все 6 ячеек (hillshade/tri × z=9..11) должны вернуть 200;
    • повторный запуск Tester'а (изменения отчёта — в виде патча версии v2 этого файла, без back-to:dev для самого ET-013);
    • переход на Deployer.
  3. 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.
  4. Если визуальная приёмка 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).