[verified] Bind managed-lock test imports to HARNESS_ROOT

This commit is contained in:
2026-10-14 14:17:46 +00:00
parent f5ef03418e
commit c06a2da159
2 changed files with 95 additions and 1 deletions
+40
View File
@@ -1,5 +1,45 @@
# Canonical harness tests # Canonical harness tests
## Installation-root prerequisite
Before executing the suite, provide `HARNESS_ROOT` in the process environment.
It names the installation root containing `harness/` and `repositories/`, not
the `harness/` directory itself. For the current installation, configure the
current agent's `$HERMES_HOME/.env` with:
```dotenv
HARNESS_ROOT=/opt/data/gitea-agent
```
The tests consume the environment supplied by Hermes; they do not open or
source `.env` files, search other profiles, or implement a second configuration
loader. When running outside Hermes, supply the variable explicitly:
```sh
export HARNESS_ROOT=/opt/data/gitea-agent
python3 -B "$HARNESS_ROOT/harness/tests/run.py"
```
On another system, replace the value with that installation's absolute root.
The managed-lock subprocess contention test requires a nonempty, existing
absolute directory and compares its resolved location with the installation
containing the test file. Missing, empty, relative, nonexistent, non-directory,
or different-installation values raise an explicit `HARNESS_ROOT` error before
creating a lock or starting the contention subprocess. There is no fallback to
`Path.cwd()` or to the test-file-derived root. Only the validated import root
is passed as a subprocess argument; no `.env` contents are read or serialized.
This test-only prerequisite does not change the production lock implementation
or the canonical runner's source-bound collection behavior; `--collect-only`
does not require the variable.
An external-cwd regression runs only the contention test from a temporary
working directory, with `PYTHONPATH` removed and an explicit fixture
`HARNESS_ROOT`, using isolated Python and bounded subprocess timeouts. Invalid
configuration coverage checks that neither lock acquisition nor subprocess
execution occurs. It does not recursively invoke the entire suite.
## Running the canonical suite
The canonical runner is anchored to its own source tree and works from any The canonical runner is anchored to its own source tree and works from any
current directory. From the repository root: current directory. From the repository root:
+55 -1
View File
@@ -241,7 +241,61 @@ class ManagedLockTests(unittest.TestCase):
after = path.stat() after = path.stat()
self.assertEqual((before.st_ino, before.st_size, before.st_mode), (after.st_ino, after.st_size, after.st_mode)) self.assertEqual((before.st_ino, before.st_size, before.st_mode), (after.st_ino, after.st_size, after.st_mode))
def test_lock_contention_from_external_cwd_without_pythonpath(self):
root = Path(__file__).resolve().parents[3]
script = """
import sys
import unittest
sys.path.insert(0, sys.argv[1])
suite = unittest.defaultTestLoader.loadTestsFromName(
'harness.tests.common.test_managed_lock.ManagedLockTests.'
'test_other_process_cannot_acquire_while_context_alive')
result = unittest.TextTestRunner().run(suite)
raise SystemExit(not result.wasSuccessful())
"""
env = os.environ.copy()
env.pop("PYTHONPATH", None)
env["HARNESS_ROOT"] = str(root)
with tempfile.TemporaryDirectory() as cwd:
result = subprocess.run(
[sys.executable, "-I", "-B", "-c", script, str(root)],
cwd=cwd, env=env, text=True, capture_output=True, timeout=30)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
def test_invalid_harness_root_stops_before_lock_and_subprocess(self):
with tempfile.TemporaryDirectory() as other:
file_path = Path(other) / "not-a-directory"
file_path.write_text("fixture")
for value in (None, "", "relative", other,
str(Path(other) / "missing"), str(file_path)):
with self.subTest(value=value), patch.dict(os.environ), \
patch(__name__ + ".ManagedLock") as lock, \
patch(__name__ + ".subprocess.run") as run:
if value is None:
os.environ.pop("HARNESS_ROOT", None)
else:
os.environ["HARNESS_ROOT"] = value
run.return_value.stdout = "blocked"
error = None
try:
self.test_other_process_cannot_acquire_while_context_alive()
except Exception as exc:
error = exc
self.assertIsInstance(error, RuntimeError)
self.assertIn("HARNESS_ROOT", str(error))
lock.assert_not_called()
run.assert_not_called()
def test_other_process_cannot_acquire_while_context_alive(self): def test_other_process_cannot_acquire_while_context_alive(self):
value = os.environ.get("HARNESS_ROOT")
if not value:
raise RuntimeError("HARNESS_ROOT must be configured")
root = Path(value)
if not root.is_absolute() or not root.is_dir():
raise RuntimeError("HARNESS_ROOT must be an existing absolute directory")
root = root.resolve()
if root != Path(__file__).resolve().parents[3]:
raise RuntimeError("HARNESS_ROOT does not match this test installation")
with tempfile.TemporaryDirectory() as d: with tempfile.TemporaryDirectory() as d:
path = Path(d) / "process.lock" path = Path(d) / "process.lock"
script = """ script = """
@@ -255,7 +309,7 @@ except LockTimeoutError:
print('blocked') print('blocked')
""" """
with ManagedLock(path): with ManagedLock(path):
result = subprocess.run([sys.executable, "-c", script, str(path), str(Path.cwd())], text=True, capture_output=True, check=True) result = subprocess.run([sys.executable, "-c", script, str(path), str(root)], text=True, capture_output=True, check=True, timeout=30)
self.assertEqual(result.stdout.strip(), "blocked") self.assertEqual(result.stdout.strip(), "blocked")