use nucleus::filesystem::FilesystemState;
use nucleus::StateTransition;
#[test]
fn test_filesystem_state_machine_happy_path() {
let states = [
FilesystemState::Unmounted,
FilesystemState::Mounted,
FilesystemState::Populated,
FilesystemState::Pivoted,
FilesystemState::UnmountedFinal,
];
for i in 0..states.len() - 1 {
assert!(
states[i].can_transition_to(&states[i + 1]),
"Invalid transition from {:?} to {:?}",
states[i],
states[i + 1]
);
}
}
#[test]
fn test_filesystem_property_context_isolation() {
let state = FilesystemState::Pivoted;
assert!(state.can_transition_to(&FilesystemState::Pivoted)); assert!(state.can_transition_to(&FilesystemState::UnmountedFinal));
assert!(!state.can_transition_to(&FilesystemState::Unmounted));
assert!(!state.can_transition_to(&FilesystemState::Mounted));
assert!(!state.can_transition_to(&FilesystemState::Populated));
}
#[test]
fn test_filesystem_property_ephemeral_guarantee() {
let state = FilesystemState::UnmountedFinal;
assert!(state.is_terminal());
assert!(!state.can_transition_to(&FilesystemState::Unmounted));
assert!(!state.can_transition_to(&FilesystemState::Mounted));
assert!(!state.can_transition_to(&FilesystemState::Populated));
assert!(!state.can_transition_to(&FilesystemState::Pivoted));
assert!(state.can_transition_to(&FilesystemState::UnmountedFinal));
}
#[test]
fn test_filesystem_property_mount_ordering() {
let state = FilesystemState::Populated;
assert!(state.can_transition_to(&FilesystemState::Populated)); assert!(state.can_transition_to(&FilesystemState::Pivoted));
assert!(state.can_transition_to(&FilesystemState::Unmounted));
assert!(!state.can_transition_to(&FilesystemState::Mounted));
assert!(!state.can_transition_to(&FilesystemState::UnmountedFinal));
}
#[test]
fn test_filesystem_no_state_skipping() {
assert!(!FilesystemState::Unmounted.can_transition_to(&FilesystemState::Populated));
assert!(!FilesystemState::Unmounted.can_transition_to(&FilesystemState::Pivoted));
assert!(!FilesystemState::Mounted.can_transition_to(&FilesystemState::Pivoted));
assert!(!FilesystemState::Mounted.can_transition_to(&FilesystemState::UnmountedFinal));
}
#[test]
fn test_filesystem_no_backwards_transitions() {
assert!(FilesystemState::Mounted.can_transition_to(&FilesystemState::Unmounted));
assert!(!FilesystemState::Populated.can_transition_to(&FilesystemState::Mounted));
assert!(!FilesystemState::Pivoted.can_transition_to(&FilesystemState::Populated));
assert!(!FilesystemState::UnmountedFinal.can_transition_to(&FilesystemState::Pivoted));
}
#[test]
fn test_filesystem_liveness() {
let states = [
FilesystemState::Unmounted,
FilesystemState::Mounted,
FilesystemState::Populated,
FilesystemState::Pivoted,
];
for initial in states {
assert!(
!initial.is_terminal(),
"{:?} should not be terminal",
initial
);
let mut current = initial;
let mut steps = 0;
while !current.is_terminal() && steps < 10 {
current = match current {
FilesystemState::Unmounted => FilesystemState::Mounted,
FilesystemState::Mounted => FilesystemState::Populated,
FilesystemState::Populated => FilesystemState::Pivoted,
FilesystemState::Pivoted => FilesystemState::UnmountedFinal,
FilesystemState::UnmountedFinal => break,
};
steps += 1;
}
assert!(
current.is_terminal(),
"Should reach terminal from {:?}",
initial
);
}
}