# test_recovery ## Модуль под тестом `firmware/bootloader/src/recovery.c` (`recovery.h`) — чистая логика решения «что делать с этой попыткой загрузки» (таксономия отказов Фазы 6, классы B/C/D), без аппаратных зависимостей (`SRC_GPR`/flash). См. `firmware/bootloader/PLAN.md`. ## Категория A — платформонезависимый модуль. Переиспользует `update_policy_slot_state_t` и `image_version_compare()` из `update_policy.c` (линкуется вместе с тестом), сам `bootutil` не линкуется. ## Моки Нет — тестируется напрямую, без фейков/стабов. ## Что проверяется - **BSP_BUTTON_2 удержана** — `RECOVERY_ENTER_RECOVERY_MODE` независимо от счётчика попыток и состояния слотов (ручной триггер главнее счётчика). - **Счётчик ниже порога** — `RECOVERY_NORMAL_BOOT`, независимо от слотов. - **Счётчик на пороге, есть фолбэк** (второй слот валиден) — `RECOVERY_ERASE_ACTIVE_THEN_BOOT_OTHER` с правильным `active_slot` (активный — слот с более высокой версией, тот же приём, что в `update_policy_decide()`), проверено для обеих сторон (А активен/Б активен). - **Счётчик выше порога** — фолбэк продолжает срабатывать (не только ровно на пороге). - **Счётчик на пороге, фолбэка нет** (единственный валидный слот, или ни одного валидного) — `RECOVERY_ENTER_RECOVERY_MODE` (стирать единственный рабочий слот нельзя). ## Гарантии - Класс A (незавершённая установка, `copy_done!=image_ok`) этой функцией не закрывается — целиком авто-откат штатным revert MCUboot, без участия загрузчика. - Фолбэк никогда не оставляет ноль валидных слотов — стирается только активный, и только когда другой уже подтверждён валидным. ## Запуск ```bash ctest --preset host-debug-test -R test_recovery -V ```