import unittest
import os
from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, TestTags, tag_test
import overrides_hack
from gi.repository import BlockDev, GLib
class PartTestCase(unittest.TestCase):
requested_plugins = BlockDev.plugin_specs_from_names(("part",))
@classmethod
def setUpClass(cls):
if not BlockDev.is_initialized():
BlockDev.init(cls.requested_plugins, None)
else:
BlockDev.reinit(cls.requested_plugins, True, None)
def setUp(self):
self.addCleanup(self._clean_up)
self.dev_file = create_sparse_tempfile("part_test", 100 * 1024**2)
self.dev_file2 = create_sparse_tempfile("part_test", 100 * 1024**2)
try:
self.loop_dev = create_lio_device(self.dev_file)
except RuntimeError as e:
raise RuntimeError("Failed to setup loop device for testing: %s" % e)
try:
self.loop_dev2 = create_lio_device(self.dev_file2)
except RuntimeError as e:
raise RuntimeError("Failed to setup loop device for testing: %s" % e)
def _clean_up(self):
try:
delete_lio_device(self.loop_dev)
except RuntimeError:
# just move on, we can do no better here
pass
os.unlink(self.dev_file)
try:
delete_lio_device(self.loop_dev2)
except RuntimeError:
# just move on, we can do no better here
pass
os.unlink(self.dev_file2)
class PartCreateTableCase(PartTestCase):
@tag_test(TestTags.CORE)
def test_create_table(self):
"""Verify that it is possible to create a new partition table"""
# doesn't matter if we want to ignore any preexisting partition tables
# or not on a nonexisting device
with self.assertRaises(GLib.GError):
BlockDev.part_create_table ("/non/existing", BlockDev.PartTableType.MSDOS, False)
with self.assertRaises(GLib.GError):
BlockDev.part_create_table ("/non/existing", BlockDev.PartTableType.MSDOS, True)
# doesn't matter if we want to ignore any preexisting partition tables
# or not on a clean device
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, False)
self.assertTrue(succ)
succ = BlockDev.part_create_table (self.loop_dev2, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# should fail because of a preexisting partition table (and not ignoring it)
with self.assertRaises(GLib.GError):
BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, False)
# should succeed if we want to ignore any preexisting partition tables
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
class PartGetDiskSpecCase(PartTestCase):
@tag_test(TestTags.CORE)
def test_get_disk_spec(self):
"""Verify that it is possible to get information about disk"""
with self.assertRaises(GLib.GError):
BlockDev.part_get_disk_spec ("/non/existing/device")
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev)
self.assertEqual(ps.sector_size, 512)
self.assertGreaterEqual(ps.size, 100 * 1024**2 - 512)
self.assertEqual(ps.table_type, BlockDev.PartTableType.UNDEF)
self.assertEqual(ps.flags, 0)
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev)
self.assertEqual(ps.sector_size, 512)
self.assertGreaterEqual(ps.size, 100 * 1024**2 - 512)
self.assertEqual(ps.table_type, BlockDev.PartTableType.MSDOS)
self.assertEqual(ps.flags, 0)
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev)
self.assertEqual(ps.sector_size, 512)
self.assertGreaterEqual(ps.size, 100 * 1024**2 - 512)
self.assertEqual(ps.table_type, BlockDev.PartTableType.GPT)
self.assertEqual(ps.flags, 0)
class PartCreatePartCase(PartTestCase):
@tag_test(TestTags.CORE)
def test_create_part_simple(self):
"""Verify that it is possible to create a parition"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.path, ps2.path)
self.assertEqual(ps.type, ps2.type);
self.assertEqual(ps.start, ps2.start)
self.assertEqual(ps.size, ps2.size)
self.assertEqual(ps.flags, ps2.flags)
pss = BlockDev.part_get_disk_parts (self.loop_dev)
self.assertEqual(len(pss), 1)
ps3 = pss[0]
self.assertEqual(ps.path, ps3.path)
self.assertEqual(ps.type, ps3.type)
self.assertEqual(ps.start, ps3.start)
self.assertEqual(ps.size, ps3.size)
self.assertEqual(ps.flags, ps3.flags)
def test_create_part_minimal_start_optimal(self):
"""Verify that it is possible to create a parition with minimal start and optimal alignment"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 1, 2 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertLessEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 2 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.path, ps2.path)
self.assertEqual(ps.type, ps2.type);
self.assertEqual(ps.start, ps2.start)
self.assertEqual(ps.size, ps2.size)
self.assertEqual(ps.flags, ps2.flags)
pss = BlockDev.part_get_disk_parts (self.loop_dev)
self.assertEqual(len(pss), 1)
ps3 = pss[0]
self.assertEqual(ps.path, ps3.path)
self.assertEqual(ps.type, ps3.type)
self.assertEqual(ps.start, ps3.start)
self.assertEqual(ps.size, ps3.size)
self.assertEqual(ps.flags, ps3.flags)
def test_create_part_minimal_start(self):
"""Verify that it is possible to create a parition with minimal start"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 1, 2 * 1024**2, BlockDev.PartAlign.NONE)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 512)
self.assertEqual(ps.size, 2 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.path, ps2.path)
self.assertEqual(ps.type, ps2.type);
self.assertEqual(ps.start, ps2.start)
self.assertEqual(ps.size, ps2.size)
self.assertEqual(ps.flags, ps2.flags)
pss = BlockDev.part_get_disk_parts (self.loop_dev)
self.assertEqual(len(pss), 1)
ps3 = pss[0]
self.assertEqual(ps.path, ps3.path)
self.assertEqual(ps.type, ps3.type)
self.assertEqual(ps.start, ps3.start)
self.assertEqual(ps.size, ps3.size)
self.assertEqual(ps.flags, ps3.flags)
class PartCreatePartFullCase(PartTestCase):
@tag_test(TestTags.CORE)
def test_full_device_partition(self):
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# create partition spanning whole device even disregarding the partition table (loop_dev size)
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, 0, 100 * 1024**2, BlockDev.PartAlign.OPTIMAL)
succ = BlockDev.part_delete_part (self.loop_dev, ps.path)
self.assertTrue(succ)
# same, but create a maximal partition automatically
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, 0, 0, BlockDev.PartAlign.OPTIMAL)
succ = BlockDev.part_delete_part (self.loop_dev, ps.path)
self.assertTrue(succ)
# start at byte 1 and create partition spanning whole device explicitly
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, 1, 100 * 1024**2, BlockDev.PartAlign.OPTIMAL)
succ = BlockDev.part_delete_part (self.loop_dev, ps.path)
self.assertTrue(succ)
# start at byte 1 and create a maximal partition automatically
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, 1, 0, BlockDev.PartAlign.OPTIMAL)
succ = BlockDev.part_delete_part (self.loop_dev, ps.path)
self.assertTrue(succ)
def test_create_part_all_primary(self):
"""Verify that partition creation works as expected with all primary parts"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps2.start - (ps.start + ps.size + 1)) < ps.start)
self.assertEqual(ps2.size, 10 * 1024**2)
self.assertEqual(ps2.flags, 0) # no flags (combination of bit flags)
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps2.start + ps2.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps3.start - (ps2.start + ps2.size + 1)) < ps.start)
self.assertEqual(ps3.size, 10 * 1024**2)
self.assertEqual(ps3.flags, 0) # no flags (combination of bit flags)
ps4 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps4)
self.assertEqual(ps4.path, self.loop_dev + "4")
self.assertEqual(ps4.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps4.start - (ps3.start + ps3.size + 1)) < ps.start)
self.assertEqual(ps4.size, 10 * 1024**2)
self.assertEqual(ps4.flags, 0) # no flags (combination of bit flags)
# no more primary partitions allowed in the MSDOS table
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps4.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps4.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
def test_create_part_with_extended(self):
"""Verify that partition creation works as expected with primary and extended parts"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps2.start - (ps.start + ps.size + 1)) < ps.start)
self.assertEqual(ps2.size, 10 * 1024**2)
self.assertEqual(ps2.flags, 0) # no flags (combination of bit flags)
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps2.start + ps2.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps3.start - (ps2.start + ps2.size + 1)) < ps.start)
self.assertEqual(ps3.size, 10 * 1024**2)
self.assertEqual(ps3.flags, 0) # no flags (combination of bit flags)
ps4 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps4)
self.assertEqual(ps4.path, self.loop_dev + "4")
self.assertEqual(ps4.type, BlockDev.PartType.EXTENDED)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps4.start - (ps3.start + ps3.size + 1)) < ps.start)
self.assertEqual(ps4.size, 10 * 1024**2)
self.assertEqual(ps4.flags, 0) # no flags (combination of bit flags)
# no more primary partitions allowed in the MSDOS table
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps4.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps4.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
@tag_test(TestTags.CORE)
def test_create_part_with_extended_logical(self):
"""Verify that partition creation works as expected with primary, extended and logical parts"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps2.start - (ps.start + ps.size + 1)) < ps.start)
self.assertEqual(ps2.size, 10 * 1024**2)
self.assertEqual(ps2.flags, 0) # no flags (combination of bit flags)
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps2.start + ps2.size + 1,
30 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.EXTENDED)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps3.start - (ps2.start + ps2.size + 1)) < ps.start)
self.assertEqual(ps3.size, 30 * 1024**2)
self.assertEqual(ps3.flags, 0) # no flags (combination of bit flags)
# the logical partition has number 5 even though the extended partition
# has number 3
ps5 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps3.start + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps5)
self.assertEqual(ps5.path, self.loop_dev + "5")
self.assertEqual(ps5.type, BlockDev.PartType.LOGICAL)
# the start has to be somewhere in the extended partition p3 which
# should need at most 2 MiB extra space
self.assertTrue(ps3.start < ps5.start < ps3.start + ps3.size)
self.assertTrue(abs(ps5.size - 10 * 1024**2) < 2 * 1024**2)
self.assertEqual(ps5.flags, 0) # no flags (combination of bit flags)
ps6 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps5.start + ps5.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps6)
self.assertEqual(ps6.path, self.loop_dev + "6")
self.assertEqual(ps6.type, BlockDev.PartType.LOGICAL)
# the start has to be somewhere in the extended partition p3 which
# should need at most 2 MiB extra space
self.assertTrue(ps3.start < ps6.start < ps3.start + ps3.size)
self.assertEqual(ps6.size, 10 * 1024**2)
self.assertEqual(ps6.flags, 0) # no flags (combination of bit flags)
ps7 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps6.start + ps6.size + 2 * 1024**2,
5 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps7)
self.assertEqual(ps7.path, self.loop_dev + "7")
self.assertEqual(ps7.type, BlockDev.PartType.LOGICAL)
# the start has to be somewhere in the extended partition p3 which
# should need at most 2 MiB extra space
self.assertTrue(ps3.start < ps7.start < ps3.start + ps3.size)
self.assertLess(abs(ps7.start - (ps6.start + ps6.size + 2 * 1024**2)), 512)
self.assertEqual(ps7.size, 5 * 1024**2)
self.assertEqual(ps7.flags, 0) # no flags (combination of bit flags)
# here we go with the partition number 4
ps4 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps4)
self.assertEqual(ps4.path, self.loop_dev + "4")
self.assertEqual(ps4.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps4.start - (ps3.start + ps3.size + 1)) < ps.start)
self.assertEqual(ps4.size, 10 * 1024**2)
self.assertEqual(ps4.flags, 0) # no flags (combination of bit flags)
# no more primary partitions allowed in the MSDOS table
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
def test_create_part_with_extended_logical_gpt(self):
"""Verify that partition creation works as expected with primary, extended and logical parts on GPT"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps2.start - (ps.start + ps.size + 1)) < ps.start)
self.assertEqual(ps2.size, 10 * 1024**2)
self.assertEqual(ps2.flags, 0) # no flags (combination of bit flags)
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps2.start + ps2.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps3.start - (ps2.start + ps2.size + 1)) < ps.start)
self.assertEqual(ps3.size, 10 * 1024**2)
self.assertEqual(ps3.flags, 0) # no flags (combination of bit flags)
# no extended partitions allowed in the GPT table
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# no logical partitions allowed in the GPT table
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
@tag_test(TestTags.CORE)
def test_create_part_next(self):
"""Verify that partition creation works as expected with the NEXT (auto) type"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps.start + ps.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps2.start - (ps.start + ps.size + 1)) < ps.start)
self.assertEqual(ps2.size, 10 * 1024**2)
self.assertEqual(ps2.flags, 0) # no flags (combination of bit flags)
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps2.start + ps2.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps3.start - (ps2.start + ps2.size + 1)) < ps.start)
self.assertEqual(ps3.size, 10 * 1024**2)
self.assertEqual(ps3.flags, 0) # no flags (combination of bit flags)
# we should get a logical partition which has number 5
ps5 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
ps4 = BlockDev.part_get_part_spec (self.loop_dev, self.loop_dev + "4")
self.assertTrue(ps4)
self.assertEqual(ps4.path, self.loop_dev + "4")
self.assertEqual(ps4.type, BlockDev.PartType.EXTENDED)
self.assertTrue(abs(ps4.start - (ps3.start + ps3.size + 1)) < ps.start)
self.assertGreater(ps4.size, 65 * 1024**2)
self.assertTrue(ps5)
self.assertEqual(ps5.path, self.loop_dev + "5")
self.assertEqual(ps5.type, BlockDev.PartType.LOGICAL)
# the start has to be somewhere in the extended partition p4 no more
# than 2 MiB after its start
self.assertLessEqual(ps5.start, ps4.start + 2*1024**2)
self.assertEqual(ps5.size, 10 * 1024**2)
self.assertEqual(ps5.flags, 0) # no flags (combination of bit flags)
ps6 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps5.start + ps5.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps6)
self.assertEqual(ps6.path, self.loop_dev + "6")
self.assertEqual(ps6.type, BlockDev.PartType.LOGICAL)
# logical partitions start 1 MiB after each other (no idea why)
self.assertLessEqual(abs(ps6.start - (ps5.start + ps5.size + 1)), 1024**2 + 512)
self.assertEqual(ps6.size, 10 * 1024**2)
self.assertEqual(ps6.flags, 0) # no flags (combination of bit flags)
ps7 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps6.start + ps6.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps7)
self.assertEqual(ps7.path, self.loop_dev + "7")
self.assertEqual(ps7.type, BlockDev.PartType.LOGICAL)
# logical partitions start 1 MiB after each other (no idea why)
self.assertLessEqual(abs(ps7.start - (ps6.start + ps6.size + 1)), 1024**2 + 512)
self.assertEqual(ps7.size, 10 * 1024**2)
self.assertEqual(ps7.flags, 0) # no flags (combination of bit flags)
# no more primary nor extended partitions allowed in the MSDOS table and
# there should be no space
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps4.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
with self.assertRaises(GLib.GError):
BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps4.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
@tag_test(TestTags.CORE)
def test_create_part_next_gpt(self):
"""Verify that partition creation works as expected with the NEXT (auto) type on GPT"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps.start + ps.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps2.start - (ps.start + ps.size + 1)) < ps.start)
self.assertEqual(ps2.size, 10 * 1024**2)
self.assertEqual(ps2.flags, 0) # no flags (combination of bit flags)
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps2.start + ps2.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps3.start - (ps2.start + ps2.size + 1)) < ps.start)
self.assertEqual(ps3.size, 10 * 1024**2)
self.assertEqual(ps3.flags, 0) # no flags (combination of bit flags)
# we should get just next primary partition (GPT)
ps4 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps4)
self.assertEqual(ps4.path, self.loop_dev + "4")
self.assertEqual(ps4.type, BlockDev.PartType.NORMAL)
self.assertTrue(abs(ps4.start - (ps3.start + ps3.size + 1)) < ps.start)
self.assertEqual(ps4.size, 10 * 1024**2)
# we should get just next primary partition (GPT)
ps5 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps4.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps5)
self.assertEqual(ps5.path, self.loop_dev + "5")
self.assertEqual(ps5.type, BlockDev.PartType.NORMAL)
self.assertTrue(abs(ps5.start - (ps4.start + ps4.size + 1)) < ps.start)
self.assertEqual(ps5.size, 10 * 1024**2)
# we should get just next primary partition (GPT)
ps6 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NEXT, ps5.start + ps4.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps6)
self.assertEqual(ps6.path, self.loop_dev + "6")
self.assertEqual(ps6.type, BlockDev.PartType.NORMAL)
self.assertTrue(abs(ps6.start - (ps5.start + ps5.size + 1)) < ps.start)
self.assertEqual(ps6.size, 10 * 1024**2)
class PartGetDiskPartsCase(PartTestCase):
def test_get_disk_parts_empty(self):
"""Verify that getting info about partitions with no label works"""
with self.assertRaises(GLib.GError):
BlockDev.part_get_disk_parts (self.loop_dev)
class PartGetDiskFreeRegions(PartTestCase):
@tag_test(TestTags.CORE)
def test_get_disk_free_regions(self):
"""Verify that it is possible to get info about free regions on a disk"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 1, 10 * 1024**2, BlockDev.PartAlign.NONE)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 512)
self.assertEqual(ps.size, 10 * 1024**2)
fis = BlockDev.part_get_disk_free_regions (self.loop_dev)
self.assertEqual(len(fis), 2) # 0-512, (512+10MiB)-EOD
fi = fis[0]
self.assertEqual(fi.start, 0)
self.assertEqual(fi.size, 512)
fi = fis[1]
self.assertEqual(fi.start, ps.start + ps.size)
self.assertGreater(fi.size, 89 * 1024**2)
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 10 * 1024**2,
10 * 1024**2, BlockDev.PartAlign.NONE)
fis = BlockDev.part_get_disk_free_regions (self.loop_dev)
self.assertEqual(len(fis), 3) # 0-512, first part, gap, second part, free
fi = fis[0]
self.assertEqual(fi.start, 0)
self.assertEqual(fi.size, 512)
fi = fis[1]
self.assertEqual(fi.start, 512 + 10 * 1024**2)
self.assertGreater(fi.size, 9 * 1024**2)
fi = fis[2]
self.assertEqual(fi.start, 512 + 30 * 1024**2)
self.assertGreater(fi.size, 69 * 1024**2)
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps.start + ps.size + 1,
50 * 1024**2, BlockDev.PartAlign.NONE)
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps.start + 1024**2,
10 * 1024**2, BlockDev.PartAlign.NONE)
fis = BlockDev.part_get_disk_free_regions (self.loop_dev)
self.assertEqual(len(fis), 6) # 0-512[0], first part, gap[1], second part, gap[2], extended, gap[3], logical, free extended[4], free[5]
fi = fis[0]
self.assertEqual(fi.start, 0)
self.assertEqual(fi.size, 512)
fi = fis[1]
self.assertEqual(fi.start, 512 + 10 * 1024**2)
self.assertGreater(fi.size, 9 * 1024**2)
fi = fis[2]
self.assertGreater(fi.start, 30 * 1024**2)
self.assertLessEqual(fi.size, 512)
fi = fis[3]
self.assertGreater(fi.start, 30 * 1024**2)
self.assertLessEqual(fi.size, 1024**2)
fi = fis[4]
self.assertGreaterEqual(fi.start, ps.start + ps.size)
self.assertGreaterEqual(fi.size, 38 * 1024**2)
fi = fis[5]
self.assertGreaterEqual(fi.start, 80 * 1024**2)
self.assertGreaterEqual(fi.size, 19 * 1024**2)
# now something simple with GPT
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 1, 10 * 1024**2, BlockDev.PartAlign.NONE)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 512)
self.assertEqual(ps.size, 10 * 1024**2)
fis = BlockDev.part_get_disk_free_regions (self.loop_dev)
self.assertEqual(len(fis), 2) # 0-512, (512+10MiB)-EOD
fi = fis[0]
self.assertEqual(fi.start, 0)
self.assertEqual(fi.size, 512)
fi = fis[1]
self.assertEqual(fi.start, ps.start + ps.size)
self.assertGreater(fi.size, 89 * 1024**2)
class PartGetBestFreeRegion(PartTestCase):
def test_get_best_free_region(self):
"""Verify that it is possible to get info about the best free region on a disk"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
ps1 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 1, 10 * 1024**2, BlockDev.PartAlign.NONE)
self.assertTrue(ps1)
self.assertEqual(ps1.path, self.loop_dev + "1")
self.assertEqual(ps1.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps1.start, 512)
self.assertEqual(ps1.size, 10 * 1024**2)
# create a 20MiB gap between the partitions
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps1.start + ps1.size + 20 * 1024**2,
10 * 1024**2, BlockDev.PartAlign.NONE)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps2.start, ps1.start + ps1.size + 20 * 1024**2)
self.assertEqual(ps2.size, 10 * 1024**2)
# normal partition should go in between the partitions because there's enough space for it
ps = BlockDev.part_get_best_free_region (self.loop_dev, BlockDev.PartType.NORMAL, 10 * 1024**2)
self.assertLess(ps.start, ps2.start)
# extended partition should be as big as possible so it shouldn't go in between the partitions
ps = BlockDev.part_get_best_free_region (self.loop_dev, BlockDev.PartType.EXTENDED, 10 * 1024**2)
self.assertGreaterEqual(ps.start, ps2.start + ps2.size)
# create a 10MiB gap between the partitions
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps2.start + ps2.size + 10 * 1024**2,
45 * 1024**2, BlockDev.PartAlign.NONE)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.EXTENDED)
self.assertEqual(ps3.start, ps2.start + ps2.size + 10 * 1024**2)
self.assertEqual(ps3.size, 45 * 1024**2)
# there should now be 5 MiB left after the third partition which is enough for a 3MiB partition
ps = BlockDev.part_get_best_free_region (self.loop_dev, BlockDev.PartType.NORMAL, 3 * 1024**2)
self.assertGreaterEqual(ps.start, ps3.start + ps3.size)
# 7MiB partition should go in between the second and third partitions because there's enough space
# for it there
ps = BlockDev.part_get_best_free_region (self.loop_dev, BlockDev.PartType.NORMAL, 7 * 1024**2)
self.assertGreaterEqual(ps.start, ps2.start + ps2.size)
self.assertLess(ps.start, ps3.start)
# 15MiB partition should go in between the first and second partitions because that's the only
# space big enough for it
ps = BlockDev.part_get_best_free_region (self.loop_dev, BlockDev.PartType.NORMAL, 15 * 1024**2)
self.assertGreaterEqual(ps.start, ps1.start + ps1.size)
self.assertLess(ps.start, ps2.start)
ps5 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps3.start + 20 * 1024**2,
15 * 1024**2, BlockDev.PartAlign.NONE)
self.assertEqual(ps5.path, self.loop_dev + "5")
self.assertEqual(ps5.type, BlockDev.PartType.LOGICAL)
self.assertEqual(ps5.start, ps3.start + 20 * 1024**2)
self.assertEqual(ps5.size, 15 * 1024**2)
# 5MiB logical partition should go after the fifth partition because there's enough space for it
ps = BlockDev.part_get_best_free_region (self.loop_dev, BlockDev.PartType.LOGICAL, 5 * 1024**2)
self.assertGreaterEqual(ps.start, ps5.start + ps5.size)
self.assertLess(ps.start, ps3.start + ps3.size)
# 15MiB logical partition should go before the fifth partition because there's enough space for it
ps = BlockDev.part_get_best_free_region (self.loop_dev, BlockDev.PartType.LOGICAL, 15 * 1024**2)
self.assertGreaterEqual(ps.start, ps3.start)
self.assertLess(ps.start, ps5.start)
class PartGetPartByPos(PartTestCase):
def test_get_part_by_pos(self):
"""Verify that getting partition by position works as expected"""
## prepare the disk with non-trivial setup first
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps)
self.assertEqual(ps.path, self.loop_dev + "1")
self.assertEqual(ps.type, BlockDev.PartType.NORMAL)
self.assertEqual(ps.start, 2048 * 512)
self.assertEqual(ps.size, 10 * 1024**2)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps2)
self.assertEqual(ps2.path, self.loop_dev + "2")
self.assertEqual(ps2.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps2.start - (ps.start + ps.size + 1)) < ps.start)
self.assertEqual(ps2.size, 10 * 1024**2)
self.assertEqual(ps2.flags, 0) # no flags (combination of bit flags)
ps3 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps2.start + ps2.size + 1,
35 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps3)
self.assertEqual(ps3.path, self.loop_dev + "3")
self.assertEqual(ps3.type, BlockDev.PartType.EXTENDED)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps3.start - (ps2.start + ps2.size + 1)) < ps.start)
self.assertEqual(ps3.size, 35 * 1024**2)
self.assertEqual(ps3.flags, 0) # no flags (combination of bit flags)
# the logical partition has number 5 even though the extended partition
# has number 3
ps5 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps3.start + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps5)
self.assertEqual(ps5.path, self.loop_dev + "5")
self.assertEqual(ps5.type, BlockDev.PartType.LOGICAL)
# the start has to be somewhere in the extended partition p3 which
# should need at most 2 MiB extra space
self.assertTrue(ps3.start < ps5.start < ps3.start + ps3.size)
self.assertTrue(abs(ps5.size - 10 * 1024**2) < 2 * 1024**2)
self.assertEqual(ps5.flags, 0) # no flags (combination of bit flags)
ps6 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps5.start + ps5.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps6)
self.assertEqual(ps6.path, self.loop_dev + "6")
self.assertEqual(ps6.type, BlockDev.PartType.LOGICAL)
# the start has to be somewhere in the extended partition p3 which
# should need at most 2 MiB extra space
self.assertTrue(ps3.start < ps6.start < ps3.start + ps3.size)
self.assertEqual(ps6.size, 10 * 1024**2)
self.assertEqual(ps6.flags, 0) # no flags (combination of bit flags)
ps7 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps6.start + ps6.size + 2 * 1024**2,
5 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps7)
self.assertEqual(ps7.path, self.loop_dev + "7")
self.assertEqual(ps7.type, BlockDev.PartType.LOGICAL)
# the start has to be somewhere in the extended partition p3 which
# should need at most 2 MiB extra space
self.assertTrue(ps3.start < ps7.start < ps3.start + ps3.size)
self.assertLess(abs(ps7.start - (ps6.start + ps6.size + 2 * 1024**2)), 512)
self.assertEqual(ps7.size, 5 * 1024**2)
self.assertEqual(ps7.flags, 0) # no flags (combination of bit flags)
# here we go with the partition number 4
ps4 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps3.start + ps3.size + 1,
10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(ps4)
self.assertEqual(ps4.path, self.loop_dev + "4")
self.assertEqual(ps4.type, BlockDev.PartType.NORMAL)
# the start has to be at most as far from the end of the previous part
# as is the start of the first part from the start of the disk
self.assertTrue(abs(ps4.start - (ps3.start + ps3.size + 1)) < ps.start)
self.assertEqual(ps4.size, 10 * 1024**2)
self.assertEqual(ps4.flags, 0) # no flags (combination of bit flags)
## now try to get the partitions
# XXX: Any way to get the extended partition (ps3)? Let's just skip it now.
for part in (ps, ps2, ps5, ps6, ps7, ps4):
ret = BlockDev.part_get_part_by_pos(self.loop_dev, part.start + 1 * 1024**2)
self.assertIsNotNone(ret)
self.assertEqual(ret.path, part.path)
self.assertEqual(ret.start, part.start)
self.assertEqual(ret.size, part.size)
self.assertEqual(ret.type, part.type)
self.assertEqual(ret.flags, part.flags)
# free space in the extended partition
ret = BlockDev.part_get_part_by_pos(self.loop_dev, ps3.start + 33 * 1024**2)
self.assertIsNotNone(ret)
self.assertIsNone(ret.path)
self.assertTrue(ret.type & BlockDev.PartType.FREESPACE)
self.assertTrue(ret.type & BlockDev.PartType.LOGICAL)
# there are two 10MiB and one 5MiB logical partitions
self.assertGreater(ret.start, ps3.start + 25 * 1024**2)
# the size of the extended partition is 35 MiB
self.assertLess(ret.size, 10 * 1024**2)
# free space at the end of the disk
ret = BlockDev.part_get_part_by_pos(self.loop_dev, 90 * 1024**2)
self.assertIsNotNone(ret)
self.assertIsNone(ret.path)
self.assertTrue(ret.type & BlockDev.PartType.FREESPACE)
self.assertEqual(ret.start, ps4.start + ps4.size)
self.assertLessEqual(ret.size, (100 * 1024**2) - (ps4.start + ps4.size))
class PartCreateResizePartCase(PartTestCase):
def test_create_resize_part_two(self):
"""Verify that it is possible to create and resize two paritions"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
ps1_half = 20 * 1024**2
ps1_start = 2 * 1024**2
# create a maximal second partition
ps2 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2* ps1_half, 0, BlockDev.PartAlign.NONE)
self.assertGreaterEqual(ps2.start, 2* ps1_half)
# create one maximal partition in the beginning
ps1 = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps1_start, 0, BlockDev.PartAlign.NONE)
self.assertGreaterEqual(ps1.size, ps1_half)
self.assertGreaterEqual(ps1.start, ps1_start)
self.assertLess(ps1.size, ps1_half * 2) # can't have full size from beginning to ps2 because of start offset
# resizing should give the same result
ps1_size = ps1.size
succ = BlockDev.part_resize_part (self.loop_dev, ps1.path, 0, BlockDev.PartAlign.NONE)
self.assertTrue(succ)
ps1 = BlockDev.part_get_part_spec(self.loop_dev, ps1.path)
self.assertEqual(ps1.start, ps1_start) # offset must not be moved
self.assertEqual(ps1.size, ps1_size)
succ = BlockDev.part_resize_part (self.loop_dev, ps1.path, ps1_half, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(succ)
ps1 = BlockDev.part_get_part_spec(self.loop_dev, ps1.path)
self.assertEqual(ps1.start, ps1_start) # offset must not be moved
self.assertGreaterEqual(ps1.size, ps1_half) # at least requested size
self.assertLess(ps1.size, ps1_half + 2 * 1024**2) # and only slightly bigger
ps2_size = ps2.size
ps2_start = ps2.start
succ = BlockDev.part_resize_part (self.loop_dev, ps2.path, 0, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(succ)
ps2 = BlockDev.part_get_part_spec(self.loop_dev, ps2.path)
self.assertEqual(ps2.start, ps2_start) # offset must not be moved
self.assertGreaterEqual(ps2.size, ps2_size - 2 * 1024**2) # almost as big as before
def test_create_resize_part_single(self):
"""Verify that it is possible to create and resize a parition"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# create a maximal partition
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2 * 1024**2, 0, BlockDev.PartAlign.OPTIMAL)
initial_start = ps.start
initial_size = ps.size
new_size = 20 * 1000**2 # resize to MB (not MiB) for a non-multiple of the blocksize
succ = BlockDev.part_resize_part (self.loop_dev, ps.path, new_size, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec(self.loop_dev, ps.path)
self.assertEqual(initial_start, ps.start) # offset must not be moved
self.assertGreaterEqual(ps.size, new_size) # at least the requested size
self.assertLess(ps.size, new_size + 1 * 1024**2) # but also not too big (assuming 1 MiB alignment)
# resize to maximum
succ = BlockDev.part_resize_part (self.loop_dev, ps.path, 0, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec(self.loop_dev, ps.path)
self.assertEqual(initial_start, ps.start)
self.assertEqual(initial_size, ps.size) # should grow to the same size again
# resize to maximum explicitly
succ = BlockDev.part_resize_part (self.loop_dev, ps.path, initial_size, BlockDev.PartAlign.OPTIMAL)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec(self.loop_dev, ps.path)
self.assertEqual(initial_start, ps.start)
self.assertGreaterEqual(ps.size, initial_size) # at least the requested size
# resize back to 20 MB (not MiB) with no alignment
succ = BlockDev.part_resize_part (self.loop_dev, ps.path, new_size, BlockDev.PartAlign.NONE)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec(self.loop_dev, ps.path)
self.assertEqual(initial_start, ps.start) # offset must not be moved
self.assertGreaterEqual(ps.size, new_size) # at least the requested size
self.assertLess(ps.size, new_size + 4 * 1024) # but also not too big (assuming max. 4 KiB blocks)
# resize to maximum with no alignment
succ = BlockDev.part_resize_part (self.loop_dev, ps.path, 0, BlockDev.PartAlign.NONE)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec(self.loop_dev, ps.path)
self.assertEqual(initial_start, ps.start)
self.assertGreaterEqual(ps.size, initial_size - 1 * 1024**2) # libparted sometimes creates smaller partitions for no alignment
new_size = ps.size
# resize to maximum with no alignment explicitly
succ = BlockDev.part_resize_part (self.loop_dev, ps.path, new_size, BlockDev.PartAlign.NONE)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec(self.loop_dev, ps.path)
self.assertEqual(initial_start, ps.start)
self.assertGreaterEqual(ps.size, new_size) # at least the requested size
# resize to previous maximum with no alignment explicitly
succ = BlockDev.part_resize_part (self.loop_dev, ps.path, initial_size, BlockDev.PartAlign.NONE)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec(self.loop_dev, ps.path)
self.assertEqual(initial_start, ps.start)
self.assertGreaterEqual(ps.size, initial_size) # at least the requested size
class PartCreateDeletePartCase(PartTestCase):
@tag_test(TestTags.CORE)
def test_create_delete_part_simple(self):
"""Verify that it is possible to create and delete a parition"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
pss = BlockDev.part_get_disk_parts (self.loop_dev)
self.assertEqual(len(pss), 1)
succ = BlockDev.part_delete_part (self.loop_dev, ps.path)
self.assertTrue(succ)
pss = BlockDev.part_get_disk_parts (self.loop_dev)
self.assertEqual(len(pss), 0)
class PartSetFlagCase(PartTestCase):
def test_set_part_flag(self):
"""Verify that it is possible to set a partition flag"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
succ = BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.BOOT, True)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.BOOT)
succ = BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.BOOT, False)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertFalse(ps.flags & BlockDev.PartFlag.BOOT)
# add another partition and do some more tests on that one
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 1, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
succ = BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.BOOT, True)
self.assertTrue(succ)
succ = BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.LVM, True)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.BOOT)
self.assertTrue(ps.flags & BlockDev.PartFlag.LVM)
# SWAP label not supported on the MSDOS table
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.SWAP, True)
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.SWAP, False)
# so isn't GPT_HIDDEN
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.GPT_HIDDEN, True)
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.GPT_HIDDEN, False)
# also try some GPT-only flags
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
succ = BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.GPT_READ_ONLY, True)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.GPT_READ_ONLY)
succ = BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.GPT_HIDDEN, True)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.GPT_HIDDEN)
succ = BlockDev.part_set_part_flag (self.loop_dev, ps.path, BlockDev.PartFlag.GPT_READ_ONLY, False)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertFalse(ps.flags & BlockDev.PartFlag.GPT_READ_ONLY)
self.assertTrue(ps.flags & BlockDev.PartFlag.GPT_HIDDEN)
class PartSetDiskFlagCase(PartTestCase):
def test_set_disk_flag(self):
"""Verify that it is possible to set disk flag(s)"""
with self.assertRaises(GLib.GError):
BlockDev.part_set_disk_flag ("/non/existing/device", BlockDev.PartDiskFlag.PART_DISK_FLAG_GPT_PMBR_BOOT, True)
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.flags, 0)
self.assertEqual(ps.table_type, BlockDev.PartTableType.UNDEF)
# no label/table
with self.assertRaises(GLib.GError):
BlockDev.part_set_disk_flag (self.loop_dev, BlockDev.PartDiskFlag.PART_DISK_FLAG_GPT_PMBR_BOOT, True)
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.table_type, BlockDev.PartTableType.MSDOS)
self.assertEqual(ps.flags, 0)
# not supported on the MSDOS table
with self.assertRaises(GLib.GError):
BlockDev.part_set_disk_flag (self.loop_dev, BlockDev.PartDiskFlag.PART_DISK_FLAG_GPT_PMBR_BOOT, True)
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.table_type, BlockDev.PartTableType.GPT)
self.assertEqual(ps.flags, 0)
succ = BlockDev.part_set_disk_flag (self.loop_dev, BlockDev.PartDiskFlag.PART_DISK_FLAG_GPT_PMBR_BOOT, True)
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.flags, BlockDev.PartDiskFlag.PART_DISK_FLAG_GPT_PMBR_BOOT)
succ = BlockDev.part_set_disk_flag (self.loop_dev, BlockDev.PartDiskFlag.PART_DISK_FLAG_GPT_PMBR_BOOT, False)
ps = BlockDev.part_get_disk_spec (self.loop_dev)
self.assertTrue(ps)
self.assertEqual(ps.flags, 0)
class PartSetFlagsCase(PartTestCase):
def test_set_part_flags(self):
"""Verify that it is possible to set multiple partition flags at once"""
# we first need a partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
succ = BlockDev.part_set_part_flags (self.loop_dev, ps.path, BlockDev.PartFlag.BOOT)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.BOOT)
# 0 -> unset all
succ = BlockDev.part_set_part_flags (self.loop_dev, ps.path, 0)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertFalse(ps.flags & BlockDev.PartFlag.BOOT)
# add another partition and do some more tests on that one
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, ps.start + ps.size + 1, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
succ = BlockDev.part_set_part_flags (self.loop_dev, ps.path, BlockDev.PartFlag.BOOT | BlockDev.PartFlag.LVM)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.BOOT)
self.assertTrue(ps.flags & BlockDev.PartFlag.LVM)
# SWAP label not supported on the MSDOS table
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_flags (self.loop_dev, ps.path, BlockDev.PartFlag.SWAP)
# also try some GPT-only flags
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertEqual(ps.flags, 0) # no flags (combination of bit flags)
succ = BlockDev.part_set_part_flags (self.loop_dev, ps.path, BlockDev.PartFlag.GPT_READ_ONLY | BlockDev.PartFlag.GPT_HIDDEN)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.GPT_READ_ONLY)
self.assertTrue(ps.flags & BlockDev.PartFlag.GPT_HIDDEN)
succ = BlockDev.part_set_part_flags (self.loop_dev, ps.path, 0) # no flags
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertFalse(ps.flags & BlockDev.PartFlag.GPT_READ_ONLY)
self.assertFalse(ps.flags & BlockDev.PartFlag.GPT_HIDDEN)
class PartSetNameCase(PartTestCase):
def test_set_part_name(self):
"""Verify that it is possible to set partition name"""
# we first need a GPT partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertIn(ps.name, ("", None)) # no name
succ = BlockDev.part_set_part_name (self.loop_dev, ps.path, "TEST")
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.name, "TEST")
succ = BlockDev.part_set_part_name (self.loop_dev, ps.path, "")
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.name, "")
# let's now test an MSDOS partition table (doesn't support names)
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertIn(ps.name, ("", None)) # no name
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_name (self.loop_dev, ps.path, "")
# we should still get proper data back though
self.assertTrue(ps)
self.assertIn(ps.name, ("", None)) # no name
class PartSetTypeCase(PartTestCase):
def test_set_part_type(self):
"""Verify that it is possible to set and get partition type"""
# we first need a GPT partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertTrue(ps.type_guid) # should have some type
succ = BlockDev.part_set_part_type (self.loop_dev, ps.path, "E6D6D379-F507-44C2-A23C-238F2A3DF928")
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.type_guid, "E6D6D379-F507-44C2-A23C-238F2A3DF928")
succ = BlockDev.part_set_part_type (self.loop_dev, ps.path, "0FC63DAF-8483-4772-8E79-3D69D8477DE4")
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.type_guid, "0FC63DAF-8483-4772-8E79-3D69D8477DE4")
# let's now test an MSDOS partition table (doesn't support type GUIDs)
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
self.assertIn(ps.type_guid, ("", None)) # no type GUID
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_type (self.loop_dev, ps.path, "0FC63DAF-8483-4772-8E79-3D69D8477DE4")
# we should still get proper data back though
self.assertTrue(ps)
self.assertIn(ps.type_guid, ("", None)) # no type GUID
class PartSetIdCase(PartTestCase):
def test_set_part_id(self):
"""Verify that it is possible to set partition id (msdos partition type)"""
# we first need an MBR partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# we should get proper data back
self.assertTrue(ps)
succ = BlockDev.part_set_part_id (self.loop_dev, ps.path, "0x8e")
self.assertTrue(succ)
part_id = BlockDev.part_get_part_id (self.loop_dev, ps.path)
self.assertEqual(part_id, "0x8e")
# we can't change part id to extended partition id
with self.assertRaises(GLib.GError):
BlockDev.part_set_part_id (self.loop_dev, ps.path, "0x85")
class PartSetGptFlagsCase(PartTestCase):
def test_set_part_type(self):
"""Verify that it is possible to set and get partition flags on GPT"""
esp_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
# we first need a GPT partition table
succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True)
self.assertTrue(succ)
# for now, let's just create a typical primary partition starting at the
# sector 2048, 10 MiB big with optimal alignment
ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL)
# set GUID (part type) to check that changing flags doesn't change it
succ = BlockDev.part_set_part_type (self.loop_dev, ps.path, esp_guid)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertEqual(ps.type_guid, esp_guid)
# set LEGACY_BOOT flag and test it
succ = BlockDev.part_set_part_flags (self.loop_dev, ps.path, BlockDev.PartFlag.LEGACY_BOOT)
self.assertTrue(succ)
ps = BlockDev.part_get_part_spec (self.loop_dev, ps.path)
self.assertTrue(ps.flags & BlockDev.PartFlag.LEGACY_BOOT)
self.assertEqual(ps.type_guid, esp_guid)