mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-09-28 15:01:00 +08:00
test: mirror the source tree for 27 misfiled root tests; one PM home fixture
Root-level tests/ is for root-level modules; 19 files testing scripts/, 3 testing pm/ and 5 testing hermes_cli/ move to the mirrored directory (workflow file lists and cross-imports updated; path arithmetic bumped one level). tests/pm gains a conftest with the isolated_machine_home fixture that seven modules had copy-pasted verbatim.
This commit is contained in:
@@ -123,7 +123,7 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
HERMES_TEST_FILE_RETRIES: '0'
|
||||
run: bash scripts/run_tests.sh tests/test_fresh_source_install.py -q -j 1
|
||||
run: bash scripts/run_tests.sh tests/scripts/test_fresh_source_install.py -q -j 1
|
||||
|
||||
windows:
|
||||
name: install.ps1 protocol surface
|
||||
|
||||
@@ -56,4 +56,4 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
HERMES_TEST_FILE_RETRIES: '0'
|
||||
run: bash scripts/run_tests.sh tests/test_source_launcher_stages.py -k powershell_stage -q -j 1
|
||||
run: bash scripts/run_tests.sh tests/pm/test_source_launcher_stages.py -k powershell_stage -q -j 1
|
||||
|
||||
@@ -50,13 +50,13 @@ jobs:
|
||||
- name: Run the native linker and wheel contracts
|
||||
run: |
|
||||
bash scripts/run_tests.sh -j 2 \
|
||||
tests/test_termux_python_linkage.py tests/test_termux_retag_wheel.py \
|
||||
tests/test_termux_build_wheels.py \
|
||||
tests/test_termux_wheelhouse_cache.py tests/test_termux_runtime_libs.py \
|
||||
tests/scripts/test_termux_python_linkage.py tests/scripts/test_termux_retag_wheel.py \
|
||||
tests/scripts/test_termux_build_wheels.py \
|
||||
tests/scripts/test_termux_wheelhouse_cache.py tests/scripts/test_termux_runtime_libs.py \
|
||||
tests/scripts/test_archive_inputs.py \
|
||||
tests/test_termux_launchers.py tests/test_pm_bionic.py \
|
||||
tests/pm/test_stage_only.py tests/pm/test_deb_safety.py tests/test_stage_apt_repo.py \
|
||||
tests/test_run_tests_shell.py
|
||||
tests/scripts/test_termux_launchers.py tests/pm/test_pm_bionic.py \
|
||||
tests/pm/test_stage_only.py tests/pm/test_deb_safety.py tests/scripts/test_stage_apt_repo.py \
|
||||
tests/scripts/test_run_tests_shell.py
|
||||
|
||||
tui:
|
||||
name: Prebuilt TUI checks
|
||||
|
||||
@@ -8,7 +8,7 @@ rely on that early (no jq guarantee; python is what uv installs on Windows).
|
||||
Instead, this script derives a plain-data fragment from pm/lock.json — the
|
||||
SAME authority the pm package manager uses for every managed tool — and
|
||||
splices it between markers in each installer. The bytes are stored, the
|
||||
truth is derived, and the drift test (tests/test_bootstrap_pins_fragment.py)
|
||||
truth is derived, and the drift test (tests/scripts/test_bootstrap_pins_fragment.py)
|
||||
fails when they disagree.
|
||||
|
||||
Run after bumping a bootstrapped tool in pm/lock.json:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""Derive a Debian package version (or channel) from a hermes-agent release tag.
|
||||
|
||||
Pure function; imported by scripts/termux/build_deb.sh and unit-tested by
|
||||
tests/test_termux_deb_version.py (Task 4 of .hermes/plans/2026-08-31_termux-deb.md).
|
||||
tests/scripts/test_termux_deb_version.py (Task 4 of .hermes/plans/2026-08-31_termux-deb.md).
|
||||
|
||||
Mapping:
|
||||
v1.2.3 -> 1.2.3-1
|
||||
@@ -26,7 +26,7 @@ import sys
|
||||
# The canary timestamp shape MUST match the canonical _CANARY_TAG_RE in
|
||||
# hermes_cli/update_channel.py (exactly 8 or 14 digits, 20-prefixed) and
|
||||
# channel_for_tag in scripts/releases/r2.py. Cross-referenced by
|
||||
# tests/test_termux_deb_version.py::test_canary_tag_shape_matches_canonical.
|
||||
# tests/scripts/test_termux_deb_version.py::test_canary_tag_shape_matches_canonical.
|
||||
_TAG_RE = re.compile(
|
||||
r"^v(?P<major>0|[1-9]\d*)\.(?P<minor>\d+)\.(?P<patch>\d+)"
|
||||
r"(?:-canary\.(?P<ts>20\d{6}(?:\d{6})?))?$"
|
||||
|
||||
@@ -39,7 +39,7 @@ print(json.dumps(result))
|
||||
"""
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-c", script], env=env,
|
||||
cwd=Path(__file__).resolve().parents[1],
|
||||
cwd=Path(__file__).resolve().parents[2],
|
||||
text=True, capture_output=True, check=True,
|
||||
)
|
||||
base = tmp_path / "AppData" / "Local" / "hermes" if sys.platform == "win32" else tmp_path / ".hermes"
|
||||
@@ -168,7 +168,7 @@ def test_retired_probes_and_refreshes_do_no_work(no_external_work, tmp_path):
|
||||
|
||||
@pytest.fixture
|
||||
def old_updater():
|
||||
path = Path(__file__).parent / "compat" / "old_updater_dependencies.py"
|
||||
path = Path(__file__).parents[1] / "compat" / "old_updater_dependencies.py"
|
||||
spec = importlib.util.spec_from_file_location("old_updater_dependencies", path)
|
||||
assert spec is not None and spec.loader is not None
|
||||
old = importlib.util.module_from_spec(spec)
|
||||
+1
-1
@@ -107,7 +107,7 @@ plugins_transaction.recover_plugin_publication(
|
||||
)
|
||||
"""
|
||||
return subprocess.run(
|
||||
[sys.executable, "-I", "-S", "-c", script, str(Path(__file__).resolve().parents[1]), str(project), str(journal)],
|
||||
[sys.executable, "-I", "-S", "-c", script, str(Path(__file__).resolve().parents[2]), str(project), str(journal)],
|
||||
input=json.dumps(row), text=True, capture_output=True, check=False,
|
||||
env={**os.environ, "HERMES_HOME": str(Path(row["metadata"]).parent.parent)},
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
"""Shared fixtures for the PM suite."""
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def isolated_machine_home(tmp_path, monkeypatch):
|
||||
"""Machine-scoped PM state (store, caches, profiles root) lands under tmp_path.
|
||||
|
||||
Opt in per module with ``pytestmark = pytest.mark.usefixtures("isolated_machine_home")``.
|
||||
Does not cross a subprocess boundary — tests that spawn set HOME/USERPROFILE themselves.
|
||||
"""
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
@@ -23,7 +23,7 @@ def test_cold_consumers_recover_after_upstream_removal(tmp_path, dl_server, monk
|
||||
archive.writestr("tool.txt", b"pinned and preserved")
|
||||
body = data.getvalue()
|
||||
if mode == "library":
|
||||
from tests.test_termux_runtime_libs import _build_deb
|
||||
from tests.scripts.test_termux_runtime_libs import _build_deb
|
||||
deb = tmp_path / "test.deb"
|
||||
_build_deb(deb, "libmirror.so", b"pinned and preserved")
|
||||
body = deb.read_bytes()
|
||||
|
||||
@@ -8,7 +8,6 @@ import json
|
||||
from functools import partial
|
||||
import threading
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -34,10 +33,7 @@ def archive(files: dict[str, bytes]) -> bytes:
|
||||
return output.getvalue()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolate_home(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
pytestmark = pytest.mark.usefixtures("isolated_machine_home")
|
||||
|
||||
|
||||
@pytest.fixture(params=["install", "stage"])
|
||||
|
||||
@@ -13,7 +13,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -15,10 +15,7 @@ from pm.lock import Facts
|
||||
from pm.runtime import runtime_environment
|
||||
from tests.pm._fixtures import _wheel
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolated_machine_home(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
pytestmark = pytest.mark.usefixtures("isolated_machine_home")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from pm.environments import install_state_dir, site_packages
|
||||
from pm.lock import Lockfile
|
||||
from tests.hermes_cli.test_source_launcher_publication import fixture_tree
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
@pytest.mark.platforms("windows")
|
||||
@@ -2,16 +2,12 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import pm.packages as pkgs
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolated_machine_home(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
pytestmark = pytest.mark.usefixtures("isolated_machine_home")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,10 +16,7 @@ from pm.package import InstallError
|
||||
from pm.packages import Python, Uv
|
||||
from pm.store import current_target
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolated_machine_home(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
pytestmark = pytest.mark.usefixtures("isolated_machine_home")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,10 +10,7 @@ import sys
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolated_machine_home(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
pytestmark = pytest.mark.usefixtures("isolated_machine_home")
|
||||
|
||||
|
||||
def test_ambient_uv_config_does_not_affect_pm_venv_sync(tmp_path, monkeypatch):
|
||||
|
||||
@@ -22,10 +22,7 @@ from pm.environment import managed_environment
|
||||
from tests.pm.test_environment_build import locked_project # noqa: F401
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolated_machine_home(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
pytestmark = pytest.mark.usefixtures("isolated_machine_home")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -12,10 +12,7 @@ from tests.pm import _fixtures
|
||||
from pm.environment import managed_environment
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def isolated_machine_home(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||
pytestmark = pytest.mark.usefixtures("isolated_machine_home")
|
||||
|
||||
|
||||
def _buildable_source(plugin):
|
||||
|
||||
@@ -13,7 +13,7 @@ from pm.downloader import HashError
|
||||
from scripts.ci import archive_inputs as inputs
|
||||
from scripts.releases import r2
|
||||
from tests.scripts.test_release_r2 import r2_server # noqa: F401
|
||||
from tests.test_termux_runtime_libs import _Server, _build_deb
|
||||
from tests.scripts.test_termux_runtime_libs import _Server, _build_deb
|
||||
|
||||
|
||||
def write_pins(repo, packages, libs=None):
|
||||
|
||||
@@ -12,7 +12,7 @@ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
+1
-1
@@ -5,7 +5,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
def test_fragments_match_the_pin_table():
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(root / "scripts/gen-bootstrap-pins.py"), "--check"],
|
||||
cwd=root, capture_output=True, text=True, timeout=60,
|
||||
@@ -14,7 +14,7 @@ import pytest
|
||||
from tests.installation_launcher_fixture import publish_fixture_launcher
|
||||
|
||||
|
||||
SCRIPTS = Path(__file__).resolve().parents[1] / "scripts" / "desktop-update"
|
||||
SCRIPTS = Path(__file__).resolve().parents[2] / "scripts" / "desktop-update"
|
||||
FAKE_CLI = """
|
||||
import json
|
||||
import os
|
||||
@@ -23,7 +23,7 @@ import sys
|
||||
|
||||
def main():
|
||||
if '--version' in sys.argv:
|
||||
print('Install directory: ' + os.environ.get('HANDOFF_FOREIGN', str(Path(__file__).resolve().parents[1]))); return 0
|
||||
print('Install directory: ' + os.environ.get('HANDOFF_FOREIGN', str(Path(__file__).resolve().parents[2]))); return 0
|
||||
if '--help' in sys.argv:
|
||||
print('update options')
|
||||
sys.exit(0)
|
||||
@@ -20,7 +20,7 @@ import pytest
|
||||
from pm.store import current_target
|
||||
from tests.pm._fixtures import _wheel, served as served
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
@pytest.mark.platforms("linux")
|
||||
+1
-1
@@ -6,7 +6,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
def test_icon_group_is_separate_from_runtime_extras():
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
uv = shutil.which("uv")
|
||||
assert uv, "uv is required for the dependency-selection contract"
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ from tests.installation_launcher_fixture import publish_fixture_launcher
|
||||
|
||||
pytestmark = pytest.mark.platforms("windows")
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
INSTALL_PS1 = REPO_ROOT / "scripts" / "install.ps1"
|
||||
|
||||
_FAKE_PY = r'''
|
||||
+1
-1
@@ -7,7 +7,7 @@ import subprocess
|
||||
import pytest
|
||||
from tests.installation_launcher_fixture import publish_fixture_launcher
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
@pytest.mark.platforms('posix')
|
||||
@pytest.mark.parametrize('stage, expected', [('setup', ['setup']), ('gateway', ['gateway', 'install']), ('desktop', ['desktop', '--build-only'])])
|
||||
+1
-1
@@ -14,7 +14,7 @@ import sys
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
pytestmark = pytest.mark.platforms("posix")
|
||||
|
||||
@@ -7,7 +7,7 @@ import subprocess
|
||||
import pytest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
SCRIPT = ROOT / "scripts" / "install.sh"
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
|
||||
# Every PowerShell script a user or CI machine actually runs. Discovered,
|
||||
# not hardcoded: a new script in scripts/ gets gated automatically.
|
||||
@@ -18,7 +18,7 @@ def test_shell_runner_executes_tests_and_propagates_failure(tmp_path):
|
||||
" assert False, 'runner failure propagation canary'\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
result = subprocess.run(
|
||||
["bash", str(root / "scripts/run_tests.sh"), "-j", "1", str(case)],
|
||||
cwd=tmp_path, capture_output=True, text=True, timeout=180,
|
||||
@@ -16,7 +16,7 @@ from pathlib import Path
|
||||
import pytest
|
||||
from tests.termux_fixtures import build_deb
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
SCRIPTS = REPO_ROOT / "scripts" / "termux"
|
||||
sys.path.insert(0, str(SCRIPTS))
|
||||
|
||||
@@ -7,7 +7,7 @@ from pathlib import Path
|
||||
import pytest
|
||||
from scripts.termux.deb_version import channel_for_tag, deb_version_for_tag
|
||||
|
||||
SCRIPT = Path(__file__).resolve().parents[1] / "scripts/termux/deb_version.py"
|
||||
SCRIPT = Path(__file__).resolve().parents[2] / "scripts/termux/deb_version.py"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("bom", ["", "\ufeff"])
|
||||
@@ -17,7 +17,7 @@ from pathlib import Path
|
||||
import pytest
|
||||
from tests.termux_fixtures import write_wheel, verify_record
|
||||
|
||||
SCRIPTS_DIR = Path(__file__).resolve().parent.parent / "scripts" / "termux"
|
||||
SCRIPTS_DIR = Path(__file__).resolve().parent.parent.parent / "scripts" / "termux"
|
||||
sys.path.insert(0, str(SCRIPTS_DIR))
|
||||
|
||||
import retag_wheel # noqa: E402
|
||||
@@ -17,7 +17,7 @@ from tests.termux_fixtures import build_deb
|
||||
|
||||
import sys
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts" / "termux"))
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ def test_cache_rejects_incomplete_or_inconsistent_manifests(tmp_path, damage):
|
||||
|
||||
def test_cache_cli_keeps_commit_and_tag_provenance_distinct(tmp_path):
|
||||
payload, _ = cache_tree(tmp_path)
|
||||
repo = Path(__file__).resolve().parents[1]
|
||||
repo = Path(__file__).resolve().parents[2]
|
||||
args = [sys.executable, str(repo / 'scripts/termux/wheelhouse_cache.py'), 'write',
|
||||
'--payload', str(payload), '--repo', str(repo), '--builder', 'fixture-image',
|
||||
'--platform-tag', 'android_24_arm64_v8a', '--python-abi', 'cp314']
|
||||
Reference in New Issue
Block a user