summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-05-12 09:15:49 +0000
committerGerrit Code Review <review@openstack.org>2021-05-12 09:15:49 +0000
commit719f20aaf5103e50a39d2c9d043b07699424ab13 (patch)
tree878dfa6a250c527669bc668b4a22be3ac3099c02
parent823e0ed743962ddda26c124f7c123aa106bb561c (diff)
parent5492f57dfd874a23c7d77198bde304e100b8714e (diff)
downloadironic-python-agent-719f20aaf5103e50a39d2c9d043b07699424ab13.tar.gz
Merge "Migrate functional tests for work_on_disk from ironic-lib"
-rw-r--r--bindep.txt1
-rw-r--r--ironic_python_agent/tests/unit/test_partition_utils.py82
2 files changed, 83 insertions, 0 deletions
diff --git a/bindep.txt b/bindep.txt
index 9a7629c8..48d6d462 100644
--- a/bindep.txt
+++ b/bindep.txt
@@ -10,6 +10,7 @@ libffi-devel [platform:rpm test]
# these are needed for functional tests
mdadm [test]
+parted [test]
# this is needed for compiling translations
gettext [test]
diff --git a/ironic_python_agent/tests/unit/test_partition_utils.py b/ironic_python_agent/tests/unit/test_partition_utils.py
index d3e1bc90..1eb2cbbf 100644
--- a/ironic_python_agent/tests/unit/test_partition_utils.py
+++ b/ironic_python_agent/tests/unit/test_partition_utils.py
@@ -1038,3 +1038,85 @@ class CreateConfigDriveTestCases(base.IronicAgentTest):
mock_fix_gpt_partition.assert_called_with(self.dev, self.node_uuid)
mock_table_type.assert_called_with(self.dev)
mock_count.assert_called_once_with(self.dev)
+
+
+# NOTE(TheJulia): trigger_device_rescan is systemwide thus pointless
+# to execute in the file test case. Also, CI unit test jobs lack sgdisk.
+@mock.patch.object(disk_utils, 'trigger_device_rescan', lambda *_: None)
+@mock.patch.object(utils, 'wait_for_disk_to_become_available', lambda *_: None)
+@mock.patch.object(disk_utils, 'is_block_device', lambda d: True)
+@mock.patch.object(disk_utils, 'block_uuid', lambda p: 'uuid')
+@mock.patch.object(disk_utils, 'dd', lambda *_: None)
+@mock.patch.object(disk_utils, 'convert_image', lambda *_: None)
+@mock.patch.object(utils, 'mkfs', lambda fs, path, label=None: None)
+# NOTE(dtantsur): destroy_disk_metadata resets file size, disabling it
+@mock.patch.object(disk_utils, 'destroy_disk_metadata', lambda *_: None)
+class RealFilePartitioningTestCase(base.IronicAgentTest):
+ """This test applies some real-world partitioning scenario to a file.
+
+ This test covers the whole partitioning, mocking everything not possible
+ on a file. That helps us assure, that we do all partitioning math properly
+ and also conducts integration testing of DiskPartitioner.
+ """
+
+ # Allow calls to utils.execute() and related functions
+ block_execute = False
+
+ def setUp(self):
+ super(RealFilePartitioningTestCase, self).setUp()
+ try:
+ utils.execute('parted', '--version')
+ except OSError as exc:
+ self.skipTest('parted utility was not found: %s' % exc)
+ self.file = tempfile.NamedTemporaryFile(delete=False)
+ # NOTE(ifarkas): the file needs to be closed, so fuser won't report
+ # any usage
+ self.file.close()
+ # NOTE(dtantsur): 20 MiB file with zeros
+ utils.execute('dd', 'if=/dev/zero', 'of=%s' % self.file.name,
+ 'bs=1', 'count=0', 'seek=20MiB')
+
+ @staticmethod
+ def _run_without_root(func, *args, **kwargs):
+ """Make sure root is not required when using utils.execute."""
+ real_execute = utils.execute
+
+ def fake_execute(*cmd, **kwargs):
+ kwargs['run_as_root'] = False
+ return real_execute(*cmd, **kwargs)
+
+ with mock.patch.object(utils, 'execute', fake_execute):
+ return func(*args, **kwargs)
+
+ def test_different_sizes(self):
+ # NOTE(dtantsur): Keep this list in order with expected partitioning
+ fields = ['ephemeral_mb', 'swap_mb', 'root_mb']
+ variants = ((0, 0, 12), (4, 2, 8), (0, 4, 10), (5, 0, 10))
+ for variant in variants:
+ kwargs = dict(zip(fields, variant))
+ self._run_without_root(partition_utils.work_on_disk,
+ self.file.name, ephemeral_format='ext4',
+ node_uuid='', image_path='path', **kwargs)
+ part_table = self._run_without_root(
+ disk_utils.list_partitions, self.file.name)
+ for part, expected_size in zip(part_table, filter(None, variant)):
+ self.assertEqual(expected_size, part['size'],
+ "comparison failed for %s" % list(variant))
+
+ def test_whole_disk(self):
+ # 6 MiB ephemeral + 3 MiB swap + 9 MiB root + 1 MiB for MBR
+ # + 1 MiB MAGIC == 20 MiB whole disk
+ # TODO(dtantsur): figure out why we need 'magic' 1 more MiB
+ # and why the is different on Ubuntu and Fedora (see below)
+ self._run_without_root(partition_utils.work_on_disk, self.file.name,
+ root_mb=9, ephemeral_mb=6, swap_mb=3,
+ ephemeral_format='ext4', node_uuid='',
+ image_path='path')
+ part_table = self._run_without_root(
+ disk_utils.list_partitions, self.file.name)
+ sizes = [part['size'] for part in part_table]
+ # NOTE(dtantsur): parted in Ubuntu 12.04 will occupy the last MiB,
+ # parted in Fedora 20 won't - thus two possible variants for last part
+ self.assertEqual([6, 3], sizes[:2],
+ "unexpected partitioning %s" % part_table)
+ self.assertIn(sizes[2], (9, 10))