summaryrefslogtreecommitdiff
path: root/ironic_python_agent/tests
diff options
context:
space:
mode:
authorIury Gregory Melo Ferreira <imelofer@redhat.com>2019-12-02 16:56:42 +0100
committerIury Gregory Melo Ferreira <imelofer@redhat.com>2020-01-16 11:23:41 +0100
commitb6210be196fea271b2c49f89d3e1638517c1198c (patch)
tree27e8dfd35248a8ece8d7bcffdd9b12f4a03018f8 /ironic_python_agent/tests
parent1b20dd9b96c9b73e45618fc88bfddfe82652d203 (diff)
downloadironic-python-agent-b6210be196fea271b2c49f89d3e1638517c1198c.tar.gz
Avoid grub2-install when on UEFI boot mode
This patch changes the workflow for whole disk images when using uefi. If we can identify the bootloader and it's valid we can update using efibootmgr since grub2-install have problems specially on secure boot mode. We also updated the regex to search for the uefi partition on the disk, since in some cases the parted command output can be without the FS for the partition with esp Flag. Change-Id: I7167e71e5d2352a045565289b200e5530d0ba11d Story: #2006847 Task: #37435
Diffstat (limited to 'ironic_python_agent/tests')
-rw-r--r--ironic_python_agent/tests/unit/extensions/test_image.py384
-rw-r--r--ironic_python_agent/tests/unit/test_utils.py24
2 files changed, 396 insertions, 12 deletions
diff --git a/ironic_python_agent/tests/unit/extensions/test_image.py b/ironic_python_agent/tests/unit/extensions/test_image.py
index aa802275..44dce7b7 100644
--- a/ironic_python_agent/tests/unit/extensions/test_image.py
+++ b/ironic_python_agent/tests/unit/extensions/test_image.py
@@ -48,25 +48,36 @@ class TestImageExtension(base.IronicAgentTest):
@mock.patch.object(iscsi, 'clean_up', autospec=True)
@mock.patch.object(image, '_install_grub2', autospec=True)
- def test_install_bootloader_bios(self, mock_grub2, mock_iscsi_clean,
- mock_execute, mock_dispatch):
- mock_dispatch.return_value = self.fake_dev
+ def test__install_bootloader_bios(self, mock_grub2, mock_iscsi_clean,
+ mock_execute, mock_dispatch):
+ mock_dispatch.side_effect = [
+ self.fake_dev, hardware.BootInfo(current_boot_mode='bios')
+ ]
self.agent_extension.install_bootloader(root_uuid=self.fake_root_uuid)
- mock_dispatch.assert_called_once_with('get_os_install_device')
+ mock_dispatch.assert_any_call('get_os_install_device')
+ mock_dispatch.assert_any_call('get_boot_info')
+ self.assertEqual(2, mock_dispatch.call_count)
mock_grub2.assert_called_once_with(
self.fake_dev, root_uuid=self.fake_root_uuid,
efi_system_part_uuid=None, prep_boot_part_uuid=None)
mock_iscsi_clean.assert_called_once_with(self.fake_dev)
@mock.patch.object(iscsi, 'clean_up', autospec=True)
+ @mock.patch.object(image, '_manage_uefi', autospec=True)
@mock.patch.object(image, '_install_grub2', autospec=True)
- def test_install_bootloader_uefi(self, mock_grub2, mock_iscsi_clean,
- mock_execute, mock_dispatch):
- mock_dispatch.return_value = self.fake_dev
+ def test__install_bootloader_uefi(self, mock_grub2, mock_uefi,
+ mock_iscsi_clean,
+ mock_execute, mock_dispatch):
+ mock_dispatch.side_effect = [
+ self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
+ ]
+ mock_uefi.return_value = False
self.agent_extension.install_bootloader(
root_uuid=self.fake_root_uuid,
efi_system_part_uuid=self.fake_efi_system_part_uuid)
- mock_dispatch.assert_called_once_with('get_os_install_device')
+ mock_dispatch.assert_any_call('get_os_install_device')
+ mock_dispatch.assert_any_call('get_boot_info')
+ self.assertEqual(2, mock_dispatch.call_count)
mock_grub2.assert_called_once_with(
self.fake_dev,
root_uuid=self.fake_root_uuid,
@@ -74,16 +85,207 @@ class TestImageExtension(base.IronicAgentTest):
prep_boot_part_uuid=None)
mock_iscsi_clean.assert_called_once_with(self.fake_dev)
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
+ @mock.patch.object(iscsi, 'clean_up', autospec=True)
+ @mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=False)
+ @mock.patch.object(os, 'makedirs', autospec=True)
+ def test__uefi_bootloader_given_partition(
+ self, mkdir_mock, mock_utils_efi_part, mock_partition,
+ mock_efi_bl, mock_iscsi_clean, mock_execute, mock_dispatch):
+ mock_dispatch.side_effect = [
+ self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
+ ]
+ mock_partition.side_effect = [self.fake_dev, self.fake_efi_system_part]
+ mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
+ mock_utils_efi_part.return_value = '1'
+
+ mock_execute.side_effect = iter([('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', ''), ('', '')])
+
+ expected = [mock.call('efibootmgr', '--version'),
+ mock.call('mount', self.fake_efi_system_part,
+ self.fake_dir + '/boot/efi'),
+ mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', '1', '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI'),
+ mock.call('umount', self.fake_dir + '/boot/efi',
+ attempts=3, delay_on_retry=True),
+ mock.call('sync')]
+
+ self.agent_extension.install_bootloader(
+ root_uuid=self.fake_root_uuid,
+ efi_system_part_uuid=self.fake_efi_system_part_uuid)
+
+ mock_dispatch.assert_any_call('get_os_install_device')
+ mock_dispatch.assert_any_call('get_boot_info')
+ mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_execute.assert_has_calls(expected)
+ mock_utils_efi_part.assert_called_once_with(self.fake_dev)
+ self.assertEqual(6, mock_execute.call_count)
+
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
+ @mock.patch.object(iscsi, 'clean_up', autospec=True)
+ @mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
+ @mock.patch.object(os, 'makedirs', autospec=True)
+ def test__uefi_bootloader_find_partition(
+ self, mkdir_mock, mock_utils_efi_part, mock_partition,
+ mock_efi_bl, mock_iscsi_clean, mock_execute, mock_dispatch):
+ mock_dispatch.side_effect = [
+ self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
+ ]
+ mock_partition.return_value = self.fake_dev
+ mock_utils_efi_part.return_value = '1'
+ mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
+ mock_execute.side_effect = iter([('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', ''), ('', '')])
+
+ expected = [mock.call('efibootmgr', '--version'),
+ mock.call('mount', self.fake_efi_system_part,
+ self.fake_dir + '/boot/efi'),
+ mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', '1', '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI'),
+ mock.call('umount', self.fake_dir + '/boot/efi',
+ attempts=3, delay_on_retry=True),
+ mock.call('sync')]
+
+ self.agent_extension.install_bootloader(
+ root_uuid=self.fake_root_uuid,
+ efi_system_part_uuid=None)
+
+ mock_dispatch.assert_any_call('get_os_install_device')
+ mock_dispatch.assert_any_call('get_boot_info')
+ mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_execute.assert_has_calls(expected)
+ mock_utils_efi_part.assert_called_once_with(self.fake_dev)
+ self.assertEqual(6, mock_execute.call_count)
+
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
+ @mock.patch.object(iscsi, 'clean_up', autospec=True)
+ @mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
+ @mock.patch.object(os, 'makedirs', autospec=True)
+ def test__uefi_bootloader_with_entry_removal(
+ self, mkdir_mock, mock_utils_efi_part, mock_partition,
+ mock_efi_bl, mock_iscsi_clean, mock_execute, mock_dispatch):
+ mock_dispatch.side_effect = [
+ self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
+ ]
+ mock_partition.return_value = self.fake_dev
+ mock_utils_efi_part.return_value = '1'
+ mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
+ stdeer_msg = """
+efibootmgr: ** Warning ** : Boot0004 has same label ironic1\n
+efibootmgr: ** Warning ** : Boot0005 has same label ironic1\n
+"""
+ mock_execute.side_effect = iter([('', ''), ('', ''),
+ ('', ''), ('', stdeer_msg),
+ ('', ''), ('', ''),
+ ('', ''), ('', '')])
+
+ expected = [mock.call('efibootmgr', '--version'),
+ mock.call('mount', self.fake_efi_system_part,
+ self.fake_dir + '/boot/efi'),
+ mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', '1', '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI'),
+ mock.call('efibootmgr', '-b', '0004', '-B'),
+ mock.call('efibootmgr', '-b', '0005', '-B'),
+ mock.call('umount', self.fake_dir + '/boot/efi',
+ attempts=3, delay_on_retry=True),
+ mock.call('sync')]
+
+ self.agent_extension.install_bootloader(
+ root_uuid=self.fake_root_uuid,
+ efi_system_part_uuid=None)
+
+ mock_dispatch.assert_any_call('get_os_install_device')
+ mock_dispatch.assert_any_call('get_boot_info')
+ mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_execute.assert_has_calls(expected)
+ mock_utils_efi_part.assert_called_once_with(self.fake_dev)
+ self.assertEqual(8, mock_execute.call_count)
+
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
+ @mock.patch.object(iscsi, 'clean_up', autospec=True)
+ @mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
+ @mock.patch.object(os, 'makedirs', autospec=True)
+ def test__add_multi_bootloaders(
+ self, mkdir_mock, mock_utils_efi_part, mock_partition,
+ mock_efi_bl, mock_iscsi_clean, mock_execute, mock_dispatch):
+ mock_dispatch.side_effect = [
+ self.fake_dev, hardware.BootInfo(current_boot_mode='uefi')
+ ]
+ mock_partition.return_value = self.fake_dev
+ mock_utils_efi_part.return_value = '1'
+ mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI',
+ '\\WINDOWS\\system32\\winload.efi']
+
+ mock_execute.side_effect = iter([('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', '')])
+
+ expected = [mock.call('efibootmgr', '--version'),
+ mock.call('mount', self.fake_efi_system_part,
+ self.fake_dir + '/boot/efi'),
+ mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', '1', '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', '1', '-w',
+ '-L', 'ironic2', '-l',
+ '\\WINDOWS\\system32\\winload.efi'),
+ mock.call('umount', self.fake_dir + '/boot/efi',
+ attempts=3, delay_on_retry=True),
+ mock.call('sync')]
+
+ self.agent_extension.install_bootloader(
+ root_uuid=self.fake_root_uuid,
+ efi_system_part_uuid=None)
+
+ mock_dispatch.assert_any_call('get_os_install_device')
+ mock_dispatch.assert_any_call('get_boot_info')
+ mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_execute.assert_has_calls(expected)
+ mock_utils_efi_part.assert_called_once_with(self.fake_dev)
+ self.assertEqual(7, mock_execute.call_count)
+
@mock.patch.object(iscsi, 'clean_up', autospec=True)
@mock.patch.object(image, '_install_grub2', autospec=True)
- def test_install_bootloader_prep(self, mock_grub2, mock_iscsi_clean,
- mock_execute, mock_dispatch):
- mock_dispatch.return_value = self.fake_dev
+ def test__install_bootloader_prep(self, mock_grub2, mock_iscsi_clean,
+ mock_execute, mock_dispatch):
+ mock_dispatch.side_effect = [
+ self.fake_dev, hardware.BootInfo(current_boot_mode='bios')
+ ]
self.agent_extension.install_bootloader(
root_uuid=self.fake_root_uuid,
efi_system_part_uuid=None,
prep_boot_part_uuid=self.fake_prep_boot_part_uuid)
- mock_dispatch.assert_called_once_with('get_os_install_device')
+ mock_dispatch.assert_any_call('get_os_install_device')
+ mock_dispatch.assert_any_call('get_boot_info')
+ self.assertEqual(2, mock_dispatch.call_count)
mock_grub2.assert_called_once_with(
self.fake_dev,
root_uuid=self.fake_root_uuid,
@@ -190,6 +392,7 @@ class TestImageExtension(base.IronicAgentTest):
uuid=self.fake_prep_boot_part_uuid)
self.assertFalse(mock_dispatch.called)
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
@mock.patch.object(image, '_is_bootloader_loaded', lambda *_: True)
@mock.patch.object(hardware, 'is_md_device', autospec=True)
@mock.patch.object(hardware, 'md_get_raid_devices', autospec=True)
@@ -523,3 +726,160 @@ class TestImageExtension(base.IronicAgentTest):
mock_execute.return_value = (parted_output, '')
result = image._is_bootloader_loaded(self.fake_dev)
self.assertFalse(result)
+
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
+ def test__manage_uefi_no_partition(self, mock_utils_efi_part,
+ mock_get_part_uuid,
+ mock_execute, mock_dispatch):
+ mock_utils_efi_part.return_value = None
+ mock_get_part_uuid.return_value = self.fake_root_part
+ result = image._manage_uefi(self.fake_dev, self.fake_root_uuid)
+ self.assertFalse(result)
+
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
+ @mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
+ @mock.patch.object(os, 'makedirs', autospec=True)
+ def test__manage_uefi(self, mkdir_mock, mock_utils_efi_part,
+ mock_get_part_uuid, mock_efi_bl, mock_execute,
+ mock_dispatch):
+ mock_utils_efi_part.return_value = '1'
+ mock_get_part_uuid.return_value = self.fake_dev
+
+ mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
+
+ mock_execute.side_effect = iter([('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', '')])
+
+ expected = [mock.call('mount', self.fake_efi_system_part,
+ self.fake_dir + '/boot/efi'),
+ mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', '1', '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI'),
+ mock.call('umount', self.fake_dir + '/boot/efi',
+ attempts=3, delay_on_retry=True),
+ mock.call('sync')]
+
+ result = image._manage_uefi(self.fake_dev, self.fake_root_uuid)
+ self.assertTrue(result)
+ mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_execute.assert_has_calls(expected)
+ self.assertEqual(5, mock_execute.call_count)
+
+ @mock.patch.object(os.path, 'exists', lambda *_: False)
+ @mock.patch.object(image, '_get_efi_bootloaders', autospec=True)
+ @mock.patch.object(image, '_get_partition', autospec=True)
+ @mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
+ @mock.patch.object(os, 'makedirs', autospec=True)
+ def test__manage_uefi_wholedisk(
+ self, mkdir_mock, mock_utils_efi_part,
+ mock_get_part_uuid, mock_efi_bl, mock_execute,
+ mock_dispatch):
+ mock_utils_efi_part.return_value = '1'
+ mock_get_part_uuid.side_effect = Exception
+
+ mock_efi_bl.return_value = ['\\EFI\\BOOT\\BOOTX64.EFI']
+
+ mock_execute.side_effect = iter([('', ''), ('', ''),
+ ('', ''), ('', ''),
+ ('', '')])
+
+ expected = [mock.call('mount', self.fake_efi_system_part,
+ self.fake_dir + '/boot/efi'),
+ mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', '1', '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI'),
+ mock.call('umount', self.fake_dir + '/boot/efi',
+ attempts=3, delay_on_retry=True),
+ mock.call('sync')]
+
+ result = image._manage_uefi(self.fake_dev, None)
+ self.assertTrue(result)
+ mkdir_mock.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_efi_bl.assert_called_once_with(self.fake_dir + '/boot/efi')
+ mock_execute.assert_has_calls(expected)
+ self.assertEqual(5, mock_execute.call_count)
+
+ @mock.patch.object(os, 'walk', autospec=True)
+ @mock.patch.object(os, 'access', autospec=False)
+ def test__no_efi_bootloaders(self, mock_access, mock_walk, mock_execute,
+ mock_dispatch):
+ # No valid efi file.
+ mock_walk.return_value = [
+ ('/boot/efi', ['EFI'], []),
+ ('/boot/efi/EFI', ['centos', 'BOOT'], []),
+ ('/boot/efi/EFI/centos', ['fw', 'fonts'],
+ ['shimx64-centos.efi', 'BOOT.CSV', 'BOOTX64.CSV',
+ 'MokManager.efi', 'mmx64.efi', 'shim.efi', 'fwupia32.efi',
+ 'fwupx64.efi', 'shimx64.efi', 'grubenv', 'grubx64.efi',
+ 'grub.cfg']),
+ ('/boot/efi/EFI/centos/fw', [], []),
+ ('/boot/efi/EFI/centos/fonts', [], ['unicode.pf2']),
+ ('/boot/efi/EFI/BOOT', [], [])
+ ]
+
+ result = image._get_efi_bootloaders("/boot/efi")
+ self.assertEqual(result, [])
+ mock_access.assert_not_called()
+
+ @mock.patch.object(os, 'walk', autospec=True)
+ @mock.patch.object(os, 'access', autospec=True)
+ def test__get_efi_bootloaders(self, mock_access, mock_walk, mock_execute,
+ mock_dispatch):
+ mock_walk.return_value = [
+ ('/boot/efi', ['EFI'], []),
+ ('/boot/efi/EFI', ['centos', 'BOOT'], []),
+ ('/boot/efi/EFI/centos', ['fw', 'fonts'],
+ ['shimx64-centos.efi', 'BOOT.CSV', 'BOOTX64.CSV',
+ 'MokManager.efi', 'mmx64.efi', 'shim.efi', 'fwupia32.efi',
+ 'fwupx64.efi', 'shimx64.efi', 'grubenv', 'grubx64.efi',
+ 'grub.cfg']),
+ ('/boot/efi/EFI/centos/fw', [], []),
+ ('/boot/efi/EFI/centos/fonts', [], ['unicode.pf2']),
+ ('/boot/efi/EFI/BOOT', [],
+ ['BOOTX64.EFI', 'fallback.efi', 'fbx64.efi'])
+ ]
+ mock_access.return_value = True
+ result = image._get_efi_bootloaders("/boot/efi")
+ self.assertEqual(result[0], '\\EFI\\BOOT\\BOOTX64.EFI')
+
+ @mock.patch.object(os, 'walk', autospec=True)
+ @mock.patch.object(os, 'access', autospec=True)
+ def test__get_windows_efi_bootloaders(self, mock_access, mock_walk,
+ mock_execute, mock_dispatch):
+ mock_walk.return_value = [
+ ('/boot/efi', ['WINDOWS'], []),
+ ('/boot/efi/WINDOWS', ['system32'], []),
+ ('/boot/efi/WINDOWS/system32', [],
+ ['winload.efi'])
+ ]
+ mock_access.return_value = True
+ result = image._get_efi_bootloaders("/boot/efi")
+ self.assertEqual(result[0], '\\WINDOWS\\system32\\winload.efi')
+
+ def test__run_efibootmgr_no_bootloaders(self, mock_execute, mock_dispatch):
+ result = image._run_efibootmgr([], self.fake_dev,
+ self.fake_efi_system_part)
+ expected = []
+ self.assertIsNone(result)
+ mock_execute.assert_has_calls(expected)
+
+ def test__run_efibootmgr(self, mock_execute, mock_dispatch):
+ result = image._run_efibootmgr(['\\EFI\\BOOT\\BOOTX64.EFI'],
+ self.fake_dev,
+ self.fake_efi_system_part)
+ expected = [mock.call('efibootmgr'),
+ mock.call('efibootmgr', '-c', '-d', self.fake_dev,
+ '-p', self.fake_efi_system_part, '-w',
+ '-L', 'ironic1', '-l',
+ '\\EFI\\BOOT\\BOOTX64.EFI')]
+ self.assertIsNone(result)
+ mock_execute.assert_has_calls(expected)
diff --git a/ironic_python_agent/tests/unit/test_utils.py b/ironic_python_agent/tests/unit/test_utils.py
index 94c3a31f..8eb505ef 100644
--- a/ironic_python_agent/tests/unit/test_utils.py
+++ b/ironic_python_agent/tests/unit/test_utils.py
@@ -45,6 +45,18 @@ Number Start End Size File system Name Flags
1 116MB 2361MB 2245MB ext4
'''
+PARTED_OUTPUT_UNFORMATTED_NOFS = '''Model: whatever
+Disk /dev/sda: 480GB
+Sector size (logical/physical): 512B/512B
+Partition Table: gpt
+Disk Flags:
+
+Number Start End Size File system Name Flags
+1 1049kB 9437kB 8389kB ESP boot, esp
+2 9437kB 17.8MB 8389kB BSP bios_grub
+3 17.8MB 40.0GB 40.0GB
+4 479GB 480GB 68.1MB
+'''
PARTED_OUTPUT_NO_EFI = '''Model: whatever
Disk /dev/sda: 450GB
@@ -631,6 +643,18 @@ class TestUtils(testtools.TestCase):
self.assertEqual('15', ret)
@mock.patch.object(utils, 'execute', autospec=True)
+ def test_get_efi_part_on_device_without_fs(self, mocked_execute):
+ parted_ret = PARTED_OUTPUT_UNFORMATTED_NOFS.format('gpt')
+ mocked_execute.side_effect = [
+ (parted_ret, None)
+ ]
+ ret = utils.get_efi_part_on_device('/dev/sda')
+ mocked_execute.assert_has_calls(
+ [mock.call('parted', '-s', '/dev/sda', '--', 'print')]
+ )
+ self.assertEqual('1', ret)
+
+ @mock.patch.object(utils, 'execute', autospec=True)
def test_get_efi_part_on_device_not_found(self, mocked_execute):
mocked_execute.side_effect = [
(PARTED_OUTPUT_NO_EFI, None)