This commit is contained in:
commit
f970031c36
3 changed files with 77 additions and 4 deletions
|
|
@ -20,4 +20,5 @@ uvicorn==0.54.0
|
||||||
sse-starlette==3.5.0
|
sse-starlette==3.5.0
|
||||||
python-multipart==0.0.32
|
python-multipart==0.0.32
|
||||||
py-spy==0.4.2
|
py-spy==0.4.2
|
||||||
watchdog==6.0.0numpy>=2.0 # ядро Коди (harness/kodi_core.py): обучение учеников
|
watchdog==6.0.0
|
||||||
|
numpy>=2.0 # ядро Коди (harness/kodi_core.py): обучение учеников
|
||||||
|
|
|
||||||
|
|
@ -166,9 +166,18 @@ os.environ["SIMBIOT_PORTAL_MCP_TOKEN_FILE"] = "/tmp/my-token"
|
||||||
check("paths: env TOKEN_FILE бьёт схему",
|
check("paths: env TOKEN_FILE бьёт схему",
|
||||||
_paths.portal_mcp_token_path() == "/tmp/my-token")
|
_paths.portal_mcp_token_path() == "/tmp/my-token")
|
||||||
del os.environ["SIMBIOT_PORTAL_MCP_TOKEN_FILE"]
|
del os.environ["SIMBIOT_PORTAL_MCP_TOKEN_FILE"]
|
||||||
check("paths: изолят → secrets/portal-mcp-token",
|
# герметичность: поведение изолята не зависит от того, на каком инстансе
|
||||||
_paths.portal_mcp_token_path().endswith("secrets/portal-mcp-token"),
|
# запущен тест (legacy-хост без SIMBIOT_HOME иначе даёт ложный FAIL) —
|
||||||
_paths.portal_mcp_token_path())
|
# патчим _HOME/IS_ISOLATED как это делают остальные тесты схемы путей
|
||||||
|
_saved = (_paths._HOME, _paths.IS_ISOLATED)
|
||||||
|
_paths._HOME = "/tmp/simbiot-test-home"
|
||||||
|
_paths.IS_ISOLATED = True
|
||||||
|
try:
|
||||||
|
check("paths: изолят → secrets/portal-mcp-token",
|
||||||
|
_paths.portal_mcp_token_path().endswith("secrets/portal-mcp-token"),
|
||||||
|
_paths.portal_mcp_token_path())
|
||||||
|
finally:
|
||||||
|
_paths._HOME, _paths.IS_ISOLATED = _saved
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print("FAILURES:", fails if fails else "нет — все проверки пройдены")
|
print("FAILURES:", fails if fails else "нет — все проверки пройдены")
|
||||||
|
|
|
||||||
63
tests/test_requirements_valid.py
Normal file
63
tests/test_requirements_valid.py
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""requirements.txt валиден для pip (t-261019001038-0eb7d7) — hermetic.
|
||||||
|
|
||||||
|
Запуск: ./venv/bin/python tests/test_requirements_valid.py
|
||||||
|
|
||||||
|
Регрессия: на origin/master строка watchdog==6.0.0numpy>=2.0 была склеена
|
||||||
|
без перевода строки — pip install -r requirements.txt падал на СВЕЖИХ
|
||||||
|
установках install.sh (curl install.sh | bash) с InvalidRequirement,
|
||||||
|
ломая канал дистрибуции харнеса. Проверяем через packaging.Requirement
|
||||||
|
(тот же парсер, что у pip): каждая строка файла — ровно одно валидное
|
||||||
|
требование, watchdog и numpy распознаны отдельными пакетами.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.path.insert(0, "/root/simbiot-harness")
|
||||||
|
|
||||||
|
from packaging.requirements import Requirement
|
||||||
|
|
||||||
|
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
REQ = os.path.join(REPO, "requirements.txt")
|
||||||
|
|
||||||
|
fails = []
|
||||||
|
|
||||||
|
|
||||||
|
def check(name, cond, extra=""):
|
||||||
|
print(("PASS" if cond else "FAIL"), name, ("| " + str(extra)) if not cond else "")
|
||||||
|
if not cond:
|
||||||
|
fails.append(name)
|
||||||
|
|
||||||
|
|
||||||
|
# все строки-требования парсятся packaging (тот же парсер, что у pip):
|
||||||
|
# склейка watchdog==6.0.0numpy>=2.0 дала бы InvalidRequirement
|
||||||
|
req_names = []
|
||||||
|
for i, line in enumerate(open(REQ, encoding="utf-8"), 1):
|
||||||
|
s = line.split("#", 1)[0].strip()
|
||||||
|
if not s:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
r = Requirement(s)
|
||||||
|
except Exception as e:
|
||||||
|
check("строка %d валидна (InvalidRequirement)" % i, False, repr(e))
|
||||||
|
continue
|
||||||
|
req_names.append(r.name.lower())
|
||||||
|
check("все строки requirements.txt валидны для pip", True)
|
||||||
|
|
||||||
|
# ключевые пакеты распознаны как отдельные требования
|
||||||
|
for name in ("watchdog", "numpy"):
|
||||||
|
check("зависимость %r отдельной строкой" % name, name in req_names)
|
||||||
|
|
||||||
|
# битая склейка действительно ловится парсером (self-check теста)
|
||||||
|
try:
|
||||||
|
Requirement("watchdog==6.0.0numpy>=2.0")
|
||||||
|
glued_raises = False
|
||||||
|
except Exception:
|
||||||
|
glued_raises = True
|
||||||
|
check("парсер отклоняет склейку watchdog==6.0.0numpy>=2.0", glued_raises)
|
||||||
|
|
||||||
|
print()
|
||||||
|
if fails:
|
||||||
|
print("FAILED:", len(fails))
|
||||||
|
sys.exit(1)
|
||||||
|
print("OK: requirements.txt валиден (watchdog и numpy отдельными строками)")
|
||||||
Loading…
Reference in a new issue