use std::collections::HashMap;
use dag_executor::state::{StateValidator, TaskRecord, TaskState};
#[test]
fn legal_transitions_are_allowed() {
assert!(TaskState::Pending.can_transition_to(TaskState::Ready));
assert!(TaskState::Ready.can_transition_to(TaskState::Running));
assert!(TaskState::Running.can_transition_to(TaskState::Completed));
assert!(TaskState::Running.can_transition_to(TaskState::Failed));
assert!(TaskState::Failed.can_transition_to(TaskState::DeadLettered));
}
#[test]
fn illegal_transitions_are_rejected() {
assert!(!TaskState::Pending.can_transition_to(TaskState::Running));
assert!(!TaskState::Completed.can_transition_to(TaskState::Running));
assert!(!TaskState::Completed.can_transition_to(TaskState::Pending));
}
#[test]
fn terminal_and_success_classification() {
assert!(TaskState::Completed.is_terminal());
assert!(TaskState::Completed.is_success());
assert!(TaskState::DeadLettered.is_failure());
assert!(!TaskState::Running.is_terminal());
}
#[test]
fn record_transition_tracks_timestamps() {
let mut r = TaskRecord::new("t");
assert!(r.transition(TaskState::Ready));
assert!(r.transition(TaskState::Running));
assert!(r.started_at.is_some());
assert!(r.transition(TaskState::Completed));
assert!(r.finished_at.is_some());
assert!(r.duration_millis().is_some());
}
#[test]
fn record_rejects_illegal_transition() {
let mut r = TaskRecord::new("t");
assert!(!r.transition(TaskState::Completed));
assert_eq!(r.state, TaskState::Pending);
}
#[test]
fn validator_repairs_orphaned_running_tasks() {
let mut records = HashMap::new();
let mut running = TaskRecord::new("crashed");
running.transition(TaskState::Ready);
running.transition(TaskState::Running);
running.attempts = 1;
records.insert("crashed".to_string(), running);
let report = StateValidator::new().repair(&mut records, 3);
assert!(!report.is_clean());
assert_eq!(report.reset_running, vec!["crashed".to_string()]);
assert_eq!(records["crashed"].state, TaskState::Pending);
}
#[test]
fn validator_fails_exhausted_running_tasks() {
let mut records = HashMap::new();
let mut running = TaskRecord::new("crashed");
running.transition(TaskState::Ready);
running.transition(TaskState::Running);
running.attempts = 3;
records.insert("crashed".to_string(), running);
StateValidator::new().repair(&mut records, 3);
assert_eq!(records["crashed"].state, TaskState::Failed);
}