106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
PORTABLE_ROOTS = (
|
|
"server",
|
|
"apps/web/src",
|
|
"apps/web/e2e",
|
|
"scripts",
|
|
"docs",
|
|
"demo-data",
|
|
"kangni-analysis",
|
|
"video",
|
|
"_shots",
|
|
"poc/pi-fallback",
|
|
)
|
|
PORTABLE_FILES = (
|
|
".env.example",
|
|
".github/workflows/ci.yml",
|
|
"Dockerfile",
|
|
"docker-image-tag.txt",
|
|
"packaging/k8s/deployment.yaml",
|
|
"README.md",
|
|
)
|
|
TEXT_SUFFIXES = {
|
|
".cjs", ".js", ".json", ".md", ".mjs", ".ps1", ".py",
|
|
".ts", ".tsx", ".txt", ".yaml", ".yml",
|
|
}
|
|
MACHINE_PATH = re.compile(
|
|
r"(?i)(?:[A-Z]:[\\/](?:ItemSpace|KimiData)[\\/]|[A-Z]:[\\/]Users[\\/](?!<|tester[\\/]))",
|
|
)
|
|
ESCAPED_MACHINE_PATH = re.compile(
|
|
r"(?i)(?:[A-Z]:\\\\(?:ItemSpace|KimiData)\\\\|[A-Z]:\\\\Users\\\\(?!<|tester\\\\))",
|
|
)
|
|
E2E_CREDENTIAL_DEFAULT = re.compile(
|
|
r"E2E_JMS_(?:USER|PASSWORD)\s*\|\|\s*['\"][^'\"]+['\"]",
|
|
)
|
|
|
|
|
|
def _is_runtime_or_fixture(path: Path) -> bool:
|
|
relative = path.relative_to(REPO_ROOT)
|
|
parts = relative.parts
|
|
if parts[:2] == ("server", "data"):
|
|
return True
|
|
if parts[:2] != ("poc", "pi-fallback"):
|
|
return False
|
|
if "runs" in parts or "runtime" in parts or "tests" in parts:
|
|
return True
|
|
return "smoke" in parts and any(part.startswith("site") for part in parts)
|
|
|
|
|
|
def _portable_files() -> list[Path]:
|
|
files = [REPO_ROOT / name for name in PORTABLE_FILES]
|
|
for root_name in PORTABLE_ROOTS:
|
|
root = REPO_ROOT / root_name
|
|
if not root.exists():
|
|
continue
|
|
files.extend(
|
|
path for path in root.rglob("*")
|
|
if path.is_file()
|
|
and path.suffix.lower() in TEXT_SUFFIXES
|
|
and "node_modules" not in path.parts
|
|
and ".pi" not in path.parts
|
|
and not _is_runtime_or_fixture(path)
|
|
)
|
|
return files
|
|
|
|
|
|
@pytest.mark.parametrize("path", _portable_files(), ids=lambda path: str(path.relative_to(REPO_ROOT)))
|
|
def test_deployable_files_do_not_embed_machine_paths_or_e2e_credentials(path: Path):
|
|
text = path.read_text(encoding="utf-8", errors="ignore")
|
|
assert not MACHINE_PATH.search(text), f"machine-bound path in {path.relative_to(REPO_ROOT)}"
|
|
assert not ESCAPED_MACHINE_PATH.search(text), (
|
|
f"escaped machine-bound path in {path.relative_to(REPO_ROOT)}"
|
|
)
|
|
assert not E2E_CREDENTIAL_DEFAULT.search(text), f"credential fallback in {path.relative_to(REPO_ROOT)}"
|
|
|
|
|
|
def test_environment_template_contains_no_secret_values():
|
|
values: dict[str, str] = {}
|
|
for raw_line in (REPO_ROOT / ".env.example").read_text(encoding="utf-8").splitlines():
|
|
line = raw_line.strip()
|
|
if not line or line.startswith("#") or "=" not in line:
|
|
continue
|
|
key, value = line.split("=", 1)
|
|
values[key.strip()] = value.strip()
|
|
for key in ("LLM_API_KEY", "JMS_AUTH_SESSION_SECRET"):
|
|
assert values.get(key, "") == "", f"{key} must stay empty in .env.example"
|
|
|
|
|
|
def test_docker_image_metadata_is_template_only():
|
|
values: dict[str, str] = {}
|
|
for raw_line in (REPO_ROOT / "docker-image-tag.txt").read_text(encoding="utf-8").splitlines():
|
|
line = raw_line.strip()
|
|
if not line or line.startswith("#") or "=" not in line:
|
|
continue
|
|
key, value = line.split("=", 1)
|
|
values[key.strip()] = value.strip()
|
|
for key in ("IMAGE_REPOSITORY", "IMAGE_TAG", "IMAGE", "IMAGE_ID", "IMAGE_SIZE"):
|
|
assert values.get(key, "") == "", f"{key} must stay empty in docker-image-tag.txt"
|