nixfleet_state_machine/rollout/transitions/
pruned.rs1use chrono::{DateTime, Utc};
7
8use super::illegal;
9use crate::rollout::effect::RolloutEffect;
10use crate::rollout::error::RolloutTransitionError;
11use crate::rollout::event::RolloutEvent;
12use crate::rollout::state::{RolloutRecord, RolloutState};
13
14pub(super) fn step(
15 record: RolloutRecord,
16 event: RolloutEvent,
17 _now: DateTime<Utc>,
18) -> Result<(RolloutRecord, Vec<RolloutEffect>), RolloutTransitionError> {
19 Err(illegal(RolloutState::Pruned, &event, record.rollout_id))
20}
21
22#[cfg(test)]
23mod tests {
24 use super::*;
25 use chrono::TimeZone;
26
27 fn t0() -> DateTime<Utc> {
28 Utc.with_ymd_and_hms(2026, 5, 16, 1, 0, 0).unwrap()
29 }
30
31 fn pruned_record() -> RolloutRecord {
32 RolloutRecord {
33 rollout_id: "r1".into(),
34 channel: "stable".into(),
35 target_ref: "ref-1".into(),
36 state: RolloutState::Pruned,
37 current_wave: 0,
38 opened_event_log_seq: None,
39 last_transition_event_log_seq: None,
40 opened_at: t0(),
41 terminal_at: Some(t0()),
42 superseded_at: None,
43 }
44 }
45
46 #[test]
47 fn every_event_is_illegal_from_pruned() {
48 let event = RolloutEvent::SuccessorOpened {
49 superseded_rollout_id: "r1".into(),
50 successor_rollout_id: "r2".into(),
51 at: t0(),
52 };
53 let err = step(pruned_record(), event, t0()).unwrap_err();
54 assert!(matches!(
55 err,
56 RolloutTransitionError::IllegalForState {
57 from: RolloutState::Pruned,
58 ..
59 }
60 ));
61 }
62}