From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 0B8F660E0D for ; Tue, 1 Dec 2020 09:24:59 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D6349E47D for ; Tue, 1 Dec 2020 09:24:28 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id A77D9E408 for ; Tue, 1 Dec 2020 09:24:26 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 74C96441FA for ; Tue, 1 Dec 2020 09:24:26 +0100 (CET) From: Fabian Ebner To: pve-devel@lists.proxmox.com Date: Tue, 1 Dec 2020 09:24:18 +0100 Message-Id: <20201201082421.4646-1-f.ebner@proxmox.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.009 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager 1/4] test: add tests for retention parameters for vzdump's new() X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Dec 2020 08:24:59 -0000 To get a more complete picture, instead of mocking storage_config, PVE::Cluster's get_config is mocked. This ensures that the prune-backups validation and the maxfiles conversion are also called. Signed-off-by: Fabian Ebner --- test/Makefile | 1 + test/vzdump_new_retention_test.pl | 413 ++++++++++++++++++++++++++++++ 2 files changed, 414 insertions(+) create mode 100755 test/vzdump_new_retention_test.pl 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(); -- 2.20.1