]>
Commit | Line | Data |
---|---|---|
91327a77 AA |
1 | # -*- coding: utf-8 -*- |
2 | ||
3 | import pytest | |
4 | from ceph_volume.util.device import Devices | |
f91f0fd5 | 5 | from ceph_volume.util.lsmdisk import LSMDisk |
2a845540 | 6 | from mock.mock import patch |
f91f0fd5 | 7 | import ceph_volume.util.lsmdisk as lsmdisk |
91327a77 AA |
8 | |
9 | ||
10 | @pytest.fixture | |
2a845540 | 11 | @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False) |
91327a77 AA |
12 | def device_report_keys(device_info): |
13 | device_info(devices={ | |
14 | # example output of disk.get_devices() | |
15 | '/dev/sdb': {'human_readable_size': '1.82 TB', | |
16 | 'locked': 0, | |
17 | 'model': 'PERC H700', | |
18 | 'nr_requests': '128', | |
19 | 'partitions': {}, | |
20 | 'path': '/dev/sdb', | |
21 | 'removable': '0', | |
22 | 'rev': '2.10', | |
23 | 'ro': '0', | |
24 | 'rotational': '1', | |
25 | 'sas_address': '', | |
26 | 'sas_device_handle': '', | |
27 | 'scheduler_mode': 'cfq', | |
28 | 'sectors': 0, | |
29 | 'sectorsize': '512', | |
30 | 'size': 1999844147200.0, | |
31 | 'support_discard': '', | |
eafe8130 | 32 | 'vendor': 'DELL', |
2a845540 TL |
33 | 'device_id': 'Vendor-Model-Serial', |
34 | 'device_nodes': 'sdb'} | |
91327a77 AA |
35 | } |
36 | ) | |
37 | report = Devices().json_report()[0] | |
38 | return list(report.keys()) | |
39 | ||
40 | @pytest.fixture | |
2a845540 | 41 | @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False) |
91327a77 AA |
42 | def device_sys_api_keys(device_info): |
43 | device_info(devices={ | |
44 | # example output of disk.get_devices() | |
45 | '/dev/sdb': {'human_readable_size': '1.82 TB', | |
46 | 'locked': 0, | |
47 | 'model': 'PERC H700', | |
48 | 'nr_requests': '128', | |
49 | 'partitions': {}, | |
50 | 'path': '/dev/sdb', | |
51 | 'removable': '0', | |
52 | 'rev': '2.10', | |
53 | 'ro': '0', | |
54 | 'rotational': '1', | |
55 | 'sas_address': '', | |
56 | 'sas_device_handle': '', | |
57 | 'scheduler_mode': 'cfq', | |
58 | 'sectors': 0, | |
59 | 'sectorsize': '512', | |
60 | 'size': 1999844147200.0, | |
61 | 'support_discard': '', | |
2a845540 TL |
62 | 'vendor': 'DELL', |
63 | 'device_nodes': 'sdb'} | |
91327a77 AA |
64 | } |
65 | ) | |
66 | report = Devices().json_report()[0] | |
67 | return list(report['sys_api'].keys()) | |
68 | ||
f91f0fd5 | 69 | @pytest.fixture |
2a845540 | 70 | @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False) |
f91f0fd5 TL |
71 | def device_data(device_info): |
72 | device_info( | |
73 | devices={ | |
74 | # example output of disk.get_devices() | |
75 | '/dev/sdb': { | |
76 | 'human_readable_size': '1.82 TB', | |
77 | 'locked': 0, | |
78 | 'model': 'PERC H700', | |
79 | 'nr_requests': '128', | |
80 | 'partitions': {}, | |
81 | 'path': '/dev/sdb', | |
82 | 'removable': '0', | |
83 | 'rev': '2.10', | |
84 | 'ro': '0', | |
85 | 'rotational': '1', | |
86 | 'sas_address': '', | |
87 | 'sas_device_handle': '', | |
88 | 'scheduler_mode': 'cfq', | |
89 | 'sectors': 0, | |
90 | 'sectorsize': '512', | |
91 | 'size': 1999844147200.0, | |
92 | 'support_discard': '', | |
93 | 'vendor': 'DELL', | |
2a845540 | 94 | 'device_nodes': 'sdb' |
f91f0fd5 TL |
95 | } |
96 | } | |
97 | ) | |
98 | ||
99 | dev = Devices().devices[0] | |
100 | dev.lsm_data = { | |
101 | "serialNum": 'S2X9NX0H935283', | |
102 | "transport": 'SAS', | |
103 | "mediaType": 'HDD', | |
104 | "rpm": 10000, | |
105 | "linkSpeed": 6000, | |
106 | "health": 'Good', | |
107 | "ledSupport": { | |
108 | "IDENTsupport": 'Supported', | |
109 | "IDENTstatus": 'Off', | |
110 | "FAILsupport": 'Supported', | |
111 | "FAILstatus": 'Off', | |
112 | }, | |
113 | "errors": [], | |
114 | } | |
115 | return dev.json_report() | |
116 | ||
91327a77 AA |
117 | |
118 | class TestInventory(object): | |
119 | ||
120 | expected_keys = [ | |
33c7a0ef | 121 | 'ceph_device', |
91327a77 AA |
122 | 'path', |
123 | 'rejected_reasons', | |
124 | 'sys_api', | |
125 | 'available', | |
126 | 'lvs', | |
eafe8130 | 127 | 'device_id', |
f91f0fd5 | 128 | 'lsm_data', |
91327a77 AA |
129 | ] |
130 | ||
131 | expected_sys_api_keys = [ | |
132 | 'human_readable_size', | |
133 | 'locked', | |
134 | 'model', | |
135 | 'nr_requests', | |
136 | 'partitions', | |
137 | 'path', | |
138 | 'removable', | |
139 | 'rev', | |
140 | 'ro', | |
141 | 'rotational', | |
142 | 'sas_address', | |
143 | 'sas_device_handle', | |
144 | 'scheduler_mode', | |
145 | 'sectors', | |
146 | 'sectorsize', | |
147 | 'size', | |
148 | 'support_discard', | |
149 | 'vendor', | |
2a845540 | 150 | 'device_nodes' |
91327a77 AA |
151 | ] |
152 | ||
f91f0fd5 TL |
153 | expected_lsm_keys = [ |
154 | 'serialNum', | |
155 | 'transport', | |
156 | 'mediaType', | |
157 | 'rpm', | |
158 | 'linkSpeed', | |
159 | 'health', | |
160 | 'ledSupport', | |
161 | 'errors', | |
162 | ] | |
163 | ||
33c7a0ef | 164 | def test_json_inventory_keys_unexpected(self, fake_call, device_report_keys): |
91327a77 AA |
165 | for k in device_report_keys: |
166 | assert k in self.expected_keys, "unexpected key {} in report".format(k) | |
167 | ||
33c7a0ef | 168 | def test_json_inventory_keys_missing(self, fake_call, device_report_keys): |
91327a77 AA |
169 | for k in self.expected_keys: |
170 | assert k in device_report_keys, "expected key {} in report".format(k) | |
171 | ||
33c7a0ef | 172 | def test_sys_api_keys_unexpected(self, fake_call, device_sys_api_keys): |
91327a77 AA |
173 | for k in device_sys_api_keys: |
174 | assert k in self.expected_sys_api_keys, "unexpected key {} in sys_api field".format(k) | |
175 | ||
33c7a0ef | 176 | def test_sys_api_keys_missing(self, fake_call, device_sys_api_keys): |
91327a77 AA |
177 | for k in self.expected_sys_api_keys: |
178 | assert k in device_sys_api_keys, "expected key {} in sys_api field".format(k) | |
179 | ||
33c7a0ef | 180 | def test_lsm_data_type_unexpected(self, fake_call, device_data): |
f91f0fd5 TL |
181 | assert isinstance(device_data['lsm_data'], dict), "lsm_data field must be of type dict" |
182 | ||
33c7a0ef | 183 | def test_lsm_data_keys_unexpected(self, fake_call, device_data): |
f91f0fd5 TL |
184 | for k in device_data['lsm_data'].keys(): |
185 | assert k in self.expected_lsm_keys, "unexpected key {} in lsm_data field".format(k) | |
186 | ||
33c7a0ef | 187 | def test_lsm_data_keys_missing(self, fake_call, device_data): |
f91f0fd5 TL |
188 | lsm_keys = device_data['lsm_data'].keys() |
189 | assert lsm_keys | |
190 | for k in self.expected_lsm_keys: | |
191 | assert k in lsm_keys, "expected key {} in lsm_data field".format(k) | |
192 | ||
193 | ||
194 | @pytest.fixture | |
195 | def lsm_info(monkeypatch): | |
196 | def mock_query_lsm(_, func, path): | |
197 | query_map = { | |
198 | 'serial_num_get': "S2X9NX0H935283", | |
199 | 'link_type_get': 6, | |
200 | 'rpm_get': 0, | |
201 | 'link_speed_get': 6000, | |
202 | 'health_status_get': 2, | |
203 | 'led_status_get': 36, | |
204 | } | |
205 | return query_map.get(func, 'Unknown') | |
206 | ||
207 | # mocked states and settings taken from the libstoragemgmt code base | |
20effc67 | 208 | # c_binding/include/libstoragemgmt/libstoragemgmt_types.h at |
f91f0fd5 TL |
209 | # https://github.com/libstorage/libstoragemgmt/ |
210 | mock_health_map = { | |
211 | -1: "Unknown", | |
212 | 0: "Fail", | |
213 | 1: "Warn", | |
214 | 2: "Good", | |
215 | } | |
216 | mock_transport_map = { | |
217 | -1: "Unavailable", | |
218 | 0: "Fibre Channel", | |
219 | 2: "IBM SSA", | |
220 | 3: "Serial Bus", | |
221 | 4: "SCSI RDMA", | |
222 | 5: "iSCSI", | |
223 | 6: "SAS", | |
224 | 7: "ADT (Tape)", | |
225 | 8: "ATA/SATA", | |
226 | 9: "USB", | |
227 | 10: "SCSI over PCI-E", | |
228 | 11: "PCI-E", | |
229 | } | |
230 | class MockLEDStates(): | |
231 | LED_STATUS_UNKNOWN = 1 | |
232 | LED_STATUS_IDENT_ON = 2 | |
233 | LED_STATUS_IDENT_OFF = 4 | |
20effc67 | 234 | LED_STATUS_IDENT_UNKNOWN = 8 |
f91f0fd5 TL |
235 | LED_STATUS_FAULT_ON = 16 |
236 | LED_STATUS_FAULT_OFF = 32 | |
237 | LED_STATUS_FAULT_UNKNOWN = 64 | |
238 | ||
239 | monkeypatch.setattr(LSMDisk, '_query_lsm', mock_query_lsm) | |
240 | monkeypatch.setattr(lsmdisk, 'health_map', mock_health_map) | |
241 | monkeypatch.setattr(lsmdisk, 'transport_map', mock_transport_map) | |
242 | monkeypatch.setattr(lsmdisk, 'lsm_Disk', MockLEDStates) | |
243 | ||
244 | return LSMDisk('/dev/sda') | |
245 | ||
246 | ||
247 | class TestLSM(object): | |
248 | def test_lsmdisk_health(self, lsm_info): | |
249 | assert lsm_info.health == "Good" | |
250 | def test_lsmdisk_transport(self, lsm_info): | |
251 | assert lsm_info.transport == 'SAS' | |
252 | def test_lsmdisk_mediatype(self, lsm_info): | |
253 | assert lsm_info.media_type == 'Flash' | |
254 | def test_lsmdisk_led_ident_support(self, lsm_info): | |
255 | assert lsm_info.led_ident_support == 'Supported' | |
256 | def test_lsmdisk_led_ident(self, lsm_info): | |
257 | assert lsm_info.led_ident_state == 'Off' | |
258 | def test_lsmdisk_led_fault_support(self, lsm_info): | |
259 | assert lsm_info.led_fault_support == 'Supported' | |
260 | def test_lsmdisk_led_fault(self, lsm_info): | |
20effc67 | 261 | assert lsm_info.led_fault_state == 'Off' |
f91f0fd5 | 262 | def test_lsmdisk_report(self, lsm_info): |
33c7a0ef | 263 | assert isinstance(lsm_info.json_report(), dict) |