feat: update terminal support messaging and enhance guest agent provisioning logic
This commit is contained in:
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
from unittest.mock import Mock
|
||||
|
||||
from tests.test_lifecycle import LifecycleTestCase
|
||||
from uvm.errors import ConflictError, GuestAgentUnavailableError, GuestExecutionError, NotFoundError
|
||||
from uvm.errors import ConflictError, GuestAgentUnavailableError, GuestExecutionError, NotFoundError, UvmError
|
||||
from uvm.guest_exec import ExecResult
|
||||
|
||||
|
||||
@@ -22,6 +22,65 @@ class GuestExecLifecycleTests(LifecycleTestCase):
|
||||
vm = self.create_vm(username="worker")
|
||||
self.assert_call_order(vm, "images.provision_agent", "process.start")
|
||||
|
||||
def test_stopped_boots_automatically_provision_agent_before_starting_the_vmm(self) -> None:
|
||||
vm = self.create_vm(username="worker", password="retained-password")
|
||||
identity = (vm.id, vm.guest_ip, vm.mac, vm.username, vm.password)
|
||||
|
||||
def provision(disk, vm_id, username):
|
||||
self.host.call("images.provision_agent", vm_id)
|
||||
record = self.store.get(vm_id)
|
||||
self.assertTrue(self.store.operation_active)
|
||||
self.assertEqual(self.process.observe(record), "gone")
|
||||
self.assertEqual((record.id, record.guest_ip, record.mac, record.username, record.password), identity)
|
||||
self.assertEqual((disk, username), (Path(vm.disk), "worker"))
|
||||
|
||||
self.provision_agent.side_effect = provision
|
||||
for action in ("start", "restart", "resize"):
|
||||
with self.subTest(action=action):
|
||||
if action == "start":
|
||||
self.service.stop(vm.id)
|
||||
self.host.events.clear()
|
||||
self.provision_agent.reset_mock()
|
||||
self.provision.reset_mock()
|
||||
if action == "resize":
|
||||
started = self.service.resize(vm.id, cpu=2)
|
||||
else:
|
||||
started = getattr(self.service, action)(vm.id)
|
||||
self.assertEqual(started.status, "running")
|
||||
self.provision_agent.assert_called_once_with(Path(vm.disk), vm.id, "worker")
|
||||
self.provision.assert_not_called()
|
||||
self.assert_call_order(vm, "images.provision_agent", "process.start")
|
||||
|
||||
def test_live_or_ambiguous_vms_never_run_offline_agent_provisioning(self) -> None:
|
||||
vm = self.create_vm()
|
||||
self.provision_agent.reset_mock()
|
||||
self.service.start(vm.id)
|
||||
self.process.unknown.add(vm.id)
|
||||
with self.assertRaises(ConflictError):
|
||||
self.service.start(vm.id)
|
||||
self.provision_agent.assert_not_called()
|
||||
|
||||
def test_default_agent_setup_failure_blocks_boot_and_keeps_the_retained_disk(self) -> None:
|
||||
vm = self.create_vm()
|
||||
self.service.stop(vm.id)
|
||||
before = Path(vm.disk).read_bytes()
|
||||
count = len(self.process.started)
|
||||
self.provision_agent.side_effect = UvmError("agent setup failed")
|
||||
with self.assertRaisesRegex(UvmError, "agent setup failed"):
|
||||
self.service.start(vm.id)
|
||||
self.assertEqual(len(self.process.started), count)
|
||||
self.assertEqual(Path(vm.disk).read_bytes(), before)
|
||||
self.assertEqual(self.store.get(vm.id).status, "failed")
|
||||
self.provision_agent.side_effect = None
|
||||
self.assertEqual(self.service.start(vm.id).status, "running")
|
||||
|
||||
def test_default_agent_setup_failure_rolls_back_a_new_vm_before_boot(self) -> None:
|
||||
self.provision_agent.side_effect = UvmError("unsupported guest image")
|
||||
with self.assertRaisesRegex(UvmError, "unsupported guest image"):
|
||||
self.create_vm()
|
||||
self.assertEqual(self.store.load().vms, {})
|
||||
self.assertEqual(self.process.started, [])
|
||||
|
||||
def test_execution_pins_the_exact_vm_under_lock_and_waits_without_holding_it(self) -> None:
|
||||
vm = self.create_vm(name="worker", ports=())
|
||||
result = ExecResult(7, "output", "problem", False, False)
|
||||
|
||||
Reference in New Issue
Block a user