5
0
mirror of git://git.proxmox.com/git/pve-storage.git synced 2025-01-11 05:18:01 +03:00
pve-storage/test/disklist_test.pm
Dominik Csapak 8cd6d7e8e3 Diskmanage: change parttype uuid detection
previously ceph included a udev rule to populate
/dev/disk/by-parttypeuuid/

but not anymore, so we now use 'lsblk --json -o path,parttype' to
get a mapping between parttype uuid and partition

fix the test by simulating empty lsblk output

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2019-07-12 15:37:57 +02:00

252 lines
6.2 KiB
Perl

package PVE::Diskmanage::Test;
use strict;
use warnings;
use lib qw(..);
use PVE::Diskmanage;
use PVE::Tools;
use Test::MockModule;
use Test::More;
use JSON;
use Data::Dumper;
my $testcasedir; # current case directory
my $testcount = 0; # testcount for TAP::Harness
my $diskmanage_module; # mockmodule for PVE::Diskmanage
my $print = 0;
sub mocked_run_command {
my ($cmd, %param) = @_;
my $outputlines = [];
if (my $ref = ref($cmd)) {
if ($cmd->[0] =~ m/udevadm/i) {
# simulate udevadm output
my $dev = $cmd->[3];
$dev =~ s|/sys/block/||;
@$outputlines = split(/\n/, read_test_file("${dev}_udevadm"));
} elsif ($cmd->[0] =~ m/smartctl/i) {
# simulate smartctl output
my $dev;
my $type;
if (@$cmd > 3) {
$dev = $cmd->[5];
$type = 'smart';
} else {
$dev = $cmd->[2];
$type = 'health';
}
$dev =~ s|/dev/||;
@$outputlines = split(/\n/, read_test_file("${dev}_${type}"));
} elsif ($cmd->[0] =~ m/sgdisk/i) {
# simulate sgdisk
die "implement me: @$cmd\n";
} elsif ($cmd->[0] =~ m/zpool/i) {
# simulate zpool output
@$outputlines = split(/\n/, read_test_file('zpool'));
} elsif ($cmd->[0] =~ m/pvs/i) {
# simulate lvs output
@$outputlines = split(/\n/, read_test_file('pvs'));
} elsif ($cmd->[0] =~ m/lvs/i) {
@$outputlines = split(/\n/, read_test_file('lvs'));
} elsif ($cmd->[0] =~ m/lsblk/i) {
my $content = read_test_file('lsblk');
if ($content eq '') {
$content = '{}';
}
@$outputlines = split(/\n/, $content);
} else {
die "unexpected run_command call: '@$cmd', aborting\n";
}
} else {
print "unexpected run_command call: '@$cmd', aborting\n";
die;
}
my $outfunc;
if ($param{outfunc}) {
$outfunc = $param{outfunc};
map { &$outfunc(($_)) } @$outputlines;
return 0;
}
}
sub mocked_get_sysdir_info {
my ($param) = @_;
my $originalsub = $diskmanage_module->original('get_sysdir_info');
$param =~ s|/sys/block|disk_tests/$testcasedir|;
return &$originalsub($param);
}
sub mocked_is_iscsi {
return 0;
}
sub mocked_dir_glob_foreach {
my ($dir, $regex, $sub) = @_;
my $lines = [];
# read lines in from file
if ($dir =~ m{^/sys/block$} ) {
@$lines = split(/\n/, read_test_file('disklist'));
} elsif ($dir =~ m{^/sys/block/([^/]+)}) {
@$lines = split(/\n/, read_test_file('partlist'));
}
foreach my $line (@$lines) {
if ($line =~ m/$regex/) {
&$sub($line);
}
}
}
sub mocked_parse_proc_mounts {
my $text = read_test_file('mounts');
my $mounts = [];
foreach my $line(split(/\n/, $text)) {
push @$mounts, [split(/\s+/, $line)];
}
return $mounts;
}
sub read_test_file {
my ($filename) = @_;
if (!-f "disk_tests/$testcasedir/$filename") {
print "file '$testcasedir/$filename' not found\n";
return '';
}
open (my $fh, '<', "disk_tests/$testcasedir/$filename")
or die "Cannot open disk_tests/$testcasedir/$filename: $!";
my $output = <$fh> // '';
chomp $output if $output;
while (my $line = <$fh>) {
chomp $line;
$output .= "\n$line";
}
return $output;
}
sub test_disk_list {
my ($testdir) = @_;
subtest "Test '$testdir'" => sub {
my $testcount = 0;
$testcasedir = $testdir;
my $disks;
my $expected_disk_list;
eval {
$disks = PVE::Diskmanage::get_disks();
};
warn $@ if $@;
$expected_disk_list = decode_json(read_test_file('disklist_expected.json'));
print Dumper($disks) if $print;
$testcount++;
is_deeply($disks, $expected_disk_list, 'disk list should be the same');
foreach my $disk (sort keys %$disks) {
my $smart;
my $expected_smart;
eval {
$smart = PVE::Diskmanage::get_smart_data("/dev/$disk");
print Dumper($smart) if $print;
$expected_smart = decode_json(read_test_file("${disk}_smart_expected.json"));
};
if ($smart && $expected_smart) {
$testcount++;
is_deeply($smart, $expected_smart, "smart data for '$disk' should be the same");
} elsif ($smart && -f "disk_tests/$testcasedir/${disk}_smart_expected.json") {
$testcount++;
ok(0, "could not parse expected smart for '$disk'\n");
}
my $disk_tmp = {};
# test single disk parameter
$disk_tmp = PVE::Diskmanage::get_disks($disk);
warn $@ if $@;
$testcount++;
print Dumper $disk_tmp if $print;
is_deeply($disk_tmp->{$disk}, $expected_disk_list->{$disk}, "disk $disk should be the same");
# test wrong parameter
eval {
PVE::Diskmanage::get_disks( { test => 1 } );
};
my $err = $@;
$testcount++;
is_deeply($err, "disks is not a string or array reference\n", "error message should be the same");
}
# test multi disk parameter
$disks = PVE::Diskmanage::get_disks( [ keys %$disks ] );
$testcount++;
is_deeply($disks, $expected_disk_list, 'disk list should be the same');
done_testing($testcount);
};
}
# start reading tests:
if (@ARGV && $ARGV[0] eq 'print') {
$print = 1;
}
print("Setting up Mocking\n");
$diskmanage_module = new Test::MockModule('PVE::Diskmanage', no_auto => 1);
$diskmanage_module->mock('run_command' => \&mocked_run_command);
print("\tMocked run_command\n");
$diskmanage_module->mock('dir_glob_foreach' => \&mocked_dir_glob_foreach);
print("\tMocked dir_glob_foreach\n");
$diskmanage_module->mock('get_sysdir_info' => \&mocked_get_sysdir_info);
print("\tMocked get_sysdir_info\n");
$diskmanage_module->mock('is_iscsi' => \&mocked_is_iscsi);
print("\tMocked is_iscsi\n");
$diskmanage_module->mock('assert_blockdev' => sub { return 1; });
print("\tMocked assert_blockdev\n");
$diskmanage_module->mock('dir_is_empty' => sub {
# all partitions have a holder dir
my $val = shift;
if ($val =~ m|^/sys/block/.+/.+/|) {
return 0;
}
return 1;
});
print("\tMocked dir_is_empty\n");
my $tools_module= new Test::MockModule('PVE::ProcFSTools', no_auto => 1);
$tools_module->mock('parse_proc_mounts' => \&mocked_parse_proc_mounts);
print("\tMocked parse_proc_mounts\n");
print("Done Setting up Mocking\n\n");
print("Beginning Tests:\n\n");
opendir (my $dh, 'disk_tests')
or die "Cannot open disk_tests: $!";
while (readdir $dh) {
my $dir = $_;
next if $dir eq '.' or $dir eq '..';
$testcount++;
test_disk_list($dir);
}
done_testing($testcount);