Files
pythonocc-step-editor/scripts/verify_scdm_backend.py
T

158 lines
6.6 KiB
Python

from __future__ import annotations
import ast
import os
import re
import subprocess
import sys
import tempfile
from contextlib import contextmanager
from pathlib import Path
from typing import Iterator
PROJECT_ROOT = Path(__file__).resolve().parent.parent
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from step_editor.scdm_backend import ( # noqa: E402
SCDM_DISABLE_ENV,
SCDM_PATH_ENV_VARS,
ScdmBackendInfo,
default_scdm_cache_path,
discover_scdm_backend_candidates,
load_scdm_backend_cache,
resolve_scdm_backend,
save_scdm_backend_cache,
scdm_run_script_command,
verify_scdm_backend,
)
def _assert(condition: bool, message: str) -> None:
if not condition:
raise AssertionError(message)
@contextmanager
def _patched_env(values: dict[str, str | None]) -> Iterator[None]:
original = {key: os.environ.get(key) for key in values}
try:
for key, value in values.items():
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value
yield
finally:
for key, value in original.items():
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value
def _fake_spaceclaim(path: Path) -> Path:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("fake", encoding="utf-8")
return path
def _fake_runner(command: list[str], **_kwargs: object) -> subprocess.CompletedProcess[str]:
script_args = [item for item in command if item.startswith("/RunScript=")]
_assert(script_args, f"missing /RunScript argument: {command}")
script_path = Path(script_args[0].split("=", 1)[1])
script = script_path.read_text(encoding="utf-8")
match = re.search(r"report_path\s*=\s*(.+)", script)
_assert(match is not None, f"smoke script should define report_path: {script}")
report_path = Path(ast.literal_eval(match.group(1).strip()))
report_path.write_text('{"ok": true, "version": "fake-2022R2", "message": "fake smoke ok"}', encoding="utf-8")
return subprocess.CompletedProcess(command, 0, stdout="", stderr="")
def main() -> int:
with tempfile.TemporaryDirectory(prefix="step_editor_scdm_backend_") as temp:
root = Path(temp)
fake_exe = _fake_spaceclaim(root / "ANSYS Inc" / "v222" / "SCDM" / "SpaceClaim.exe")
backend = ScdmBackendInfo(
path=fake_exe,
source="test",
version="v222",
verified_at="2026-08-18T00:00:00Z",
run_script_ok=True,
license_ok=True,
message="cached",
)
cache_path = save_scdm_backend_cache(backend, project_root_override=root)
_assert(cache_path == default_scdm_cache_path(root), f"unexpected cache path: {cache_path}")
loaded = load_scdm_backend_cache(project_root_override=root)
_assert(loaded is not None, "cache should load")
_assert(loaded.path == fake_exe.resolve(strict=False), f"cache should preserve path: {loaded}")
_assert(loaded.run_script_ok is True and loaded.license_ok is True, f"cache should preserve verification: {loaded}")
with tempfile.TemporaryDirectory(prefix="step_editor_scdm_backend_env_") as temp:
root = Path(temp)
fake_exe = _fake_spaceclaim(root / "SpaceClaim.exe")
env_clear = {name: None for name in SCDM_PATH_ENV_VARS}
env_clear[SCDM_DISABLE_ENV] = None
env_clear["STEP_EDITOR_SCDM_EXE"] = str(fake_exe)
with _patched_env(env_clear):
candidates = discover_scdm_backend_candidates(
include_registry=False,
include_common=False,
include_path=False,
)
_assert(len(candidates) == 1, f"env discovery should find exactly one candidate: {candidates}")
_assert(candidates[0].source == "env:STEP_EDITOR_SCDM_EXE", f"bad source: {candidates[0]}")
resolved = resolve_scdm_backend(
project_root_override=root,
validate=False,
include_registry=False,
include_common=False,
include_path=False,
)
_assert(resolved.get("ok") is True, f"env backend should resolve: {resolved}")
_assert(Path(str(resolved.get("path"))) == fake_exe.resolve(strict=False), f"bad resolved path: {resolved}")
_assert(load_scdm_backend_cache(project_root_override=root) is not None, "resolve should write cache")
with tempfile.TemporaryDirectory(prefix="step_editor_scdm_backend_common_") as temp:
root = Path(temp)
common_root = root / "Program Files" / "ANSYS Inc"
fake_exe = _fake_spaceclaim(common_root / "v231" / "SCDM" / "SpaceClaim.exe")
candidates = discover_scdm_backend_candidates(
include_env=False,
include_registry=False,
include_common=True,
include_path=False,
common_roots=(common_root,),
)
_assert(candidates and candidates[0].path == fake_exe.resolve(strict=False), f"common discovery failed: {candidates}")
_assert(candidates[0].version == "v231", f"version should be parsed from ANSYS folder: {candidates[0]}")
with tempfile.TemporaryDirectory(prefix="step_editor_scdm_backend_smoke_") as temp:
root = Path(temp)
fake_exe = _fake_spaceclaim(root / "SpaceClaim.exe")
command = scdm_run_script_command(fake_exe, root / "smoke.py")
_assert(command[0].endswith("SpaceClaim.exe"), f"bad command executable: {command}")
_assert(any(item.startswith("/RunScript=") for item in command), f"bad command script arg: {command}")
smoke = verify_scdm_backend(fake_exe, work_dir=root, runner=_fake_runner)
_assert(smoke.get("ok") is True, f"fake smoke should pass: {smoke}")
_assert(smoke.get("runScriptOk") is True and smoke.get("licenseOk") is True, f"bad smoke flags: {smoke}")
with tempfile.TemporaryDirectory(prefix="step_editor_scdm_backend_disabled_") as temp:
root = Path(temp)
with _patched_env({SCDM_DISABLE_ENV: "1"}):
resolved = resolve_scdm_backend(project_root_override=root, validate=False)
_assert(resolved.get("ok") is False and resolved.get("reason") == "disabled", f"disable env failed: {resolved}")
missing = verify_scdm_backend(Path("Z:/not-installed/SpaceClaim.exe"))
_assert(missing.get("ok") is False and missing.get("reason") == "missing-exe", f"missing path should be clean: {missing}")
print("scdm backend discovery ok")
return 0
if __name__ == "__main__":
raise SystemExit(main())