northstar_runtime/npk/manifest/
sched.rs

1use serde::{Deserialize, Serialize};
2use validator::{Validate, ValidationError};
3
4/// Policy.
5#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
6#[serde(rename_all = "snake_case")]
7pub enum Policy {
8    /// The standard round-robin time-sharing policy.
9    Other {
10        /// Nice level. +19 (low priority) to -20 (high
11        nice: i8,
12    },
13    /// First-in, first-out policy.
14    Fifo {
15        /// Priority of the process.
16        priority: u32,
17    },
18    /// Round-robin policy.
19    RoundRobin {
20        /// Priority of the process.
21        priority: u32,
22    },
23    /// Batch style execution of processes.
24    Batch {
25        /// Nice level. +19 (low priority) to -20 (high
26        nice: i8,
27    },
28    /// Running very low priority background jobs.
29    Idle,
30    /// Deadline policy.
31    Deadline,
32}
33
34/// Scheduling policy.
35#[derive(Clone, Eq, PartialEq, Debug, Serialize, Validate, Deserialize)]
36#[serde(rename_all = "snake_case")]
37pub struct Sched {
38    /// Scheduling policy.
39    #[validate(custom(function = "validate_policy"))]
40    pub policy: Policy,
41}
42
43fn validate_policy(policy: &Policy) -> Result<(), ValidationError> {
44    match policy {
45        Policy::Other { nice } if !(-20..=19).contains(nice) => {
46            let mut error = ValidationError::new("nice must be between -20 and 19");
47            error.add_param("nice".into(), nice);
48            Err(error)
49        }
50        Policy::Fifo { priority } if !(1..=99).contains(priority) => {
51            let mut error = ValidationError::new("fifo priority must be between 1 and 99");
52            error.add_param("priority".into(), priority);
53            Err(error)
54        }
55        Policy::RoundRobin { priority } => {
56            let mut error = ValidationError::new("round robing priority must be between 1 and 99");
57            error.add_param("priority".into(), priority);
58            Err(error)
59        }
60        Policy::Batch { nice } if !(-20..=19).contains(nice) => {
61            let mut error = ValidationError::new("nice must be between -20 and 19");
62            error.add_param("nice".into(), nice);
63            Err(error)
64        }
65        _ => Ok(()),
66    }
67}
68
69#[cfg(test)]
70mod test {
71    use super::{Policy, Sched};
72    use anyhow::Result;
73    use validator::Validate;
74
75    #[test]
76    fn parse_other() -> Result<()> {
77        assert_eq!(
78            serde_yaml::from_str::<Sched>("policy:\n  !other\n    nice: 0")?,
79            Sched {
80                policy: Policy::Other { nice: 0 },
81            }
82        );
83        Ok(())
84    }
85
86    #[test]
87    fn parse_other_with_nice_value() -> Result<()> {
88        assert_eq!(
89            serde_yaml::from_str::<Sched>("policy:\n  !other\n    nice: 10")?,
90            Sched {
91                policy: Policy::Other { nice: 10 },
92            }
93        );
94        Ok(())
95    }
96
97    #[test]
98    fn parse_other_with_too_big_nice_value() -> Result<()> {
99        let policy = serde_yaml::from_str::<Sched>("policy:\n  !other\n    nice: 55")?;
100        assert!(policy.validate().is_err());
101        Ok(())
102    }
103
104    #[test]
105    fn parse_other_with_too_small_nice_value() -> Result<()> {
106        let policy = serde_yaml::from_str::<Sched>("policy:\n  !other\n    nice: -40")?;
107        assert!(policy.validate().is_err());
108        Ok(())
109    }
110
111    #[test]
112    fn parse_fifo() -> Result<()> {
113        assert_eq!(
114            serde_yaml::from_str::<Sched>("policy:\n  !fifo\n    priority: 10")?,
115            Sched {
116                policy: Policy::Fifo { priority: 10 },
117            }
118        );
119        Ok(())
120    }
121
122    #[test]
123    fn parse_fifo_with_zero_priority() -> Result<()> {
124        assert!(
125            serde_yaml::from_str::<Sched>("policy:\n  !fifo\n    priority: 0")?
126                .validate()
127                .is_err()
128        );
129        Ok(())
130    }
131
132    #[test]
133    fn parse_fifo_with_too_high_priority() -> Result<()> {
134        assert!(
135            serde_yaml::from_str::<Sched>("policy:\n  !fifo\n    priority: 200")?
136                .validate()
137                .is_err()
138        );
139        Ok(())
140    }
141
142    #[test]
143    fn parse_round_robing_with_too_zero_priority() -> Result<()> {
144        assert!(
145            serde_yaml::from_str::<Sched>("policy:\n  !round_robin\n    priority: 0")?
146                .validate()
147                .is_err()
148        );
149        Ok(())
150    }
151
152    #[test]
153    fn parse_round_robing_with_too_high_priority() -> Result<()> {
154        assert!(
155            serde_yaml::from_str::<Sched>("policy:\n  !round_robin\n    priority: 200")?
156                .validate()
157                .is_err()
158        );
159        Ok(())
160    }
161}