diff --git a/test/Makefile b/test/Makefile index 44f3b0d7..5c4478ce 100644 --- a/test/Makefile +++ b/test/Makefile @@ -23,6 +23,7 @@ mail_test: vzdump_test: ./vzdump_guest_included_test.pl + ./vzdump_new_retention_test.pl .PHONY: install install: diff --git a/test/vzdump_new_retention_test.pl b/test/vzdump_new_retention_test.pl new file mode 100755 index 00000000..87faa899 --- /dev/null +++ b/test/vzdump_new_retention_test.pl @@ -0,0 +1,413 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use lib '..'; + +use Test::More; +use Test::MockModule; + +use PVE::VZDump; + +my $vzdump_config; +my $storage_config; + +sub prepare_storage_config { + my ($param) = @_; + + $storage_config = "dir: local\n"; + $storage_config .= "\tcontent backup\n"; + $storage_config .= "\tpath /var/lib/vz\n"; + + foreach my $key (keys %{$param}) { + my $value = $param->{$key}; + $storage_config .= "\t${key} ${value}\n"; + } +} + +sub prepare_vzdump_config { + my ($param) = @_; + + $vzdump_config = ""; + foreach my $key (keys %{$param}) { + my $value = $param->{$key}; + $vzdump_config .= "${key}: ${value}\n"; + } +} + +my $pve_vzdump_module = Test::MockModule->new('PVE::VZDump'); +$pve_vzdump_module->mock( + mkpath => sub { + return; + }, + check_bin => sub { + return; + }, +); + +my $pve_storage_module = Test::MockModule->new('PVE::Storage'); +$pve_storage_module->mock( + activate_storage => sub { + return; + }, +); + +my $pve_cluster_module = Test::MockModule->new('PVE::Cluster'); +$pve_cluster_module->mock( + get_config => sub { + my ($filename) = @_; + + die "unexpected filename '$filename'\n" if $filename ne 'storage.cfg'; + return $storage_config; + }, +); + +my $pve_tools_module = Test::MockModule->new('PVE::Tools'); +$pve_tools_module->mock( + file_get_contents => sub { + my ($filename) = @_; + + die "unexpected filename '$filename'\n" if $filename ne '/etc/vzdump.conf'; + return $vzdump_config; + }, +); + +my @tested_options = qw(prune-backups remove); + +# each test consists of the following: +# name - unique name for the test +# cli_param - CLI parameters to be passed to new(); vmid and storage are hardcoded +# storage_param - parameters for the mocked storage configuration +# vzdump_param - parameters for the mocked /etc/vzdump.conf +# expected - expected options +my @tests = ( + { + description => 'no params', + expected => { + 'prune-backups' => { + 'keep-last' => 1, + }, + remove => 1, + }, + }, + # TODO make parse error critical? + { + description => 'maxfiles vzdump 1', + vzdump_param => { + maxfiles => 0, + }, + expected => { + 'prune-backups' => { + 'keep-last' => 1, + }, + remove => 1, + }, + }, + { + description => 'maxfiles vzdump 2', + vzdump_param => { + maxfiles => 7, + }, + expected => { + 'prune-backups' => { + 'keep-last' => 7, + }, + remove => 1, + }, + }, + { + description => 'maxfiles storage 1', + storage_param => { + maxfiles => 0, + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'maxfiles storage 2', + storage_param => { + maxfiles => 7, + }, + expected => { + 'prune-backups' => { + 'keep-last' => 7, + }, + remove => 1, + }, + }, + { + description => 'maxfiles CLI 1', + cli_param => { + maxfiles => 0, + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'maxfiles CLI 2', + cli_param => { + maxfiles => 7, + }, + expected => { + 'prune-backups' => { + 'keep-last' => 7, + }, + remove => 1, + }, + }, + { + description => 'prune-backups storage 1', + storage_param => { + 'prune-backups' => 'keep-last=1,keep-hourly=2,keep-daily=3,' . + 'keep-weekly=4,keep-monthly=5,keep-yearly=6', + }, + expected => { + 'prune-backups' => { + 'keep-last' => 1, + 'keep-hourly' => 2, + 'keep-daily' => 3, + 'keep-weekly' => 4, + 'keep-monthly' => 5, + 'keep-yearly' => 6, + }, + remove => 1, + }, + }, + { + description => 'prune-backups storage 2', + storage_param => { + 'prune-backups' => 'keep-last=0,keep-hourly=0,keep-daily=0,' . + 'keep-weekly=0,keep-monthly=0,keep-yearly=0', + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'prune-backups storage 3', + storage_param => { + 'prune-backups' => 'keep-hourly=0,keep-monthly=0,keep-yearly=0', + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'both storage 1', + storage_param => { + 'prune-backups' => 'keep-hourly=1,keep-monthly=2,keep-yearly=3', + maxfiles => 0, + }, + expected => { + 'prune-backups' => { + 'keep-hourly' => 1, + 'keep-monthly' => 2, + 'keep-yearly' => 3, + }, + remove => 1, + }, + }, + { + description => 'prune-backups CLI 1', + cli_param => { + 'prune-backups' => 'keep-last=1,keep-hourly=2,keep-daily=3,' . + 'keep-weekly=4,keep-monthly=5,keep-yearly=6', + }, + expected => { + 'prune-backups' => { + 'keep-last' => 1, + 'keep-hourly' => 2, + 'keep-daily' => 3, + 'keep-weekly' => 4, + 'keep-monthly' => 5, + 'keep-yearly' => 6, + }, + remove => 1, + }, + }, + { + description => 'prune-backups CLI 2', + cli_param => { + 'prune-backups' => 'keep-last=0,keep-hourly=0,keep-daily=0,' . + 'keep-weekly=0,keep-monthly=0,keep-yearly=0', + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'prune-backups CLI 3', + cli_param => { + 'prune-backups' => 'foo=bar', + }, + expected => "format error\n" . + "foo: property is not defined in schema and the schema does not allow additional properties\n", + }, + { + description => 'both CLI 1', + cli_param => { + 'prune-backups' => 'keep-hourly=1,keep-monthly=2,keep-yearly=3', + maxfiles => 4, + }, + expected => "400 Parameter verification failed.\n" . + "prune-backups: option conflicts with option 'maxfiles'\n", + }, + { + description => 'mixed 1', + vzdump_param => { + maxfiles => 7, + }, + storage_param => { + 'prune-backups' => 'keep-hourly=24', + }, + expected => { + 'prune-backups' => { + 'keep-hourly' => 24, + }, + remove => 1, + }, + }, + # TODO make parse error critical? + { + description => 'mixed 2', + vzdump_param => { + maxfiles => 7, + }, + storage_param => { + 'prune-backups' => 'keephourly=24', + }, + expected => { + 'prune-backups' => { + 'keep-last' => 7, + }, + remove => 1, + }, + }, + { + description => 'mixed 3', + vzdump_param => { + maxfiles => 7, + }, + cli_param => { + 'prune-backups' => 'keep-all=1', + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'mixed 4', + vzdump_param => { + maxfiles => 7, + }, + storage_param => { + 'prune-backups' => 'keep-all=0,keep-last=10', + }, + cli_param => { + 'prune-backups' => 'keep-all=1', + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'mixed 5', + vzdump_param => { + maxfiles => 7, + }, + storage_param => { + 'prune-backups' => 'keep-all=0,keep-last=10', + }, + expected => { + 'prune-backups' => { + 'keep-last' => 10, + }, + remove => 1, + }, + }, + { + description => 'mixed 6', + storage_param => { + 'prune-backups' => 'keep-last=10', + }, + cli_param => { + 'prune-backups' => 'keep-all=1', + }, + expected => { + 'prune-backups' => { + 'keep-all' => 1, + }, + remove => 0, + }, + }, + { + description => 'mixed 7', + storage_param => { + 'prune-backups' => 'keep-all=1', + }, + cli_param => { + 'prune-backups' => 'keep-last=10', + }, + expected => { + 'prune-backups' => { + 'keep-last' => 10, + }, + remove => 1, + }, + }, +); + +plan tests => scalar @tests; + +foreach my $test (@tests) { + prepare_storage_config($test->{storage_param}); + prepare_vzdump_config($test->{vzdump_param}); + + $test->{cli_param}->{vmid} = 100; + $test->{cli_param}->{storage} = 'local'; + + my $got = eval { + PVE::VZDump::verify_vzdump_parameters($test->{cli_param}, 1); + + my $vzdump = PVE::VZDump->new('fake cmdline', $test->{cli_param}, undef); + + my $opts = $vzdump->{opts} or die "did not get options\n"; + die "maxfiles is defined" if defined($opts->{maxfiles}); + + my $res = {}; + foreach my $opt (@tested_options) { + next if !defined($opts->{$opt}); + $res->{$opt} = $opts->{$opt}; + } + return $res; + }; + $got = $@ if $@; + + is_deeply($got, $test->{expected}, $test->{description}) || diag(explain($got)); +} + +done_testing();