fix(cron): patched compatibility constants take precedence over a repointed env

Review follow-up: tests that monkeypatch CRON_DIR/JOBS_FILE/OUTPUT_DIR (the
documented process-wide compatibility surface) were bypassed by the lazy
env fallback — 3 file-permission tests, the cross-process lock test, and
the heartbeat roundtrip regressed. _current_cron_store() now snapshots the
constants at import and honors any deliberate re-point of them ahead of
the env resolution, so the precedence is: use_cron_store() override >
patched constants > fresh HERMES_HOME > import defaults. Adds a test
pinning constants-beat-env; the late-env sentinel behavior is unchanged.
tests/cron: failure set byte-identical to unpatched main on this box
(the 5 regressions gone); 138 pass in the touched files.
This commit is contained in:
slow4cyl 2026-07-16 12:02:43 -05:00 committed by kshitij
parent 5c121f157f
commit 65d6bd2b9f
2 changed files with 38 additions and 11 deletions

View file

@ -115,26 +115,40 @@ _cron_store_override: ContextVar[Optional[_CronStorePaths]] = ContextVar(
)
# Import-time snapshot of the compatibility constants, so deliberate
# re-pointing of the module surface (monkeypatched CRON_DIR/JOBS_FILE/
# OUTPUT_DIR — the documented escape hatch existing tests/embedders use)
# is distinguishable from the constants merely being stale.
_IMPORT_STORE = _CronStorePaths(CRON_DIR, JOBS_FILE, OUTPUT_DIR)
def _current_cron_store() -> _CronStorePaths:
"""Return paths pinned to this execution context's profile.
With no use_cron_store() override active, the active profile home is
resolved FRESH via get_hermes_home() (context-local override, then the
HERMES_HOME env var) instead of trusting the import-time capture. A test
or embedder that re-points HERMES_HOME after this module was imported
therefore reads/writes ITS OWN store not whatever jobs.json the import
happened to freeze (the filed incident: fixtures that patched the env too
late silently rewrote the user's real jobs file). The module-level
constants keep their import-time values as the documented compatibility
surface, and the common path (home unchanged since import) still returns
them unchanged.
Precedence, most explicit first:
1. an active use_cron_store() override (ContextVar);
2. deliberately re-pointed module constants if CRON_DIR/JOBS_FILE/
OUTPUT_DIR no longer match their import-time values, someone chose
the documented process-wide compatibility surface; honor it;
3. the ACTIVE profile home, resolved fresh via get_hermes_home()
(context-local override, then the HERMES_HOME env var) so a test
or embedder that re-points HERMES_HOME after this module was
imported reads/writes ITS OWN store, not whatever jobs.json the
import happened to freeze (the filed incident: fixtures that patched
the env too late silently rewrote the user's real jobs file);
4. the import-time constants (home unchanged since import the common
path, returned unchanged).
"""
override = _cron_store_override.get()
if override is not None:
return override
live_constants = _CronStorePaths(CRON_DIR, JOBS_FILE, OUTPUT_DIR)
if live_constants != _IMPORT_STORE:
return live_constants
home = get_hermes_home().resolve()
if home == HERMES_DIR:
return _CronStorePaths(CRON_DIR, JOBS_FILE, OUTPUT_DIR)
return live_constants
cron_dir = home / "cron"
return _CronStorePaths(cron_dir, cron_dir / "jobs.json", cron_dir / "output")

View file

@ -1978,3 +1978,16 @@ class TestLateEnvRepointScopesStore:
with jobs.use_cron_store(tmp_path / "override-home"):
store = jobs._current_cron_store()
assert store.jobs_file == (tmp_path / "override-home").resolve() / "cron" / "jobs.json"
def test_patched_compatibility_constants_beat_env(self, tmp_path, monkeypatch):
"""Deliberately re-pointed module constants are the documented
process-wide escape hatch they win over a repointed HERMES_HOME."""
import cron.jobs as jobs
patched_dir = tmp_path / "patched-cron"
monkeypatch.setattr(jobs, "CRON_DIR", patched_dir)
monkeypatch.setattr(jobs, "JOBS_FILE", patched_dir / "jobs.json")
monkeypatch.setattr(jobs, "OUTPUT_DIR", patched_dir / "output")
monkeypatch.setenv("HERMES_HOME", str(tmp_path / "env-home"))
store = jobs._current_cron_store()
assert store.jobs_file == patched_dir / "jobs.json"