Files
hermes-agent/tests/test_load_yaml_file_readonly.py
kshitijk4poor bd6ff8b4a8 test: keep the invariant tests for the config-read caches
Trim the picked test files to the tests that pin an invariant a regression
would break: 115070 keeps the shared-object-mutation-poisons-cache test and
one signature-invalidation test (drops 4 that re-test yaml parse/missing
behaviour or duplicate invalidation); 117440 keeps the blocked-read-completes
test and the hook-timeout-reads-config-once test (drops 7 restating the
clamp/fallback contract already covered by test_plugins.py). Adds one test
for the tuple memo: under a writer thread flipping config.yaml, a lock-free
reader never sees a sig paired with another publish's value.
2026-09-22 16:15:34 +05:30

48 lines
1.7 KiB
Python

"""``load_yaml_file_readonly`` re-parses only when the file signature changes."""
import os
from utils import load_yaml_file_readonly
def test_cache_hit_returns_same_object_and_invalidates_on_rewrite(tmp_path):
path = tmp_path / "config.yaml"
path.write_text("secrets: {a: 1}\n")
first = load_yaml_file_readonly(path)
assert first == {"secrets": {"a": 1}}
assert load_yaml_file_readonly(path) is first
path.write_text("secrets: {a: 2}\n")
os.utime(path, ns=(os.stat(path).st_mtime_ns + 1_000_000,) * 2)
second = load_yaml_file_readonly(path)
assert second == {"secrets": {"a": 2}}
assert second is not first
def test_callers_do_not_mutate_the_shared_cached_object(tmp_path, monkeypatch):
"""Both callers only read one section; the cached mapping must survive them byte-for-byte,
otherwise a later reader of the same file would observe another caller's edits."""
import copy
from hermes_cli.env_loader import _load_secrets_config
from tools.terminal_scope import build_profile_terminal_scope
home = tmp_path / "profiles" / "work"
home.mkdir(parents=True)
path = home / "config.yaml"
path.write_text(
"terminal:\n backend: local\n cwd: auto\n timeout: 5\n"
"secrets:\n onepassword: {enabled: false}\n"
)
monkeypatch.setattr("hermes_cli.env_loader._process_hermes_home", lambda: tmp_path / "other")
cached = load_yaml_file_readonly(path)
snapshot = copy.deepcopy(cached)
scope = build_profile_terminal_scope(home)
secrets = _load_secrets_config(home)
assert scope["TERMINAL_ENV"] == "local"
assert secrets == {"onepassword": {"enabled": False}}
assert cached == snapshot
assert load_yaml_file_readonly(path) is cached