mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 13:26:40 +00:00
Eight tests became two. The kept end-to-end test runs a real streamed sync against a fake uv whose compile error is followed by a flood that evicts it from the 2000-character tail. It goes red if the marker stitch, the LiveTail discard, or the flag-only retry is removed. The second keeps an unrelated uv failure from being retried.
78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
"""uv --compile-bytecode is an optimization. A compile-step failure must not
|
|
fail the dependency sync (#124268).
|
|
|
|
Windows real-time AV can lock uv's temporary compile script (os error 1224)
|
|
after packages are already installed. The sync has to retry once without the
|
|
flag so pm repair/bootstrap still produce a usable environment.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import io
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from pm import environment
|
|
from pm.environment import PythonEnvironment
|
|
from pm.package import InstallError
|
|
|
|
|
|
def _env(tmp_path: Path, output=None) -> PythonEnvironment:
|
|
return PythonEnvironment(
|
|
uv=tmp_path / "uv",
|
|
python=tmp_path / "python",
|
|
destination=tmp_path / "venv",
|
|
cache=tmp_path / "cache",
|
|
env={},
|
|
output=output,
|
|
)
|
|
|
|
|
|
def test_streamed_sync_retries_without_bytecode_compile_and_reports_no_failure(tmp_path, monkeypatch):
|
|
"""Repair streams uv through LiveTail, and verbose output after the compile error can
|
|
evict it from the 2000-character tail. The marker must survive, the retry must drop only
|
|
--compile-bytecode, and the recovered sync must not paint a failure banner."""
|
|
fake_uv = tmp_path / "fake_uv.py"
|
|
fake_uv.write_text(
|
|
"import sys\n"
|
|
"if '--compile-bytecode' in sys.argv:\n"
|
|
" print('error: Failed to bytecode-compile Python file in: venv')\n"
|
|
" print('N' * 4000)\n"
|
|
" raise SystemExit(1)\n",
|
|
encoding="utf-8",
|
|
)
|
|
calls: list[list[str]] = []
|
|
real_stream = environment._run_streaming
|
|
|
|
def spawn_fake_uv(command, **kwargs):
|
|
calls.append(command[1:])
|
|
return real_stream([sys.executable, str(fake_uv), *command[1:]], **kwargs)
|
|
|
|
monkeypatch.setattr(environment, "_run_streaming", spawn_fake_uv)
|
|
monkeypatch.setattr(environment, "verbose_output", lambda: False)
|
|
notes = io.StringIO()
|
|
_env(tmp_path, output=notes).sync(tmp_path, extras=("web",))
|
|
|
|
assert len(calls) == 2
|
|
assert "--compile-bytecode" in calls[0]
|
|
assert calls[1] == [arg for arg in calls[0] if arg != "--compile-bytecode"]
|
|
assert "✗" not in notes.getvalue()
|
|
|
|
|
|
def test_sync_does_not_retry_an_unrelated_uv_failure(tmp_path, monkeypatch):
|
|
calls: list[list[str]] = []
|
|
|
|
def fake_run(self, args, *, cwd, timeout):
|
|
calls.append(list(args))
|
|
return subprocess.CompletedProcess(args, 1, stdout="",
|
|
stderr="error: No solution found for the requested dependencies")
|
|
|
|
monkeypatch.setattr(PythonEnvironment, "_run", fake_run)
|
|
with pytest.raises(InstallError):
|
|
_env(tmp_path).sync(tmp_path)
|
|
assert len(calls) == 1
|
|
assert "--compile-bytecode" in calls[0]
|