use arcbox_vm_driver::VmState;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GuestHold {
Resume,
Hold,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Capture {
Succeeded,
Failed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Settlement {
AsRequested,
Frozen,
}
pub fn settlement(state: VmState, hold: GuestHold, capture: Capture) -> Settlement {
let frozen =
state == VmState::Quiesced && (hold == GuestHold::Resume || capture == Capture::Failed);
if frozen {
Settlement::Frozen
} else {
Settlement::AsRequested
}
}
#[cfg(test)]
mod tests {
use super::*;
use arcbox_vm_driver::ExitStatus;
#[test]
fn a_guest_is_stranded_only_where_no_verb_can_thaw_it() {
use Capture::{Failed, Succeeded};
use GuestHold::{Hold, Resume};
use Settlement::{AsRequested, Frozen};
let table = [
(VmState::Running, Resume, Succeeded, AsRequested),
(VmState::Running, Resume, Failed, AsRequested),
(VmState::Running, Hold, Succeeded, AsRequested),
(VmState::Running, Hold, Failed, AsRequested),
(VmState::Quiesced, Resume, Succeeded, Frozen),
(VmState::Quiesced, Resume, Failed, Frozen),
(VmState::Quiesced, Hold, Succeeded, AsRequested),
(VmState::Quiesced, Hold, Failed, Frozen),
(
VmState::Exited(ExitStatus::exited(0)),
Resume,
Succeeded,
AsRequested,
),
(
VmState::Exited(ExitStatus::exited(0)),
Resume,
Failed,
AsRequested,
),
(
VmState::Exited(ExitStatus::exited(0)),
Hold,
Succeeded,
AsRequested,
),
(
VmState::Exited(ExitStatus::exited(0)),
Hold,
Failed,
AsRequested,
),
];
for (state, hold, capture, expected) in table {
assert_eq!(
settlement(state, hold, capture),
expected,
"{state} {hold:?} {capture:?}"
);
}
}
}