158 lines
6.6 KiB
Python
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())
|