]> git.proxmox.com Git - pve-storage.git/blame - test/disklist_test.pm
fix content listing for user mode iscsi plugin
[pve-storage.git] / test / disklist_test.pm
CommitLineData
5774fe62
DC
1package PVE::Diskmanage::Test;
2
3use strict;
4use warnings;
5
6use lib qw(..);
7
8use PVE::Diskmanage;
9use PVE::Tools;
10
11use Test::MockModule;
12use Test::More;
13use JSON;
14use Data::Dumper;
15
16my $testcasedir; # current case directory
17my $testcount = 0; # testcount for TAP::Harness
18my $diskmanage_module; # mockmodule for PVE::Diskmanage
19my $print = 0;
20
21sub mocked_run_command {
22 my ($cmd, %param) = @_;
23
24 my $outputlines = [];
25 if (my $ref = ref($cmd)) {
26 if ($cmd->[0] =~ m/udevadm/i) {
27 # simulate udevadm output
28 my $dev = $cmd->[3];
29 $dev =~ s|/sys/block/||;
30 @$outputlines = split(/\n/, read_test_file("${dev}_udevadm"));
31
32 } elsif ($cmd->[0] =~ m/smartctl/i) {
33 # simulate smartctl output
34 my $dev;
35 my $type;
36 if (@$cmd > 3) {
37 $dev = $cmd->[5];
38 $type = 'smart';
39 } else {
40 $dev = $cmd->[2];
41 $type = 'health';
42 }
43 $dev =~ s|/dev/||;
44 @$outputlines = split(/\n/, read_test_file("${dev}_${type}"));
45 } elsif ($cmd->[0] =~ m/sgdisk/i) {
46 # simulate sgdisk
47 die "implement me: @$cmd\n";
48 } elsif ($cmd->[0] =~ m/zpool/i) {
49 # simulate zpool output
50 @$outputlines = split(/\n/, read_test_file('zpool'));
51
52 } elsif ($cmd->[0] =~ m/pvs/i) {
53 # simulate lvs output
54 @$outputlines = split(/\n/, read_test_file('pvs'));
55 } else {
56 print "unexpected run_command call: '@$cmd', aborting\n";
57 die;
58 }
59 } else {
60 print "unexpected run_command call: '@$cmd', aborting\n";
61 die;
62 }
63
64 my $outfunc;
65 if ($param{outfunc}) {
66 $outfunc = $param{outfunc};
67 map { &$outfunc(($_)) } @$outputlines;
68
69 return 0;
70 }
71}
72
73sub mocked_get_sysdir_info {
74 my ($param) = @_;
75
76 my $originalsub = $diskmanage_module->original('get_sysdir_info');
77
78 $param =~ s|/sys/block|disk_tests/$testcasedir|;
79
80 return &$originalsub($param);
81}
82
83sub mocked_dir_glob_foreach {
84 my ($dir, $regex, $sub) = @_;
85
86 my $lines = [];
87
88 # read lines in from file
89 if ($dir =~ m{^/sys/block$} ) {
90 @$lines = split(/\n/, read_test_file('disklist'));
91 } elsif ($dir =~ m{^/sys/block/([^/]+)}) {
92 @$lines = split(/\n/, read_test_file('partlist'));
93 }
94
95 foreach my $line (@$lines) {
96 if ($line =~ m/$regex/) {
97 &$sub($line);
98 }
99 }
100}
101
102sub mocked_parse_proc_mounts {
103 my $text = read_test_file('mounts');
104
105 my $mounts = [];
106
107 foreach my $line(split(/\n/, $text)) {
108 push @$mounts, [split(/\s+/, $line)];
109 }
110
111 return $mounts;
112}
113
114sub read_test_file {
115 my ($filename) = @_;
116
117 if (!-f "disk_tests/$testcasedir/$filename") {
118 print "file '$testcasedir/$filename' not found\n";
119 return '';
120 }
121 open (my $fh, '<', "disk_tests/$testcasedir/$filename")
122 or die "Cannot open disk_tests/$testcasedir/$filename: $!";
123
124 my $output = <$fh> // '';
125 chomp $output if $output;
126 while (my $line = <$fh>) {
127 chomp $line;
128 $output .= "\n$line";
129 }
130
131 return $output;
132}
133
134
135sub test_disk_list {
136 my ($testdir) = @_;
137 subtest "Test '$testdir'" => sub {
138 my $testcount = 0;
139 $testcasedir = $testdir;
140
141 my $disks;
142 my $expected_disk_list;
143 eval {
144 $disks = PVE::Diskmanage::get_disks();
145 };
146 warn $@ if $@;
147 $expected_disk_list = decode_json(read_test_file('disklist_expected.json'));
148
149 print Dumper($disks) if $print;
150 $testcount++;
151 is_deeply($disks, $expected_disk_list, 'disk list should be the same');
152
153 foreach my $disk (sort keys %$disks) {
154 my $smart;
155 my $expected_smart;
156 eval {
157 $smart = PVE::Diskmanage::get_smart_data("/dev/$disk");
158 print Dumper($smart) if $print;
159 $expected_smart = decode_json(read_test_file("${disk}_smart_expected.json"));
160 };
161
162 if ($smart && $expected_smart) {
163 $testcount++;
164 is_deeply($smart, $expected_smart, "smart data for '$disk' should be the same");
165 } elsif ($smart && -f "disk_tests/$testcasedir/${disk}_smart_expected.json") {
166 $testcount++;
167 ok(0, "could not parse expected smart for '$disk'\n");
168 }
169 }
170
171 done_testing($testcount);
172 };
173}
174
175# start reading tests:
176
177if (@ARGV && $ARGV[0] eq 'print') {
178 $print = 1;
179}
180
181print("Setting up Mocking\n");
182$diskmanage_module = new Test::MockModule('PVE::Diskmanage', no_auto => 1);
183$diskmanage_module->mock('run_command' => \&mocked_run_command);
184print("\tMocked run_command\n");
185$diskmanage_module->mock('dir_glob_foreach' => \&mocked_dir_glob_foreach);
186print("\tMocked dir_glob_foreach\n");
187$diskmanage_module->mock('get_sysdir_info' => \&mocked_get_sysdir_info);
188print("\tMocked get_sysdir_info\n");
189$diskmanage_module->mock('assert_blockdev' => sub { return 1; });
190print("\tMocked assert_blockdev\n");
191$diskmanage_module->mock('dir_is_empty' => sub {
192 # all partitions have a holder dir
193 my $val = shift;
194 if ($val =~ m|^/sys/block/.+/.+/|) {
195 return 0;
196 }
197 return 1;
198 });
199print("\tMocked dir_is_empty\n");
200my $tools_module= new Test::MockModule('PVE::ProcFSTools', no_auto => 1);
201$tools_module->mock('parse_proc_mounts' => \&mocked_parse_proc_mounts);
202print("\tMocked parse_proc_mounts\n");
203print("Done Setting up Mocking\n\n");
204
205print("Beginning Tests:\n\n");
206opendir (my $dh, 'disk_tests')
207 or die "Cannot open disk_tests: $!";
208
209while (readdir $dh) {
210 my $dir = $_;
211 next if $dir eq '.' or $dir eq '..';
212 $testcount++;
213 test_disk_list($dir);
214}
215
216done_testing($testcount);