pve-storage/test/disklist_test.pm
Dominik Csapak eebcdb1119 fix tests when one has iscsi devices
the test would read the real device and if one is an iscsi device
it would fail, move the test code to a sub and mock it in the tests

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2019-03-07 11:08:43 +01:00

223 lines
5.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'));
} else {
print "unexpected run_command call: '@$cmd', aborting\n";
die;
}
} 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");
}
}
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);