"""A slow kernel stop must not block other sessions or allow a duplicate kernel.""" import json import unittest from harness import no_spares, ROOT, Albedo, Provider, exclusive, python, text from inspect_support import Inspection @exclusive class KernelStopTests(unittest.TestCase): # no spares: the test stops a kernel it keeps open across turns @no_spares def test_runtime_serves_reads_and_other_boots_while_stopping(self): def prepare(app): app.daemon.env["ALBEDO_INSPECT"] = "1" def script(request): if request["messages"][-1].get("role") == "tool": return text("ready") return python("sentinel = 42") provider = Provider(script) self.addCleanup(provider.close) with Albedo(provider, prepare=prepare) as app: probe = Inspection(app, ROOT / "test/e2e/albedo_kernel_stop_probe.erl") for action in ("delete", "reset", "forget"): with self.subTest(action=action): session, kernel = self.boot(app) other = app.session() arguments = self.arguments( session, other, str(app.workspace), kernel ) report = probe.call_json( "run_json", arguments[:-1] + "," + action + "]" ) print("kernel stop probe:", action, report) self.assertTrue(report["observed"], report) self.assertTrue(report["other_ready"], report) self.assertTrue(report["same_session_blocked"], report) self.assertTrue(report["deleted"], report) self.assertTrue(report["replaced"], report) session, kernel = self.boot(app) report = probe.call_json( "failure_json", self.arguments(session, kernel, str(app.workspace)) ) self.assertEqual( report, {"reported": True, "retained": True, "refused": True, "retry": True}, ) pending = app.session() report = probe.call_json( "boot_fifo_json", self.arguments(pending, str(app.workspace)) ) self.assertEqual( report, {"expired": True, "old_stopped": True, "replacement_alive": True}, ) def boot(self, app): session = app.session() app.prompt(session, "boot").close() app.idle(session) with app.api(f"/sessions/{session}?view=status") as response: kernel = json.load(response)["kernel"] return session, kernel["instance_id"] def arguments(self, *values): return "[" + ",".join("<<" + json.dumps(value) + ">>" for value in values) + "]"