fix(agent): OSError при подтверждении версии — только лог, повтор на следующем claim (M-3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-15 00:47:57 +04:00
parent 255931845c
commit b57f815846
2 changed files with 24 additions and 1 deletions

View File

@ -998,7 +998,11 @@ class Updater:
"""Первый успешный claim новой версии: trial этой версии → ok (запускатель перестаёт ждать отката).""" """Первый успешный claim новой версии: trial этой версии → ok (запускатель перестаёт ждать отката)."""
st = self.state() st = self.state()
if st and st.get("state") == "trial" and st.get("to_version") == AGENT_VERSION: if st and st.get("state") == "trial" and st.get("to_version") == AGENT_VERSION:
write_update_state(self.state_path, "ok", st.get("from_version"), AGENT_VERSION, st.get("sha256")) try:
write_update_state(self.state_path, "ok", st.get("from_version"), AGENT_VERSION, st.get("sha256"))
except OSError as e: # диск полон — не падать; trial остался, повтор на следующем claim (M-3)
log("не удалось записать update.json: %s" % e)
return
log("обновление до v%d подтверждено" % AGENT_VERSION) log("обновление до v%d подтверждено" % AGENT_VERSION)
def _hint(self, kind: str, msg: str) -> None: def _hint(self, kind: str, msg: str) -> None:

View File

@ -42,6 +42,25 @@ class UpdateStateTest(unittest.TestCase):
st = agent.read_update_state(u.state_path) st = agent.read_update_state(u.state_path)
self.assertEqual((st["state"], st["from_version"], st["to_version"], st["sha256"]), ("ok", 4, agent.AGENT_VERSION, "s")) self.assertEqual((st["state"], st["from_version"], st["to_version"], st["sha256"]), ("ok", 4, agent.AGENT_VERSION, "s"))
def test_confirm_write_error_only_logged(self):
"""M-3 финального ревью: диск полон в момент подтверждения — агент не падает, подтвердит на следующем claim."""
u = agent.Updater(None, self.dir.name, 1)
agent.write_update_state(u.state_path, "trial", 4, agent.AGENT_VERSION, "s")
logs = []
def full(*a, **kw):
raise OSError(28, "No space left on device")
orig_log, orig_write = agent.log, agent.write_update_state
agent.log, agent.write_update_state = logs.append, full
try:
u.confirm()
finally:
agent.log, agent.write_update_state = orig_log, orig_write
self.assertEqual(u.state()["state"], "trial")
self.assertTrue(any(l.startswith("не удалось записать update.json") for l in logs), logs)
u.confirm()
self.assertEqual(u.state()["state"], "ok")
def test_confirm_ignores_other_states(self): def test_confirm_ignores_other_states(self):
u = agent.Updater(None, self.dir.name, 1) u = agent.Updater(None, self.dir.name, 1)
u.confirm() u.confirm()