From: Alwin Antreich Date: Tue, 28 Apr 2020 13:58:13 +0000 (+0200) Subject: storage: test: split archive format/compressor X-Git-Url: https://git.proxmox.com/?p=pve-storage.git;a=commitdiff_plain;h=cd554b79d1f868dbe499c570dc352ee0b851b1eb storage: test: split archive format/compressor detection into separate functions so they are reusable and easier modifiable. This patch also adds the test for archive_info. Signed-off-by: Alwin Antreich --- diff --git a/PVE/Storage.pm b/PVE/Storage.pm index 0848176..bdd6ebc 100755 --- a/PVE/Storage.pm +++ b/PVE/Storage.pm @@ -1351,6 +1351,53 @@ sub foreach_volid { } } +sub decompressor_info { + my ($format, $comp) = @_; + + if ($format eq 'tgz' && !defined($comp)) { + ($format, $comp) = ('tar', 'gz'); + } + + my $decompressor = { + tar => { + gz => ['tar', '-z'], + lzo => ['tar', '--lzop'], + }, + vma => { + gz => ['zcat'], + lzo => ['lzop', '-d', '-c'], + }, + }; + + die "ERROR: archive format not defined\n" + if !defined($decompressor->{$format}); + + my $decomp = $decompressor->{$format}->{$comp} if $comp; + + my $info = { + format => $format, + compression => $comp, + decompressor => $decomp, + }; + + return $info; +} + +sub archive_info { + my ($archive) = shift; + my $info; + + my $volid = basename($archive); + if ($volid =~ /vzdump-(lxc|openvz|qemu)-\d+-(?:\d{4})_(?:\d{2})_(?:\d{2})-(?:\d{2})_(?:\d{2})_(?:\d{2})\.(tgz$|tar|vma)(?:\.(gz|lzo))?$/) { + $info = decompressor_info($2, $3); + $info->{type} = $1; + } else { + die "ERROR: couldn't determine format and compression type\n"; + } + + return $info; +} + sub extract_vzdump_config_tar { my ($archive, $conf_re) = @_; @@ -1396,16 +1443,12 @@ sub extract_vzdump_config_vma { }; + my $info = archive_info($archive); + $comp //= $info->{compression}; + my $decompressor = $info->{decompressor}; + if ($comp) { - my $uncomp; - if ($comp eq 'gz') { - $uncomp = ["zcat", $archive]; - } elsif ($comp eq 'lzo') { - $uncomp = ["lzop", "-d", "-c", $archive]; - } else { - die "unknown compression method '$comp'\n"; - } - $cmd = [$uncomp, ["vma", "config", "-"]]; + $cmd = [ [@$decompressor, $archive], ["vma", "config", "-"] ]; # in some cases, lzop/zcat exits with 1 when its stdout pipe is # closed early by vma, detect this and ignore the exit code later @@ -1455,20 +1498,14 @@ sub extract_vzdump_config { } my $archive = abs_filesystem_path($cfg, $volid); + my $info = archive_info($archive); + my $format = $info->{format}; + my $comp = $info->{compression}; + my $type = $info->{type}; - if ($volid =~ /vzdump-(lxc|openvz)-\d+-(\d{4})_(\d{2})_(\d{2})-(\d{2})_(\d{2})_(\d{2})\.(tgz|(tar(\.(gz|lzo))?))$/) { + if ($type eq 'lxc' || $type eq 'openvz') { return extract_vzdump_config_tar($archive, qr!^(\./etc/vzdump/(pct|vps)\.conf)$!); - } elsif ($volid =~ /vzdump-qemu-\d+-(\d{4})_(\d{2})_(\d{2})-(\d{2})_(\d{2})_(\d{2})\.(tgz|((tar|vma)(\.(gz|lzo))?))$/) { - my $format; - my $comp; - if ($7 eq 'tgz') { - $format = 'tar'; - $comp = 'gz'; - } else { - $format = $9; - $comp = $11 if defined($11); - } - + } elsif ($type eq 'qemu') { if ($format eq 'tar') { return extract_vzdump_config_tar($archive, qr!\(\./qemu-server\.conf\)!); } else { diff --git a/test/Makefile b/test/Makefile index 833a597..c54b10f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ all: test -test: test_zfspoolplugin test_disklist test_bwlimit +test: test_zfspoolplugin test_disklist test_bwlimit test_plugin test_zfspoolplugin: run_test_zfspoolplugin.pl ./run_test_zfspoolplugin.pl @@ -10,3 +10,6 @@ test_disklist: run_disk_tests.pl test_bwlimit: run_bwlimit_tests.pl ./run_bwlimit_tests.pl + +test_plugin: run_plugin_tests.pl + ./run_plugin_tests.pl diff --git a/test/archive_info_test.pm b/test/archive_info_test.pm new file mode 100644 index 0000000..c9bb1b7 --- /dev/null +++ b/test/archive_info_test.pm @@ -0,0 +1,125 @@ +package PVE::Storage::TestArchiveInfo; + +use strict; +use warnings; + +use lib qw(..); + +use PVE::Storage; +use Test::More; + +my $vmid = 16110; + +# an array of test cases, each test is comprised of the following keys: +# description => to identify a single test +# archive => the input filename for archive_info +# expected => the hash that archive_info returns +# +# most of them are created further below +my $tests = [ + # backup archives + { + description => 'Backup archive, lxc, tgz', + archive => "backup/vzdump-lxc-$vmid-2020_03_30-21_39_30.tgz", + expected => { + 'type' => 'lxc', + 'format' => 'tar', + 'decompressor' => ['tar', '-z'], + 'compression' => 'gz', + }, + }, + { + description => 'Backup archive, openvz, tgz', + archive => "backup/vzdump-openvz-$vmid-2020_03_30-21_39_30.tgz", + expected => { + 'type' => 'openvz', + 'format' => 'tar', + 'decompressor' => ['tar', '-z'], + 'compression' => 'gz', + }, + }, +]; + +# add new compression fromats to test +my $decompressor = { + tar => { + gz => ['tar', '-z'], + lzo => ['tar', '--lzop'], + }, + vma => { + gz => ['zcat'], + lzo => ['lzop', '-d', '-c'], + }, +}; + +my $bkp_suffix = { + qemu => [ 'vma', $decompressor->{vma}, ], + lxc => [ 'tar', $decompressor->{tar}, ], + openvz => [ 'tar', $decompressor->{tar}, ], +}; + +# create more test cases for backup files matches +foreach my $virt (keys %$bkp_suffix) { + my ($format, $decomp) = @{ $bkp_suffix->{$virt} }; + + foreach my $suffix (keys %$decomp) { + my @arr = ( + { + description => "Backup archive, $virt, $format.$suffix", + archive => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$format.$suffix", + expected => { + 'type' => "$virt", + 'format' => "$format", + 'decompressor' => $decomp->{$suffix}, + 'compression' => "$suffix", + }, + }, + ); + + push @$tests, @arr; + } +} + + +# add compression formats to test failed matches +my $non_bkp_suffix = { + 'openvz' => [ 'zip', 'tgz.lzo', 'tar.bz2', 'zip.gz', '', ], + 'lxc' => [ 'zip', 'tgz.lzo', 'tar.bz2', 'zip.gz', '', ], + 'qemu' => [ 'vma.xz', 'vms.gz', '', ], + 'none' => [ 'tar.gz', ], +}; + +# create tests for failed matches +foreach my $virt (keys %$non_bkp_suffix) { + my $suffix = $non_bkp_suffix->{$virt}; + foreach my $s (@$suffix) { + my @arr = ( + { + description => "Failed match: Backup archive, $virt, $s", + archive => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s", + expected => "ERROR: couldn't determine format and compression type\n", + }, + ); + + push @$tests, @arr; + } +} + + +plan tests => scalar @$tests; + +# run through tests array +foreach my $tt (@$tests) { + my $description = $tt->{description}; + my $archive = $tt->{archive}; + my $expected = $tt->{expected}; + my $got; + eval { $got = PVE::Storage::archive_info($archive) }; + $got = $@ if $@; + + is_deeply($got, $expected, $description) || diag(explain($got)); +} + +done_testing(); + +1; diff --git a/test/run_plugin_tests.pl b/test/run_plugin_tests.pl new file mode 100755 index 0000000..6568752 --- /dev/null +++ b/test/run_plugin_tests.pl @@ -0,0 +1,12 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use TAP::Harness; + +my $harness = TAP::Harness->new( { verbosity => -1 }); +my $res = $harness->runtests("archive_info_test.pm"); + +exit -1 if !$res || $res->{failed} || $res->{parse_errors}; +