Skip to content

Commit 52840ec

Browse files
committed
Adding a few more tests for the inspector.
Signed-off-by: Rob Dobson <rob.dobson@citrix.com>
1 parent 1a05bbb commit 52840ec

2 files changed

Lines changed: 159 additions & 17 deletions

File tree

hwinfo/tools/inspector.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
from argparse import ArgumentParser
44
from prettytable import PrettyTable
55
import paramiko
6+
import subprocess
67

78
from hwinfo.pci import PCIDevice
89
from hwinfo.pci.lspci import *
9-
from hwinfo.host.dmidecode import *
10+
11+
from hwinfo.host import dmidecode
1012

1113
def remote_command(host, username, password, cmd):
1214
client = paramiko.SSHClient()
@@ -18,12 +20,19 @@ def remote_command(host, username, password, cmd):
1820
output = stdout.readlines()
1921
error = stderr.readlines()
2022
if error:
21-
print "stderr: %s" % error
23+
raise Exception("stderr: %s" % error)
2224
client.close()
2325
return ''.join(output)
2426

2527
def local_command(cmd):
26-
return cmd
28+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
29+
stdout, stderr = process.communicate()
30+
if process.returncode == 0:
31+
return str(stdout).strip()
32+
else:
33+
print "RC: %s" % process.returncode
34+
print stdout
35+
raise Exception("stderr: %s" % str(stderr))
2736

2837
class Host(object):
2938

@@ -46,7 +55,8 @@ def get_pci_devices(self):
4655

4756
def get_info(self):
4857
data = self.exec_command(['dmidecode'])
49-
parser = DmidecodeParser(data)
58+
parser = dmidecode.DmidecodeParser(data)
59+
print "test : '%s'" % parser
5060
rec = parser.parse()
5161
return rec
5262

@@ -71,19 +81,6 @@ def pci_filter_for_gpu(devices):
7181
gpu_types = ['03']
7282
return pci_filter(devices, gpu_types)
7383

