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