]> git.proxmox.com Git - ceph.git/blame - ceph/src/python-common/ceph/tests/test_drive_group.py
import ceph quincy 17.2.6
[ceph.git] / ceph / src / python-common / ceph / tests / test_drive_group.py
CommitLineData
9f95a23c 1# flake8: noqa
f67539c2
TL
2import re
3
9f95a23c 4import pytest
1911f103 5import yaml
9f95a23c
TL
6
7from ceph.deployment import drive_selection, translate
f67539c2 8from ceph.deployment.hostspec import HostSpec, SpecValidationError
9f95a23c 9from ceph.deployment.inventory import Device
f67539c2 10from ceph.deployment.service_spec import PlacementSpec
9f95a23c
TL
11from ceph.tests.utils import _mk_inventory, _mk_device
12from ceph.deployment.drive_group import DriveGroupSpec, DeviceSelection, \
13 DriveGroupValidationError
14
15@pytest.mark.parametrize("test_input",
16[
20effc67
TL
17 ( # new style json
18 """service_type: osd
19service_id: testing_drivegroup
20placement:
21 host_pattern: hostname
39ae355f 22crush_device_class: ssd
20effc67
TL
23data_devices:
24 paths:
39ae355f 25 - /dev/sda
20effc67
TL
26"""
27 ),
9f95a23c 28 (
20effc67
TL
29 """service_type: osd
30service_id: testing_drivegroup
31placement:
32 host_pattern: hostname
33data_devices:
34 paths:
39ae355f
TL
35 - path: /dev/sda
36 crush_device_class: ssd"""
9f95a23c
TL
37 ),
38])
39def test_DriveGroup(test_input):
39ae355f 40
20effc67 41 dg = DriveGroupSpec.from_json(yaml.safe_load(test_input))
9f95a23c
TL
42 assert dg.service_id == 'testing_drivegroup'
43 assert all([isinstance(x, Device) for x in dg.data_devices.paths])
39ae355f
TL
44 if isinstance(dg.data_devices.paths[0].path, str):
45 assert dg.data_devices.paths[0].path == '/dev/sda'
46
47
9f95a23c 48
f67539c2 49@pytest.mark.parametrize("match,test_input",
1911f103
TL
50[
51 (
f67539c2
TL
52 re.escape('Service Spec is not an (JSON or YAML) object. got "None"'),
53 ''
54 ),
55 (
20effc67
TL
56 'Failed to validate OSD spec "<unnamed>": `placement` required',
57 """data_devices:
58 all: True
59"""
1911f103
TL
60 ),
61 (
20effc67 62 'Failed to validate OSD spec "mydg.data_devices": device selection cannot be empty', """
1911f103
TL
63service_type: osd
64service_id: mydg
65placement:
66 host_pattern: '*'
67data_devices:
68 limit: 1
f67539c2
TL
69"""
70 ),
71 (
20effc67 72 'Failed to validate OSD spec "mydg": filter_logic must be either <AND> or <OR>', """
f6b5b4d7
TL
73service_type: osd
74service_id: mydg
75placement:
76 host_pattern: '*'
77data_devices:
78 all: True
79filter_logic: XOR
f67539c2
TL
80"""
81 ),
82 (
20effc67 83 'Failed to validate OSD spec "mydg": `data_devices` element is required.', """
f67539c2
TL
84service_type: osd
85service_id: mydg
86placement:
87 host_pattern: '*'
88spec:
89 db_devices:
90 model: model
20effc67
TL
91"""
92 ),
93 (
94 'Failed to validate OSD spec "mydg.db_devices": Filtering for `unknown_key` is not supported', """
95service_type: osd
96service_id: mydg
97placement:
98 host_pattern: '*'
99spec:
100 db_devices:
101 unknown_key: 1
102"""
103 ),
104 (
105 'Failed to validate OSD spec "mydg": Feature `unknown_key` is not supported', """
106service_type: osd
107service_id: mydg
108placement:
109 host_pattern: '*'
110spec:
111 db_devices:
112 all: true
113 unknown_key: 1
f67539c2
TL
114"""
115 ),
1911f103 116])
f67539c2
TL
117def test_DriveGroup_fail(match, test_input):
118 with pytest.raises(SpecValidationError, match=match):
119 osd_spec = DriveGroupSpec.from_json(yaml.safe_load(test_input))
120 osd_spec.validate()
9f95a23c
TL
121
122
123def test_drivegroup_pattern():
f91f0fd5
TL
124 dg = DriveGroupSpec(
125 PlacementSpec(host_pattern='node[1-3]'),
126 service_id='foobar',
127 data_devices=DeviceSelection(all=True))
f6b5b4d7 128 assert dg.placement.filter_matching_hostspecs([HostSpec('node{}'.format(i)) for i in range(10)]) == ['node1', 'node2', 'node3']
9f95a23c
TL
129
130
131def test_drive_selection():
132 devs = DeviceSelection(paths=['/dev/sda'])
f91f0fd5
TL
133 spec = DriveGroupSpec(
134 PlacementSpec('node_name'),
135 service_id='foobar',
136 data_devices=devs)
9f95a23c
TL
137 assert all([isinstance(x, Device) for x in spec.data_devices.paths])
138 assert spec.data_devices.paths[0].path == '/dev/sda'
139
140 with pytest.raises(DriveGroupValidationError, match='exclusive'):
20effc67
TL
141 ds = DeviceSelection(paths=['/dev/sda'], rotational=False)
142 ds.validate('')
9f95a23c
TL
143
144
145def test_ceph_volume_command_0():
146 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 147 service_id='foobar',
9f95a23c
TL
148 data_devices=DeviceSelection(all=True)
149 )
f91f0fd5 150 spec.validate()
9f95a23c
TL
151 inventory = _mk_inventory(_mk_device()*2)
152 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
153 cmds = translate.to_ceph_volume(sel, []).run()
154 assert all(cmd == 'lvm batch --no-auto /dev/sda /dev/sdb --yes --no-systemd' for cmd in cmds), f'Expected {cmd} in {cmds}'
9f95a23c
TL
155
156
157def test_ceph_volume_command_1():
158 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 159 service_id='foobar',
9f95a23c
TL
160 data_devices=DeviceSelection(rotational=True),
161 db_devices=DeviceSelection(rotational=False)
162 )
f91f0fd5 163 spec.validate()
9f95a23c
TL
164 inventory = _mk_inventory(_mk_device(rotational=True)*2 + _mk_device(rotational=False)*2)
165 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
166 cmds = translate.to_ceph_volume(sel, []).run()
167 assert all(cmd == ('lvm batch --no-auto /dev/sda /dev/sdb '
168 '--db-devices /dev/sdc /dev/sdd --yes --no-systemd') for cmd in cmds), f'Expected {cmd} in {cmds}'
9f95a23c
TL
169
170
171def test_ceph_volume_command_2():
172 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 173 service_id='foobar',
9f95a23c
TL
174 data_devices=DeviceSelection(size='200GB:350GB', rotational=True),
175 db_devices=DeviceSelection(size='200GB:350GB', rotational=False),
176 wal_devices=DeviceSelection(size='10G')
177 )
f91f0fd5 178 spec.validate()
9f95a23c
TL
179 inventory = _mk_inventory(_mk_device(rotational=True, size="300.00 GB")*2 +
180 _mk_device(rotational=False, size="300.00 GB")*2 +
181 _mk_device(size="10.0 GB", rotational=False)*2
182 )
183 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
184 cmds = translate.to_ceph_volume(sel, []).run()
185 assert all(cmd == ('lvm batch --no-auto /dev/sda /dev/sdb '
9f95a23c 186 '--db-devices /dev/sdc /dev/sdd --wal-devices /dev/sde /dev/sdf '
33c7a0ef 187 '--yes --no-systemd') for cmd in cmds), f'Expected {cmd} in {cmds}'
9f95a23c
TL
188
189
190def test_ceph_volume_command_3():
191 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 192 service_id='foobar',
9f95a23c
TL
193 data_devices=DeviceSelection(size='200GB:350GB', rotational=True),
194 db_devices=DeviceSelection(size='200GB:350GB', rotational=False),
195 wal_devices=DeviceSelection(size='10G'),
196 encrypted=True
197 )
f91f0fd5 198 spec.validate()
9f95a23c
TL
199 inventory = _mk_inventory(_mk_device(rotational=True, size="300.00 GB")*2 +
200 _mk_device(rotational=False, size="300.00 GB")*2 +
201 _mk_device(size="10.0 GB", rotational=False)*2
202 )
203 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
204 cmds = translate.to_ceph_volume(sel, []).run()
205 assert all(cmd == ('lvm batch --no-auto /dev/sda /dev/sdb '
9f95a23c
TL
206 '--db-devices /dev/sdc /dev/sdd '
207 '--wal-devices /dev/sde /dev/sdf --dmcrypt '
33c7a0ef 208 '--yes --no-systemd') for cmd in cmds), f'Expected {cmd} in {cmds}'
9f95a23c
TL
209
210
211def test_ceph_volume_command_4():
212 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 213 service_id='foobar',
9f95a23c
TL
214 data_devices=DeviceSelection(size='200GB:350GB', rotational=True),
215 db_devices=DeviceSelection(size='200GB:350GB', rotational=False),
216 wal_devices=DeviceSelection(size='10G'),
217 block_db_size='500M',
218 block_wal_size='500M',
219 osds_per_device=3,
220 encrypted=True
221 )
f91f0fd5 222 spec.validate()
9f95a23c
TL
223 inventory = _mk_inventory(_mk_device(rotational=True, size="300.00 GB")*2 +
224 _mk_device(rotational=False, size="300.00 GB")*2 +
225 _mk_device(size="10.0 GB", rotational=False)*2
226 )
227 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
228 cmds = translate.to_ceph_volume(sel, []).run()
229 assert all(cmd == ('lvm batch --no-auto /dev/sda /dev/sdb '
9f95a23c
TL
230 '--db-devices /dev/sdc /dev/sdd --wal-devices /dev/sde /dev/sdf '
231 '--block-wal-size 500M --block-db-size 500M --dmcrypt '
33c7a0ef 232 '--osds-per-device 3 --yes --no-systemd') for cmd in cmds), f'Expected {cmd} in {cmds}'
9f95a23c
TL
233
234
235def test_ceph_volume_command_5():
236 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 237 service_id='foobar',
9f95a23c
TL
238 data_devices=DeviceSelection(rotational=True),
239 objectstore='filestore'
240 )
f91f0fd5
TL
241 with pytest.raises(DriveGroupValidationError):
242 spec.validate()
9f95a23c
TL
243 inventory = _mk_inventory(_mk_device(rotational=True)*2)
244 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
245 cmds = translate.to_ceph_volume(sel, []).run()
246 assert all(cmd == 'lvm batch --no-auto /dev/sda /dev/sdb --filestore --yes --no-systemd' for cmd in cmds), f'Expected {cmd} in {cmds}'
9f95a23c
TL
247
248
249def test_ceph_volume_command_6():
250 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 251 service_id='foobar',
9f95a23c
TL
252 data_devices=DeviceSelection(rotational=False),
253 journal_devices=DeviceSelection(rotational=True),
254 journal_size='500M',
255 objectstore='filestore'
256 )
f91f0fd5
TL
257 with pytest.raises(DriveGroupValidationError):
258 spec.validate()
9f95a23c
TL
259 inventory = _mk_inventory(_mk_device(rotational=True)*2 + _mk_device(rotational=False)*2)
260 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
261 cmds = translate.to_ceph_volume(sel, []).run()
262 assert all(cmd == ('lvm batch --no-auto /dev/sdc /dev/sdd '
9f95a23c 263 '--journal-size 500M --journal-devices /dev/sda /dev/sdb '
33c7a0ef 264 '--filestore --yes --no-systemd') for cmd in cmds), f'Expected {cmd} in {cmds}'
1911f103
TL
265
266
267def test_ceph_volume_command_7():
268 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 269 service_id='foobar',
1911f103
TL
270 data_devices=DeviceSelection(all=True),
271 osd_id_claims={'host1': ['0', '1']}
272 )
f91f0fd5 273 spec.validate()
1911f103
TL
274 inventory = _mk_inventory(_mk_device(rotational=True)*2)
275 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
276 cmds = translate.to_ceph_volume(sel, ['0', '1']).run()
277 assert all(cmd == 'lvm batch --no-auto /dev/sda /dev/sdb --osd-ids 0 1 --yes --no-systemd' for cmd in cmds), f'Expected {cmd} in {cmds}'
f6b5b4d7
TL
278
279
280def test_ceph_volume_command_8():
281 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
f91f0fd5 282 service_id='foobar',
f6b5b4d7
TL
283 data_devices=DeviceSelection(rotational=True, model='INTEL SSDS'),
284 db_devices=DeviceSelection(model='INTEL SSDP'),
285 filter_logic='OR',
286 osd_id_claims={}
287 )
f91f0fd5 288 spec.validate()
f6b5b4d7
TL
289 inventory = _mk_inventory(_mk_device(rotational=True, size='1.82 TB', model='ST2000DM001-1ER1') + # data
290 _mk_device(rotational=False, size="223.0 GB", model='INTEL SSDSC2KG24') + # data
291 _mk_device(rotational=False, size="349.0 GB", model='INTEL SSDPED1K375GA') # wal/db
292 )
293 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
294 cmds = translate.to_ceph_volume(sel, []).run()
295 assert all(cmd == 'lvm batch --no-auto /dev/sda /dev/sdb --db-devices /dev/sdc --yes --no-systemd' for cmd in cmds), f'Expected {cmd} in {cmds}'
20effc67
TL
296
297
298def test_ceph_volume_command_9():
299 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
300 service_id='foobar',
301 data_devices=DeviceSelection(all=True),
302 data_allocate_fraction=0.8
303 )
304 spec.validate()
305 inventory = _mk_inventory(_mk_device()*2)
306 sel = drive_selection.DriveSelection(spec, inventory)
33c7a0ef
TL
307 cmds = translate.to_ceph_volume(sel, []).run()
308 assert all(cmd == 'lvm batch --no-auto /dev/sda /dev/sdb --data-allocate-fraction 0.8 --yes --no-systemd' for cmd in cmds), f'Expected {cmd} in {cmds}'
309
39ae355f
TL
310
311@pytest.mark.parametrize("test_input_base",
312[
313 (
314 """service_type: osd
315service_id: testing_drivegroup
316placement:
317 host_pattern: hostname
318crush_device_class: ssd
319data_devices:
320 paths:
321 - /dev/sda
322"""
323 ),
324 ])
325def test_ceph_volume_command_10(test_input_base):
326 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input_base))
327 spec.validate()
328 drive = drive_selection.DriveSelection(spec, spec.data_devices.paths)
329 cmds = translate.to_ceph_volume(drive, []).run()
330
331 assert all(cmd == 'lvm batch --no-auto /dev/sda --crush-device-class ssd --yes --no-systemd' for cmd in cmds), f'Expected {cmd} in {cmds}'
332
333
334@pytest.mark.parametrize("test_input1",
335[
336 (
337 """service_type: osd
338service_id: testing_drivegroup
339placement:
340 host_pattern: hostname
341crush_device_class: ssd
342data_devices:
343 paths:
344 - path: /dev/sda
345 crush_device_class: hdd
346 - path: /dev/sdb
347 crush_device_class: hdd
348"""
349 ),
350 ])
351def test_ceph_volume_command_11(test_input1):
352 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input1))
353 spec.validate()
354 drive = drive_selection.DriveSelection(spec, spec.data_devices.paths)
355 cmds = translate.to_ceph_volume(drive, []).run()
356
357 assert all(cmd == 'lvm batch --no-auto /dev/sda /dev/sdb --crush-device-class hdd --yes --no-systemd' for cmd in cmds), f'Expected {cmd} in {cmds}'
358
359
360@pytest.mark.parametrize("test_input2",
361[
362 (
363 """service_type: osd
364service_id: testing_drivegroup
365placement:
366 host_pattern: hostname
367crush_device_class: ssd
368data_devices:
369 paths:
370 - path: /dev/sda
371 crush_device_class: hdd
372 - path: /dev/sdb
373"""
374 ),
375 ])
376def test_ceph_volume_command_12(test_input2):
377
378 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input2))
379 spec.validate()
380 drive = drive_selection.DriveSelection(spec, spec.data_devices.paths)
381 cmds = translate.to_ceph_volume(drive, []).run()
382
383 assert (cmds[0] == 'lvm batch --no-auto /dev/sdb --crush-device-class ssd --yes --no-systemd') # noqa E501
384 assert (cmds[1] == 'lvm batch --no-auto /dev/sda --crush-device-class hdd --yes --no-systemd') # noqa E501
385
386
387@pytest.mark.parametrize("test_input3",
388[
389 (
390 """service_type: osd
391service_id: testing_drivegroup
392placement:
393 host_pattern: hostname
394data_devices:
395 paths:
396 - path: /dev/sda
397 crush_device_class: hdd
398 - path: /dev/sdb
399"""
400 ),
401 ])
402def test_ceph_volume_command_13(test_input3):
403
404 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input3))
405 spec.validate()
406 drive = drive_selection.DriveSelection(spec, spec.data_devices.paths)
407 cmds = translate.to_ceph_volume(drive, []).run()
408
409 assert (cmds[0] == 'lvm batch --no-auto /dev/sdb --yes --no-systemd') # noqa E501
410 assert (cmds[1] == 'lvm batch --no-auto /dev/sda --crush-device-class hdd --yes --no-systemd') # noqa E501
411
412
413@pytest.mark.parametrize("test_input4",
414[
415 (
416 """service_type: osd
417service_id: testing_drivegroup
418placement:
419 host_pattern: hostname
420data_devices:
421 paths:
422 - crush_device_class: hdd
423"""
424 ),
425 ])
426def test_ceph_volume_command_14(test_input4):
427
428 with pytest.raises(DriveGroupValidationError, match='Device path'):
429 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input4))
430 spec.validate()
431
432
33c7a0ef
TL
433def test_raw_ceph_volume_command_0():
434 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
435 service_id='foobar',
436 data_devices=DeviceSelection(rotational=True),
437 db_devices=DeviceSelection(rotational=False),
438 method='raw',
439 )
440 spec.validate()
441 inventory = _mk_inventory(_mk_device(rotational=True) + # data
442 _mk_device(rotational=True) + # data
443 _mk_device(rotational=False) + # db
444 _mk_device(rotational=False) # db
445 )
446 exp_cmds = ['raw prepare --bluestore --data /dev/sda --block.db /dev/sdc', 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sdd']
447 sel = drive_selection.DriveSelection(spec, inventory)
448 cmds = translate.to_ceph_volume(sel, []).run()
449 assert all(cmd in exp_cmds for cmd in cmds), f'Expected {exp_cmds} to match {cmds}'
450
451def test_raw_ceph_volume_command_1():
452 spec = DriveGroupSpec(placement=PlacementSpec(host_pattern='*'),
453 service_id='foobar',
454 data_devices=DeviceSelection(rotational=True),
455 db_devices=DeviceSelection(rotational=False),
456 method='raw',
457 )
458 spec.validate()
459 inventory = _mk_inventory(_mk_device(rotational=True) + # data
460 _mk_device(rotational=True) + # data
461 _mk_device(rotational=False) # db
462 )
463 sel = drive_selection.DriveSelection(spec, inventory)
464 with pytest.raises(ValueError):
465 cmds = translate.to_ceph_volume(sel, []).run()
39ae355f
TL
466
467@pytest.mark.parametrize("test_input5",
468[
469 (
470 """service_type: osd
471service_id: testing_drivegroup
472placement:
473 host_pattern: hostname
474method: raw
475data_devices:
476 paths:
477 - path: /dev/sda
478 crush_device_class: hdd
479 - path: /dev/sdb
480 crush_device_class: hdd
481 - path: /dev/sdc
482 crush_device_class: hdd
483db_devices:
484 paths:
485 - /dev/sdd
486 - /dev/sde
487 - /dev/sdf
488
489"""
490 ),
491 ])
492def test_raw_ceph_volume_command_2(test_input5):
493
494 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input5))
495 spec.validate()
496 drive = drive_selection.DriveSelection(spec, spec.data_devices.paths)
497 cmds = translate.to_ceph_volume(drive, []).run()
498
499 assert cmds[0] == 'raw prepare --bluestore --data /dev/sda --block.db /dev/sdd --crush-device-class hdd'
500 assert cmds[1] == 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sde --crush-device-class hdd'
501 assert cmds[2] == 'raw prepare --bluestore --data /dev/sdc --block.db /dev/sdf --crush-device-class hdd'
502
503
504@pytest.mark.parametrize("test_input6",
505[
506 (
507 """service_type: osd
508service_id: testing_drivegroup
509placement:
510 host_pattern: hostname
511method: raw
512data_devices:
513 paths:
514 - path: /dev/sda
515 crush_device_class: hdd
516 - path: /dev/sdb
517 crush_device_class: hdd
518 - path: /dev/sdc
519 crush_device_class: ssd
520db_devices:
521 paths:
522 - /dev/sdd
523 - /dev/sde
524 - /dev/sdf
525
526"""
527 ),
528 ])
529def test_raw_ceph_volume_command_3(test_input6):
530
531 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input6))
532 spec.validate()
533 drive = drive_selection.DriveSelection(spec, spec.data_devices.paths)
534 cmds = translate.to_ceph_volume(drive, []).run()
535
536 assert cmds[0] == 'raw prepare --bluestore --data /dev/sda --block.db /dev/sdd --crush-device-class hdd'
537 assert cmds[1] == 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sde --crush-device-class hdd'
538 assert cmds[2] == 'raw prepare --bluestore --data /dev/sdc --block.db /dev/sdf --crush-device-class ssd'
539
540
541@pytest.mark.parametrize("test_input7",
542[
543 (
544 """service_type: osd
545service_id: testing_drivegroup
546placement:
547 host_pattern: hostname
548method: raw
549data_devices:
550 paths:
551 - path: /dev/sda
552 crush_device_class: hdd
553 - path: /dev/sdb
554 crush_device_class: nvme
555 - path: /dev/sdc
556 crush_device_class: ssd
557db_devices:
558 paths:
559 - /dev/sdd
560 - /dev/sde
561 - /dev/sdf
562wal_devices:
563 paths:
564 - /dev/sdg
565 - /dev/sdh
566 - /dev/sdi
567
568"""
569 ),
570 ])
571def test_raw_ceph_volume_command_4(test_input7):
572
573 spec = DriveGroupSpec.from_json(yaml.safe_load(test_input7))
574 spec.validate()
575 drive = drive_selection.DriveSelection(spec, spec.data_devices.paths)
576 cmds = translate.to_ceph_volume(drive, []).run()
577
578 assert cmds[0] == 'raw prepare --bluestore --data /dev/sda --block.db /dev/sdd --block.wal /dev/sdg --crush-device-class hdd'
579 assert cmds[1] == 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sdf --block.wal /dev/sdi --crush-device-class nvme'
580 assert cmds[2] == 'raw prepare --bluestore --data /dev/sdc --block.db /dev/sde --block.wal /dev/sdh --crush-device-class ssd'