zapretgui/tests/test_worker_ui_boundary.py
loop-uh f88541fa6b Перестроить BlockCheck на единый планировщик проб
Проверки шли семью последовательными фазами, и один хост резолвился до пяти
раз: в preflight, в каждой TLS-пробе, в ISP-пробе и в ping-пробе. Теперь этапа
три — опорная точка с однократным резолвом, параллельная группа проб под общим
дедлайном и чистый анализ, — а массовый preflight убран: те же проверки делает
планировщик, и отдельная фаза означала только двойной коннект к каждому хосту.

Вместе с этим:

- вердикт вынесен в отдельный движок с сигнатурами, данные списков — в
  data_lists, подписи DPI для интерфейса — в ui/dpi_labels;
- удалён blockcheck2.py и файлы данных, которые он обслуживал;
- наблюдатель за зависаниями интерфейса ставится из entry.py, где живёт event
  loop, а не из post-startup задач;
- profile payload и background worker gate приведены к одному пути обновления.

Проверки: compileall, architecture_checks, 369 тестов затронутых областей.
Полный прогон — 4121 passed; падения в preset-UI (Qt/fluent на Linux),
preset_folder_actions (тест не знает про папку 1.10.0) и build_resource_layout
(состояние приватного репозитория) существовали и до этих правок.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 15:46:08 +03:00

56 lines
2 KiB
Python
Raw Permalink 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.

from __future__ import annotations
import ast
from pathlib import Path
import unittest
SRC_ROOT = Path(__file__).resolve().parents[1] / "src"
ALLOWED_UI_IMPORTS = {
"ui.latest_value_worker_state",
"app.ui_texts",
"ui.one_shot_worker_runtime",
"ui.queued_worker_state",
# Инфраструктура запуска воркеров, а не страницы: гейт параллелизма и
# проверка потокового контракта.
"ui.background_worker_gate",
"ui.ui_thread_guard",
}
class WorkerUiBoundaryTests(unittest.TestCase):
def test_worker_modules_do_not_import_page_ui_packages(self) -> None:
offenders: list[str] = []
for path in self._iter_worker_modules():
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
rel_path = path.relative_to(SRC_ROOT).as_posix()
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
module = str(alias.name or "")
if self._is_forbidden_ui_import(module):
offenders.append(f"{rel_path}:{node.lineno}:import {module}")
elif isinstance(node, ast.ImportFrom):
module = str(node.module or "")
if self._is_forbidden_ui_import(module):
offenders.append(f"{rel_path}:{node.lineno}:from {module} import ...")
self.assertEqual([], offenders)
def _iter_worker_modules(self) -> list[Path]:
return sorted(
path
for path in SRC_ROOT.rglob("*.py")
if "worker" in path.name or path.name.endswith("workers.py")
)
def _is_forbidden_ui_import(self, module: str) -> bool:
clean = str(module or "")
if clean in ALLOWED_UI_IMPORTS:
return False
return clean.startswith("ui.") or ".ui." in clean or clean.endswith(".ui")
if __name__ == "__main__":
unittest.main()