7 from ceph
.deployment
import drive_selection
, translate
8 from ceph
.deployment
.hostspec
import HostSpec
, SpecValidationError
9 from ceph
.deployment
.inventory
import Device
10 from ceph
.deployment
.service_spec
import PlacementSpec
11 from ceph
.tests
.utils
import _mk_inventory
, _mk_device
12 from ceph
.deployment
.drive_group
import DriveGroupSpec
, DeviceSelection
, \
13 DriveGroupValidationError
15 @pytest.mark
.parametrize("test_input",
19 service_id: testing_drivegroup
21 host_pattern: hostname
22 crush_device_class: ssd
30 service_id: testing_drivegroup
32 host_pattern: hostname
36 crush_device_class: ssd"""
40 service_id: testing_drivegroup
42 host_pattern: hostname
48 crush_device_class: hdd"""
51 def test_DriveGroup(test_input
):
53 dg
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input
))
54 assert dg
.service_id
== 'testing_drivegroup'
55 assert all([isinstance(x
, Device
) for x
in dg
.data_devices
.paths
])
56 if isinstance(dg
.data_devices
.paths
[0].path
, str):
57 assert dg
.data_devices
.paths
[0].path
== '/dev/sda'
61 @pytest.mark
.parametrize("match,test_input",
64 re
.escape('Service Spec is not an (JSON or YAML) object. got "None"'),
68 'Failed to validate OSD spec "<unnamed>": `placement` required',
74 'Failed to validate OSD spec "mydg.data_devices": device selection cannot be empty', """
84 'Failed to validate OSD spec "mydg": filter_logic must be either <AND> or <OR>', """
95 'Failed to validate OSD spec "mydg": `data_devices` element is required.', """
106 'Failed to validate OSD spec "mydg.db_devices": Filtering for `unknown_key` is not supported', """
117 'Failed to validate OSD spec "mydg": Feature `unknown_key` is not supported', """
129 def test_DriveGroup_fail(match
, test_input
):
130 with pytest
.raises(SpecValidationError
, match
=match
):
131 osd_spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input
))
135 def test_drivegroup_pattern():
137 PlacementSpec(host_pattern
='node[1-3]'),
139 data_devices
=DeviceSelection(all
=True))
140 assert dg
.placement
.filter_matching_hostspecs([HostSpec('node{}'.format(i
)) for i
in range(10)]) == ['node1', 'node2', 'node3']
143 def test_drive_selection():
144 devs
= DeviceSelection(paths
=['/dev/sda'])
145 spec
= DriveGroupSpec(
146 PlacementSpec('node_name'),
149 assert all([isinstance(x
, Device
) for x
in spec
.data_devices
.paths
])
150 assert spec
.data_devices
.paths
[0].path
== '/dev/sda'
152 with pytest
.raises(DriveGroupValidationError
, match
='exclusive'):
153 ds
= DeviceSelection(paths
=['/dev/sda'], rotational
=False)
157 def test_ceph_volume_command_0():
158 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
160 data_devices
=DeviceSelection(all
=True)
163 inventory
= _mk_inventory(_mk_device()*2)
164 sel
= drive_selection
.DriveSelection(spec
, inventory
)
165 cmds
= translate
.to_ceph_volume(sel
, []).run()
166 assert all(cmd
== 'lvm batch --no-auto /dev/sda /dev/sdb --yes --no-systemd' for cmd
in cmds
), f
'Expected {cmd} in {cmds}'
169 def test_ceph_volume_command_1():
170 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
172 data_devices
=DeviceSelection(rotational
=True),
173 db_devices
=DeviceSelection(rotational
=False)
176 inventory
= _mk_inventory(_mk_device(rotational
=True)*2 + _mk_device(rotational
=False)*2)
177 sel
= drive_selection
.DriveSelection(spec
, inventory
)
178 cmds
= translate
.to_ceph_volume(sel
, []).run()
179 assert all(cmd
== ('lvm batch --no-auto /dev/sda /dev/sdb '
180 '--db-devices /dev/sdc /dev/sdd --yes --no-systemd') for cmd
in cmds
), f
'Expected {cmd} in {cmds}'
183 def test_ceph_volume_command_2():
184 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
186 data_devices
=DeviceSelection(size
='200GB:350GB', rotational
=True),
187 db_devices
=DeviceSelection(size
='200GB:350GB', rotational
=False),
188 wal_devices
=DeviceSelection(size
='10G')
191 inventory
= _mk_inventory(_mk_device(rotational
=True, size
="300.00 GB")*2 +
192 _mk_device(rotational
=False, size
="300.00 GB")*2 +
193 _mk_device(size
="10.0 GB", rotational
=False)*2
195 sel
= drive_selection
.DriveSelection(spec
, inventory
)
196 cmds
= translate
.to_ceph_volume(sel
, []).run()
197 assert all(cmd
== ('lvm batch --no-auto /dev/sda /dev/sdb '
198 '--db-devices /dev/sdc /dev/sdd --wal-devices /dev/sde /dev/sdf '
199 '--yes --no-systemd') for cmd
in cmds
), f
'Expected {cmd} in {cmds}'
202 def test_ceph_volume_command_3():
203 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
205 data_devices
=DeviceSelection(size
='200GB:350GB', rotational
=True),
206 db_devices
=DeviceSelection(size
='200GB:350GB', rotational
=False),
207 wal_devices
=DeviceSelection(size
='10G'),
211 inventory
= _mk_inventory(_mk_device(rotational
=True, size
="300.00 GB")*2 +
212 _mk_device(rotational
=False, size
="300.00 GB")*2 +
213 _mk_device(size
="10.0 GB", rotational
=False)*2
215 sel
= drive_selection
.DriveSelection(spec
, inventory
)
216 cmds
= translate
.to_ceph_volume(sel
, []).run()
217 assert all(cmd
== ('lvm batch --no-auto /dev/sda /dev/sdb '
218 '--db-devices /dev/sdc /dev/sdd '
219 '--wal-devices /dev/sde /dev/sdf --dmcrypt '
220 '--yes --no-systemd') for cmd
in cmds
), f
'Expected {cmd} in {cmds}'
223 def test_ceph_volume_command_4():
224 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
226 data_devices
=DeviceSelection(size
='200GB:350GB', rotational
=True),
227 db_devices
=DeviceSelection(size
='200GB:350GB', rotational
=False),
228 wal_devices
=DeviceSelection(size
='10G'),
229 block_db_size
='500M',
230 block_wal_size
='500M',
235 inventory
= _mk_inventory(_mk_device(rotational
=True, size
="300.00 GB")*2 +
236 _mk_device(rotational
=False, size
="300.00 GB")*2 +
237 _mk_device(size
="10.0 GB", rotational
=False)*2
239 sel
= drive_selection
.DriveSelection(spec
, inventory
)
240 cmds
= translate
.to_ceph_volume(sel
, []).run()
241 assert all(cmd
== ('lvm batch --no-auto /dev/sda /dev/sdb '
242 '--db-devices /dev/sdc /dev/sdd --wal-devices /dev/sde /dev/sdf '
243 '--block-wal-size 500M --block-db-size 500M --dmcrypt '
244 '--osds-per-device 3 --yes --no-systemd') for cmd
in cmds
), f
'Expected {cmd} in {cmds}'
247 def test_ceph_volume_command_5():
248 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
250 data_devices
=DeviceSelection(rotational
=True),
251 objectstore
='filestore'
253 with pytest
.raises(DriveGroupValidationError
):
255 inventory
= _mk_inventory(_mk_device(rotational
=True)*2)
256 sel
= drive_selection
.DriveSelection(spec
, inventory
)
257 cmds
= translate
.to_ceph_volume(sel
, []).run()
258 assert all(cmd
== 'lvm batch --no-auto /dev/sda /dev/sdb --filestore --yes --no-systemd' for cmd
in cmds
), f
'Expected {cmd} in {cmds}'
261 def test_ceph_volume_command_6():
262 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
264 data_devices
=DeviceSelection(rotational
=False),
265 journal_devices
=DeviceSelection(rotational
=True),
267 objectstore
='filestore'
269 with pytest
.raises(DriveGroupValidationError
):
271 inventory
= _mk_inventory(_mk_device(rotational
=True)*2 + _mk_device(rotational
=False)*2)
272 sel
= drive_selection
.DriveSelection(spec
, inventory
)
273 cmds
= translate
.to_ceph_volume(sel
, []).run()
274 assert all(cmd
== ('lvm batch --no-auto /dev/sdc /dev/sdd '
275 '--journal-size 500M --journal-devices /dev/sda /dev/sdb '
276 '--filestore --yes --no-systemd') for cmd
in cmds
), f
'Expected {cmd} in {cmds}'
279 def test_ceph_volume_command_7():
280 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
282 data_devices
=DeviceSelection(all
=True),
283 osd_id_claims
={'host1': ['0', '1']}
286 inventory
= _mk_inventory(_mk_device(rotational
=True)*2)
287 sel
= drive_selection
.DriveSelection(spec
, inventory
)
288 cmds
= translate
.to_ceph_volume(sel
, ['0', '1']).run()
289 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}'
292 def test_ceph_volume_command_8():
293 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
295 data_devices
=DeviceSelection(rotational
=True, model
='INTEL SSDS'),
296 db_devices
=DeviceSelection(model
='INTEL SSDP'),
301 inventory
= _mk_inventory(_mk_device(rotational
=True, size
='1.82 TB', model
='ST2000DM001-1ER1') + # data
302 _mk_device(rotational
=False, size
="223.0 GB", model
='INTEL SSDSC2KG24') + # data
303 _mk_device(rotational
=False, size
="349.0 GB", model
='INTEL SSDPED1K375GA') # wal/db
305 sel
= drive_selection
.DriveSelection(spec
, inventory
)
306 cmds
= translate
.to_ceph_volume(sel
, []).run()
307 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}'
310 def test_ceph_volume_command_9():
311 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
313 data_devices
=DeviceSelection(all
=True),
314 data_allocate_fraction
=0.8
317 inventory
= _mk_inventory(_mk_device()*2)
318 sel
= drive_selection
.DriveSelection(spec
, inventory
)
319 cmds
= translate
.to_ceph_volume(sel
, []).run()
320 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}'
323 @pytest.mark
.parametrize("test_input_base",
327 service_id: testing_drivegroup
329 host_pattern: hostname
330 crush_device_class: ssd
337 def test_ceph_volume_command_10(test_input_base
):
338 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input_base
))
340 drive
= drive_selection
.DriveSelection(spec
, spec
.data_devices
.paths
)
341 cmds
= translate
.to_ceph_volume(drive
, []).run()
343 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}'
346 @pytest.mark
.parametrize("test_input1",
350 service_id: testing_drivegroup
352 host_pattern: hostname
353 crush_device_class: ssd
357 crush_device_class: hdd
359 crush_device_class: hdd
363 def test_ceph_volume_command_11(test_input1
):
364 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input1
))
366 drive
= drive_selection
.DriveSelection(spec
, spec
.data_devices
.paths
)
367 cmds
= translate
.to_ceph_volume(drive
, []).run()
369 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}'
372 @pytest.mark
.parametrize("test_input2",
376 service_id: testing_drivegroup
378 host_pattern: hostname
379 crush_device_class: ssd
383 crush_device_class: hdd
388 def test_ceph_volume_command_12(test_input2
):
390 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input2
))
392 drive
= drive_selection
.DriveSelection(spec
, spec
.data_devices
.paths
)
393 cmds
= translate
.to_ceph_volume(drive
, []).run()
395 assert (cmds
[0] == 'lvm batch --no-auto /dev/sdb --crush-device-class ssd --yes --no-systemd') # noqa E501
396 assert (cmds
[1] == 'lvm batch --no-auto /dev/sda --crush-device-class hdd --yes --no-systemd') # noqa E501
399 @pytest.mark
.parametrize("test_input3",
403 service_id: testing_drivegroup
405 host_pattern: hostname
409 crush_device_class: hdd
414 def test_ceph_volume_command_13(test_input3
):
416 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input3
))
418 drive
= drive_selection
.DriveSelection(spec
, spec
.data_devices
.paths
)
419 cmds
= translate
.to_ceph_volume(drive
, []).run()
421 assert (cmds
[0] == 'lvm batch --no-auto /dev/sdb --yes --no-systemd') # noqa E501
422 assert (cmds
[1] == 'lvm batch --no-auto /dev/sda --crush-device-class hdd --yes --no-systemd') # noqa E501
425 @pytest.mark
.parametrize("test_input4",
429 service_id: testing_drivegroup
431 host_pattern: hostname
434 - crush_device_class: hdd
438 def test_ceph_volume_command_14(test_input4
):
440 with pytest
.raises(DriveGroupValidationError
, match
='Device path'):
441 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input4
))
445 def test_raw_ceph_volume_command_0():
446 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
448 data_devices
=DeviceSelection(rotational
=True),
449 db_devices
=DeviceSelection(rotational
=False),
453 inventory
= _mk_inventory(_mk_device(rotational
=True) + # data
454 _mk_device(rotational
=True) + # data
455 _mk_device(rotational
=False) + # db
456 _mk_device(rotational
=False) # db
458 exp_cmds
= ['raw prepare --bluestore --data /dev/sda --block.db /dev/sdc', 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sdd']
459 sel
= drive_selection
.DriveSelection(spec
, inventory
)
460 cmds
= translate
.to_ceph_volume(sel
, []).run()
461 assert all(cmd
in exp_cmds
for cmd
in cmds
), f
'Expected {exp_cmds} to match {cmds}'
463 def test_raw_ceph_volume_command_1():
464 spec
= DriveGroupSpec(placement
=PlacementSpec(host_pattern
='*'),
466 data_devices
=DeviceSelection(rotational
=True),
467 db_devices
=DeviceSelection(rotational
=False),
471 inventory
= _mk_inventory(_mk_device(rotational
=True) + # data
472 _mk_device(rotational
=True) + # data
473 _mk_device(rotational
=False) # db
475 sel
= drive_selection
.DriveSelection(spec
, inventory
)
476 with pytest
.raises(ValueError):
477 cmds
= translate
.to_ceph_volume(sel
, []).run()
479 @pytest.mark
.parametrize("test_input5",
483 service_id: testing_drivegroup
485 host_pattern: hostname
490 crush_device_class: hdd
492 crush_device_class: hdd
494 crush_device_class: hdd
504 def test_raw_ceph_volume_command_2(test_input5
):
506 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input5
))
508 drive
= drive_selection
.DriveSelection(spec
, spec
.data_devices
.paths
)
509 cmds
= translate
.to_ceph_volume(drive
, []).run()
511 assert cmds
[0] == 'raw prepare --bluestore --data /dev/sda --block.db /dev/sdd --crush-device-class hdd'
512 assert cmds
[1] == 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sde --crush-device-class hdd'
513 assert cmds
[2] == 'raw prepare --bluestore --data /dev/sdc --block.db /dev/sdf --crush-device-class hdd'
516 @pytest.mark
.parametrize("test_input6",
520 service_id: testing_drivegroup
522 host_pattern: hostname
527 crush_device_class: hdd
529 crush_device_class: hdd
531 crush_device_class: ssd
541 def test_raw_ceph_volume_command_3(test_input6
):
543 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input6
))
545 drive
= drive_selection
.DriveSelection(spec
, spec
.data_devices
.paths
)
546 cmds
= translate
.to_ceph_volume(drive
, []).run()
548 assert cmds
[0] == 'raw prepare --bluestore --data /dev/sda --block.db /dev/sdd --crush-device-class hdd'
549 assert cmds
[1] == 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sde --crush-device-class hdd'
550 assert cmds
[2] == 'raw prepare --bluestore --data /dev/sdc --block.db /dev/sdf --crush-device-class ssd'
553 @pytest.mark
.parametrize("test_input7",
557 service_id: testing_drivegroup
559 host_pattern: hostname
564 crush_device_class: hdd
566 crush_device_class: nvme
568 crush_device_class: ssd
583 def test_raw_ceph_volume_command_4(test_input7
):
585 spec
= DriveGroupSpec
.from_json(yaml
.safe_load(test_input7
))
587 drive
= drive_selection
.DriveSelection(spec
, spec
.data_devices
.paths
)
588 cmds
= translate
.to_ceph_volume(drive
, []).run()
590 assert cmds
[0] == 'raw prepare --bluestore --data /dev/sda --block.db /dev/sdd --block.wal /dev/sdg --crush-device-class hdd'
591 assert cmds
[1] == 'raw prepare --bluestore --data /dev/sdb --block.db /dev/sdf --block.wal /dev/sdi --crush-device-class nvme'
592 assert cmds
[2] == 'raw prepare --bluestore --data /dev/sdc --block.db /dev/sde --block.wal /dev/sdh --crush-device-class ssd'