74-
def print_lines(lines):
75-
max_len = 0
76-
output = []
77-
for line in lines:
78-
output.append(line)
79-
if len(line) > max_len:
80-
max_len = len(line)
81-
print ""
82-
print "-" * max_len
83-
print '\n'.join(output)
84-
print "-" * max_len
85-
print ""
86-
8784
def rec_to_table(rec):
8885
table = PrettyTable(["Key", "Value"])
8986
table.align['Key'] = 'l'
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import unittest
2+
import mock
3+
from mock import patch
4+
from StringIO import StringIO
5+
6+
from hwinfo.tools import inspector
7+
8+
class HostObjectTests(unittest.TestCase):
9+
10+
@patch('hwinfo.tools.inspector.local_command')
11+
def test_local_exec_command(self, local_command):
12+
host = inspector.Host()
13+
host.exec_command('ls')
14+
inspector.local_command.assert_called_once_with('ls')
15+
16+
@patch('hwinfo.tools.inspector.remote_command')
17+
def test_remote_exec_command(self, remote_command):
18+
host = inspector.Host('mymachine', 'root', 'pass')
19+
host.exec_command('ls')
20+
inspector.remote_command.assert_called_once_with('mymachine', 'root', 'pass', 'ls')
21+
22+
@patch('hwinfo.tools.inspector.Host.exec_command')
23+
def test_get_pci_devices(self, exec_command):
24+
host = inspector.Host()
25+
devs = host.get_pci_devices()
26+
exec_command.assert_called_once_with(['lspci', '-nnmm'])
27+
28+
@patch('hwinfo.host.dmidecode.DmidecodeParser')
29+
@patch('hwinfo.tools.inspector.Host.exec_command')
30+
def test_get_info(self, mock_exec_command, mock_dmidecode_parser_cls):
31+
mock_exec_command.return_value = 'blah'
32+
mparser = mock_dmidecode_parser_cls.return_value = mock.Mock()
33+
mparser.parse.return_value = {'key':'value'}
34+
host = inspector.Host()
35+
rec = host.get_info()
36+
self.assertEqual(rec, {'key':'value'})
37+
38+
39+
class RemoteCommandTests(unittest.TestCase):
40+
41+
def setUp(self):
42+
self.stdout = StringIO('')
43+
self.stdin = StringIO('')
44+
self.stderr = StringIO('')
45+
46+
@patch('paramiko.SSHClient')
47+
def test_ssh_connect(self, ssh_client_cls):
48+
client = ssh_client_cls.return_value = mock.Mock()
49+
client.exec_command.return_value = self.stdout, self.stdin, self.stderr
50+
inspector.remote_command('test', 'user', 'pass', 'ls')
51+
client.connect.assert_called_with('test', password='pass', username='user', timeout=10)
52+
53+
@patch('paramiko.SSHClient')
54+
def test_ssh_connect_error(self, ssh_client_cls):
55+
client = ssh_client_cls.return_value = mock.Mock()
56+
client.exec_command.return_value = self.stdout, self.stdin, StringIO("Error")
57+
with self.assertRaises(Exception) as context:
58+
inspector.remote_command('test', 'user', 'pass', 'ls')
59+
self.assertEqual(context.exception.message, "stderr: ['Error']")
60+
61+
class LocalCommandTests(unittest.TestCase):
62+
63+
@patch('subprocess.Popen')
64+
def test_local_call(self, mock_popen_cls):
65+
mprocess =mock_popen_cls.return_value = mock.MagicMock()
66+
mprocess.communicate.return_value = 'test', None
67+
mprocess.returncode = 0
68+
stdout = inspector.local_command("echo 'test'")
69+
self.assertEqual(stdout, 'test')
70+
71+
@patch('subprocess.Popen')
72+
def test_local_call_error(self, mock_popen_cls):
73+
mprocess =mock_popen_cls.return_value = mock.MagicMock()
74+
mprocess.communicate.return_value = 'test', 'my error'
75+
mprocess.returncode = 1
76+
with self.assertRaises(Exception) as context:
77+
stdout = inspector.local_command("echo 'test'")
78+
self.assertEqual(context.exception.message, "stderr: my error")
79+
80+
81+
class PCIFilterTests(unittest.TestCase):
82+
83+
def setUp(self):
84+
device_a = mock.MagicMock()
85+
device_b = mock.MagicMock()
86+
device_c = mock.MagicMock()
87+
device_d = mock.MagicMock()
88+
89+
device_a.get_pci_class.return_value = '0230'
90+
device_b.get_pci_class.return_value = '0340'
91+
device_c.get_pci_class.return_value = '0210'
92+
device_d.get_pci_class.return_value = '0100'
93+
94+
self.devices = [device_a, device_b, device_c, device_d]
95+
96+
def test_pci_filter_match_all(self):
97+
devs = inspector.pci_filter(self.devices, ['0'])
98+
self.assertEqual(len(devs), len(self.devices))
99+
100+
def test_pci_filter_match_two(self):
101+
devs = inspector.pci_filter(self.devices, ['02'])
102+
for dev in devs:
103+
print dev.get_pci_class()
104+
self.assertEqual(len(devs), 2)
105+
106+
def test_pci_filter_match_one(self):
107+
devs = inspector.pci_filter(self.devices, ['023'])
108+
self.assertEqual(len(devs), 1)
109+
self.assertEqual(devs[0].get_pci_class(), '0230')
110+
111+
def test_pci_filter_match_none(self):
112+
devs = inspector.pci_filter(self.devices, ['0234'])
113+
self.assertEqual(devs, [])
114+
115+
def test_pci_filter_for_nics(self):
116+
devs = inspector.pci_filter_for_nics(self.devices)
117+
self.assertEqual(len(devs), 2)
118+
119+
def test_pci_filter_for_storage(self):
120+
devs = inspector.pci_filter_for_storage(self.devices)
121+
self.assertEqual(len(devs), 1)
122+
self.assertEqual(devs[0].get_pci_class(), '0100')
123+
124+
def test_pci_filter_for_gpu(self):
125+
devs = inspector.pci_filter_for_gpu(self.devices)
126+
self.assertEqual(len(devs), 1)
127+
self.assertEqual(devs[0].get_pci_class(), '0340')
128+
129+
130+
class TabulateTests(unittest.TestCase):
131+
132+
@patch('hwinfo.tools.inspector.PrettyTable')
133+
def test_rec_to_table(self, mock_pt_cls):
134+
mock_table = mock_pt_cls.return_value = mock.MagicMock()
135+
rec = {'one': 1, 'two': 2, 'three': 3}
136+
inspector.rec_to_table(rec)
137+
self.assertEqual(mock_table.add_row.call_count, 3)
138+
expected_calls = [
139+
mock.call(['one', 1]),
140+
mock.call(['two', 2]),
141+
mock.call(['three', 3]),
142+
]
143+
mock_table.add_row.assert_has_calls(expected_calls, any_order=True)
144+
145+

0 commit comments

Comments
 (0)