diff options
| author | Dmitry Tantsur <dtantsur@protonmail.com> | 2020-03-16 13:16:05 +0100 |
|---|---|---|
| committer | Dmitry Tantsur <dtantsur@protonmail.com> | 2020-03-17 13:03:24 +0100 |
| commit | ddbba070216233e695f90095334ab7ddaef563f2 (patch) | |
| tree | 759a41231b5685a0bd9be41567a8aa4ad1199939 /ironic_python_agent/tests | |
| parent | af5f05a0ee6125d9f3c2a541ba164f768b47d2ea (diff) | |
| download | ironic-python-agent-ddbba070216233e695f90095334ab7ddaef563f2.tar.gz | |
Allow specifying target devices for software RAID
This change adds support for the physical_disks RAID parameter in
a form of device hints (same as for root device selection).
Change-Id: I9751ab0f86ada41e3b668670dc112d58093b8099
Story: #2006369
Task: #39080
Diffstat (limited to 'ironic_python_agent/tests')
| -rw-r--r-- | ironic_python_agent/tests/unit/test_hardware.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/ironic_python_agent/tests/unit/test_hardware.py b/ironic_python_agent/tests/unit/test_hardware.py index 18407c4f..80140796 100644 --- a/ironic_python_agent/tests/unit/test_hardware.py +++ b/ironic_python_agent/tests/unit/test_hardware.py @@ -3142,6 +3142,81 @@ class TestGenericHardwareManager(base.IronicAgentTest): self.assertEqual(raid_config, result) @mock.patch.object(utils, 'execute', autospec=True) + def test_create_configuration_with_hints(self, mocked_execute): + node = self.node + raid_config = { + "logical_disks": [ + { + "size_gb": "10", + "raid_level": "1", + "controller": "software", + "physical_disks": [ + {'size': '>= 50'} + ] * 2, + }, + { + "size_gb": "MAX", + "raid_level": "0", + "controller": "software", + "physical_disks": [ + {'rotational': True} + ] * 2, + }, + ] + } + node['target_raid_config'] = raid_config + device1 = hardware.BlockDevice('/dev/sda', 'sda', 107374182400, True) + device2 = hardware.BlockDevice('/dev/sdb', 'sdb', 107374182400, True) + self.hardware.list_block_devices = mock.Mock() + self.hardware.list_block_devices.return_value = [ + device1, + hardware.BlockDevice('/dev/sdc', 'sdc', 21474836480, False), + device2, + hardware.BlockDevice('/dev/sdd', 'sdd', 21474836480, False), + ] + + mocked_execute.side_effect = [ + None, # mklabel sda + ('42', None), # sgdisk -F sda + None, # mklabel sda + ('42', None), # sgdisk -F sdb + None, None, # parted + partx sda + None, None, # parted + partx sdb + None, None, # parted + partx sda + None, None, # parted + partx sdb + None, None # mdadms + ] + + result = self.hardware.create_configuration(node, []) + + mocked_execute.assert_has_calls([ + mock.call('parted', '/dev/sda', '-s', '--', 'mklabel', + 'msdos'), + mock.call('sgdisk', '-F', '/dev/sda'), + mock.call('parted', '/dev/sdb', '-s', '--', 'mklabel', + 'msdos'), + mock.call('sgdisk', '-F', '/dev/sdb'), + mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', + 'mkpart', 'primary', '42s', '10GiB'), + mock.call('partx', '-u', '/dev/sda', check_exit_code=False), + mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', + 'mkpart', 'primary', '42s', '10GiB'), + mock.call('partx', '-u', '/dev/sdb', check_exit_code=False), + mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--', + 'mkpart', 'primary', '10GiB', '-1'), + mock.call('partx', '-u', '/dev/sda', check_exit_code=False), + mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--', + 'mkpart', 'primary', '10GiB', '-1'), + mock.call('partx', '-u', '/dev/sdb', check_exit_code=False), + mock.call('mdadm', '--create', '/dev/md0', '--force', '--run', + '--metadata=1', '--level', '1', '--raid-devices', 2, + '/dev/sda1', '/dev/sdb1'), + mock.call('mdadm', '--create', '/dev/md1', '--force', '--run', + '--metadata=1', '--level', '0', '--raid-devices', 2, + '/dev/sda2', '/dev/sdb2')]) + self.assertEqual(raid_config, result) + + @mock.patch.object(utils, 'execute', autospec=True) def test_create_configuration_invalid_raid_config(self, mocked_execute): raid_config = { "logical_disks": [ @@ -3163,6 +3238,60 @@ class TestGenericHardwareManager(base.IronicAgentTest): self.node, []) @mock.patch.object(utils, 'execute', autospec=True) + def test_create_configuration_invalid_hints(self, mocked_execute): + for hints in [ + [], + [{'size': '>= 50'}], # more than one disk required, + "size >= 50", + [{'size': '>= 50'}, "size >= 50"], + ]: + raid_config = { + "logical_disks": [ + { + "size_gb": "MAX", + "raid_level": "1", + "controller": "software", + "physical_disks": hints, + } + ] + } + self.node['target_raid_config'] = raid_config + self.assertRaises(errors.SoftwareRAIDError, + self.hardware.create_configuration, + self.node, []) + + @mock.patch.object(utils, 'execute', autospec=True) + def test_create_configuration_mismatching_hints(self, mocked_execute): + device1 = hardware.BlockDevice('/dev/sda', 'sda', 107374182400, True) + device2 = hardware.BlockDevice('/dev/sdb', 'sdb', 107374182400, True) + self.hardware.list_block_devices = mock.Mock() + self.hardware.list_block_devices.return_value = [ + device1, + hardware.BlockDevice('/dev/sdc', 'sdc', 21474836480, False), + device2, + hardware.BlockDevice('/dev/sdd', 'sdd', 21474836480, False), + ] + for hints in [ + [{'size': '>= 150'}] * 2, + [{'name': '/dev/sda'}] * 2, + ]: + raid_config = { + "logical_disks": [ + { + "size_gb": "MAX", + "raid_level": "1", + "controller": "software", + "physical_disks": hints, + } + ] + } + self.node['target_raid_config'] = raid_config + self.assertRaisesRegex(errors.SoftwareRAIDError, + 'No candidates', + self.hardware.create_configuration, + self.node, []) + + @mock.patch.object(utils, 'execute', autospec=True) def test_create_configuration_partitions_detected(self, mocked_execute): raid_config = { "logical_disks": [ |
