capsule_core/wasm/utilities/
task_config.rs1use serde::Deserialize;
2
3use crate::wasm::execution_policy::{Compute, ExecutionPolicy};
4
5#[derive(Debug, Deserialize, Default)]
6pub struct TaskConfig {
7 name: Option<String>,
8 compute: Option<String>,
9 ram: Option<String>,
10 timeout: Option<String>,
11
12 #[serde(alias = "maxRetries")]
13 max_retries: Option<u64>,
14}
15
16impl TaskConfig {
17 pub fn to_execution_policy(&self) -> ExecutionPolicy {
18 let compute = self
19 .compute
20 .as_ref()
21 .map(|c| match c.to_uppercase().as_str() {
22 "LOW" => Compute::Low,
23 "MEDIUM" => Compute::Medium,
24 "HIGH" => Compute::High,
25 _ => c
26 .parse::<u64>()
27 .map(Compute::Custom)
28 .unwrap_or(Compute::Medium),
29 });
30
31 let ram = self.ram.as_ref().and_then(|r| Self::parse_ram_string(r));
32
33 ExecutionPolicy::new()
34 .name(self.name.clone())
35 .compute(compute)
36 .ram(ram)
37 .timeout(self.timeout.clone())
38 .max_retries(self.max_retries)
39 }
40
41 pub fn parse_ram_string(s: &str) -> Option<u64> {
42 let s = s.trim().to_uppercase();
43 if s.ends_with("GB") {
44 s.trim_end_matches("GB")
45 .trim()
46 .parse::<u64>()
47 .ok()
48 .map(|v| v * 1024 * 1024 * 1024)
49 } else if s.ends_with("MB") {
50 s.trim_end_matches("MB")
51 .trim()
52 .parse::<u64>()
53 .ok()
54 .map(|v| v * 1024 * 1024)
55 } else if s.ends_with("KB") {
56 s.trim_end_matches("KB")
57 .trim()
58 .parse::<u64>()
59 .ok()
60 .map(|v| v * 1024)
61 } else {
62 s.parse::<u64>().ok()
63 }
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_parse_ram_string() {
73 assert_eq!(
74 TaskConfig::parse_ram_string("2GB"),
75 Some(2 * 1024 * 1024 * 1024)
76 );
77 assert_eq!(
78 TaskConfig::parse_ram_string("1 GB"),
79 Some(1024 * 1024 * 1024)
80 );
81 assert_eq!(
82 TaskConfig::parse_ram_string("4gb"),
83 Some(4 * 1024 * 1024 * 1024)
84 );
85
86 assert_eq!(
87 TaskConfig::parse_ram_string("512MB"),
88 Some(512 * 1024 * 1024)
89 );
90 assert_eq!(
91 TaskConfig::parse_ram_string("256 MB"),
92 Some(256 * 1024 * 1024)
93 );
94 assert_eq!(
95 TaskConfig::parse_ram_string("128mb"),
96 Some(128 * 1024 * 1024)
97 );
98
99 assert_eq!(TaskConfig::parse_ram_string("1024KB"), Some(1024 * 1024));
100 assert_eq!(TaskConfig::parse_ram_string("512 KB"), Some(512 * 1024));
101 assert_eq!(TaskConfig::parse_ram_string("256kb"), Some(256 * 1024));
102
103 assert_eq!(TaskConfig::parse_ram_string("1024"), Some(1024));
104 assert_eq!(TaskConfig::parse_ram_string("512"), Some(512));
105 }
106
107 #[test]
108 fn test_parse_ram_string_invalid() {
109 assert_eq!(TaskConfig::parse_ram_string("invalid"), None);
110 assert_eq!(TaskConfig::parse_ram_string(""), None);
111 assert_eq!(TaskConfig::parse_ram_string("GB"), None);
112 }
113
114 #[test]
115 fn test_to_execution_policy_default() {
116 let config = TaskConfig::default();
117 let policy = config.to_execution_policy();
118
119 assert_eq!(policy.name, "default");
120 assert_eq!(policy.compute, Compute::Medium);
121 assert_eq!(policy.ram, None);
122 assert_eq!(policy.timeout, None);
123 assert_eq!(policy.max_retries, 0);
124 }
125
126 #[test]
127 fn test_to_execution_policy_with_values() {
128 let config = TaskConfig {
129 name: Some("test_task".to_string()),
130 compute: Some("HIGH".to_string()),
131 ram: Some("2GB".to_string()),
132 timeout: Some("30s".to_string()),
133 max_retries: Some(3),
134 };
135
136 let policy = config.to_execution_policy();
137
138 assert_eq!(policy.name, "test_task");
139 assert_eq!(policy.compute, Compute::High);
140 assert_eq!(policy.ram, Some(2 * 1024 * 1024 * 1024));
141 assert_eq!(policy.timeout, Some("30s".to_string()));
142 assert_eq!(policy.max_retries, 3);
143 }
144
145 #[test]
146 fn test_to_execution_policy_compute_variants() {
147 let low = TaskConfig {
148 compute: Some("LOW".to_string()),
149 ..Default::default()
150 };
151 assert_eq!(low.to_execution_policy().compute, Compute::Low);
152
153 let medium = TaskConfig {
154 compute: Some("MEDIUM".to_string()),
155 ..Default::default()
156 };
157 assert_eq!(medium.to_execution_policy().compute, Compute::Medium);
158
159 let high = TaskConfig {
160 compute: Some("HIGH".to_string()),
161 ..Default::default()
162 };
163 assert_eq!(high.to_execution_policy().compute, Compute::High);
164
165 let invalid = TaskConfig {
166 compute: Some("INVALID".to_string()),
167 ..Default::default()
168 };
169 assert_eq!(invalid.to_execution_policy().compute, Compute::Medium);
170 }
171}