]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | # flake8: noqa |
2 | import pytest | |
3 | ||
20effc67 | 4 | from ceph.deployment.drive_selection.matchers import _MatchInvalid |
9f95a23c TL |
5 | from ceph.deployment.inventory import Devices, Device |
6 | ||
f91f0fd5 TL |
7 | from ceph.deployment.drive_group import DriveGroupSpec, DeviceSelection, \ |
8 | DriveGroupValidationError | |
9f95a23c TL |
9 | |
10 | from ceph.deployment import drive_selection | |
11 | from ceph.deployment.service_spec import PlacementSpec | |
12 | from ceph.tests.factories import InventoryFactory | |
13 | from ceph.tests.utils import _mk_inventory, _mk_device | |
14 | ||
15 | ||
16 | class TestMatcher(object): | |
17 | """ Test Matcher base class | |
18 | """ | |
19 | ||
20 | def test_get_disk_key_3(self): | |
21 | """ | |
22 | virtual is False | |
23 | key is found | |
24 | retrun value of key is expected | |
25 | """ | |
26 | disk_map = Device(path='/dev/vdb', sys_api={'foo': 'bar'}) | |
27 | ret = drive_selection.Matcher('foo', 'bar')._get_disk_key(disk_map) | |
28 | assert ret is disk_map.sys_api.get('foo') | |
29 | ||
30 | def test_get_disk_key_4(self): | |
31 | """ | |
32 | virtual is False | |
33 | key is not found | |
34 | expect raise Exception | |
35 | """ | |
36 | disk_map = Device(path='/dev/vdb') | |
37 | with pytest.raises(Exception): | |
38 | drive_selection.Matcher('bar', 'foo')._get_disk_key(disk_map) | |
39 | pytest.fail("No disk_key found for foo or None") | |
40 | ||
41 | ||
42 | class TestSubstringMatcher(object): | |
43 | def test_compare(self): | |
44 | disk_dict = Device(path='/dev/vdb', sys_api=dict(model='samsung')) | |
45 | matcher = drive_selection.SubstringMatcher('model', 'samsung') | |
46 | ret = matcher.compare(disk_dict) | |
47 | assert ret is True | |
48 | ||
49 | def test_compare_false(self): | |
50 | disk_dict = Device(path='/dev/vdb', sys_api=dict(model='nothing_matching')) | |
51 | matcher = drive_selection.SubstringMatcher('model', 'samsung') | |
52 | ret = matcher.compare(disk_dict) | |
53 | assert ret is False | |
54 | ||
55 | ||
56 | class TestEqualityMatcher(object): | |
57 | def test_compare(self): | |
58 | disk_dict = Device(path='/dev/vdb', sys_api=dict(rotates='1')) | |
59 | matcher = drive_selection.EqualityMatcher('rotates', '1') | |
60 | ret = matcher.compare(disk_dict) | |
61 | assert ret is True | |
62 | ||
63 | def test_compare_false(self): | |
64 | disk_dict = Device(path='/dev/vdb', sys_api=dict(rotates='1')) | |
65 | matcher = drive_selection.EqualityMatcher('rotates', '0') | |
66 | ret = matcher.compare(disk_dict) | |
67 | assert ret is False | |
68 | ||
69 | ||
70 | class TestAllMatcher(object): | |
71 | def test_compare(self): | |
72 | disk_dict = Device(path='/dev/vdb') | |
73 | matcher = drive_selection.AllMatcher('all', 'True') | |
74 | ret = matcher.compare(disk_dict) | |
75 | assert ret is True | |
76 | ||
77 | def test_compare_value_not_true(self): | |
78 | disk_dict = Device(path='/dev/vdb') | |
79 | matcher = drive_selection.AllMatcher('all', 'False') | |
80 | ret = matcher.compare(disk_dict) | |
81 | assert ret is True | |
82 | ||
83 | ||
84 | class TestSizeMatcher(object): | |
85 | def test_parse_filter_exact(self): | |
86 | """ Testing exact notation with 20G """ | |
87 | matcher = drive_selection.SizeMatcher('size', '20G') | |
88 | assert isinstance(matcher.exact, tuple) | |
89 | assert matcher.exact[0] == '20' | |
90 | assert matcher.exact[1] == 'GB' | |
91 | ||
92 | def test_parse_filter_exact_GB_G(self): | |
93 | """ Testing exact notation with 20G """ | |
94 | matcher = drive_selection.SizeMatcher('size', '20GB') | |
95 | assert isinstance(matcher.exact, tuple) | |
96 | assert matcher.exact[0] == '20' | |
97 | assert matcher.exact[1] == 'GB' | |
98 | ||
99 | def test_parse_filter_high_low(self): | |
100 | """ Testing high-low notation with 20G:50G """ | |
101 | ||
102 | matcher = drive_selection.SizeMatcher('size', '20G:50G') | |
103 | assert isinstance(matcher.exact, tuple) | |
104 | assert matcher.low[0] == '20' | |
105 | assert matcher.high[0] == '50' | |
106 | assert matcher.low[1] == 'GB' | |
107 | assert matcher.high[1] == 'GB' | |
108 | ||
109 | def test_parse_filter_max_high(self): | |
110 | """ Testing high notation with :50G """ | |
111 | ||
112 | matcher = drive_selection.SizeMatcher('size', ':50G') | |
113 | assert isinstance(matcher.exact, tuple) | |
114 | assert matcher.high[0] == '50' | |
115 | assert matcher.high[1] == 'GB' | |
116 | ||
117 | def test_parse_filter_min_low(self): | |
118 | """ Testing low notation with 20G: """ | |
119 | ||
120 | matcher = drive_selection.SizeMatcher('size', '50G:') | |
121 | assert isinstance(matcher.exact, tuple) | |
122 | assert matcher.low[0] == '50' | |
123 | assert matcher.low[1] == 'GB' | |
124 | ||
39ae355f TL |
125 | def test_to_byte_KB(self): |
126 | """ I doubt anyone ever thought we'd need to understand KB """ | |
127 | ||
128 | ret = drive_selection.SizeMatcher('size', '4K').to_byte(('4', 'KB')) | |
129 | assert ret == 4 * 1e+3 | |
130 | ||
9f95a23c TL |
131 | def test_to_byte_GB(self): |
132 | """ Pretty nonesense test..""" | |
133 | ||
134 | ret = drive_selection.SizeMatcher('size', '10G').to_byte(('10', 'GB')) | |
135 | assert ret == 10 * 1e+9 | |
136 | ||
137 | def test_to_byte_MB(self): | |
138 | """ Pretty nonesense test..""" | |
139 | ||
140 | ret = drive_selection.SizeMatcher('size', '10M').to_byte(('10', 'MB')) | |
141 | assert ret == 10 * 1e+6 | |
142 | ||
143 | def test_to_byte_TB(self): | |
144 | """ Pretty nonesense test..""" | |
145 | ||
146 | ret = drive_selection.SizeMatcher('size', '10T').to_byte(('10', 'TB')) | |
147 | assert ret == 10 * 1e+12 | |
148 | ||
149 | def test_to_byte_PB(self): | |
150 | """ Expect to raise """ | |
151 | ||
20effc67 | 152 | with pytest.raises(_MatchInvalid): |
9f95a23c TL |
153 | drive_selection.SizeMatcher('size', '10P').to_byte(('10', 'PB')) |
154 | assert 'Unit \'P\' is not supported' | |
155 | ||
156 | def test_compare_exact(self): | |
157 | ||
158 | matcher = drive_selection.SizeMatcher('size', '20GB') | |
159 | disk_dict = Device(path='/dev/vdb', sys_api=dict(size='20.00 GB')) | |
160 | ret = matcher.compare(disk_dict) | |
161 | assert ret is True | |
162 | ||
b3b6e05e TL |
163 | def test_compare_exact_decimal(self): |
164 | ||
165 | matcher = drive_selection.SizeMatcher('size', '20.12GB') | |
166 | disk_dict = Device(path='/dev/vdb', sys_api=dict(size='20.12 GB')) | |
167 | ret = matcher.compare(disk_dict) | |
168 | assert ret is True | |
169 | ||
9f95a23c TL |
170 | @pytest.mark.parametrize("test_input,expected", [ |
171 | ("1.00 GB", False), | |
172 | ("20.00 GB", True), | |
173 | ("50.00 GB", True), | |
174 | ("100.00 GB", True), | |
175 | ("101.00 GB", False), | |
176 | ("1101.00 GB", False), | |
177 | ]) | |
178 | def test_compare_high_low(self, test_input, expected): | |
179 | ||
180 | matcher = drive_selection.SizeMatcher('size', '20GB:100GB') | |
181 | disk_dict = Device(path='/dev/vdb', sys_api=dict(size=test_input)) | |
182 | ret = matcher.compare(disk_dict) | |
183 | assert ret is expected | |
184 | ||
185 | @pytest.mark.parametrize("test_input,expected", [ | |
186 | ("1.00 GB", True), | |
187 | ("20.00 GB", True), | |
188 | ("50.00 GB", True), | |
189 | ("100.00 GB", False), | |
190 | ("101.00 GB", False), | |
191 | ("1101.00 GB", False), | |
192 | ]) | |
193 | def test_compare_high(self, test_input, expected): | |
194 | ||
195 | matcher = drive_selection.SizeMatcher('size', ':50GB') | |
196 | disk_dict = Device(path='/dev/vdb', sys_api=dict(size=test_input)) | |
197 | ret = matcher.compare(disk_dict) | |
198 | assert ret is expected | |
199 | ||
200 | @pytest.mark.parametrize("test_input,expected", [ | |
201 | ("1.00 GB", False), | |
202 | ("20.00 GB", False), | |
203 | ("50.00 GB", True), | |
204 | ("100.00 GB", True), | |
205 | ("101.00 GB", True), | |
206 | ("1101.00 GB", True), | |
207 | ]) | |
208 | def test_compare_low(self, test_input, expected): | |
209 | ||
210 | matcher = drive_selection.SizeMatcher('size', '50GB:') | |
211 | disk_dict = Device(path='/dev/vdb', sys_api=dict(size=test_input)) | |
212 | ret = matcher.compare(disk_dict) | |
213 | assert ret is expected | |
214 | ||
215 | @pytest.mark.parametrize("test_input,expected", [ | |
216 | ("1.00 GB", False), | |
217 | ("20.00 GB", False), | |
218 | ("50.00 GB", False), | |
219 | ("100.00 GB", False), | |
220 | ("101.00 GB", False), | |
221 | ("1101.00 GB", True), | |
222 | ("9.10 TB", True), | |
223 | ]) | |
224 | def test_compare_at_least_1TB(self, test_input, expected): | |
225 | ||
226 | matcher = drive_selection.SizeMatcher('size', '1TB:') | |
227 | disk_dict = Device(path='/dev/sdz', sys_api=dict(size=test_input)) | |
228 | ret = matcher.compare(disk_dict) | |
229 | assert ret is expected | |
230 | ||
231 | def test_compare_raise(self): | |
232 | ||
233 | matcher = drive_selection.SizeMatcher('size', 'None') | |
234 | disk_dict = Device(path='/dev/vdb', sys_api=dict(size='20.00 GB')) | |
235 | with pytest.raises(Exception): | |
236 | matcher.compare(disk_dict) | |
237 | pytest.fail("Couldn't parse size") | |
238 | ||
239 | @pytest.mark.parametrize("test_input,expected", [ | |
240 | ("10G", ('10', 'GB')), | |
241 | ("20GB", ('20', 'GB')), | |
242 | ("10g", ('10', 'GB')), | |
243 | ("20gb", ('20', 'GB')), | |
244 | ]) | |
245 | def test_get_k_v(self, test_input, expected): | |
246 | assert drive_selection.SizeMatcher('size', '10G')._get_k_v(test_input) == expected | |
247 | ||
248 | @pytest.mark.parametrize("test_input,expected", [ | |
249 | ("10G", ('GB')), | |
250 | ("10g", ('GB')), | |
251 | ("20GB", ('GB')), | |
252 | ("20gb", ('GB')), | |
253 | ("20TB", ('TB')), | |
254 | ("20tb", ('TB')), | |
255 | ("20T", ('TB')), | |
256 | ("20t", ('TB')), | |
257 | ("20MB", ('MB')), | |
258 | ("20mb", ('MB')), | |
259 | ("20M", ('MB')), | |
260 | ("20m", ('MB')), | |
261 | ]) | |
262 | def test_parse_suffix(self, test_input, expected): | |
263 | assert drive_selection.SizeMatcher('size', '10G')._parse_suffix(test_input) == expected | |
264 | ||
265 | @pytest.mark.parametrize("test_input,expected", [ | |
266 | ("G", 'GB'), | |
267 | ("GB", 'GB'), | |
268 | ("TB", 'TB'), | |
269 | ("T", 'TB'), | |
270 | ("MB", 'MB'), | |
271 | ("M", 'MB'), | |
272 | ]) | |
273 | def test_normalize_suffix(self, test_input, expected): | |
274 | ||
275 | assert drive_selection.SizeMatcher('10G', 'size')._normalize_suffix(test_input) == expected | |
276 | ||
277 | def test_normalize_suffix_raises(self): | |
278 | ||
20effc67 | 279 | with pytest.raises(_MatchInvalid): |
9f95a23c TL |
280 | drive_selection.SizeMatcher('10P', 'size')._normalize_suffix("P") |
281 | pytest.fail("Unit 'P' not supported") | |
282 | ||
283 | ||
284 | class TestDriveGroup(object): | |
285 | @pytest.fixture(scope='class') | |
286 | def test_fix(self, empty=None): | |
287 | def make_sample_data(empty=empty, | |
288 | data_limit=0, | |
289 | wal_limit=0, | |
290 | db_limit=0, | |
291 | osds_per_device='', | |
292 | disk_format='bluestore'): | |
293 | raw_sample_bluestore = { | |
294 | 'service_type': 'osd', | |
f91f0fd5 | 295 | 'service_id': 'foo', |
9f95a23c TL |
296 | 'placement': {'host_pattern': 'data*'}, |
297 | 'data_devices': { | |
298 | 'size': '30G:50G', | |
299 | 'model': '42-RGB', | |
300 | 'vendor': 'samsung', | |
301 | 'limit': data_limit | |
302 | }, | |
303 | 'wal_devices': { | |
304 | 'model': 'fast', | |
305 | 'limit': wal_limit | |
306 | }, | |
307 | 'db_devices': { | |
308 | 'size': ':20G', | |
309 | 'limit': db_limit | |
310 | }, | |
311 | 'db_slots': 5, | |
312 | 'wal_slots': 5, | |
313 | 'block_wal_size': '5G', | |
314 | 'block_db_size': '10G', | |
315 | 'objectstore': disk_format, | |
316 | 'osds_per_device': osds_per_device, | |
317 | 'encrypted': True, | |
318 | } | |
319 | raw_sample_filestore = { | |
320 | 'service_type': 'osd', | |
f91f0fd5 | 321 | 'service_id': 'foo', |
9f95a23c TL |
322 | 'placement': {'host_pattern': 'data*'}, |
323 | 'objectstore': 'filestore', | |
324 | 'data_devices': { | |
325 | 'size': '30G:50G', | |
326 | 'model': 'foo', | |
327 | 'vendor': '1x', | |
328 | 'limit': data_limit | |
329 | }, | |
330 | 'journal_devices': { | |
331 | 'size': ':20G' | |
332 | }, | |
333 | 'journal_size': '5G', | |
334 | 'osds_per_device': osds_per_device, | |
335 | 'encrypted': True, | |
336 | } | |
337 | if disk_format == 'filestore': | |
338 | raw_sample = raw_sample_filestore | |
339 | else: | |
340 | raw_sample = raw_sample_bluestore | |
341 | ||
342 | if empty: | |
343 | raw_sample = { | |
344 | 'service_type': 'osd', | |
f91f0fd5 | 345 | 'service_id': 'foo', |
f6b5b4d7 TL |
346 | 'placement': {'host_pattern': 'data*'}, |
347 | 'data_devices': { | |
348 | 'all': True | |
349 | }, | |
9f95a23c TL |
350 | } |
351 | ||
352 | dgo = DriveGroupSpec.from_json(raw_sample) | |
353 | return dgo | |
354 | ||
355 | return make_sample_data | |
356 | ||
357 | def test_encryption_prop(self, test_fix): | |
358 | test_fix = test_fix() | |
359 | assert test_fix.encrypted is True | |
360 | ||
361 | def test_encryption_prop_empty(self, test_fix): | |
362 | test_fix = test_fix(empty=True) | |
363 | assert test_fix.encrypted is False | |
364 | ||
365 | def test_db_slots_prop(self, test_fix): | |
366 | test_fix = test_fix() | |
367 | assert test_fix.db_slots == 5 | |
368 | ||
369 | def test_db_slots_prop_empty(self, test_fix): | |
370 | test_fix = test_fix(empty=True) | |
371 | assert test_fix.db_slots is None | |
372 | ||
373 | def test_wal_slots_prop(self, test_fix): | |
374 | test_fix = test_fix() | |
375 | assert test_fix.wal_slots == 5 | |
376 | ||
377 | def test_wal_slots_prop_empty(self, test_fix): | |
378 | test_fix = test_fix(empty=True) | |
379 | assert test_fix.wal_slots is None | |
380 | ||
381 | def test_block_wal_size_prop(self, test_fix): | |
382 | test_fix = test_fix() | |
f91f0fd5 | 383 | assert test_fix.block_wal_size == '5G' |
9f95a23c TL |
384 | |
385 | def test_block_wal_size_prop_empty(self, test_fix): | |
386 | test_fix = test_fix(empty=True) | |
387 | assert test_fix.block_wal_size is None | |
388 | ||
389 | def test_block_db_size_prop(self, test_fix): | |
390 | test_fix = test_fix() | |
f91f0fd5 | 391 | assert test_fix.block_db_size == '10G' |
9f95a23c TL |
392 | |
393 | def test_block_db_size_prop_empty(self, test_fix): | |
394 | test_fix = test_fix(empty=True) | |
395 | assert test_fix.block_db_size is None | |
396 | ||
397 | def test_data_devices_prop(self, test_fix): | |
398 | test_fix = test_fix() | |
399 | assert test_fix.data_devices == DeviceSelection( | |
400 | model='42-RGB', | |
401 | size='30G:50G', | |
402 | vendor='samsung', | |
403 | limit=0, | |
404 | ) | |
405 | ||
406 | def test_data_devices_prop_empty(self, test_fix): | |
407 | test_fix = test_fix(empty=True) | |
f6b5b4d7 | 408 | assert test_fix.db_devices is None |
9f95a23c TL |
409 | |
410 | def test_db_devices_prop(self, test_fix): | |
411 | test_fix = test_fix() | |
412 | assert test_fix.db_devices == DeviceSelection( | |
413 | size=':20G', | |
414 | limit=0, | |
415 | ) | |
416 | ||
417 | def test_db_devices_prop_empty(self, test_fix): | |
418 | test_fix = test_fix(empty=True) | |
419 | assert test_fix.db_devices is None | |
420 | ||
421 | def test_wal_device_prop(self, test_fix): | |
422 | test_fix = test_fix() | |
423 | assert test_fix.wal_devices == DeviceSelection( | |
424 | model='fast', | |
425 | limit=0, | |
426 | ) | |
427 | ||
9f95a23c TL |
428 | def test_wal_device_prop_empty(self, test_fix): |
429 | test_fix = test_fix(empty=True) | |
430 | assert test_fix.wal_devices is None | |
431 | ||
9f95a23c TL |
432 | def test_bluestore_format_prop(self, test_fix): |
433 | test_fix = test_fix(disk_format='bluestore') | |
434 | assert test_fix.objectstore == 'bluestore' | |
435 | ||
436 | def test_default_format_prop(self, test_fix): | |
437 | test_fix = test_fix(empty=True) | |
438 | assert test_fix.objectstore == 'bluestore' | |
439 | ||
9f95a23c TL |
440 | def test_osds_per_device(self, test_fix): |
441 | test_fix = test_fix(osds_per_device='3') | |
442 | assert test_fix.osds_per_device == '3' | |
443 | ||
444 | def test_osds_per_device_default(self, test_fix): | |
445 | test_fix = test_fix() | |
446 | assert test_fix.osds_per_device == '' | |
447 | ||
448 | def test_journal_size_empty(self, test_fix): | |
449 | test_fix = test_fix(empty=True) | |
450 | assert test_fix.journal_size is None | |
451 | ||
452 | @pytest.fixture | |
453 | def inventory(self, available=True): | |
454 | def make_sample_data(available=available, | |
455 | data_devices=10, | |
456 | wal_devices=0, | |
457 | db_devices=2, | |
458 | human_readable_size_data='50.00 GB', | |
459 | human_readable_size_wal='20.00 GB', | |
460 | size=5368709121, | |
461 | human_readable_size_db='20.00 GB'): | |
462 | factory = InventoryFactory() | |
463 | inventory_sample = [] | |
464 | data_disks = factory.produce( | |
465 | pieces=data_devices, | |
466 | available=available, | |
467 | size=size, | |
468 | human_readable_size=human_readable_size_data) | |
469 | wal_disks = factory.produce( | |
470 | pieces=wal_devices, | |
471 | human_readable_size=human_readable_size_wal, | |
472 | rotational='0', | |
473 | model='ssd_type_model', | |
474 | size=size, | |
475 | available=available) | |
476 | db_disks = factory.produce( | |
477 | pieces=db_devices, | |
478 | human_readable_size=human_readable_size_db, | |
479 | rotational='0', | |
480 | size=size, | |
481 | model='ssd_type_model', | |
482 | available=available) | |
483 | inventory_sample.extend(data_disks) | |
484 | inventory_sample.extend(wal_disks) | |
485 | inventory_sample.extend(db_disks) | |
486 | ||
487 | return Devices(devices=inventory_sample) | |
488 | ||
489 | return make_sample_data | |
490 | ||
491 | ||
492 | class TestDriveSelection(object): | |
493 | ||
494 | testdata = [ | |
495 | ( | |
f91f0fd5 TL |
496 | DriveGroupSpec( |
497 | placement=PlacementSpec(host_pattern='*'), | |
498 | service_id='foobar', | |
499 | data_devices=DeviceSelection(all=True)), | |
9f95a23c TL |
500 | _mk_inventory(_mk_device() * 5), |
501 | ['/dev/sda', '/dev/sdb', '/dev/sdc', '/dev/sdd', '/dev/sde'], [] | |
502 | ), | |
503 | ( | |
504 | DriveGroupSpec( | |
505 | placement=PlacementSpec(host_pattern='*'), | |
f91f0fd5 | 506 | service_id='foobar', |
9f95a23c TL |
507 | data_devices=DeviceSelection(all=True, limit=3), |
508 | db_devices=DeviceSelection(all=True) | |
509 | ), | |
510 | _mk_inventory(_mk_device() * 5), | |
511 | ['/dev/sda', '/dev/sdb', '/dev/sdc'], ['/dev/sdd', '/dev/sde'] | |
512 | ), | |
513 | ( | |
514 | DriveGroupSpec( | |
515 | placement=PlacementSpec(host_pattern='*'), | |
f91f0fd5 | 516 | service_id='foobar', |
9f95a23c TL |
517 | data_devices=DeviceSelection(rotational=True), |
518 | db_devices=DeviceSelection(rotational=False) | |
519 | ), | |
520 | _mk_inventory(_mk_device(rotational=False) + _mk_device(rotational=True)), | |
521 | ['/dev/sdb'], ['/dev/sda'] | |
522 | ), | |
523 | ( | |
524 | DriveGroupSpec( | |
525 | placement=PlacementSpec(host_pattern='*'), | |
f91f0fd5 | 526 | service_id='foobar', |
9f95a23c TL |
527 | data_devices=DeviceSelection(rotational=True), |
528 | db_devices=DeviceSelection(rotational=False) | |
529 | ), | |
530 | _mk_inventory(_mk_device(rotational=True)*2 + _mk_device(rotational=False)), | |
531 | ['/dev/sda', '/dev/sdb'], ['/dev/sdc'] | |
532 | ), | |
533 | ( | |
534 | DriveGroupSpec( | |
535 | placement=PlacementSpec(host_pattern='*'), | |
f91f0fd5 | 536 | service_id='foobar', |
9f95a23c TL |
537 | data_devices=DeviceSelection(rotational=True), |
538 | db_devices=DeviceSelection(rotational=False) | |
539 | ), | |
540 | _mk_inventory(_mk_device(rotational=True)*2), | |
541 | ['/dev/sda', '/dev/sdb'], [] | |
542 | ), | |
543 | ] | |
544 | ||
545 | @pytest.mark.parametrize("spec,inventory,expected_data,expected_db", testdata) | |
546 | def test_disk_selection(self, spec, inventory, expected_data, expected_db): | |
547 | sel = drive_selection.DriveSelection(spec, inventory) | |
548 | assert [d.path for d in sel.data_devices()] == expected_data | |
549 | assert [d.path for d in sel.db_devices()] == expected_db | |
20effc67 TL |
550 | |
551 | def test_disk_selection_raise(self): | |
552 | spec = DriveGroupSpec( | |
553 | placement=PlacementSpec(host_pattern='*'), | |
554 | service_id='foobar', | |
555 | data_devices=DeviceSelection(size='wrong'), | |
556 | ) | |
557 | inventory = _mk_inventory(_mk_device(rotational=True)*2) | |
558 | m = 'Failed to validate OSD spec "foobar.data_devices": No filters applied' | |
559 | with pytest.raises(DriveGroupValidationError, match=m): | |
560 | drive_selection.DriveSelection(spec, inventory) |