Files
eco/tests/test_assembly_memory_degrades.py
T
lemke_handClaude Sonnet 5 8637d8096c Don't crash Assembly construction when an account can't create its shared memory directory
A brand new namespace object's memory/presets directory doesn't exist yet,
and accounts differ in whether they're in the group the shared memory tree
(eco_cnf_bernina/memory/) is setgid to -- gac-bernina's default group isn't
unx-sf_bernina_bs and that can't easily be changed. ensure_dir() already
warns-and-continues on a permission failure, but AdjustableFS's write then
turned that into an uncaught FileNotFoundError, taking the whole Assembly
(and anything wrapping it, e.g. Namespace.append_obj) down -- hit live when
constructing the new bernina.status_server object.

Memory.setup_path() now falls back to a private, per-account directory under
home (the same pattern AdjustableFS's own group_writable=False already uses
for RecentComponents/ComponentBookmarks) when the shared one can't be
created, so an account like gac-bernina still gets working memory/presets,
just not cross-account-shared for objects it's the first to touch.
Assembly.__init__ additionally degrades to self.memory = None on any other
unexpected failure there, rather than ever letting it take the object down.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 18:51:24 +02:00

36 lines
1.5 KiB
Python

"""A brand new namespace object's memory/presets directory doesn't exist yet,
and not every account that can construct namespace objects is in the group
that can create one in the shared memory tree (eco_cnf_bernina/memory/) --
this hit StatusServer live: an account outside unx-sf_bernina_bs got
`PermissionError` from `ensure_dir`, which `AdjustableFS._write_value` then
turned into an uncaught `FileNotFoundError`, taking the entire Assembly
construction down. Memory/presets is a nice-to-have on top of an object, not
load-bearing for whether it can be constructed at all, so Assembly.__init__
now degrades to `self.memory = None` (a state other code already expects,
see memory.py's own `getattr(ancestor, "memory", None)`) instead of letting
that failure propagate."""
from eco.elements import memory
from eco.elements.assembly import Assembly
def test_assembly_construction_survives_a_memory_setup_failure(monkeypatch, tmp_path):
monkeypatch.setattr(memory, "global_memory_dir", tmp_path)
def _boom(self, *args, **kwargs):
raise PermissionError("could not create memory directory")
monkeypatch.setattr(memory.Memory, "__init__", _boom)
asm = Assembly(name="brand_new_thing")
assert asm.memory is None
def test_assembly_memory_still_works_when_the_directory_is_writable(tmp_path, monkeypatch):
monkeypatch.setattr(memory, "global_memory_dir", tmp_path)
asm = Assembly(name="normal_thing")
assert asm.memory is not None
assert isinstance(asm.memory, memory.Memory)