# Проверка 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).