Files
ewsdr/test/serial/README.md
T
ew8bakandClaude Opus 5 f88b1615e7 fix(serial): контракт SerValid — платформенный, ноль значит разное
Ноль на Unix и на Windows означает не одно и то же, и одной проверкой тут не
обойтись. На Unix это законный дескриптор (при закрытом стандартном вводе
fpOpen отдаёт именно его), а ядро Windows нулевой хендл не выдаёт никогда —
там ноль это либо отказ RTL, либо неинициализированное поле. Внутренний путь
был безопасен и раньше (SerOpen переводит ноль RTL в SER_INVALID_HANDLE, свои
поля инициализируются им же), но публичный контракт для значения, пришедшего
извне, оказывался неверным. Теперь проверка разведена по платформам.

★Стенд научился ПРОГОНЯТЬ windows-ветку, а не только компилировать её.
Заглушка модуля Serial — чистый Паскаль, поэтому ветку можно собрать и
запустить прямо на Linux: test/platform/win_probe проверяет перевод нулевого
хендла в SER_INVALID_HANDLE, ответ SerValid и правило имени COM10+. До сих пор
у windows-пути обёртки не было никакого поведенческого покрытия вовсе.

Негативный контроль: если убрать windows-ветку из SerValid, прогон падает на
«★нулевой хендл под Windows негоден».

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bkwwyj7xVRrqnSVEseTRfV
2026-08-24 22:43:14 +03:00

54 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Стенд последовательного порта
Проверяет обёртку `SerialPort.pas` на **псевдотерминале**: настоящего COM-порта
на сборочной машине нет, а проверить надо ровно то, на чём обжигается перенос —
как обёртка **настраивает** порт.
```
test/serial/run.sh
```
## Что проверяется
* **Открытие**: несуществующий порт даёт `SER_INVALID_HANDLE` (а не ноль и не
случайное число), живой — годный хендл.
* ★**Дескриптор 0 — законный порт**: стенд закрывает стандартный ввод, после
чего порт открывается именно как `0`, и проверяет, что он считается годным и
через него идут данные. Признак неудачи ровно один — `SER_INVALID_HANDLE`.
Проверка вида «ноль = ошибка» теряла бы рабочий порт у демона и вдобавок не
закрывала дескриптор (`SerClose` смотрит на ту же проверку).
* ★**Имя устройства для Windows**: `COM10` и выше `CreateFile` открывает только
в форме `\\.\COM10` — короткое имя система резолвит лишь для `COM1..COM9`, а у
USB-переходников номер за десяток заезжает легко. Правило чистое
(`SerWinDeviceName`), поэтому проверяется и на Linux: короткие имена не
трогаются, длинные получают префикс, уже полная форма не удваивается, пути
Unix не задеваются.
* **termios обратным чтением**: скорость, стоп-биты, `CREAD`/`CLOCAL`, сырой
режим (нет `ICANON`, `ECHO`, `OPOST`).
* ★**Аппаратный поток `CRTSCTS` не включается сам** — только по явной просьбе.
Это главная проверка стенда: на кабеле без CTS случайно включённый CRTSCTS
вешает передачу намертво, и никакой ошибки при этом нет. Ровно так ломается
RTL-модуль `Serial` на BSD и macOS — там B-константы это числа, а он кладёт
их в `c_cflag` (подробнее — в шапке `SerialPort.pas`).
* ★**В `c_cflag` нет ничего, кроме наших флагов** (маска `CBAUD` снимается) —
прямая ловушка на ту же ошибку. Негативный контроль: если в `SerSetParams`
дописать `or Cardinal(BitsPerSec)`, проверка падает с «1CAB0 против 8B0».
* **Формат** (размер символа, чётность, стоп-биты, флаг потока) — через чистую
`SerCFlags`. Обратным чтением его не проверить: pty восьмибитно-чистый, ядро
молча заменяет `CS7` на `CS8` и снимает `PARENB`.
* **Обмен**: запись и чтение в обе стороны, срок у `SerReadTimeout`, `CR` не
превращается в `CR+LF`, эха нет.
* **Сквозной прогон**: байты на мастере → поток `CATSerial``TCATEngine`
ответ обратно (командой `ID`, она отвечает константой и радио не трогает).
## Чего стенд НЕ проверяет
Модемные линии `DTR`/`RTS`/`CTS`/`DSR`/`CD`/`RI`: ioctl `TIOCM*` на
псевдотерминале не работает. Это остаётся на живой порт с железкой — там же
проверяется и телеграфный ключ на `CWKeyer`.
Платформенные ветви (Windows, macOS) проверяет соседний стенд `test/platform`:
компиляцию обеих, а windows-ветку ещё и прогоном на заглушке модуля `Serial`
перевод нулевого хендла RTL в `SER_INVALID_HANDLE`, ответ `SerValid` (там ноль
негоден, в отличие от Unix) и правило имени `COM10+`.