diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh index a54b7163d3f67..1027957ee85a4 100755 --- a/scripts/run_tests.sh +++ b/scripts/run_tests.sh @@ -39,9 +39,17 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # ── Activate venv ─────────────────────────────────────────────────────────── VENV="" -for candidate in "$REPO_ROOT/.venv" "$REPO_ROOT/venv" "$HOME/.hermes/hermes-agent/venv"; do +PYTHON="" +for candidate in "$REPO_ROOT/.venv" "$REPO_ROOT/venv" \ + "$HOME/.hermes/hermes-agent/.venv" "$HOME/.hermes/hermes-agent/venv"; do if [ -f "$candidate/bin/activate" ]; then VENV="$candidate" + PYTHON="$candidate/bin/python" + break + fi + if [ -f "$candidate/Scripts/python.exe" ]; then + VENV="$candidate" + PYTHON="$candidate/Scripts/python.exe" break fi done @@ -51,9 +59,6 @@ if [ -z "$VENV" ]; then exit 1 fi -PYTHON="$VENV/bin/python" - - # ── Live-gateway plugin (computed before we drop env) ─────────────────────── EXTRA_PYTHONPATH="" EXTRA_PYTEST_PLUGINS="" @@ -74,6 +79,8 @@ cd "$REPO_ROOT" exec env -i \ PATH="$PATH" \ HOME="$HOME" \ + USERPROFILE="${USERPROFILE:-$HOME}" \ + PYTHONUTF8=1 \ TZ=UTC \ LANG=C.UTF-8 \ LC_ALL=C.UTF-8 \ diff --git a/tests/scripts/test_run_tests_windows_venv.py b/tests/scripts/test_run_tests_windows_venv.py new file mode 100644 index 0000000000000..fdb34b6fae970 --- /dev/null +++ b/tests/scripts/test_run_tests_windows_venv.py @@ -0,0 +1,22 @@ +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] +RUNNER = REPO_ROOT / "scripts" / "run_tests.sh" + + +def test_runner_supports_posix_and_windows_virtualenv_layouts(): + script = RUNNER.read_text(encoding="utf-8") + + assert 'if [ -f "$candidate/bin/activate" ]' in script + assert 'PYTHON="$candidate/bin/python"' in script + assert 'if [ -f "$candidate/Scripts/python.exe" ]' in script + assert 'PYTHON="$candidate/Scripts/python.exe"' in script + assert 'PYTHON="$VENV/bin/python"' not in script + + +def test_runner_preserves_windows_home_and_utf8_in_clean_environment(): + script = RUNNER.read_text(encoding="utf-8") + + assert 'USERPROFILE="${USERPROFILE:-$HOME}"' in script + assert "PYTHONUTF8=1" in script diff --git a/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md b/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md index 2dde2ad9d1244..8ff01a3c20715 100644 --- a/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md +++ b/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md @@ -784,8 +784,9 @@ diagnostic recipe in `references/execute-code-sandbox-env-windows.md`. ### Testing / Contributing -**`scripts/run_tests.sh` doesn't work as-is on Windows** — it looks for -POSIX venv layouts (`.venv/bin/activate`). The Hermes-installed venv at +**`scripts/run_tests.sh` supports native Windows venv layouts** — it probes +both POSIX (`.venv/bin/python`) and Windows (`.venv/Scripts/python.exe`) +interpreters. The Hermes-installed venv at `venv/Scripts/` has no pip or pytest either (stripped for install size). Workaround: install `pytest + pytest-xdist + pyyaml` into a system Python 3.11 user site, then invoke pytest directly with `PYTHONPATH` set: @@ -1004,14 +1005,15 @@ python -m pytest tests/tools/ -q # Specific area - Run full suite before pushing any change - Use `-o 'addopts='` to clear any baked-in pytest flags -**Windows contributors:** `scripts/run_tests.sh` currently looks for POSIX venvs (`.venv/bin/activate` / `venv/bin/activate`) and will error out on Windows where the layout is `venv/Scripts/activate` + `python.exe`. The Hermes-installed venv at `venv/Scripts/` also has no `pip` or `pytest` — it's stripped for end-user install size. Workaround: install pytest + pytest-xdist + pyyaml into a system Python 3.11 user site (`/c/Program Files/Python311/python -m pip install --user pytest pytest-xdist pyyaml`), then run tests directly: +**Windows contributors:** `scripts/run_tests.sh` recognizes `venv/Scripts/python.exe` and preserves `USERPROFILE` plus UTF-8 mode in its clean environment. The Hermes-installed end-user venv may still omit `pip` or `pytest` to reduce install size; use a development venv with the test dependencies installed. ```bash export PYTHONPATH="$(pwd)" "/c/Program Files/Python311/python" -m pytest tests/tools/test_foo.py -v --tb=short -n 0 ``` -Use `-n 0` (not `-n 4`) because `pyproject.toml`'s default `addopts` already includes `-n`, and the wrapper's CI-parity story doesn't apply off-POSIX. +When invoking pytest directly, use `-n 0` (not `-n 4`) because +`pyproject.toml`'s default `addopts` already includes `-n`. **Cross-platform test guards:** tests that use POSIX-only syscalls need a skip marker. Common ones already in the codebase: - Symlink creation → `@pytest.mark.skipif(sys.platform == "win32", reason="Symlinks require elevated privileges on Windows")` (see `tests/cron/test_cron_script.py`)