fix(smolmachines): raise SmolvmError instead of die() on wait_exec_ready timeout
die() raises Die(SystemExit), which implies a process exit. A timeout in wait_exec_ready is a bringup failure — raising SmolvmError lets the caller decide whether it's fatal, consistent with how machine_start failures propagate.
This commit was merged in pull request #123.
This commit is contained in:
@@ -32,7 +32,6 @@ from dataclasses import dataclass
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Mapping, Sequence
|
from typing import Mapping, Sequence
|
||||||
|
|
||||||
from ...log import die
|
|
||||||
|
|
||||||
|
|
||||||
_SMOLVM = "smolvm"
|
_SMOLVM = "smolvm"
|
||||||
@@ -218,9 +217,13 @@ def wait_exec_ready(name: str, *, timeout: float = 5.0) -> None:
|
|||||||
break
|
break
|
||||||
time.sleep(min(delay, remaining))
|
time.sleep(min(delay, remaining))
|
||||||
delay = min(delay * 2, 0.5)
|
delay = min(delay * 2, 0.5)
|
||||||
die(
|
argv = ["smolvm", "machine", "exec", "--name", name, "--", "true"]
|
||||||
f"smolvm machine {name!r}: exec channel not ready after "
|
raise SmolvmError(
|
||||||
f"{timeout:.0f}s — VM may have failed to boot."
|
argv,
|
||||||
|
subprocess.CompletedProcess(
|
||||||
|
args=argv, returncode=-1, stdout="",
|
||||||
|
stderr=f"exec channel not ready after {timeout:.0f}s — VM may have failed to boot.",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ class TestWaitExecReady(unittest.TestCase):
|
|||||||
wait_exec_ready("vm-x")
|
wait_exec_ready("vm-x")
|
||||||
self.assertEqual(3, m.call_count)
|
self.assertEqual(3, m.call_count)
|
||||||
|
|
||||||
def test_dies_on_timeout(self):
|
def test_raises_smolvm_error_on_timeout(self):
|
||||||
# machine_exec always returns non-zero; monotonic advances past
|
# machine_exec always returns non-zero; monotonic advances past
|
||||||
# the deadline after the first sleep so the loop exits.
|
# the deadline after the first sleep so the loop exits.
|
||||||
ticks = [0.0, 0.0, 10.0] # third call puts us past deadline
|
ticks = [0.0, 0.0, 10.0] # third call puts us past deadline
|
||||||
@@ -236,13 +236,11 @@ class TestWaitExecReady(unittest.TestCase):
|
|||||||
return_value=SmolvmRunResult(1, "", "")), \
|
return_value=SmolvmRunResult(1, "", "")), \
|
||||||
patch.object(smolvm_mod.time, "monotonic",
|
patch.object(smolvm_mod.time, "monotonic",
|
||||||
side_effect=ticks), \
|
side_effect=ticks), \
|
||||||
patch.object(smolvm_mod.time, "sleep"), \
|
patch.object(smolvm_mod.time, "sleep"):
|
||||||
patch.object(smolvm_mod, "die",
|
with self.assertRaises(SmolvmError) as cm:
|
||||||
side_effect=SystemExit("die")) as die_mock:
|
|
||||||
with self.assertRaises(SystemExit):
|
|
||||||
wait_exec_ready("vm-x", timeout=5.0)
|
wait_exec_ready("vm-x", timeout=5.0)
|
||||||
die_mock.assert_called_once()
|
self.assertIn("vm-x", str(cm.exception))
|
||||||
self.assertIn("vm-x", die_mock.call_args.args[0])
|
self.assertIn("not ready", str(cm.exception))
|
||||||
|
|
||||||
|
|
||||||
class TestIsAvailable(unittest.TestCase):
|
class TestIsAvailable(unittest.TestCase):
|
||||||
|
|||||||
Reference in New Issue
Block a user