feat: 推进SCDM-first后端接入和大模型编辑优化
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
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())
|
||||
Reference in New Issue
Block a user