exchanger/docs/hardware/BOARD_ACCEPTANCE_TESTS.md

12 KiB
Raw Permalink Blame History

Аппаратные приёмочные тесты контроллера

Назначение

Проект tests/Exchanger.HardwareTests предназначен для проверки реальной платы через Windows USB-COM сразу после её подключения. Он использует те же SerialPortHardware, ControllerAuthenticator, AES-ключ, parser и PeripheryMachineController, что и приложение, поэтому проверяет production-путь, а не отдельную тестовую реализацию.

Аппаратные тесты включены в solution для проверки компиляции, но без EXCHANGER_BOARD_TESTS=1 пропускаются. Обычный dotnet test Exchanger.sln не открывает COM-порт, не включает приёмники оплаты и не запускает хоппер.

Перед запуском

  1. Подключить и запитать контроллер.
  2. Узнать его COM-порт в диспетчере устройств Windows.
  3. Закрыть Exchanger, терминал производителя и другие программы, которые могут удерживать этот порт.
  4. Освободить лоток хоппера и подготовить тестовые деньги только перед интерактивными группами.
  5. Начинать с группы Safe.

Все команды ниже выполняются из корня репозитория. Результат каждого запуска сохраняется как TRX в локальном каталоге artifacts/board-tests/, который исключён из Git.

Безопасная автоматическая проверка

powershell -ExecutionPolicy Bypass -File .\tests\Exchanger.HardwareTests\run-board-tests.ps1 `
  -Port COM5 `
  -Group Safe

Группа HardwareSafe проверяет:

  • открытие порта с профилем 115200 8N1/None;
  • аппаратный RTS-reset и полный startup-handshake periphery controller ver_<version> → 2000 ms → 07 → CHAL → 08 → RAES → READY! с production AES-256 ECB/NoPadding и обязательной проверкой proof; AUTH_PC_OK и AUTH_CNT_OK распознаются как промежуточные кадры, но не заменяют точный READY!;
  • переходы Authenticating → Ready → Disconnected;
  • ответ INPUT на команду 91;
  • соответствие active-low входу: сигнал на IN1 (бит 0) → Low, отсутствие сигнала (бит 1) → Enough;
  • ответы на 140, 150, 160, 3090 и 99 без вывода сырых кадров в отчёт;
  • три цикла закрытия, повторного открытия и повторной авторизации; число циклов меняется параметром -ReconnectCycles от 1 до 20.

Привязка кнопок и переходов приложения к 141/142, 151/152, 161/162/163, обязательным ASK:* и пакетным командам 309N проверяется обычным набором Exchanger.Tests через wire-симулятор. Группа Safe намеренно не включает приём денег и мотор.

Status-тест намеренно требует хотя бы один ответный не-handshake кадр. Если реальная прошивка не отвечает на команду или формат отличается от документации, тест завершится ошибкой и тем самым зафиксирует несовместимость для корректировки parser/документации.

На подключённой плате CP210x/COM3 группа Safe исторически пройдена 2026-08-27: 9/9 тестов, включая INPUT<decimal>, active-low преобразование IN1 в типизированный уровень запаса, ответы на status-команды и три повторные авторизации. Эти результаты относятся к прежней прошивке и старым запросам 309?/409?; актуальный runner использует 3090, поэтому после подключения обновлённой платы пакет требуется повторить.

Повторный прогон 2026-08-31 подтвердил новый startup-контракт: отдельный Probe прошёл 1/1, а Safe — 8/9. Исторически были успешны авторизация, INPUT/IN1, 140, 150, старый запрос состояния хоппера, 99 и три reconnect-цикла. Только 160 дважды не получил ответ, поэтому эта проверка остаётся красной до уточнения наличия/состояния Вендиста или поведения прошивки. Результаты: artifacts/board-tests/board-probe-20260831-105348.trx и artifacts/board-tests/board-safe-20260831-104124.trx.

Если плата возвращает CHAL/RAES, но production-проверка proof не проходит, используйте безопасный фиксированный probe. Он не запускает периферию и не пишет сырые handshake-блоки в отчёт: сравнивает только семантику proof и короткие SHA-256 fingerprints.

powershell -ExecutionPolicy Bypass -File .\tests\Exchanger.HardwareTests\run-board-tests.ps1 `
  -Port COM5 `
  -Group Probe

Кнопка SERVICE, монетник, купюроприёмник и датчик

Эти тесты ждут ручное действие и не запускаются без -ConfirmInteractive.

