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())