2026-07-14 00:40:36 +08:00
|
|
|
"""Keyless runtime-resolution tests; launch coverage lives in test_bundled_runtime.py."""
|
2026-07-11 14:08:24 +08:00
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
2026-07-29 23:20:08 +08:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
import deepseek_harness_runtime as runtime
|
2026-07-11 14:08:24 +08:00
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
from deepseek_harness_runtime import (
|
|
|
|
|
RUNTIME_MODE_ENV_VAR,
|
|
|
|
|
bundled_package_dir,
|
feat(python-runtime): package the dsh CLI and profile assets
Make the zero-code dsh-python-runtime-closure depend on the real @deepseek-ai/dsh application and every required profile peer, then package apps/cli's built bin instead of the deleted Python carrier. Rename executables to deepseek-harness-sdk-runtime-<platform>-<arch>, update wheel/platform/build workflow discovery, and install a Python dsh console command that requires explicit DSH_HOME before exec.
Include profile, bundle, preset, native addon, and shared-library assets needed by the full CLI. Remove the checked-in default cordis.yml and preserve the existing wheel distribution names, Python module names, sidecar validation, and wire identity. Runtime resolution and release tests pin the new artifacts and dev Node carrier.
2026-08-23 14:56:02 +08:00
|
|
|
main,
|
2026-07-11 14:08:24 +08:00
|
|
|
resolve_bundled_launch_args,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_unknown_explicit_mode_fails_loud() -> None:
|
|
|
|
|
with pytest.raises(ValueError, match="expected 'exe' or 'node'"):
|
|
|
|
|
resolve_bundled_launch_args("bogus")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_unknown_env_mode_fails_loud(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
|
|
|
monkeypatch.setenv(RUNTIME_MODE_ENV_VAR, "bogus")
|
|
|
|
|
with pytest.raises(ValueError, match="expected 'exe' or 'node'"):
|
|
|
|
|
resolve_bundled_launch_args()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_explicit_mode_wins_over_env_mode(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
|
|
|
monkeypatch.setenv(RUNTIME_MODE_ENV_VAR, "bogus")
|
|
|
|
|
try:
|
|
|
|
|
args = resolve_bundled_launch_args("exe")
|
|
|
|
|
except FileNotFoundError:
|
|
|
|
|
return # explicit 'exe' was honored; only the artifact is missing
|
|
|
|
|
assert args[0].endswith(("-x64", "-arm64"))
|
2026-07-29 23:20:08 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_runtime_requires_spawn_helper_only_on_macos(
|
2026-07-30 01:29:18 +08:00
|
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
2026-07-29 23:20:08 +08:00
|
|
|
) -> None:
|
|
|
|
|
runtime_dir = tmp_path / "runtime"
|
|
|
|
|
runtime_dir.mkdir()
|
feat(python-runtime): package the dsh CLI and profile assets
Make the zero-code dsh-python-runtime-closure depend on the real @deepseek-ai/dsh application and every required profile peer, then package apps/cli's built bin instead of the deleted Python carrier. Rename executables to deepseek-harness-sdk-runtime-<platform>-<arch>, update wheel/platform/build workflow discovery, and install a Python dsh console command that requires explicit DSH_HOME before exec.
Include profile, bundle, preset, native addon, and shared-library assets needed by the full CLI. Remove the checked-in default cordis.yml and preserve the existing wheel distribution names, Python module names, sidecar validation, and wire identity. Runtime resolution and release tests pin the new artifacts and dev Node carrier.
2026-08-23 14:56:02 +08:00
|
|
|
linux = runtime_dir / "deepseek-harness-sdk-runtime-linux-x64"
|
2026-07-30 01:29:18 +08:00
|
|
|
linux.touch()
|
2026-08-14 13:59:49 +08:00
|
|
|
Path(f"{linux}-rg").touch()
|
feat(python-runtime): package the dsh CLI and profile assets
Make the zero-code dsh-python-runtime-closure depend on the real @deepseek-ai/dsh application and every required profile peer, then package apps/cli's built bin instead of the deleted Python carrier. Rename executables to deepseek-harness-sdk-runtime-<platform>-<arch>, update wheel/platform/build workflow discovery, and install a Python dsh console command that requires explicit DSH_HOME before exec.
Include profile, bundle, preset, native addon, and shared-library assets needed by the full CLI. Remove the checked-in default cordis.yml and preserve the existing wheel distribution names, Python module names, sidecar validation, and wire identity. Runtime resolution and release tests pin the new artifacts and dev Node carrier.
2026-08-23 14:56:02 +08:00
|
|
|
macos = runtime_dir / "deepseek-harness-sdk-runtime-macos-arm64"
|
2026-08-14 13:59:49 +08:00
|
|
|
macos.touch()
|
|
|
|
|
Path(f"{macos}-rg").touch()
|
2026-07-29 23:20:08 +08:00
|
|
|
monkeypatch.setattr(runtime, "bundled_package_dir", lambda: tmp_path)
|
|
|
|
|
|
2026-07-30 01:29:18 +08:00
|
|
|
monkeypatch.setattr(runtime, "_current_platform_tag", lambda: "macos-arm64")
|
|
|
|
|
with pytest.raises(FileNotFoundError, match="node-pty spawn helper"):
|
|
|
|
|
runtime.bundled_runtime_path()
|
|
|
|
|
monkeypatch.setattr(runtime, "_current_platform_tag", lambda: "linux-x64")
|
|
|
|
|
assert runtime.bundled_runtime_path() == linux
|
2026-08-14 13:59:49 +08:00
|
|
|
|
|
|
|
|
|
feat(python-runtime): package the Windows x64 dsh executable
Add node24-win-x64 as the only supported Windows runtime target and publish it as a py3-none-win_amd64 wheel containing the conventional dsh and ripgrep .exe payload names. Keep Windows ARM64 rejected explicitly so Python cannot claim a carrier that CI and release automation do not build.
Teach the pkg builder to require a native x64 Windows host, validate both node-pty ConPTY addons, copy @vscode's win32 ripgrep executable, and recognize pkg's .exe output. Extend runtime resolution, wheel staging, payload validation, and the preset closure check so the Windows-specific PowerShell plugins and sidecars fail loud when omitted.
The sidecar resolver now maps a packaged main.exe to main-rg.exe; focused TypeScript and Python tests cover that name, the win_amd64 manifest, x64-only host selection, complete wheel payload, ConPTY inventory, and platform-conditioned plugin closure.
2026-08-23 15:39:18 +08:00
|
|
|
def test_windows_runtime_uses_exe_payload_and_exe_sidecar(
|
|
|
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
|
|
|
) -> None:
|
|
|
|
|
runtime_dir = tmp_path / "runtime"
|
|
|
|
|
runtime_dir.mkdir()
|
|
|
|
|
executable = runtime_dir / "deepseek-harness-sdk-runtime-win-x64.exe"
|
|
|
|
|
executable.touch()
|
|
|
|
|
(runtime_dir / "deepseek-harness-sdk-runtime-win-x64-rg.exe").touch()
|
|
|
|
|
monkeypatch.setattr(runtime, "bundled_package_dir", lambda: tmp_path)
|
|
|
|
|
monkeypatch.setattr(runtime, "_current_platform_tag", lambda: "win-x64")
|
|
|
|
|
|
|
|
|
|
assert runtime.bundled_runtime_path() == executable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_current_platform_supports_windows_x64_only(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
|
|
|
monkeypatch.setattr(runtime.sys, "platform", "win32")
|
|
|
|
|
monkeypatch.setattr(runtime.platform, "machine", lambda: "AMD64")
|
|
|
|
|
assert runtime._current_platform_tag() == "win-x64"
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(runtime.platform, "machine", lambda: "ARM64")
|
|
|
|
|
with pytest.raises(FileNotFoundError, match="Windows x64"):
|
|
|
|
|
runtime._current_platform_tag()
|
|
|
|
|
|
|
|
|
|
|
2026-08-23 19:18:59 +08:00
|
|
|
def test_current_platform_rejects_macos_x64(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
|
|
|
monkeypatch.setattr(runtime.sys, "platform", "darwin")
|
|
|
|
|
monkeypatch.setattr(runtime.platform, "machine", lambda: "x86_64")
|
|
|
|
|
|
|
|
|
|
with pytest.raises(FileNotFoundError, match="macOS arm64"):
|
|
|
|
|
runtime._current_platform_tag()
|
|
|
|
|
|
|
|
|
|
|
2026-08-14 13:59:49 +08:00
|
|
|
def test_runtime_requires_ripgrep_sidecar(
|
|
|
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
|
|
|
) -> None:
|
|
|
|
|
runtime_dir = tmp_path / "runtime"
|
|
|
|
|
runtime_dir.mkdir()
|
feat(python-runtime): package the dsh CLI and profile assets
Make the zero-code dsh-python-runtime-closure depend on the real @deepseek-ai/dsh application and every required profile peer, then package apps/cli's built bin instead of the deleted Python carrier. Rename executables to deepseek-harness-sdk-runtime-<platform>-<arch>, update wheel/platform/build workflow discovery, and install a Python dsh console command that requires explicit DSH_HOME before exec.
Include profile, bundle, preset, native addon, and shared-library assets needed by the full CLI. Remove the checked-in default cordis.yml and preserve the existing wheel distribution names, Python module names, sidecar validation, and wire identity. Runtime resolution and release tests pin the new artifacts and dev Node carrier.
2026-08-23 14:56:02 +08:00
|
|
|
(runtime_dir / "deepseek-harness-sdk-runtime-linux-x64").touch()
|
2026-08-14 13:59:49 +08:00
|
|
|
monkeypatch.setattr(runtime, "bundled_package_dir", lambda: tmp_path)
|
|
|
|
|
monkeypatch.setattr(runtime, "_current_platform_tag", lambda: "linux-x64")
|
|
|
|
|
|
|
|
|
|
with pytest.raises(FileNotFoundError, match="ripgrep sidecar"):
|
|
|
|
|
runtime.bundled_runtime_path()
|
feat(python-runtime): package the dsh CLI and profile assets
Make the zero-code dsh-python-runtime-closure depend on the real @deepseek-ai/dsh application and every required profile peer, then package apps/cli's built bin instead of the deleted Python carrier. Rename executables to deepseek-harness-sdk-runtime-<platform>-<arch>, update wheel/platform/build workflow discovery, and install a Python dsh console command that requires explicit DSH_HOME before exec.
Include profile, bundle, preset, native addon, and shared-library assets needed by the full CLI. Remove the checked-in default cordis.yml and preserve the existing wheel distribution names, Python module names, sidecar validation, and wire identity. Runtime resolution and release tests pin the new artifacts and dev Node carrier.
2026-08-23 14:56:02 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_node_mode_runs_the_deployed_dsh_cli(
|
|
|
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
|
|
|
) -> None:
|
|
|
|
|
bin_js = tmp_path / "runtime" / "node" / "node_modules" / "@deepseek-ai" / "dsh" / "lib" / "bin.js"
|
|
|
|
|
bin_js.parent.mkdir(parents=True)
|
|
|
|
|
bin_js.touch()
|
|
|
|
|
monkeypatch.setattr(runtime, "bundled_package_dir", lambda: tmp_path)
|
|
|
|
|
monkeypatch.setattr(runtime.shutil, "which", lambda _name: "/node")
|
|
|
|
|
|
|
|
|
|
assert resolve_bundled_launch_args("node") == ("/node", str(bin_js))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_python_dsh_command_requires_explicit_home(
|
|
|
|
|
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
|
|
|
) -> None:
|
|
|
|
|
monkeypatch.delenv("DSH_HOME", raising=False)
|
|
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
|
|
|
main()
|
|
|
|
|
|
|
|
|
|
assert excinfo.value.code == 2
|
|
|
|
|
assert "explicit DSH_HOME" in capsys.readouterr().err
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_python_dsh_command_executes_the_bundled_cli(
|
|
|
|
|
monkeypatch: pytest.MonkeyPatch
|
|
|
|
|
) -> None:
|
|
|
|
|
called: dict[str, object] = {}
|
|
|
|
|
monkeypatch.setenv("DSH_HOME", "/explicit/home")
|
|
|
|
|
monkeypatch.setattr(runtime, "resolve_bundled_launch_args", lambda: ("/runtime",))
|
|
|
|
|
monkeypatch.setattr(runtime.sys, "argv", ["dsh", "plugin", "--profile", "sdk", "list"])
|
|
|
|
|
|
|
|
|
|
def execvpe(file: str, args: tuple[str, ...], env: dict[str, str]) -> None:
|
|
|
|
|
called.update(file=file, args=args, home=env.get("DSH_HOME"))
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(runtime.os, "execvpe", execvpe)
|
|
|
|
|
|
|
|
|
|
main()
|
|
|
|
|
|
|
|
|
|
assert called == {
|
|
|
|
|
"file": "/runtime",
|
|
|
|
|
"args": ("/runtime", "plugin", "--profile", "sdk", "list"),
|
|
|
|
|
"home": "/explicit/home",
|
|
|
|
|
}
|