powershell -ExecutionPolicy Bypass -File .\tests\Exchanger.HardwareTests\run-board-tests.ps1 `
  -Port COM5 `
  -Group Interactive `
  -ConfirmInteractive `
  -CoinRubles 10 `
  -BillRubles 100 `
  -StockInput 1 `
  -ExpectedStock Enough `
  -InteractionTimeoutSeconds 90

Во время запуска тест попросит:

  • нажать физическую кнопку SERVICE;
  • внести одну монету указанного номинала;
  • внести одну купюру указанного номинала;
  • заранее привести датчик хоппера к ожидаемому состоянию.

Для проверки обоих сигналов датчика тест запускается дважды: сначала с -ExpectedStock Enough, затем после физического изменения уровня с -ExpectedStock Low. По умолчанию используется подтверждённая active-low разводка: сигнал на IN1 (бит 0) → Low; альтернативная active-high полярность задаётся как -StockLowWhenHigh:$true.

Если конкретная периферия ещё не подключена, соответствующий номинал можно не передавать: такой тест будет отмечен пропущенным, остальные продолжат работу.

Реальная банковская операция

Тест Вендиста может списать реальные деньги и требует отдельного осознанного подтверждения:

powershell -ExecutionPolicy Bypass -File .\tests\Exchanger.HardwareTests\run-board-tests.ps1 `
  -Port COM5 `
  -Group Payment `
  -CardRubles 10 `
  -ConfirmRealPayment `
  -InteractionTimeoutSeconds 120

Проверяется команда оплаты, событие MONEY:CASHLESS:<сумма>, обязательный ASK:CASHLESS:<сумма> и типизированный итог Approved. Автоматический возврат денежных средств тест не выполняет.

Физическая выдача жетонов

Тест запускает мотор хоппера и требует отдельного подтверждения:

powershell -ExecutionPolicy Bypass -File .\tests\Exchanger.HardwareTests\run-board-tests.ps1 `
  -Port COM5 `
  -Group Dispense `
  -DispenseCount 2 `
  -ConfirmDispense `
  -InteractionTimeoutSeconds 60

За один тест разрешено от 1 до 10 жетонов. Текущий интерактивный runner физически проверяет первый хоппер командой 309N; production-runtime дополнительно поддерживает второй канал 409N, который покрыт программными тестами. Перед аппаратной приёмкой двух хопперов runner нужно запускать отдельными явно подтверждёнными сценариями, чтобы один запуск не включал два двигателя неожиданно.

Прошивочный предел одной пакетной команды — 99 жетонов: приложение не отправляет 309100 или 409100, на которые плата отвечает ошибками групп 30 и 40. Крупные выдачи обоих каналов проверяются программными тестами как последовательность пакетов максимум по 99.

Отдельный интерактивный тест прямого мотора пока использует только 301/300 и считает строки HOPPER1 PULSE=1. Production-приложение уже поддерживает симметричный пересчёт второго хоппера 401/400 → HOPPER2 PULSE=1; его физический прогон требует отдельного явного подтверждения владельца.

Реальный приёмочный runner сохраняет предел 10 за один запуск, чтобы случайная проверка не опустошила хоппер. Многожетонная логика и суммарный partial-result проверяются детерминированно в симуляторе.

Отключение USB-кабеля

powershell -ExecutionPolicy Bypass -File .\tests\Exchanger.HardwareTests\run-board-tests.ps1 `
  -Port COM5 `
  -Group Cable `
  -ConfirmCable `
  -InteractionTimeoutSeconds 120

После приглашения нужно отключить USB, дождаться сообщения о потере связи и подключить кабель обратно. Тест периодически пытается открыть то же имя COM-порта и требует второй успешный handshake. Если Windows назначит другое имя порта, запуск завершится ошибкой; новый порт следует передать в следующем прогоне.

Границы набора

Набор проверяет все интерфейсы, которые сейчас использует Exchanger. Он специально не отправляет:

  • 00 RESET и команды обновления прошивки;
  • произвольные команды силовых выходов 20/21/22;
  • команды световых каналов и конфигурации конкретного автомата;
  • автоматический повтор выдачи после обрыва;
  • недокументированные команды возврата платежа.

Такие операции требуют отдельной схемы конкретного аппарата и явного решения владельца. Сырые handshake-кадры, AES-данные и полные ответы платы не включаются в NUnit/TRX-отчёты; сохраняются только безопасные категории сообщений и результаты проверок.