package PVE::Storage::TestParseVolname; use strict; use warnings; use lib qw(..); use PVE::Storage; use Test::More; my $vmid = 1234; # an array of test cases, each test is comprised of the following keys: # description => to identify a single test # volname => the input for parse_volname # expected => the array that parse_volname returns my $tests = [ # # VM images # { description => 'VM disk image, linked, qcow2, vm- as base-', volname => "$vmid/vm-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2", expected => [ 'images', "vm-$vmid-disk-0.qcow2", "$vmid", "vm-$vmid-disk-0.qcow2", "$vmid", undef, 'qcow2', ], }, # # iso # { description => 'ISO image, iso', volname => 'iso/some-installation-disk.iso', expected => ['iso', 'some-installation-disk.iso'], }, { description => 'ISO image, img', volname => 'iso/some-other-installation-disk.img', expected => ['iso', 'some-other-installation-disk.img'], }, # # container templates # { description => 'Container template tar.gz', volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz', expected => ['vztmpl', 'debian-10.0-standard_10.0-1_amd64.tar.gz'], }, { description => 'Container template tar.xz', volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.xz', expected => ['vztmpl', 'debian-10.0-standard_10.0-1_amd64.tar.xz'], }, # # container rootdir # { description => 'Container rootdir, sub directory', volname => "rootdir/$vmid", expected => ['rootdir', "$vmid", "$vmid"], }, { description => 'Container rootdir, subvol', volname => "$vmid/subvol-$vmid-disk-0.subvol", expected => [ 'images', "subvol-$vmid-disk-0.subvol", "$vmid", undef, undef, undef, 'subvol' ], }, { description => 'Backup archive, no virtualization type', volname => "backup/vzdump-none-$vmid-2020_03_30-21_39_30.tar", expected => ['backup', "vzdump-none-$vmid-2020_03_30-21_39_30.tar"], }, # # Snippets # { description => 'Snippets, yaml', volname => 'snippets/userconfig.yaml', expected => ['snippets', 'userconfig.yaml'], }, { description => 'Snippets, perl', volname => 'snippets/hookscript.pl', expected => ['snippets', 'hookscript.pl'], }, # # failed matches # { description => "Failed match: VM disk image, base, raw", volname => "ssss/base-$vmid-disk-0.raw", expected => "unable to parse directory volume name 'ssss/base-$vmid-disk-0.raw'\n", }, { description => 'Failed match: ISO image, dvd', volname => 'iso/yet-again-a-installation-disk.dvd', expected => "unable to parse directory volume name 'iso/yet-again-a-installation-disk.dvd'\n", }, { description => 'Failed match: Container template, zip.gz', volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.zip.gz', expected => "unable to parse directory volume name 'vztmpl/debian-10.0-standard_10.0-1_amd64.zip.gz'\n", }, { description => 'Failed match: Container template, tar.bz2', volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.bz2', expected => "unable to parse directory volume name 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.bz2'\n", }, { description => 'Failed match: Container rootdir, subvol', volname => "rootdir/subvol-$vmid-disk-0", expected => "unable to parse directory volume name 'rootdir/subvol-$vmid-disk-0'\n", }, { description => 'Failed match: VM disk image, linked, vhdx', volname => "$vmid/base-$vmid-disk-0.vhdx/$vmid/vm-$vmid-disk-0.vhdx", expected => "unable to parse volume filename 'base-$vmid-disk-0.vhdx'\n", }, { description => 'Failed match: VM disk image, linked, qcow2, first vmid', volname => "ssss/base-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2", expected => "unable to parse directory volume name 'ssss/base-$vmid-disk-0.qcow2/$vmid/vm-$vmid-disk-0.qcow2'\n", }, { description => 'Failed match: VM disk image, linked, qcow2, second vmid', volname => "$vmid/base-$vmid-disk-0.qcow2/ssss/vm-$vmid-disk-0.qcow2", expected => "unable to parse volume filename 'base-$vmid-disk-0.qcow2/ssss/vm-$vmid-disk-0.qcow2'\n", }, ]; # create more test cases for VM disk images matches my $disk_suffix = [ 'raw', 'qcow2', 'vmdk' ]; foreach my $s (@$disk_suffix) { my @arr = ( { description => "VM disk image, $s", volname => "$vmid/vm-$vmid-disk-1.$s", expected => [ 'images', "vm-$vmid-disk-1.$s", "$vmid", undef, undef, undef, "$s", ], }, { description => "VM disk image, linked, $s", volname => "$vmid/base-$vmid-disk-0.$s/$vmid/vm-$vmid-disk-0.$s", expected => [ 'images', "vm-$vmid-disk-0.$s", "$vmid", "base-$vmid-disk-0.$s", "$vmid", undef, "$s", ], }, { description => "VM disk image, base, $s", volname => "$vmid/base-$vmid-disk-0.$s", expected => [ 'images', "base-$vmid-disk-0.$s", "$vmid", undef, undef, 'base-', "$s" ], }, ); push @$tests, @arr; } # create more test cases for backup files matches my $bkp_suffix = { qemu => [ 'vma', 'vma.gz', 'vma.lzo', 'vma.zst' ], lxc => [ 'tar', 'tgz', 'tar.gz', 'tar.lzo', 'tar.zst' ], openvz => [ 'tar', 'tgz', 'tar.gz', 'tar.lzo', 'tar.zst' ], }; foreach my $virt (keys %$bkp_suffix) { my $suffix = $bkp_suffix->{$virt}; foreach my $s (@$suffix) { my @arr = ( { description => "Backup archive, $virt, $s", volname => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s", expected => [ 'backup', "vzdump-$virt-$vmid-2020_03_30-21_12_40.$s", "$vmid" ], }, ); push @$tests, @arr; } } # create more test cases for failed backup files matches my $non_bkp_suffix = { qemu => [ 'vms.gz', 'vma.xz' ], lxc => [ 'tar.bz2', 'zip.gz', 'tgz.lzo' ], }; 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", volname => "backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s", expected => "unable to parse directory volume name 'backup/vzdump-$virt-$vmid-2020_03_30-21_12_40.$s'\n", }, ); push @$tests, @arr; } } # # run through test case array # plan tests => scalar @$tests + 1; my $seen_vtype; my $vtype_subdirs = { map { $_ => 1 } keys %{ PVE::Storage::Plugin::get_vtype_subdirs() } }; foreach my $t (@$tests) { my $description = $t->{description}; my $volname = $t->{volname}; my $expected = $t->{expected}; my $got; eval { $got = [ PVE::Storage::Plugin->parse_volname($volname) ] }; $got = $@ if $@; is_deeply($got, $expected, $description); $seen_vtype->{@$expected[0]} = 1 if ref $expected eq 'ARRAY'; } # to check if all $vtype_subdirs are defined in path_to_volume_id # or have a test is_deeply($seen_vtype, $vtype_subdirs, "vtype_subdir check"); done_testing(); 1;