]> git.proxmox.com Git - proxmox.git/blame - proxmox-time/src/test.rs
proxmox-time: calendar-events: make compute_next_event a method
[proxmox.git] / proxmox-time / src / test.rs
CommitLineData
676146fd
DC
1use anyhow::bail;
2
3use super::*;
4
5fn test_event(v: &'static str) -> Result<(), Error> {
6 match parse_calendar_event(v) {
7 Ok(event) => println!("CalendarEvent '{}' => {:?}", v, event),
8 Err(err) => bail!("parsing '{}' failed - {}", v, err),
9 }
10
11 Ok(())
12}
13
14const fn make_test_time(mday: i32, hour: i32, min: i32) -> i64 {
15 (mday * 3600 * 24 + hour * 3600 + min * 60) as i64
16}
17
18#[test]
19fn test_compute_next_event() -> Result<(), Error> {
20 let test_value = |v: &'static str, last: i64, expect: i64| -> Result<i64, Error> {
21 let event = match parse_calendar_event(v) {
22 Ok(event) => event,
23 Err(err) => bail!("parsing '{}' failed - {}", v, err),
24 };
25
a96e9fb7 26 match event.compute_next_event(last, true) {
676146fd
DC
27 Ok(Some(next)) => {
28 if next == expect {
29 println!("next {:?} => {}", event, next);
30 } else {
31 bail!(
32 "next {:?} failed\nnext: {:?}\nexpect: {:?}",
33 event,
34 crate::gmtime(next),
35 crate::gmtime(expect),
36 );
37 }
38 }
39 Ok(None) => bail!("next {:?} failed to find a timestamp", event),
40 Err(err) => bail!("compute next for '{}' failed - {}", v, err),
41 }
42
43 Ok(expect)
44 };
45
46 let test_never = |v: &'static str, last: i64| -> Result<(), Error> {
47 let event = match parse_calendar_event(v) {
48 Ok(event) => event,
49 Err(err) => bail!("parsing '{}' failed - {}", v, err),
50 };
51
a96e9fb7 52 match event.compute_next_event(last, true)? {
676146fd
DC
53 None => Ok(()),
54 Some(next) => bail!(
55 "compute next for '{}' succeeded, but expected fail - result {}",
56 v,
57 next
58 ),
59 }
60 };
61
62 const MIN: i64 = 60;
63 const HOUR: i64 = 3600;
64 const DAY: i64 = 3600 * 24;
65
66 const THURSDAY_00_00: i64 = make_test_time(0, 0, 0);
67 const THURSDAY_15_00: i64 = make_test_time(0, 15, 0);
68
69 const JUL_31_2020: i64 = 1596153600; // Friday, 2020-07-31 00:00:00
70 const DEC_31_2020: i64 = 1609372800; // Thursday, 2020-12-31 00:00:00
71
72 // minute only syntax
73 test_value("0", THURSDAY_00_00, THURSDAY_00_00 + HOUR)?;
74 test_value("*", THURSDAY_00_00, THURSDAY_00_00 + MIN)?;
75
76 test_value("*:0", THURSDAY_00_00, THURSDAY_00_00 + HOUR)?;
77 test_value("*:*", THURSDAY_00_00, THURSDAY_00_00 + MIN)?;
78 test_value("*:*:*", THURSDAY_00_00, THURSDAY_00_00 + 1)?;
79 test_value("*:3:5", THURSDAY_00_00, THURSDAY_00_00 + 3 * MIN + 5)?;
80
81 test_value("mon *:*", THURSDAY_00_00, THURSDAY_00_00 + 4 * DAY)?;
82 test_value(
83 "mon 2:*",
84 THURSDAY_00_00,
85 THURSDAY_00_00 + 4 * DAY + 2 * HOUR,
86 )?;
87 test_value(
88 "mon 2:50",
89 THURSDAY_00_00,
90 THURSDAY_00_00 + 4 * DAY + 2 * HOUR + 50 * MIN,
91 )?;
92
93 test_value("tue", THURSDAY_00_00, THURSDAY_00_00 + 5 * DAY)?;
94 test_value("wed", THURSDAY_00_00, THURSDAY_00_00 + 6 * DAY)?;
95 test_value("thu", THURSDAY_00_00, THURSDAY_00_00 + 7 * DAY)?;
96 test_value("fri", THURSDAY_00_00, THURSDAY_00_00 + 1 * DAY)?;
97 test_value("sat", THURSDAY_00_00, THURSDAY_00_00 + 2 * DAY)?;
98 test_value("sun", THURSDAY_00_00, THURSDAY_00_00 + 3 * DAY)?;
99
100 // test repeated ranges
101 test_value("4..10/2:0", THURSDAY_00_00, THURSDAY_00_00 + 4 * HOUR)?;
102 test_value(
103 "4..10/2:0",
104 THURSDAY_00_00 + 5 * HOUR,
105 THURSDAY_00_00 + 6 * HOUR,
106 )?;
107 test_value(
108 "4..10/2:0",
109 THURSDAY_00_00 + 11 * HOUR,
110 THURSDAY_00_00 + 1 * DAY + 4 * HOUR,
111 )?;
112
113 // test multiple values for a single field
114 // and test that the order does not matter
115 test_value(
116 "5,10:4,8",
117 THURSDAY_00_00,
118 THURSDAY_00_00 + 5 * HOUR + 4 * MIN,
119 )?;
120 test_value(
121 "10,5:8,4",
122 THURSDAY_00_00,
123 THURSDAY_00_00 + 5 * HOUR + 4 * MIN,
124 )?;
125 test_value(
126 "6,4..10:23,5/5",
127 THURSDAY_00_00,
128 THURSDAY_00_00 + 4 * HOUR + 5 * MIN,
129 )?;
130 test_value(
131 "4..10,6:5/5,23",
132 THURSDAY_00_00,
133 THURSDAY_00_00 + 4 * HOUR + 5 * MIN,
134 )?;
135
136 // test month wrapping
137 test_value("sat", JUL_31_2020, JUL_31_2020 + 1 * DAY)?;
138 test_value("sun", JUL_31_2020, JUL_31_2020 + 2 * DAY)?;
139 test_value("mon", JUL_31_2020, JUL_31_2020 + 3 * DAY)?;
140 test_value("tue", JUL_31_2020, JUL_31_2020 + 4 * DAY)?;
141 test_value("wed", JUL_31_2020, JUL_31_2020 + 5 * DAY)?;
142 test_value("thu", JUL_31_2020, JUL_31_2020 + 6 * DAY)?;
143 test_value("fri", JUL_31_2020, JUL_31_2020 + 7 * DAY)?;
144
145 // test year wrapping
146 test_value("fri", DEC_31_2020, DEC_31_2020 + 1 * DAY)?;
147 test_value("sat", DEC_31_2020, DEC_31_2020 + 2 * DAY)?;
148 test_value("sun", DEC_31_2020, DEC_31_2020 + 3 * DAY)?;
149 test_value("mon", DEC_31_2020, DEC_31_2020 + 4 * DAY)?;
150 test_value("tue", DEC_31_2020, DEC_31_2020 + 5 * DAY)?;
151 test_value("wed", DEC_31_2020, DEC_31_2020 + 6 * DAY)?;
152 test_value("thu", DEC_31_2020, DEC_31_2020 + 7 * DAY)?;
153
154 test_value("daily", THURSDAY_00_00, THURSDAY_00_00 + DAY)?;
155 test_value("daily", THURSDAY_00_00 + 1, THURSDAY_00_00 + DAY)?;
156
157 let n = test_value("5/2:0", THURSDAY_00_00, THURSDAY_00_00 + 5 * HOUR)?;
158 let n = test_value("5/2:0", n, THURSDAY_00_00 + 7 * HOUR)?;
159 let n = test_value("5/2:0", n, THURSDAY_00_00 + 9 * HOUR)?;
160 test_value("5/2:0", n, THURSDAY_00_00 + 11 * HOUR)?;
161
162 let mut n = test_value("*:*", THURSDAY_00_00, THURSDAY_00_00 + MIN)?;
163 for i in 2..100 {
164 n = test_value("*:*", n, THURSDAY_00_00 + i * MIN)?;
165 }
166
167 let mut n = test_value("*:0", THURSDAY_00_00, THURSDAY_00_00 + HOUR)?;
168 for i in 2..100 {
169 n = test_value("*:0", n, THURSDAY_00_00 + i * HOUR)?;
170 }
171
172 let mut n = test_value("1:0", THURSDAY_15_00, THURSDAY_00_00 + DAY + HOUR)?;
173 for i in 2..100 {
174 n = test_value("1:0", n, THURSDAY_00_00 + i * DAY + HOUR)?;
175 }
176
177 // test date functionality
178
179 test_value("2020-07-31", 0, JUL_31_2020)?;
180 test_value("02-28", 0, (31 + 27) * DAY)?;
181 test_value("02-29", 0, 2 * 365 * DAY + (31 + 28) * DAY)?; // 1972-02-29
182 test_value("1965/5-01-01", -1, THURSDAY_00_00)?;
183 test_value("2020-7..9-2/2", JUL_31_2020, JUL_31_2020 + 2 * DAY)?;
184 test_value("2020,2021-12-31", JUL_31_2020, DEC_31_2020)?;
185
186 test_value("monthly", 0, 31 * DAY)?;
187 test_value("quarterly", 0, (31 + 28 + 31) * DAY)?;
188 test_value("semiannually", 0, (31 + 28 + 31 + 30 + 31 + 30) * DAY)?;
189 test_value("yearly", 0, (365) * DAY)?;
190
191 test_never("2021-02-29", 0)?;
192 test_never("02-30", 0)?;
193
194 Ok(())
195}
196
197#[test]
198fn test_calendar_event_weekday() -> Result<(), Error> {
199 test_event("mon,wed..fri")?;
200 test_event("fri..mon")?;
201
202 test_event("mon")?;
203 test_event("MON")?;
204 test_event("monDay")?;
205 test_event("tue")?;
206 test_event("Tuesday")?;
207 test_event("wed")?;
208 test_event("wednesday")?;
209 test_event("thu")?;
210 test_event("thursday")?;
211 test_event("fri")?;
212 test_event("friday")?;
213 test_event("sat")?;
214 test_event("saturday")?;
215 test_event("sun")?;
216 test_event("sunday")?;
217
218 test_event("mon..fri")?;
219 test_event("mon,tue,fri")?;
220 test_event("mon,tue..wednesday,fri..sat")?;
221
222 Ok(())
223}
224
225#[test]
226fn test_time_span_parser() -> Result<(), Error> {
227 let test_value = |ts_str: &str, expect: f64| -> Result<(), Error> {
228 let ts = parse_time_span(ts_str)?;
229 assert_eq!(f64::from(ts), expect, "{}", ts_str);
230 Ok(())
231 };
232
233 test_value("2", 2.0)?;
234 test_value("2s", 2.0)?;
235 test_value("2sec", 2.0)?;
236 test_value("2second", 2.0)?;
237 test_value("2seconds", 2.0)?;
238
239 test_value(" 2s 2 s 2", 6.0)?;
240
241 test_value("1msec 1ms", 0.002)?;
242 test_value("1usec 1us 1µs", 0.000_003)?;
243 test_value("1nsec 1ns", 0.000_000_002)?;
244 test_value("1minutes 1minute 1min 1m", 4.0 * 60.0)?;
245 test_value("1hours 1hour 1hr 1h", 4.0 * 3600.0)?;
246 test_value("1days 1day 1d", 3.0 * 86400.0)?;
247 test_value("1weeks 1 week 1w", 3.0 * 86400.0 * 7.0)?;
248 test_value("1months 1month 1M", 3.0 * 86400.0 * 30.44)?;
249 test_value("1years 1year 1y", 3.0 * 86400.0 * 365.25)?;
250
251 test_value("2h", 7200.0)?;
252 test_value(" 2 h", 7200.0)?;
253 test_value("2hours", 7200.0)?;
254 test_value("48hr", 48.0 * 3600.0)?;
255 test_value(
256 "1y 12month",
257 365.25 * 24.0 * 3600.0 + 12.0 * 30.44 * 24.0 * 3600.0,
258 )?;
259 test_value("55s500ms", 55.5)?;
260 test_value("300ms20s 5day", 5.0 * 24.0 * 3600.0 + 20.0 + 0.3)?;
261
262 Ok(())
263}