arcbox-computer-runtime 0.10.1

Sandbox orchestration over nested microVMs behind the arcbox-vm-driver port: boot, exec, files, checkpoints, warm pools. The in-sandbox init is arcbox-vm-agent; the wire vocabulary is arcbox-vm-proto.
Documentation
//! Reachability, and the two projections over every leaf.

use super::harness::{LEAVES, explore, ordinal};
use crate::sandbox::ComputerState;
use crate::sandbox::record::PersistPhase;

#[test]
fn every_leaf_is_reachable_by_driving_events() {
    let mut seen = [false; LEAVES];
    for node in explore() {
        seen[ordinal(node.state)] = true;
    }
    assert!(
        seen.iter().all(|reached| *reached),
        "unreachable leaves: {:?}",
        seen.iter()
            .enumerate()
            .filter(|(_, reached)| !**reached)
            .map(|(index, _)| index)
            .collect::<Vec<_>>()
    );
}

#[test]
fn every_leaf_projects_onto_a_public_state() {
    // An arm nobody projects is how a state becomes invisible to callers, so
    // this asserts the whole table rather than sampling it. `gating` is the
    // one leaf with two answers: the boot's own `cmd` claims the workload
    // slot before READY, and from there a caller reads `Running` — which is
    // what stops an Inspect-polling client from stealing that slot.
    let expected: [&[ComputerState]; LEAVES] = [
        &[ComputerState::Starting],                         // provisioning
        &[ComputerState::Starting],                         // staging
        &[ComputerState::Starting],                         // booting
        &[ComputerState::Starting],                         // restoring
        &[ComputerState::Starting, ComputerState::Running], // gating
        &[ComputerState::Ready],                            // ready
        &[ComputerState::Running],                          // running
        &[ComputerState::Ready],                            // checkpointing
        &[ComputerState::Pausing],                          // capturing
        &[ComputerState::Pausing],                          // releasing
        &[ComputerState::Paused],                           // paused
        &[ComputerState::Starting],                         // resuming
        &[ComputerState::Stopping],                         // stopping
        &[ComputerState::Stopped],                          // stopped
        &[ComputerState::Failed],                           // failed
        &[ComputerState::Stopping],                         // removing
        &[ComputerState::Stopped],                          // gone
        &[ComputerState::Ready],                            // detached
    ];
    for node in explore() {
        let public = node.state.to_public();
        assert!(
            expected[ordinal(node.state)].contains(&public),
            "{:?} projects {public}",
            node.state
        );
    }
}

#[test]
fn every_leaf_projects_onto_a_durable_phase() {
    use PersistPhase as P;
    // Indexed by `ordinal`. `gating` is the one leaf two paths reach on
    // different phases, so it carries the discriminator and lists both; the
    // walk below pins which one each path actually holds.
    let expected: [&[Option<P>]; LEAVES] = [
        &[Some(P::Creating)],                 // provisioning: the reserved intent
        &[Some(P::Starting)],                 // staging
        &[Some(P::Starting)],                 // booting
        &[Some(P::Creating)],                 // restoring: commits Ready in one hop
        &[Some(P::Starting), Some(P::Ready)], // gating
        &[Some(P::Ready)],                    // ready
        &[Some(P::Ready)],                    // running: the hot path writes nothing
        &[Some(P::Ready)],                    // checkpointing
        &[Some(P::Pausing)],                  // capturing
        &[Some(P::Pausing)],                  // releasing
        &[Some(P::Paused)],                   // paused
        &[Some(P::Resuming)],                 // resuming
        &[Some(P::Stopping)],                 // stopping
        &[Some(P::Stopped)],                  // stopped
        &[Some(P::Failed)],                   // failed
        &[Some(P::Removing)],                 // removing
        &[None],                              // gone: the record is forgotten
        &[Some(P::Ready)],                    // detached: a handover writes nothing
    ];
    for node in explore() {
        let durable = node.state.durable();
        assert!(
            expected[ordinal(node.state)].contains(&durable),
            "{:?} projects {durable:?}",
            node.state
        );
    }
}

#[test]
fn the_durable_projection_is_the_phase_actually_in_effect() {
    for node in explore() {
        assert_eq!(
            node.state.durable(),
            node.phase,
            "{:?} reached via {:?}",
            node.state,
            node.path
        );
    }
}