test: add tests for zpool status parsing of the ZFS disk API
The detail call of the ZFS disk API parses the output of 'zpool status' into the vdev tree of a pool. Add a test for it, which mocks the zpool command and checks the result for a healthy pool with log, cache and spare devices, so that fixes for the parser can extend it with their cases. Signed-off-by: Michal Fox <me@dualfroz.com>
This commit is contained in:
1 parent
f0e989f1dc
commit
ab748c8530
2 files changed
+166
-1
No files matched your search
@@ -6,7 +6,7 @@ use warnings;
|
|||||||
use TAP::Harness;
|
use TAP::Harness;
|
||||||
|
|
||||||
my $harness = TAP::Harness->new({ verbosity => -2 });
|
my $harness = TAP::Harness->new({ verbosity => -2 });
|
||||||
my $res = $harness->runtests("disklist_test.pm");
|
my $res = $harness->runtests("disklist_test.pm", "zfs_pool_detail_test.pm");
|
||||||
|
|
||||||
exit -1 if !$res || $res->{failed} || $res->{parse_errors};
|
exit -1 if !$res || $res->{failed} || $res->{parse_errors};
|
||||||
|
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
package PVE::API2::Disks::ZFS::TestPoolDetail;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use lib qw(..);
|
||||||
|
|
||||||
|
use PVE::API2::Disks::ZFS;
|
||||||
|
use Test::More;
|
||||||
|
use Test::MockModule;
|
||||||
|
|
||||||
|
my $zpool_status_output;
|
||||||
|
|
||||||
|
my $zfs_api_module = Test::MockModule->new('PVE::API2::Disks::ZFS');
|
||||||
|
$zfs_api_module->mock(
|
||||||
|
run_command => sub {
|
||||||
|
my ($cmd, %param) = @_;
|
||||||
|
|
||||||
|
my $cmdline = join(' ', @$cmd);
|
||||||
|
die "unexpected run_command call: '$cmdline'\n"
|
||||||
|
if $cmdline ne '/sbin/zpool status -P tank';
|
||||||
|
|
||||||
|
$param{outfunc}->($_) for split(/\n/, $zpool_status_output);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
# each test is comprised of the following keys:
|
||||||
|
# description => what the test is about
|
||||||
|
# status => output of 'zpool status' for the pool 'tank'
|
||||||
|
# expected => pool details as returned by the API
|
||||||
|
my $tests = [
|
||||||
|
{
|
||||||
|
description => 'healthy pool with log, cache and spare',
|
||||||
|
status => <<"EOF",
|
||||||
|
pool: tank
|
||||||
|
state: ONLINE
|
||||||
|
scan: scrub repaired 0B in 00:00:01 with 0 errors on Sun Sep 13 00:24:02 2026
|
||||||
|
config:
|
||||||
|
|
||||||
|
\tNAME STATE READ WRITE CKSUM
|
||||||
|
\ttank ONLINE 0 0 0
|
||||||
|
\t mirror-0 ONLINE 0 0 0
|
||||||
|
\t /dev/disk/by-id/ata-DISK_A-part1 ONLINE 0 0 0
|
||||||
|
\t /dev/disk/by-id/ata-DISK_B-part1 ONLINE 0 0 0
|
||||||
|
\tlogs
|
||||||
|
\t /dev/disk/by-id/nvme-LOG-part1 ONLINE 0 0 0
|
||||||
|
\tcache
|
||||||
|
\t /dev/disk/by-id/nvme-CACHE-part1 ONLINE 0 0 0
|
||||||
|
\tspares
|
||||||
|
\t /dev/disk/by-id/ata-DISK_C-part1 AVAIL
|
||||||
|
|
||||||
|
errors: No known data errors
|
||||||
|
EOF
|
||||||
|
expected => {
|
||||||
|
name => 'tank',
|
||||||
|
state => 'ONLINE',
|
||||||
|
scan => 'scrub repaired 0B in 00:00:01 with 0 errors on Sun Sep 13 00:24:02 2026',
|
||||||
|
errors => 'No known data errors',
|
||||||
|
leaf => 0,
|
||||||
|
children => [
|
||||||
|
{
|
||||||
|
name => 'tank',
|
||||||
|
state => 'ONLINE',
|
||||||
|
read => 0,
|
||||||
|
write => 0,
|
||||||
|
cksum => 0,
|
||||||
|
msg => '',
|
||||||
|
leaf => 0,
|
||||||
|
children => [
|
||||||
|
{
|
||||||
|
name => 'mirror-0',
|
||||||
|
state => 'ONLINE',
|
||||||
|
read => 0,
|
||||||
|
write => 0,
|
||||||
|
cksum => 0,
|
||||||
|
msg => '',
|
||||||
|
leaf => 0,
|
||||||
|
children => [
|
||||||
|
{
|
||||||
|
name => '/dev/disk/by-id/ata-DISK_A-part1',
|
||||||
|
state => 'ONLINE',
|
||||||
|
read => 0,
|
||||||
|
write => 0,
|
||||||
|
cksum => 0,
|
||||||
|
msg => '',
|
||||||
|
leaf => 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name => '/dev/disk/by-id/ata-DISK_B-part1',
|
||||||
|
state => 'ONLINE',
|
||||||
|
read => 0,
|
||||||
|
write => 0,
|
||||||
|
cksum => 0,
|
||||||
|
msg => '',
|
||||||
|
leaf => 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name => 'logs',
|
||||||
|
msg => '',
|
||||||
|
leaf => 0,
|
||||||
|
children => [
|
||||||
|
{
|
||||||
|
name => '/dev/disk/by-id/nvme-LOG-part1',
|
||||||
|
state => 'ONLINE',
|
||||||
|
read => 0,
|
||||||
|
write => 0,
|
||||||
|
cksum => 0,
|
||||||
|
msg => '',
|
||||||
|
leaf => 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name => 'cache',
|
||||||
|
msg => '',
|
||||||
|
leaf => 0,
|
||||||
|
children => [
|
||||||
|
{
|
||||||
|
name => '/dev/disk/by-id/nvme-CACHE-part1',
|
||||||
|
state => 'ONLINE',
|
||||||
|
read => 0,
|
||||||
|
write => 0,
|
||||||
|
cksum => 0,
|
||||||
|
msg => '',
|
||||||
|
leaf => 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name => 'spares',
|
||||||
|
msg => '',
|
||||||
|
leaf => 0,
|
||||||
|
children => [
|
||||||
|
{
|
||||||
|
name => '/dev/disk/by-id/ata-DISK_C-part1',
|
||||||
|
state => 'AVAIL',
|
||||||
|
msg => '',
|
||||||
|
leaf => 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
plan tests => scalar @$tests;
|
||||||
|
|
||||||
|
for my $test (@$tests) {
|
||||||
|
$zpool_status_output = $test->{status};
|
||||||
|
|
||||||
|
my $pool = eval { PVE::API2::Disks::ZFS->detail({ node => 'localhost', name => 'tank' }) };
|
||||||
|
diag("unexpected error: $@") if $@;
|
||||||
|
is_deeply($pool, $test->{expected}, $test->{description});
|
||||||
|
}
|
||||||
|
|
||||||
|
done_testing();
|
||||||
|
|
||||||
|
1;
|
||||||
Reference in new issue
Block a user