generated from mononoki/pyproj
120 lines
9.9 KiB
Markdown
120 lines
9.9 KiB
Markdown
# Проверка SIRMENT/core — 7 октября 2026
|
||
|
||
Изменены тесты и Markdown. Исходники `src` при этой доработке не редактировались;
|
||
сохранённые изменения автора проекта оставлены на месте.
|
||
|
||
## Уточнённые ожидания
|
||
|
||
Тесты проверяют согласованное поведение системы:
|
||
|
||
- Ошибка разбора входного пакета может завершать обработчик этого клиента.
|
||
Проверяется закрытие транспорта, сохранение записи на окно восстановления,
|
||
последующее удаление записи/маршрутов и работа другого TCP-соединения.
|
||
Разрешается только проверенное исключение конкретного плохого клиента;
|
||
остальные ошибки не скрываются.
|
||
- Отсутствующая команда отключает сразу. Неверная команда до handshake
|
||
проверяется на установленном лимите из пяти логических ошибок.
|
||
- Отказ handshake означает только буквальный JSON `false`. Остальные значения
|
||
`status`, включая `0`, `null`, пустые строку/массив/объект, должны разрешать
|
||
продолжение. Проверяются три представителя: True, False и Other = 0.
|
||
Требование boolean и перебор всех ложных значений удалены.
|
||
- Полезная нагрузка данных сохраняется и пересылается как исходное JSON-значение,
|
||
без преобразования в словарь. Содержимое heartbeat не используется.
|
||
- `connection.payload.token` хранится как `auth` робота; отсутствие/null и
|
||
строковый токен проверяются отдельно от UID/upf восстановления.
|
||
Будущая whitelist-проверка не вводится.
|
||
- Фоновые отправки продолжают работать отдельными задачами. Проверяется, что
|
||
ожидание отправки не блокирует обработку данных.
|
||
- Сетевая ошибка фоновой отправки должна быть видна с исходным исключением.
|
||
Стандартное логирование asyncio допустимо. Немедленное отключение от одной
|
||
ошибки отдельной задачи не требуется; закрытие проверяется через настоящий EOF.
|
||
- При разрыве во время отправки допустимы сетевая ошибка или отмена задачи.
|
||
Проверяются однократное закрытие и работа другого соединения.
|
||
- Ошибка закрытия вводится в `writer.wait_closed` настоящего `Connection.close`,
|
||
чтобы проверить защиту на уровне транспорта и последующую очистку менеджером.
|
||
|
||
Удалены искусственная сериализация Python set, обязательная отмена уже
|
||
запланированной отправки при смене состояния, запрет сообщения
|
||
`Task exception was never retrieved` и требование нулевого числа исключений
|
||
при корректном отключении некорректного клиента. Реальные TCP-интеграционные
|
||
тесты сохранены; мок сервера не используется.
|
||
|
||
## Последний полный прогон
|
||
|
||
Среда: Windows, Python 3.11.15 из Anaconda `sites`, pytest 9.1.1,
|
||
pytest-cov 7.1.0, coverage 7.16.2.
|
||
|
||
```sh
|
||
python -m pytest -q --cov=src --cov-branch --cov-report=term-missing --cov-report=xml
|
||
```
|
||
|
||
**106 сценариев: 105 passed, 1 failed.**
|
||
|
||
| Причина | Падений | Что происходит |
|
||
| --- | ---: | --- |
|
||
| test_handshake_status_follows_protocol[other] | 1 | Other = 0 должен разрешать handshake; текущий if not status запускает retry, и ожидание heartbeat_answer завершается TimeoutError |
|
||
|
||
True проходит полный handshake и heartbeat. False сохраняет ready, вызывает
|
||
повторный handshake и допускает последующий успешный ответ True. Значение 0
|
||
выбрано единственным Other: оно отличает буквальный false от ложности Python.
|
||
|
||
Сохранённые исправления автора проекта в Connection.close и Session.send
|
||
проверены: проходят обработка ошибки writer.wait_closed с последующей очисткой,
|
||
запрет новых отправок в stop/migrated, handshake, heartbeat и фоновые отправки.
|
||
|
||
Проходят также изоляция/очистка некорректных пакетов, TCP-фрейминг,
|
||
гонка watcher/finally, восстановление, видимость фоновых сетевых ошибок,
|
||
разрыв во время отправки и настоящий main.py/TCP.run в отдельном процессе.
|
||
Тесты не имеют xfail или пропусков. Исходники src не исправлялись тестами.
|
||
|
||
## Покрытие последнего прогона
|
||
|
||
pytest-cov с учётом ветвей показывает **99%**:
|
||
|
||
- строки: **192 из 193**, 99,48%;
|
||
- ветви: **55 из 56**, 98,21%.
|
||
|
||
Дочерний процесс включён в покрытие: main.py и TCP.run выполнены.
|
||
Единственный непокрытый путь — отсутствующий UID в SessionManager.__getitem__,
|
||
строка 63. Отдельный тест простого getter ради процента не добавлен.
|
||
|
||
Высокий процент не отменяет оставшееся расхождение status: один тест падает.
|
||
Порог 100% и исключения ради повышения процента не вводились.
|
||
|
||
## Воспроизводимость и ограничения
|
||
|
||
Общий клиент находится в отслеживаемом `examples/client.py`; fixture не зависит
|
||
от игнорируемого `src/.test`. Перенос ранее проверен чистым локальным Git-клоном
|
||
снимка рабочих файлов: клиент доступен без этой папки. Новая редакция тестов
|
||
проверена в рабочем дереве; повторный клон этого снимка не запускался.
|
||
|
||
Процессный тест выполняет настоящий main.py через `tests/entrypoint_runner.py`.
|
||
Обёртка меняет только адрес/порт настоящего asyncio.start_server на
|
||
`127.0.0.1:0`, запускает собственный stdin-контроль отмены главной корутины
|
||
и позволяет сохранить покрытие дочернего процесса. Production CLI настройки
|
||
порта и обработка SIGTERM/CTRL+C самим main.py не проверяются.
|
||
|
||
Сохранены проверки реконекта: перенос данных и динамических метаданных,
|
||
маршруты в обе стороны, отдельный handshake, неверный upf,
|
||
активная/отсутствующая/перенесённая сессия, однократность и безопасность старой
|
||
очистки после восстановления.
|
||
|
||
Оставшиеся ограничения:
|
||
|
||
- Сроки 60 секунд до первого heartbeat, 5 секунд после heartbeat и 60 секунд
|
||
восстановления проверяются управляемыми часами, без настоящих длинных пауз.
|
||
- Проверяется выбранное пересечение watcher/TCP-finally, но не длительный
|
||
стресс множества соединений, переполнение буферов и задержки event loop.
|
||
- Не охвачены все поля метаданных/типы UID и upf, повреждённый UTF-8,
|
||
предельная длина пакетов и исчерпание ресурсов.
|
||
- Не проверена доступная внешнему JSON-клиенту ошибка сериализации:
|
||
искусственный Python set не является таким сценарием.
|
||
- Linux/Gitea/Docker в этой среде не запускались.
|
||
- GUI/API и автоматическое создание маршрутов, авторизация по whitelist,
|
||
полноценное переключение диалектов, WebSocket/sio и сохранение состояния
|
||
после перезапуска ещё не реализованы и не предполагаются тестами.
|
||
- Отдельного ответа о результате восстановления пока нет; правило объединения
|
||
старых и новых статических метаданных и назначение com ещё не закреплены.
|
||
|
||
Команды запуска и методика описаны в [README.md](README.md).
|