[pve-devel] [PATCH storage 1/4] base plugin: Increase test coverage

Alwin Antreich a.antreich at proxmox.com
Thu Apr 9 09:37:37 CEST 2020


On Thu, Apr 02, 2020 at 01:34:11PM +0200, Dominic Jäger wrote:
> Signed-off-by: Dominic Jäger <d.jaeger at proxmox.com>
> ---
> This did not exist separately in RFC
> 
>  test/Makefile            |   5 +-
>  test/run_plugin_tests.pl | 184 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 188 insertions(+), 1 deletion(-)
>  create mode 100755 test/run_plugin_tests.pl
> 
> 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/run_plugin_tests.pl b/test/run_plugin_tests.pl
> new file mode 100755
> index 0000000..cd93430
> --- /dev/null
> +++ b/test/run_plugin_tests.pl
> @@ -0,0 +1,184 @@
> +#!/usr/bin/perl
> +use strict;
> +use warnings;
> +
> +use lib ('.', '..');
> +use Test::More tests => 32;
> +use Test::MockModule qw(new);
> +use File::Temp qw(tempdir);
> +use File::Path qw(make_path);
> +use Data::Dumper qw(Dumper);
> +use Storable qw(dclone);
> +use PVE::Storage;
> +
> +my $plugin = 'PVE::Storage::Plugin';
> +my $basename = 'test';
> +
> +my $iso_type = 'iso';
> +my $iso_suffix = '.iso';
> +my $iso_notdir = "$basename$iso_suffix";
> +my $iso_volname = "$iso_type/$iso_notdir";
> +
> +my $vztmpl_type = 'vztmpl';
> +my $vztmpl_suffix = '.tar.gz';
> +my $vztmpl_notdir = "$basename$vztmpl_suffix";
> +my $vztmpl_volname = "$vztmpl_type/$vztmpl_notdir";
> +
> +my $iso_with_dots = "$iso_type/../$iso_notdir";
> +my $vztmpl_with_dots = "$vztmpl_type/../$vztmpl_notdir";
> +
> +my $image_type = 'images';
> +my $vmid = '100';
> +my $image_basename = 'vm-100-disk-0';
> +my $raw_image_format = 'raw'; # Tests for parse_volname don't need the dot
> +my $raw_image_notdir = "$image_basename.$raw_image_format";
> +my $raw_image_volname = "$vmid/$raw_image_notdir";
> +my $qcow_image_format = 'qcow2';
> +my $qcow_image_notdir = "$image_basename.$qcow_image_format";
> +my $qcow_image_volname = "$vmid/$qcow_image_notdir";
> +my $vmdk_image_format = 'vmdk';
> +my $vmdk_image_notdir = "$image_basename.$vmdk_image_format";
> +my $vmdk_image_volname = "$vmid/$vmdk_image_notdir";
> +
> +my $type_index = 0;
> +my $notdir_index = 1;
> +my $format_index = 6;
> +
> +is (($plugin->parse_volname($iso_volname))[$type_index],
> +    $iso_type, 'parse_volname: type for iso');
> +is (($plugin->parse_volname($iso_volname))[$notdir_index],
> +    $iso_notdir, 'parse_volname: notdir for iso');
> +
> +is (($plugin->parse_volname($vztmpl_volname))[$type_index],
> +    $vztmpl_type, 'parse_volname: type for vztmpl');
> +is (($plugin->parse_volname($vztmpl_volname))[$notdir_index],
> +    $vztmpl_notdir, 'parse_volname: notdir for vztmpl');
> +
> +is (($plugin->parse_volname($raw_image_volname))[$type_index],
> +    $image_type, 'parse_volname: type for raw image');
> +is (($plugin->parse_volname($raw_image_volname))[$notdir_index],
> +    $raw_image_notdir, 'parse_volname: notdir for raw image');
> +is (($plugin->parse_volname($raw_image_volname))[$format_index],
> +    $raw_image_format, 'parse_volname: format for raw image');
> +
> +is (($plugin->parse_volname($qcow_image_volname))[$type_index],
> +    $image_type, 'parse_volname: type for qcow image');
> +is (($plugin->parse_volname($qcow_image_volname))[$notdir_index],
> +    $qcow_image_notdir, 'parse_volname: notdir for qcow image');
> +is (($plugin->parse_volname($qcow_image_volname))[$format_index],
> +    $qcow_image_format, 'parse_volname: format for qcow image');
> +
> +is (($plugin->parse_volname($vmdk_image_volname))[$type_index],
> +    $image_type, 'parse_volname: type for vmdk image');
> +is (($plugin->parse_volname($vmdk_image_volname))[$notdir_index],
> +    $vmdk_image_notdir, 'parse_volname: notdir for vmdk image');
> +is (($plugin->parse_volname($vmdk_image_volname))[$format_index],
> +    $vmdk_image_format, 'parse_volname: format for vmdk image');
> +
> +
> +my $scfg_with_path = { path => '/some/path' };
> +is ($plugin->get_subdir($scfg_with_path, 'iso'),
> +    "$scfg_with_path->{path}/template/iso", 'get_subdir for iso' );
> +is ($plugin->get_subdir($scfg_with_path, 'vztmpl'),
> +    "$scfg_with_path->{path}/template/cache", 'get_subdir for vztmpl');
> +is ($plugin->get_subdir($scfg_with_path, 'backup'),
> +    "$scfg_with_path->{path}/dump", 'get_subdir for backup');
> +is ($plugin->get_subdir($scfg_with_path, 'images'),
> +    "$scfg_with_path->{path}/images", 'get_subdir for images');
> +is ($plugin->get_subdir($scfg_with_path, 'rootdir'),
> +    "$scfg_with_path->{path}/private", 'get_subdir for rootdir');
> +
> +is ($plugin->filesystem_path($scfg_with_path, $iso_volname),
> +    "$scfg_with_path->{path}/template/$iso_volname",
> +    'filesystem_path for iso');
> +is ($plugin->filesystem_path($scfg_with_path, $vztmpl_volname),
> +    "$scfg_with_path->{path}/template/cache/$vztmpl_notdir",
> +    'filesystem_path for vztmpl');
> +is ($plugin->filesystem_path($scfg_with_path, $raw_image_volname),
> +    "$scfg_with_path->{path}/images/$raw_image_volname",
> +    'filesystem_path for raw images');
> +is ($plugin->filesystem_path($scfg_with_path, $qcow_image_volname),
> +    "$scfg_with_path->{path}/images/$qcow_image_volname",
> +    'filesystem_path for qcow image');
> +is ($plugin->filesystem_path($scfg_with_path, $vmdk_image_volname),
> +    "$scfg_with_path->{path}/images/$vmdk_image_volname",
> +    'filesystem_path for vmdk image');
> +
> +
> +# $expected_volnames may be unsorted
> +sub test_list_volumes {
> +    my ($scfg, $required_type, $expected_volnames, $param) = @_;
> +    my $storage_id = 'sid';
> +    my $volumes_ref = $plugin->list_volumes($storage_id, $scfg, undef,
> +	$required_type, $param);
> +    my $get_volname = sub { my $i = $_->{volid}; $i =~ s/$storage_id://g; $i };
> +    my @received = map ($get_volname->(), @$volumes_ref);
> +    my @x = sort @received;
> +    my @y = sort(@$expected_volnames);
> +    ok (@x ~~ @y, "list_volumes with required type [@$required_type]")
> +    || diag ("Expected\n", Dumper (@y), "but received\n", Dumper(@x));
> +}
> +
> +sub add_test_files {
> +    my ($paths) = @_;
> +    foreach my $path (@$paths) {
> +#	note "Adding test files to path $path";
> +	make_path($path) || BAIL_OUT "Could not create directory $path!";
> +	IO::File->new("$path/$iso_notdir", 'w');
> +	IO::File->new("$path/$iso_notdir", 'w');
> +	IO::File->new("$path/$raw_image_notdir", 'w');
> +	IO::File->new("$path/$qcow_image_notdir", 'w');
> +	IO::File->new("$path/$vmdk_image_notdir", 'w');
> +	IO::File->new("$path/$vztmpl_notdir", 'w');
> +	IO::File->new("$path/garbage", 'w');
> +    }
> +}
> +
> +my $storage_dir_no_rec = File::Temp->newdir();
> +my $paths = [
> +    "$storage_dir_no_rec/template/cache",
> +    "$storage_dir_no_rec/template/iso",
> +    "$storage_dir_no_rec/images/$vmid"
> +];
> +add_test_files($paths);
> +
> +note 'Tests without recursion';
> +# note "Temp dir is:\n", `tree $storage_dir_no_rec`;
> +my $scfg_no_rec = { path => $storage_dir_no_rec };
> +test_list_volumes($scfg_no_rec, [$iso_type], [$iso_volname]);
> +test_list_volumes($scfg_no_rec, [$vztmpl_type], [$vztmpl_volname]);
> +
> +my $scfg_with_type = { path => $storage_dir_no_rec, type => 'dir' };
> +my $plugin_mock = Test::MockModule->new('PVE::Cluster');
> +$plugin_mock->redefine('get_vmlist' => sub { return undef });
> +my $expected_volnames_guests = [$qcow_image_volname, $raw_image_volname,
> +   $vmdk_image_volname];
> +note 'Tests for undefined VM type => KVM/Qemu';
> +test_list_volumes($scfg_with_type, ['images'], $expected_volnames_guests);
> +test_list_volumes($scfg_with_type, ['rootdir'], []);
> +test_list_volumes($scfg_with_type, ['images', 'rootdir'],
> +    $expected_volnames_guests);
> +
> +note 'Tests for VM type lxc';
> +$plugin_mock->redefine('get_vmlist' => sub
> +    { return { ids => { $vmid => { type => 'lxc' }}}});
> +test_list_volumes($scfg_with_type, ['images'], []);
> +test_list_volumes($scfg_with_type, ['rootdir'], $expected_volnames_guests);
> +test_list_volumes($scfg_with_type, ['images', 'rootdir'],
> +    $expected_volnames_guests);
> +
> +
> +# see bug report
> +# https://pve.proxmox.com/pipermail/pve-devel/2020-January/041096.html
> +sub test_unmodified_cluster_vmlist {
> +    my ($scfg, $original_vmlist) = @_;
> +    my $tested_vmlist = dclone($original_vmlist);
> +    my $plugin_mock = Test::MockModule->new('PVE::Cluster');
> +    $plugin_mock->redefine('get_vmlist' => sub { return $tested_vmlist });
> +    $plugin->list_volumes('sid', $scfg, undef, ['images']);
> +    is_deeply ($tested_vmlist, $original_vmlist,
> +	'PVE::Cluster::vmlist remains unmodified')
> +    || diag ("Expected vmlist to remain\n", Dumper($original_vmlist),
> +	"but it turned to\n", Dumper($tested_vmlist));
> +}
> +test_unmodified_cluster_vmlist($scfg_with_type, { ids => {} });
> -- 
> 2.20.1
It seems to me, that we both wrote a test for list_volumes. :)

https://pve.proxmox.com/pipermail/pve-devel/2020-April/042888.html





More information about the pve-devel mailing list