]> git.proxmox.com Git - pve-common.git/blob - test/calendar_event_test.pl
bump version to 8.1.2
[pve-common.git] / test / calendar_event_test.pl
1 #!/usr/bin/perl
2
3 use lib '../src';
4 use strict;
5 use warnings;
6 use POSIX ();
7 use Data::Dumper;
8 use Time::Local;
9 use Test::More;
10
11 use PVE::CalendarEvent;
12
13 # Time tests should run in a controlled setting
14 $ENV{TZ} = 'UTC';
15 POSIX::tzset();
16
17 my $alldays = [0,1,2,3,4,5,6];
18 my $tests = [
19 [
20 '*',
21 undef,
22 [
23 [0, 60],
24 [30, 60],
25 [59, 60],
26 [60, 120],
27 ]
28 ],
29 [
30 '*/10',
31 undef,
32 [
33 [0, 600],
34 [599, 600],
35 [600, 1200],
36 [50*60, 60*60]
37 ]
38 ],
39 [
40 '*/12:0' ,
41 undef,
42 [
43 [ 10, 43200],
44 [ 13*3600, 24*3600],
45 ]
46 ],
47 [
48 '1/12:0/15' ,
49 undef,
50 [
51 [0, 3600],
52 [3600, 3600+15*60],
53 [3600+16*60, 3600+30*60 ],
54 [3600+30*60, 3600+45*60 ],
55 [3600+45*60, 3600+12*3600],
56 [13*3600 + 1, 13*3600+15*60],
57 [13*3600 + 15*60, 13*3600+30*60],
58 [13*3600 + 30*60, 13*3600+45*60],
59 [13*3600 + 45*60, 25*3600],
60 ],
61 ],
62 [
63 '1,4,6',
64 undef,
65 [
66 [0, 60],
67 [60, 4*60],
68 [4*60+60, 6*60],
69 [6*60, 3600+60],
70 ]
71 ],
72 [
73 '0..3',
74 undef,
75 ],
76 [
77 '23..23:0..3',
78 undef,
79 ],
80 [
81 'Mon',
82 undef,
83 [
84 [0, 4*86400], # Note: Epoch 0 is Thursday, 1. January 1970
85 [4*86400, 11*86400],
86 [11*86400, 18*86400],
87 ],
88 ],
89 [
90 'sat..sun',
91 undef,
92 [
93 [0, 2*86400],
94 [2*86400, 3*86400],
95 [3*86400, 9*86400],
96 ]
97 ],
98 [
99 'sun..sat',
100 undef,
101 ],
102 [
103 'Fri..Mon',
104 { error => "wrong order in range 'Fri..Mon'" },
105 ],
106 [
107 'wed,mon..tue,fri',
108 undef,
109 ],
110 [
111 'mon */15',
112 undef,
113 ],
114 [
115 '22/1:0',
116 undef,
117 [
118 [0, 22*60*60],
119 [22*60*60, 23*60*60],
120 [22*60*60 + 59*60, 23*60*60]
121 ],
122 ],
123 [
124 '*/2:*',
125 undef,
126 [
127 [0, 60],
128 [60*60, 2*60*60],
129 [2*60*60, 2*60*60 + 60]
130 ]
131 ],
132 [
133 '20..22:*/30',
134 undef,
135 [
136 [0, 20*60*60],
137 [20*60*60, 20*60*60 + 30*60],
138 [22*60*60 + 30*60, 44*60*60]
139 ]
140 ],
141 [
142 '61',
143 { error => "value '61' out of range" },
144 ],
145 [
146 '*/61',
147 { error => "repetition '61' out of range" },
148 ],
149 [
150 '0..80',
151 { error => "range end '80' out of range" },
152 ],
153 [
154 ' mon 0 0 0',
155 { error => "unable to parse calendar event - unused parts" },
156 ],
157 [
158 '',
159 { error => "unable to parse calendar event - event is empty" },
160 ],
161 [
162 ' mon 0 0',
163 { error => "unable to parse calendar event - unused parts" },
164 ],
165 [
166 '0,1,3..5',
167 undef,
168 [
169 [0, 60],
170 [60, 3*60],
171 [5*60, 60*60]
172 ]
173 ],
174 [
175 '2,4:0,1,3..5',
176 undef,
177 [
178 [0, 2*60*60],
179 [2*60*60 + 60, 2*60*60 + 3*60],
180 [2*60*60 + 5*60, 4*60*60]
181 ]
182 ],
183 ];
184
185 foreach my $test (@$tests) {
186 my ($t, $expect, $nextsync) = @$test;
187
188 $expect //= {};
189
190 my $timespec;
191 eval { $timespec = PVE::CalendarEvent::parse_calendar_event($t); };
192 my $err = $@;
193
194 if ($expect->{error}) {
195 chomp $err if $err;
196 ok(defined($err) == defined($expect->{error}), "parsing '$t' failed expectedly");
197 die "unable to execute nextsync tests" if $nextsync;
198 }
199
200 next if !$nextsync;
201
202 foreach my $nt (@$nextsync) {
203 my ($last, $expect_next) = @$nt;
204 my $msg = "next event '$t' $last => ${expect_next}";
205 $timespec->{utc} = 1;
206 my $next = PVE::CalendarEvent::compute_next_event($timespec, $last);
207 is($next, $expect_next, $msg);
208 }
209 };
210
211 sub tztest {
212 my ($calspec, $last) = @_;
213 my $spec = PVE::CalendarEvent::parse_calendar_event($calspec);
214 return PVE::CalendarEvent::compute_next_event($spec, $last);
215 }
216
217 # Test loop termination at CEST/CET switch (cannot happen here in UTC)
218 is(tztest('mon..fri', timelocal(0, 0, 0, 28, 9, 2018)),
219 timelocal(0, 0, 0, 29, 9, 2018));
220 is(tztest('mon..fri UTC', timelocal(0, 0, 0, 28, 9, 2018)),
221 timelocal(0, 0, 0, 29, 9, 2018));
222
223 # Now in the affected time zone
224 $ENV{TZ} = ':Europe/Vienna';
225 POSIX::tzset();
226 is(tztest('mon..fri', timelocal(0, 0, 0, 28, 9, 2018)),
227 timelocal(0, 0, 0, 29, 9, 2018));
228 # Specifically requesting UTC in the calendar spec means the resulting output
229 # time as seen locally (timelocal() as opposed to timegm()) is shifted by 1
230 # hour.
231 is(tztest('mon..fri UTC', timelocal(0, 0, 0, 28, 9, 2018)),
232 timelocal(0, 0, 1, 29, 9, 2018));
233 $ENV{TZ} = 'UTC';
234 POSIX::tzset();
235
236 done_testing();