Files
xy/crates/xy-supervisor/src/policy.rs
T

103 lines
2.3 KiB
Rust

use xy_protocol::RestartPolicy;
#[derive(Debug, PartialEq, Eq)]
pub enum RestartDecision {
Restart,
StayStopped,
MarkFailed,
}
pub fn decide(
policy: RestartPolicy,
exit_code: Option<i32>,
retry_cap_reached: bool,
) -> RestartDecision {
let clean = matches!(exit_code, Some(0));
let want = match policy {
RestartPolicy::Never => false,
RestartPolicy::OnFailure => !clean,
RestartPolicy::Always => true,
};
if !want {
return RestartDecision::StayStopped;
}
if retry_cap_reached {
RestartDecision::MarkFailed
} else {
RestartDecision::Restart
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn never_never_restarts() {
assert_eq!(
decide(RestartPolicy::Never, Some(0), false),
RestartDecision::StayStopped
);
assert_eq!(
decide(RestartPolicy::Never, Some(1), false),
RestartDecision::StayStopped
);
assert_eq!(
decide(RestartPolicy::Never, None, false),
RestartDecision::StayStopped
);
}
#[test]
fn on_failure_skips_clean() {
assert_eq!(
decide(RestartPolicy::OnFailure, Some(0), false),
RestartDecision::StayStopped
);
}
#[test]
fn on_failure_restarts_nonzero() {
assert_eq!(
decide(RestartPolicy::OnFailure, Some(1), false),
RestartDecision::Restart
);
}
#[test]
fn on_failure_restarts_signal() {
assert_eq!(
decide(RestartPolicy::OnFailure, None, false),
RestartDecision::Restart
);
}
#[test]
fn always_restarts_on_clean() {
assert_eq!(
decide(RestartPolicy::Always, Some(0), false),
RestartDecision::Restart
);
}
#[test]
fn cap_reached_marks_failed() {
assert_eq!(
decide(RestartPolicy::Always, Some(0), true),
RestartDecision::MarkFailed
);
assert_eq!(
decide(RestartPolicy::OnFailure, Some(1), true),
RestartDecision::MarkFailed
);
}
#[test]
fn cap_reached_never_still_stopped() {
assert_eq!(
decide(RestartPolicy::Never, Some(1), true),
RestartDecision::StayStopped
);
}
}