]> git.proxmox.com Git - pve-storage.git/blame - test/prune_backups_test.pm
fix #3199: by fixing usage of strftime
[pve-storage.git] / test / prune_backups_test.pm
CommitLineData
8f26b391
FE
1package PVE::Storage::TestPruneBackups;
2
3use strict;
4use warnings;
5
6use lib qw(..);
7
8use PVE::Storage;
9use Test::More;
10use Test::MockModule;
11
12my $storeid = 'BackTest123';
13my @vmids = (1234, 9001);
14
15# only includes the information needed for prune_backups
16my $mocked_backups_lists = {};
17
18my $basetime = 1577881101; # 2020_01_01-12_18_21 UTC
19
20foreach my $vmid (@vmids) {
21 push @{$mocked_backups_lists->{default}}, (
22 {
23 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2018_05_26-11_18_21.tar.zst",
24 'ctime' => $basetime - 585*24*60*60 - 60*60,
25 'vmid' => $vmid,
26 },
27 {
28 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_21.tar.zst",
29 'ctime' => $basetime - 24*60*60 - 60*60,
30 'vmid' => $vmid,
31 },
32 {
33 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_19_21.tar.zst",
34 'ctime' => $basetime - 24*60*60 - 60*60 + 60,
35 'vmid' => $vmid,
36 },
37 {
38 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-11_18_21.tar.zst",
39 'ctime' => $basetime - 60*60,
40 'vmid' => $vmid,
41 },
42 {
43 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-12_18_21.tar.zst",
44 'ctime' => $basetime,
45 'vmid' => $vmid,
46 },
47 {
48 'volid' => "$storeid:backup/vzdump-lxc-$vmid-2020_01_01-12_18_21.tar.zst",
49 'ctime' => $basetime,
50 'vmid' => $vmid,
51 },
52 {
53 'volid' => "$storeid:backup/vzdump-$vmid-renamed.tar.zst",
54 'ctime' => 1234,
55 'vmid' => $vmid,
56 },
57 );
58}
59push @{$mocked_backups_lists->{year1970}}, (
60 {
61 'volid' => "$storeid:backup/vzdump-lxc-321-1970_01_01-00_01_23.tar.zst",
62 'ctime' => 83,
63 'vmid' => 321,
64 },
65 {
66 'volid' => "$storeid:backup/vzdump-lxc-321-2070_01_01-00_01_00.tar.zst",
67 'ctime' => 60*60*24 * (365*100 + 25) + 60,
68 'vmid' => 321,
69 },
70);
71push @{$mocked_backups_lists->{novmid}}, (
72 {
73 'volid' => "$storeid:backup/vzdump-lxc-novmid.tar.gz",
74 'ctime' => 1234,
75 },
76);
10dfeb9e
FE
77push @{$mocked_backups_lists->{threeway}}, (
78 {
79 'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_25-12_18_21.tar.zst",
80 'ctime' => $basetime - 7*24*60*60,
81 'vmid' => 7654,
82 },
83 {
84 'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_31-12_18_21.tar.zst",
85 'ctime' => $basetime - 24*60*60,
86 'vmid' => 7654,
87 },
88 {
89 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_01_01-12_18_21.tar.zst",
90 'ctime' => $basetime,
91 'vmid' => 7654,
92 },
93);
189e67ff
FE
94push @{$mocked_backups_lists->{weekboundary}}, (
95 {
96 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_03-12_18_21.tar.zst",
97 'ctime' => $basetime + (366-31+2)*24*60*60,
98 'vmid' => 7654,
99 },
100 {
101 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_04-12_18_21.tar.zst",
102 'ctime' => $basetime + (366-31+3)*24*60*60,
103 'vmid' => 7654,
104 },
105 {
106 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_07-12_18_21.tar.zst",
107 'ctime' => $basetime + (366-31+6)*24*60*60,
108 'vmid' => 7654,
109 },
110);
8f26b391
FE
111my $current_list;
112my $mock_plugin = Test::MockModule->new('PVE::Storage::Plugin');
113$mock_plugin->redefine(list_volumes => sub {
114 my ($class, $storeid, $scfg, $vmid, $content_types) = @_;
115
116 my $list = $mocked_backups_lists->{$current_list};
117
118 return $list if !defined($vmid);
119
120 return [ grep { $_->{vmid} eq $vmid } @{$list} ];
121});
122
123sub generate_expected {
124 my ($vmids, $type, $marks) = @_;
125
126 my @expected;
127 foreach my $vmid (@{$vmids}) {
128 push @expected, (
129 {
130 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2018_05_26-11_18_21.tar.zst",
131 'type' => 'qemu',
132 'ctime' => $basetime - 585*24*60*60 - 60*60,
133 'mark' => $marks->[0],
134 'vmid' => $vmid,
135 },
136 {
137 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_18_21.tar.zst",
138 'type' => 'qemu',
139 'ctime' => $basetime - 24*60*60 - 60*60,
140 'mark' => $marks->[1],
141 'vmid' => $vmid,
142 },
143 {
144 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2019_12_31-11_19_21.tar.zst",
145 'type' => 'qemu',
146 'ctime' => $basetime - 24*60*60 - 60*60 + 60,
147 'mark' => $marks->[2],
148 'vmid' => $vmid,
149 },
150 {
151 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-11_18_21.tar.zst",
152 'type' => 'qemu',
153 'ctime' => $basetime - 60*60,
154 'mark' => $marks->[3],
155 'vmid' => $vmid,
156 },
157 {
158 'volid' => "$storeid:backup/vzdump-qemu-$vmid-2020_01_01-12_18_21.tar.zst",
159 'type' => 'qemu',
160 'ctime' => $basetime,
161 'mark' => $marks->[4],
162 'vmid' => $vmid,
163 },
164 ) if !defined($type) || $type eq 'qemu';
165 push @expected, (
166 {
167 'volid' => "$storeid:backup/vzdump-lxc-$vmid-2020_01_01-12_18_21.tar.zst",
168 'type' => 'lxc',
169 'ctime' => $basetime,
170 'mark' => $marks->[5],
171 'vmid' => $vmid,
172 },
173 ) if !defined($type) || $type eq 'lxc';
174 push @expected, (
175 {
176 'volid' => "$storeid:backup/vzdump-$vmid-renamed.tar.zst",
177 'type' => 'unknown',
178 'ctime' => 1234,
179 'mark' => 'protected',
180 'vmid' => $vmid,
181 },
182 ) if !defined($type);
183 }
184 return [ sort { $a->{volid} cmp $b->{volid} } @expected ];
185}
186
187# an array of test cases, each test is comprised of the following keys:
188# description => to identify a single test
189# vmid => VMID or undef for all
190# type => 'qemu' or 'lxc' or undef for all
191# keep => options describing what to keep
192# list => backups list to use. defaults to 'default'
193# expected => what prune_backups should return
194#
195# most of them are created further below
196my $tests = [
197 {
198 description => 'last=3, multiple IDs',
199 keep => {
200 'keep-last' => 3,
201 },
202 expected => generate_expected(\@vmids, undef, ['remove', 'remove', 'keep', 'keep', 'keep', 'keep']),
203 },
204 {
205 description => 'weekly=2, one ID',
206 vmid => $vmids[0],
207 keep => {
208 'keep-weekly' => 2,
209 },
210 expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'remove', 'remove', 'keep', 'keep']),
211 },
212 {
213 description => 'daily=weekly=monthly=1, multiple IDs',
214 keep => {
215 'keep-hourly' => 0,
216 'keep-daily' => 1,
217 'keep-weekly' => 1,
218 'keep-monthly' => 1,
219 },
220 expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
221 },
222 {
223 description => 'hourly=4, one ID',
224 vmid => $vmids[0],
225 keep => {
226 'keep-hourly' => 4,
227 'keep-daily' => 0,
228 },
229 expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'keep', 'keep', 'keep', 'keep']),
230 },
231 {
232 description => 'yearly=2, multiple IDs',
233 keep => {
234 'keep-hourly' => 0,
235 'keep-daily' => 0,
236 'keep-weekly' => 0,
237 'keep-monthly' => 0,
238 'keep-yearly' => 2,
239 },
240 expected => generate_expected(\@vmids, undef, ['remove', 'remove', 'keep', 'remove', 'keep', 'keep']),
241 },
242 {
243 description => 'last=2,hourly=2 one ID',
244 vmid => $vmids[0],
245 keep => {
246 'keep-last' => 2,
247 'keep-hourly' => 2,
248 },
249 expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'keep', 'keep', 'keep', 'keep']),
250 },
251 {
252 description => 'last=1,monthly=2, multiple IDs',
253 keep => {
254 'keep-last' => 1,
255 'keep-monthly' => 2,
256 },
257 expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
258 },
259 {
260 description => 'monthly=3, one ID',
261 vmid => $vmids[0],
262 keep => {
263 'keep-monthly' => 3,
264 },
265 expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
266 },
267 {
268 description => 'last=daily=weekly=1, multiple IDs',
269 keep => {
270 'keep-last' => 1,
271 'keep-daily' => 1,
272 'keep-weekly' => 1,
273 },
274 expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
275 },
f514181d
FE
276 {
277 description => 'last=daily=weekly=1, others zero, multiple IDs',
278 keep => {
279 'keep-hourly' => 0,
280 'keep-last' => 1,
281 'keep-daily' => 1,
282 'keep-weekly' => 1,
283 'keep-monthly' => 0,
284 'keep-yearly' => 0,
285 },
286 expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'keep', 'remove', 'keep', 'keep']),
287 },
8f26b391
FE
288 {
289 description => 'daily=2, one ID',
290 vmid => $vmids[0],
291 keep => {
292 'keep-daily' => 2,
293 },
294 expected => generate_expected([$vmids[0]], undef, ['remove', 'remove', 'keep', 'remove', 'keep', 'keep']),
295 },
296 {
297 description => 'weekly=monthly=1, multiple IDs',
298 keep => {
299 'keep-weekly' => 1,
300 'keep-monthly' => 1,
301 },
302 expected => generate_expected(\@vmids, undef, ['keep', 'remove', 'remove', 'remove', 'keep', 'keep']),
303 },
304 {
305 description => 'weekly=yearly=1, one ID',
306 vmid => $vmids[0],
307 keep => {
308 'keep-weekly' => 1,
309 'keep-yearly' => 1,
310 },
311 expected => generate_expected([$vmids[0]], undef, ['keep', 'remove', 'remove', 'remove', 'keep', 'keep']),
312 },
313 {
314 description => 'weekly=yearly=1, one ID, type qemu',
315 vmid => $vmids[0],
316 type => 'qemu',
317 keep => {
318 'keep-weekly' => 1,
319 'keep-yearly' => 1,
320 },
321 expected => generate_expected([$vmids[0]], 'qemu', ['keep', 'remove', 'remove', 'remove', 'keep', '']),
322 },
323 {
324 description => 'week=yearly=1, one ID, type lxc',
325 vmid => $vmids[0],
326 type => 'lxc',
327 keep => {
328 'keep-last' => 1,
329 },
330 expected => generate_expected([$vmids[0]], 'lxc', ['', '', '', '', '', 'keep']),
331 },
332 {
333 description => 'yearly=1, year before 2000',
334 keep => {
335 'keep-yearly' => 1,
336 },
337 list => 'year1970',
338 expected => [
339 {
340 'volid' => "$storeid:backup/vzdump-lxc-321-1970_01_01-00_01_23.tar.zst",
341 'ctime' => 83,
342 'mark' => 'remove',
343 'type' => 'lxc',
344 'vmid' => 321,
345 },
346 {
347 'volid' => "$storeid:backup/vzdump-lxc-321-2070_01_01-00_01_00.tar.zst",
348 'ctime' => 60*60*24 * (365*100 + 25) + 60,
349 'mark' => 'keep',
350 'type' => 'lxc',
351 'vmid' => 321,
352 },
353 ],
354 },
355 {
356 description => 'last=1, ne ID, year before 2000',
357 keep => {
358 'keep-last' => 1,
359 },
360 list => 'novmid',
361 expected => [
362 {
363 'volid' => "$storeid:backup/vzdump-lxc-novmid.tar.gz",
364 'ctime' => 1234,
365 'mark' => 'protected',
366 'type' => 'lxc',
367 },
368 ],
369 },
f514181d
FE
370 {
371 description => 'all missing, multiple IDs',
372 keep => {},
373 expected => generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
374 },
375 {
376 description => 'all zero, multiple IDs',
377 keep => {
378 'keep-last' => 0,
379 'keep-hourly' => 0,
380 'keep-daily' => 0,
381 'keep-weekly' => 0,
382 'keep-monthyl' => 0,
383 'keep-yearly' => 0,
384 },
385 expected => generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
386 },
387 {
388 description => 'some zero, some missing, multiple IDs',
389 keep => {
390 'keep-last' => 0,
391 'keep-hourly' => 0,
392 'keep-daily' => 0,
393 'keep-monthyl' => 0,
394 'keep-yearly' => 0,
395 },
396 expected => generate_expected(\@vmids, undef, ['keep', 'keep', 'keep', 'keep', 'keep', 'keep']),
397 },
10dfeb9e
FE
398 {
399 description => 'daily=weekly=monthly=1',
400 keep => {
401 'keep-daily' => 1,
402 'keep-weekly' => 1,
403 'keep-monthly' => 1,
404 },
405 list => 'threeway',
406 expected => [
407 {
408 'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_25-12_18_21.tar.zst",
409 'ctime' => $basetime - 7*24*60*60,
410 'type' => 'qemu',
411 'vmid' => 7654,
412 'mark' => 'keep',
413 },
414 {
415 'volid' => "$storeid:backup/vzdump-qemu-7654-2019_12_31-12_18_21.tar.zst",
416 'ctime' => $basetime - 24*60*60,
417 'type' => 'qemu',
418 'vmid' => 7654,
419 'mark' => 'remove', # month is already covered by the backup kept by keep-weekly!
420 },
421 {
422 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_01_01-12_18_21.tar.zst",
423 'ctime' => $basetime,
424 'type' => 'qemu',
425 'vmid' => 7654,
426 'mark' => 'keep',
427 },
428 ],
429 },
189e67ff
FE
430 {
431 description => 'daily=weekly=1,weekboundary',
432 keep => {
433 'keep-daily' => 1,
434 'keep-weekly' => 1,
435 },
436 list => 'weekboundary',
437 expected => [
438 {
439 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_03-12_18_21.tar.zst",
440 'ctime' => $basetime + (366-31+2)*24*60*60,
441 'type' => 'qemu',
442 'vmid' => 7654,
443 'mark' => 'remove',
444 },
445 {
446 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_04-12_18_21.tar.zst",
447 'ctime' => $basetime + (366-31+3)*24*60*60,
448 'type' => 'qemu',
449 'vmid' => 7654,
450 'mark' => 'keep',
451 },
452 {
453 'volid' => "$storeid:backup/vzdump-qemu-7654-2020_12_07-12_18_21.tar.zst",
454 'ctime' => $basetime + (366-31+6)*24*60*60,
455 'type' => 'qemu',
456 'vmid' => 7654,
457 'mark' => 'keep',
458 },
459 ],
460 },
8f26b391
FE
461];
462
463plan tests => scalar @$tests;
464
465for my $tt (@$tests) {
466
467 my $got = eval {
468 $current_list = $tt->{list} // 'default';
469 my $res = PVE::Storage::Plugin->prune_backups($tt->{scfg}, $storeid, $tt->{keep}, $tt->{vmid}, $tt->{type}, 1);
470 return [ sort { $a->{volid} cmp $b->{volid} } @{$res} ];
471 };
472 $got = $@ if $@;
473
474 is_deeply($got, $tt->{expected}, $tt->{description}) || diag(explain($got));
475}
476
477done_testing();
478
4791;