Skip to content

Commit 915c0ab

Browse files
committed
Create tests for smartmon
1 parent eac9ad2 commit 915c0ab

File tree

1 file changed

+265
-0
lines changed

1 file changed

+265
-0
lines changed
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
import unittest
2+
from unittest.mock import patch
3+
from smartmon import (
4+
parse_smartctl_info,
5+
parse_smartctl_attributes,
6+
main,
7+
)
8+
9+
class TestSmartMon(unittest.TestCase):
10+
@patch('smartmon.run_command')
11+
def test_parse_smartctl_info(self, mock_run_command):
12+
devices_info = [
13+
{
14+
'disk': '/dev/nvme0',
15+
'disk_type': 'nvme',
16+
'json_output': {
17+
'device': {
18+
'name': '/dev/nvme0',
19+
'info_name': '/dev/nvme0',
20+
'type': 'nvme',
21+
'protocol': 'NVMe',
22+
},
23+
'model_name': 'Dell Ent NVMe CM6 RI 7.68TB',
24+
'serial_number': 'Y2Q0A0BGTCF8',
25+
'firmware_version': '2.2.0',
26+
'smart_status': {
27+
'passed': True,
28+
'available': True,
29+
'enabled': True
30+
},
31+
}
32+
},
33+
{
34+
'disk': '/dev/nvme1',
35+
'disk_type': 'nvme',
36+
'json_output': {
37+
'device': {
38+
'name': '/dev/nvme1',
39+
'info_name': '/dev/nvme1',
40+
'type': 'nvme',
41+
'protocol': 'NVMe',
42+
},
43+
'model_name': 'Dell Ent NVMe CM6 RI 7.68TB',
44+
'serial_number': 'Y2Q0A09PTCF8',
45+
'firmware_version': '2.2.0',
46+
'smart_status': {
47+
'passed': True,
48+
'available': True,
49+
'enabled': True
50+
},
51+
}
52+
},
53+
]
54+
55+
for device_info in devices_info:
56+
disk = device_info['disk']
57+
disk_type = device_info['disk_type']
58+
json_output = device_info['json_output']
59+
serial_number = json_output.get('serial_number', '').lower()
60+
61+
expected_metrics = [
62+
f'device_info{{disk="{disk}",type="{disk_type}",vendor="",product="",revision="",lun_id="",model_family="",device_model="{json_output.get("model_name", "")}",serial_number="{serial_number}",firmware_version="{json_output.get("firmware_version", "")}"}} 1',
63+
f'device_smart_available{{disk="{disk}",type="{disk_type}",serial_number="{serial_number}"}} 1',
64+
f'device_smart_enabled{{disk="{disk}",type="{disk_type}",serial_number="{serial_number}"}} 1',
65+
f'device_smart_healthy{{disk="{disk}",type="{disk_type}",serial_number="{serial_number}"}} 1',
66+
]
67+
68+
metrics = parse_smartctl_info(disk, disk_type, json_output)
69+
for expected_metric in expected_metrics:
70+
self.assertIn(expected_metric, metrics)
71+
72+
@patch('smartmon.run_command')
73+
def test_parse_smartctl_attributes(self, mock_run_command):
74+
devices_attributes = [
75+
{
76+
'disk': '/dev/nvme0',
77+
'disk_type': 'nvme',
78+
'serial': 'y2q0a0bgtcf8',
79+
'json_output': {
80+
'nvme_smart_health_information_log': {
81+
'critical_warning': 0,
82+
'temperature': 36,
83+
'available_spare': 100,
84+
'available_spare_threshold': 10,
85+
'percentage_used': 0,
86+
'data_units_read': 117446405,
87+
'data_units_written': 84630284,
88+
'host_reads': 634894145,
89+
'host_writes': 4502620984,
90+
'controller_busy_time': 92090,
91+
'power_cycles': 746,
92+
'power_on_hours': 12494,
93+
'unsafe_shutdowns': 35,
94+
'media_errors': 0,
95+
'num_err_log_entries': 827,
96+
'warning_temp_time': 0,
97+
'critical_comp_time': 0
98+
}
99+
}
100+
},
101+
{
102+
'disk': '/dev/nvme1',
103+
'disk_type': 'nvme',
104+
'serial': 'y2q0a09ptcf8',
105+
'json_output': {
106+
'nvme_smart_health_information_log': {
107+
'critical_warning': 0,
108+
'temperature': 35,
109+
'available_spare': 99,
110+
'available_spare_threshold': 10,
111+
'percentage_used': 1,
112+
'data_units_read': 50000000,
113+
'data_units_written': 40000000,
114+
'host_reads': 300000000,
115+
'host_writes': 2000000000,
116+
'controller_busy_time': 80000,
117+
'power_cycles': 700,
118+
'power_on_hours': 12000,
119+
'unsafe_shutdowns': 30,
120+
'media_errors': 0,
121+
'num_err_log_entries': 800,
122+
'warning_temp_time': 0,
123+
'critical_comp_time': 0
124+
}
125+
}
126+
},
127+
]
128+
129+
for device_attr in devices_attributes:
130+
disk = device_attr['disk']
131+
disk_type = device_attr['disk_type']
132+
serial = device_attr['serial']
133+
json_output = device_attr['json_output']
134+
135+
metrics = parse_smartctl_attributes(disk, disk_type, serial, json_output)
136+
137+
expected_metrics = [
138+
f'temperature{{disk="{disk}",type="{disk_type}",serial_number="{serial}"}} {json_output["nvme_smart_health_information_log"]["temperature"]}',
139+
f'available_spare{{disk="{disk}",type="{disk_type}",serial_number="{serial}"}} {json_output["nvme_smart_health_information_log"]["available_spare"]}',
140+
]
141+
142+
for expected_metric in expected_metrics:
143+
self.assertIn(expected_metric, metrics)
144+
145+
@patch('smartmon.run_command')
146+
def test_main(self, mock_run_command):
147+
def side_effect(command, parse_json=False):
148+
if '--scan-open' in command:
149+
return {
150+
'devices': [
151+
{'name': '/dev/nvme0', 'info_name': '/dev/nvme0', 'type': 'nvme'},
152+
{'name': '/dev/nvme1', 'info_name': '/dev/nvme1', 'type': 'nvme'},
153+
]
154+
} if parse_json else ''
155+
elif '-n' in command:
156+
return {'power_mode': 'active'} if parse_json else ''
157+
elif '-i' in command:
158+
if '/dev/nvme0' in command:
159+
return {
160+
'device': {
161+
'name': '/dev/nvme0',
162+
'info_name': '/dev/nvme0',
163+
'type': 'nvme',
164+
'protocol': 'NVMe',
165+
},
166+
'model_name': 'Dell Ent NVMe CM6 RI 7.68TB',
167+
'serial_number': 'Y2Q0A0BGTCF8',
168+
'firmware_version': '2.2.0',
169+
'smart_status': {
170+
'passed': True,
171+
'available': True,
172+
'enabled': True
173+
},
174+
} if parse_json else ''
175+
elif '/dev/nvme1' in command:
176+
return {
177+
'device': {
178+
'name': '/dev/nvme1',
179+
'info_name': '/dev/nvme1',
180+
'type': 'nvme',
181+
'protocol': 'NVMe',
182+
},
183+
'model_name': 'Dell Ent NVMe CM6 RI 7.68TB',
184+
'serial_number': 'Y2Q0A09PTCF8',
185+
'firmware_version': '2.2.0',
186+
'smart_status': {
187+
'passed': True,
188+
'available': True,
189+
'enabled': True
190+
},
191+
} if parse_json else ''
192+
elif '-A' in command:
193+
if '/dev/nvme0' in command:
194+
return {
195+
'nvme_smart_health_information_log': {
196+
'critical_warning': 0,
197+
'temperature': 36,
198+
'available_spare': 100,
199+
'available_spare_threshold': 10,
200+
'percentage_used': 0,
201+
'data_units_read': 117446405,
202+
'data_units_written': 84630284,
203+
'host_reads': 634894145,
204+
'host_writes': 4502620984,
205+
'controller_busy_time': 92090,
206+
'power_cycles': 746,
207+
'power_on_hours': 12494,
208+
'unsafe_shutdowns': 35,
209+
'media_errors': 0,
210+
'num_err_log_entries': 827,
211+
'warning_temp_time': 0,
212+
'critical_comp_time': 0
213+
}
214+
} if parse_json else ''
215+
elif '/dev/nvme1' in command:
216+
return {
217+
'nvme_smart_health_information_log': {
218+
'critical_warning': 0,
219+
'temperature': 35,
220+
'available_spare': 99,
221+
'available_spare_threshold': 10,
222+
'percentage_used': 1,
223+
'data_units_read': 50000000,
224+
'data_units_written': 40000000,
225+
'host_reads': 300000000,
226+
'host_writes': 2000000000,
227+
'controller_busy_time': 80000,
228+
'power_cycles': 700,
229+
'power_on_hours': 12000,
230+
'unsafe_shutdowns': 30,
231+
'media_errors': 0,
232+
'num_err_log_entries': 800,
233+
'warning_temp_time': 0,
234+
'critical_comp_time': 0
235+
}
236+
} if parse_json else ''
237+
elif '-j' in command and len(command) == 2:
238+
return {
239+
'smartctl': {
240+
'version': [7, 2],
241+
'svn_revision': '5155',
242+
'platform_info': 'x86_64-linux-5.15.0-122-generic',
243+
'build_info': '(local build)',
244+
}
245+
} if parse_json else ''
246+
else:
247+
return {} if parse_json else ''
248+
249+
mock_run_command.side_effect = side_effect
250+
251+
with patch('builtins.print') as mock_print:
252+
main()
253+
output_lines = []
254+
for call in mock_print.call_args_list:
255+
output_lines.extend(call[0][0].split('\n'))
256+
expected_metrics = [
257+
'smartmon_device_info{disk="/dev/nvme0",type="nvme",vendor="",product="",revision="",lun_id="",model_family="",device_model="Dell Ent NVMe CM6 RI 7.68TB",serial_number="y2q0a0bgtcf8",firmware_version="2.2.0"} 1',
258+
'smartmon_device_info{disk="/dev/nvme1",type="nvme",vendor="",product="",revision="",lun_id="",model_family="",device_model="Dell Ent NVMe CM6 RI 7.68TB",serial_number="y2q0a09ptcf8",firmware_version="2.2.0"} 1',
259+
]
260+
for expected_metric in expected_metrics:
261+
self.assertIn(expected_metric, output_lines)
262+
263+
264+
if __name__ == '__main__':
265+
unittest.main()

0 commit comments

Comments
 (0)