def setUp(self): disk1 = DiskDevice("testdisk", size=Size("300 GiB"), exists=True, fmt=get_format("disklabel", exists=True)) disk1.format._supported = False with self.assertLogs("blivet", level="INFO") as cm: partition1 = PartitionDevice("testpart1", size=Size("150 GiB"), exists=True, parents=[disk1], fmt=get_format("ext4", exists=True)) self.assertTrue("disklabel is unsupported" in "\n".join(cm.output)) with self.assertLogs("blivet", level="INFO") as cm: partition2 = PartitionDevice("testpart2", size=Size("100 GiB"), exists=True, parents=[disk1], fmt=get_format("lvmpv", exists=True)) self.assertTrue("disklabel is unsupported" in "\n".join(cm.output)) # To be supported, all of a devices ancestors must be supported. disk2 = DiskDevice("testdisk2", size=Size("300 GiB"), exists=True, fmt=get_format("lvmpv", exists=True)) vg = LVMVolumeGroupDevice("testvg", exists=True, parents=[partition2, disk2]) lv = LVMLogicalVolumeDevice("testlv", exists=True, size=Size("64 GiB"), parents=[vg], fmt=get_format("ext4", exists=True)) with sparsetmpfile("addparttest", Size("50 MiB")) as disk_file: disk3 = DiskFile(disk_file) disk3.format = get_format("disklabel", device=disk3.path, exists=False) self.disk1 = disk1 self.disk2 = disk2 self.disk3 = disk3 self.partition1 = partition1 self.partition2 = partition2 self.vg = vg self.lv = lv
def test_msdos_disk_chunk1(self): disk_size = Size("100 MiB") with sparsetmpfile("chunktest", disk_size) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, exists=False, label_type="msdos") p1 = PartitionDevice("p1", size=Size("10 MiB"), grow=True) p2 = PartitionDevice("p2", size=Size("30 MiB"), grow=True) disks = [disk] partitions = [p1, p2] free = get_free_regions([disk]) self.assertEqual(len(free), 1, "free region count %d not expected" % len(free)) b = Mock(spec=Blivet) allocate_partitions(b, disks, partitions, free) requests = [PartitionRequest(p) for p in partitions] chunk = DiskChunk(free[0], requests=requests) # parted reports a first free sector of 32 for msdos on disk files. whatever. # XXX on gpt, the start is increased to 34 and the end is reduced from 204799 to 204766, # yielding an expected length of 204733 length_expected = 204768 self.assertEqual(chunk.length, length_expected) base_expected = sum(p.parted_partition.geometry.length for p in partitions) self.assertEqual(chunk.base, base_expected) pool_expected = chunk.length - base_expected self.assertEqual(chunk.pool, pool_expected) self.assertEqual(chunk.done, False) self.assertEqual(chunk.remaining, 2) chunk.grow_requests() self.assertEqual(chunk.done, True) self.assertEqual(chunk.pool, 0) self.assertEqual(chunk.remaining, 2) # # validate the growth (everything in sectors) # # The chunk length is 204768. The base of p1 is 20480. The base of # p2 is 61440. The chunk has a base of 81920 and a pool of 122848. # # p1 should grow by 30712 while p2 grows by 92136 since p2's base # size is exactly three times that of p1. self.assertEqual(requests[0].growth, 30712) self.assertEqual(requests[1].growth, 92136)
def test_extended_min_size(self): with sparsetmpfile("extendedtest", Size("10 MiB")) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, label_type="msdos") grain_size = Size(disk.format.alignment.grainSize) sector_size = Size(disk.format.parted_device.sectorSize) extended_start = int(grain_size) extended_end = extended_start + int(Size("6 MiB") / sector_size) disk.format.add_partition(extended_start, extended_end, parted.PARTITION_EXTENDED) extended = disk.format.extended_partition self.assertNotEqual(extended, None) extended_device = PartitionDevice(os.path.basename(extended.path)) extended_device.disk = disk extended_device.exists = True extended_device.parted_partition = extended # existing extended partition should be always resizable self.assertTrue(extended_device.resizable) # no logical partitions --> min size should be max of 1 KiB and grain_size self.assertEqual( extended_device.min_size, extended_device.align_target_size( max(grain_size, Size("1 KiB")))) logical_start = extended_start + 1 logical_end = extended_end // 2 disk.format.add_partition(logical_start, logical_end, parted.PARTITION_LOGICAL) logical = disk.format.parted_disk.getPartitionBySector( logical_start) self.assertNotEqual(logical, None) logical_device = PartitionDevice(os.path.basename(logical.path)) logical_device.disk = disk logical_device.exists = True logical_device.parted_partition = logical # logical partition present --> min size should be based on its end sector end_free = (extended_end - logical_end) * sector_size self.assertEqual( extended_device.min_size, extended_device.align_target_size( extended_device.current_size - end_free))
def test_extended_min_size(self): with sparsetmpfile("extendedtest", Size("10 MiB")) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, label_type="msdos") grain_size = Size(disk.format.alignment.grainSize) sector_size = Size(disk.format.parted_device.sectorSize) extended_start = int(grain_size) extended_end = extended_start + int(Size("6 MiB") / sector_size) disk.format.add_partition(extended_start, extended_end, parted.PARTITION_EXTENDED) extended = disk.format.extended_partition self.assertNotEqual(extended, None) extended_device = PartitionDevice(os.path.basename(extended.path)) extended_device.disk = disk extended_device.exists = True extended_device.parted_partition = extended # no logical partitions --> min size should be max of 1 KiB and grain_size self.assertEqual(extended_device.min_size, extended_device.align_target_size(max(grain_size, Size("1 KiB")))) logical_start = extended_start + 1 logical_end = extended_end // 2 disk.format.add_partition(logical_start, logical_end, parted.PARTITION_LOGICAL) logical = disk.format.parted_disk.getPartitionBySector(logical_start) self.assertNotEqual(logical, None) logical_device = PartitionDevice(os.path.basename(logical.path)) logical_device.disk = disk logical_device.exists = True logical_device.parted_partition = logical # logical partition present --> min size should be based on its end sector end_free = (extended_end - logical_end) * sector_size self.assertEqual(extended_device.min_size, extended_device.align_target_size(extended_device.current_size - end_free))
def test_msdos_disk_chunk2(self): disk_size = Size("100 MiB") with sparsetmpfile("chunktest", disk_size) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, exists=False, label_type="msdos") p1 = PartitionDevice("p1", size=Size("10 MiB"), grow=True) p2 = PartitionDevice("p2", size=Size("30 MiB"), grow=True) # format max size should be reflected in request max growth fmt = get_format("dummy") fmt._max_size = Size("12 MiB") p3 = PartitionDevice("p3", size=Size("10 MiB"), grow=True, fmt=fmt) p4 = PartitionDevice("p4", size=Size("7 MiB")) # partition max size should be reflected in request max growth p5 = PartitionDevice("p5", size=Size("5 MiB"), grow=True, maxsize=Size("6 MiB")) disks = [disk] partitions = [p1, p2, p3, p4, p5] free = get_free_regions([disk]) self.assertEqual(len(free), 1, "free region count %d not expected" % len(free)) b = Mock(spec=Blivet) allocate_partitions(b, disks, partitions, free) requests = [PartitionRequest(p) for p in partitions] chunk = DiskChunk(free[0], requests=requests) self.assertEqual(len(chunk.requests), len(partitions)) # parted reports a first free sector of 32 for disk files. whatever. length_expected = 204768 self.assertEqual(chunk.length, length_expected) growable = [p for p in partitions if p.req_grow] fixed = [p for p in partitions if not p.req_grow] base_expected = sum(p.parted_partition.geometry.length for p in growable) self.assertEqual(chunk.base, base_expected) base_fixed = sum(p.parted_partition.geometry.length for p in fixed) pool_expected = chunk.length - base_expected - base_fixed self.assertEqual(chunk.pool, pool_expected) self.assertEqual(chunk.done, False) # since p5 is not growable it is initially done self.assertEqual(chunk.remaining, 4) chunk.grow_requests() # # validate the growth (in sectors) # # The chunk length is 204768. # Request bases: # p1 20480 # p2 61440 # p3 20480 # p4 14336 (not included in chunk base since it isn't growable) # p5 10240 # # The chunk has a base 112640 and a pool of 77792. # # Request max growth: # p1 0 # p2 0 # p3 4096 # p4 0 # p5 2048 # # The first round should allocate to p1, p2, p3, p5 at a ratio of # 2:6:2:1, which is 14144, 42432, 14144, 7072. Due to max growth, # p3 and p5 will be limited and the extra (10048, 5024) will remain # in the pool. In the second round the remaining requests will be # p1 and p2. They will divide up the pool of 15072 at a ratio of # 1:3, which is 3768 and 11304. At this point the pool should be # empty. # # Total growth: # p1 17912 # p2 53736 # p3 4096 # p4 0 # p5 2048 # self.assertEqual(chunk.done, True) self.assertEqual(chunk.pool, 0) self.assertEqual(chunk.remaining, 2) # p1, p2 have no max # chunk.requests got sorted, so use the list whose order we know self.assertEqual(requests[0].growth, 17912) self.assertEqual(requests[1].growth, 53736) self.assertEqual(requests[2].growth, 4096) self.assertEqual(requests[3].growth, 0) self.assertEqual(requests[4].growth, 2048)
def test_add_partition(self): with sparsetmpfile("addparttest", Size("50 MiB")) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, exists=False, label_type="msdos") free = disk.format.parted_disk.getFreeSpaceRegions()[0] # # add a partition with an unaligned size # self.assertEqual(len(disk.format.partitions), 0) part = add_partition(disk.format, free, parted.PARTITION_NORMAL, Size("10 MiB") - Size(37)) self.assertEqual(len(disk.format.partitions), 1) # an unaligned size still yields an aligned partition alignment = disk.format.alignment geom = part.geometry sector_size = Size(geom.device.sectorSize) self.assertEqual(alignment.isAligned(free, geom.start), True) self.assertEqual(alignment.isAligned(free, geom.end + 1), True) self.assertEqual(part.geometry.length, int(Size("10 MiB") // sector_size)) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 0) # # adding a partition smaller than the optimal io size should yield # a partition aligned using the minimal io size instead # opt_str = 'parted.Device.optimumAlignment' min_str = 'parted.Device.minimumAlignment' opt_al = parted.Alignment(offset=0, grainSize=8192) # 4 MiB min_al = parted.Alignment(offset=0, grainSize=2048) # 1 MiB with patch(opt_str, opt_al) as optimal, patch(min_str, min_al) as minimal: optimal_end = disk.format.get_end_alignment(alignment=optimal) minimal_end = disk.format.get_end_alignment(alignment=minimal) sector_size = Size(disk.format.sector_size) length = 4096 # 2 MiB size = Size(sector_size * length) part = add_partition(disk.format, free, parted.PARTITION_NORMAL, size) self.assertEqual(part.geometry.length, length) self.assertEqual(optimal.isAligned(free, part.geometry.start), False) self.assertEqual(minimal.isAligned(free, part.geometry.start), True) self.assertEqual(optimal_end.isAligned(free, part.geometry.end), False) self.assertEqual(minimal_end.isAligned(free, part.geometry.end), True) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 0) # # add a partition with an unaligned start sector # start_sector = 5003 end_sector = 15001 part = add_partition(disk.format, free, parted.PARTITION_NORMAL, None, start_sector, end_sector) self.assertEqual(len(disk.format.partitions), 1) # start and end sectors are exactly as specified self.assertEqual(part.geometry.start, start_sector) self.assertEqual(part.geometry.end, end_sector) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 0) # # fail: add a logical partition to a primary free region # with six.assertRaisesRegex(self, parted.PartitionException, "no extended partition"): part = add_partition(disk.format, free, parted.PARTITION_LOGICAL, Size("10 MiB")) # add an extended partition to the disk placeholder = add_partition(disk.format, free, parted.PARTITION_NORMAL, Size("10 MiB")) all_free = disk.format.parted_disk.getFreeSpaceRegions() add_partition(disk.format, all_free[1], parted.PARTITION_EXTENDED, Size("30 MiB"), alignment.alignUp(all_free[1], placeholder.geometry.end)) disk.format.remove_partition(placeholder) self.assertEqual(len(disk.format.partitions), 1) all_free = disk.format.parted_disk.getFreeSpaceRegions() # # add a logical partition to an extended free regions # part = add_partition(disk.format, all_free[1], parted.PARTITION_LOGICAL, Size("10 MiB"), all_free[1].start) self.assertEqual(part.type, parted.PARTITION_LOGICAL) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 1) # # fail: add a primary partition to an extended free region # with six.assertRaisesRegex(self, parted.PartitionException, "overlap"): part = add_partition(disk.format, all_free[1], parted.PARTITION_NORMAL, Size("10 MiB"), all_free[1].start)
def test_target_size(self): with sparsetmpfile("targetsizetest", Size("10 MiB")) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, label_type="msdos") grain_size = Size(disk.format.alignment.grainSize) sector_size = Size(disk.format.parted_device.sectorSize) start = int(grain_size) orig_size = Size("6 MiB") end = start + int(orig_size / sector_size) - 1 disk.format.add_partition(start, end) partition = disk.format.parted_disk.getPartitionBySector(start) self.assertNotEqual(partition, None) self.assertEqual(orig_size, Size(partition.getLength(unit='B'))) device = PartitionDevice(os.path.basename(partition.path), size=orig_size) device.disk = disk device.exists = True device.parted_partition = partition device.format = get_format("ext4", device=device.path) device.format.exists = True # grain size should be 1 MiB device.format._min_instance_size = Size("2 MiB") + (grain_size / 2) device.format._resizable = True # Make sure things are as expected to begin with. self.assertEqual(device.size, orig_size) self.assertEqual(device.min_size, Size("3 MiB")) # start sector's at 1 MiB self.assertEqual(device.max_size, Size("9 MiB")) # ValueError if not Size with six.assertRaisesRegex(self, ValueError, "new size must.*type Size"): device.target_size = 22 self.assertEqual(device.target_size, orig_size) # ValueError if size smaller than min_size with six.assertRaisesRegex(self, ValueError, "size.*smaller than the minimum"): device.target_size = Size("1 MiB") self.assertEqual(device.target_size, orig_size) # ValueError if size larger than max_size with six.assertRaisesRegex(self, ValueError, "size.*larger than the maximum"): device.target_size = Size("11 MiB") self.assertEqual(device.target_size, orig_size) # ValueError if unaligned with six.assertRaisesRegex(self, ValueError, "new size.*not.*aligned"): device.target_size = Size("3.1 MiB") self.assertEqual(device.target_size, orig_size) # successfully set a new target size new_target = device.max_size device.target_size = new_target self.assertEqual(device.target_size, new_target) self.assertEqual(device.size, new_target) parted_size = Size(device.parted_partition.getLength(unit='B')) self.assertEqual(parted_size, device.target_size) # reset target size to original size device.target_size = orig_size self.assertEqual(device.target_size, orig_size) self.assertEqual(device.size, orig_size) parted_size = Size(device.parted_partition.getLength(unit='B')) self.assertEqual(parted_size, device.target_size)
def test_min_max_size_alignment(self): with sparsetmpfile("minsizetest", Size("10 MiB")) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path) grain_size = Size(disk.format.alignment.grainSize) sector_size = Size(disk.format.parted_device.sectorSize) start = int(grain_size) end = start + int(Size("6 MiB") / sector_size) disk.format.add_partition(start, end) partition = disk.format.parted_disk.getPartitionBySector(start) self.assertNotEqual(partition, None) device = PartitionDevice(os.path.basename(partition.path)) device.disk = disk device.exists = True device.parted_partition = partition # Typical sector size is 512 B. # Default optimum alignment grain size is 2048 sectors, or 1 MiB. device.format = get_format("ext4", device=device.path) device.format.exists = True device.format._min_instance_size = Size("2 MiB") + (grain_size / 2) device.format._resizable = True ## # min_size ## # The end sector based only on format min size should be unaligned. min_sectors = int(device.format.min_size / sector_size) min_end_sector = partition.geometry.start + min_sectors - 1 self.assertEqual( disk.format.end_alignment.isAligned(partition.geometry, min_end_sector), False) # The end sector based on device min size should be aligned. min_sectors = int(device.min_size / sector_size) min_end_sector = partition.geometry.start + min_sectors - 1 self.assertEqual( disk.format.end_alignment.isAligned(partition.geometry, min_end_sector), True) ## # max_size ## # Add a partition starting three sectors past an aligned sector and # extending to the end of the disk so that there's a free region # immediately following the first partition with an unaligned end # sector. free = disk.format.parted_disk.getFreeSpaceRegions()[-1] raw_start = int(Size("9 MiB") / sector_size) start = disk.format.alignment.alignUp(free, raw_start) + 3 disk.format.add_partition(start, disk.format.parted_device.length - 1) # Verify the end of the free region immediately following the first # partition is unaligned. free = disk.format.parted_disk.getFreeSpaceRegions()[1] self.assertEqual(disk.format.end_alignment.isAligned(free, free.end), False) # The end sector based on device min size should be aligned. max_sectors = int(device.max_size / sector_size) max_end_sector = partition.geometry.start + max_sectors - 1 self.assertEqual( disk.format.end_alignment.isAligned(free, max_end_sector), True)
def test_disk_chunk2(self): disk_size = Size("100 MiB") with sparsetmpfile("chunktest", disk_size) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, exists=False) p1 = PartitionDevice("p1", size=Size("10 MiB"), grow=True) p2 = PartitionDevice("p2", size=Size("30 MiB"), grow=True) # format max size should be reflected in request max growth fmt = get_format("dummy") fmt._max_size = Size("12 MiB") p3 = PartitionDevice("p3", size=Size("10 MiB"), grow=True, fmt=fmt) p4 = PartitionDevice("p4", size=Size("7 MiB")) # partition max size should be reflected in request max growth p5 = PartitionDevice("p5", size=Size("5 MiB"), grow=True, maxsize=Size("6 MiB")) disks = [disk] partitions = [p1, p2, p3, p4, p5] free = get_free_regions([disk]) self.assertEqual(len(free), 1, "free region count %d not expected" % len(free)) b = Mock(spec=Blivet) allocate_partitions(b, disks, partitions, free) requests = [PartitionRequest(p) for p in partitions] chunk = DiskChunk(free[0], requests=requests) self.assertEqual(len(chunk.requests), len(partitions)) # parted reports a first free sector of 32 for disk files. whatever. length_expected = 204768 self.assertEqual(chunk.length, length_expected) growable = [p for p in partitions if p.req_grow] fixed = [p for p in partitions if not p.req_grow] base_expected = sum(p.parted_partition.geometry.length for p in growable) self.assertEqual(chunk.base, base_expected) base_fixed = sum(p.parted_partition.geometry.length for p in fixed) pool_expected = chunk.length - base_expected - base_fixed self.assertEqual(chunk.pool, pool_expected) self.assertEqual(chunk.done, False) # since p5 is not growable it is initially done self.assertEqual(chunk.remaining, 4) chunk.grow_requests() # # validate the growth (in sectors) # # The chunk length is 204768. # Request bases: # p1 20480 # p2 61440 # p3 20480 # p4 14336 (not included in chunk base since it isn't growable) # p5 10240 # # The chunk has a base 112640 and a pool of 77792. # # Request max growth: # p1 0 # p2 0 # p3 4096 # p4 0 # p5 2048 # # The first round should allocate to p1, p2, p3, p5 at a ratio of # 2:6:2:1, which is 14144, 42432, 14144, 7072. Due to max growth, # p3 and p5 will be limited and the extra (10048, 5024) will remain # in the pool. In the second round the remaining requests will be # p1 and p2. They will divide up the pool of 15072 at a ratio of # 1:3, which is 3768 and 11304. At this point the pool should be # empty. # # Total growth: # p1 17912 # p2 53736 # p3 4096 # p4 0 # p5 2048 # self.assertEqual(chunk.done, True) self.assertEqual(chunk.pool, 0) self.assertEqual(chunk.remaining, 2) # p1, p2 have no max # chunk.requests got sorted, so use the list whose order we know self.assertEqual(requests[0].growth, 17912) self.assertEqual(requests[1].growth, 53736) self.assertEqual(requests[2].growth, 4096) self.assertEqual(requests[3].growth, 0) self.assertEqual(requests[4].growth, 2048)
def test_add_partition(self): with sparsetmpfile("addparttest", Size("50 MiB")) as disk_file: disk = DiskFile(disk_file) disk.format = get_format("disklabel", device=disk.path, exists=False) free = disk.format.parted_disk.getFreeSpaceRegions()[0] # # add a partition with an unaligned size # self.assertEqual(len(disk.format.partitions), 0) part = add_partition(disk.format, free, parted.PARTITION_NORMAL, Size("10 MiB") - Size(37)) self.assertEqual(len(disk.format.partitions), 1) # an unaligned size still yields an aligned partition alignment = disk.format.alignment geom = part.geometry sector_size = Size(geom.device.sectorSize) self.assertEqual(alignment.isAligned(free, geom.start), True) self.assertEqual(alignment.isAligned(free, geom.end + 1), True) self.assertEqual(part.geometry.length, int(Size("10 MiB") // sector_size)) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 0) # # adding a partition smaller than the optimal io size should yield # a partition aligned using the minimal io size instead # opt_str = 'parted.Device.optimumAlignment' min_str = 'parted.Device.minimumAlignment' opt_al = parted.Alignment(offset=0, grainSize=8192) # 4 MiB min_al = parted.Alignment(offset=0, grainSize=2048) # 1 MiB with patch(opt_str, opt_al) as optimal, patch(min_str, min_al) as minimal: optimal_end = disk.format.get_end_alignment(alignment=optimal) minimal_end = disk.format.get_end_alignment(alignment=minimal) sector_size = Size(disk.format.sector_size) length = 4096 # 2 MiB size = Size(sector_size * length) part = add_partition(disk.format, free, parted.PARTITION_NORMAL, size) self.assertEqual(part.geometry.length, length) self.assertEqual(optimal.isAligned(free, part.geometry.start), False) self.assertEqual(minimal.isAligned(free, part.geometry.start), True) self.assertEqual( optimal_end.isAligned(free, part.geometry.end), False) self.assertEqual( minimal_end.isAligned(free, part.geometry.end), True) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 0) # # add a partition with an unaligned start sector # start_sector = 5003 end_sector = 15001 part = add_partition(disk.format, free, parted.PARTITION_NORMAL, None, start_sector, end_sector) self.assertEqual(len(disk.format.partitions), 1) # start and end sectors are exactly as specified self.assertEqual(part.geometry.start, start_sector) self.assertEqual(part.geometry.end, end_sector) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 0) # # fail: add a logical partition to a primary free region # with self.assertRaisesRegex(parted.PartitionException, "no extended partition"): part = add_partition(disk.format, free, parted.PARTITION_LOGICAL, Size("10 MiB")) # add an extended partition to the disk placeholder = add_partition(disk.format, free, parted.PARTITION_NORMAL, Size("10 MiB")) all_free = disk.format.parted_disk.getFreeSpaceRegions() add_partition( disk.format, all_free[1], parted.PARTITION_EXTENDED, Size("30 MiB"), alignment.alignUp(all_free[1], placeholder.geometry.end)) disk.format.remove_partition(placeholder) self.assertEqual(len(disk.format.partitions), 1) all_free = disk.format.parted_disk.getFreeSpaceRegions() # # add a logical partition to an extended free regions # part = add_partition(disk.format, all_free[1], parted.PARTITION_LOGICAL, Size("10 MiB"), all_free[1].start) self.assertEqual(part.type, parted.PARTITION_LOGICAL) disk.format.remove_partition(part) self.assertEqual(len(disk.format.partitions), 1) # # fail: add a primary partition to an extended free region # with self.assertRaisesRegex(parted.PartitionException, "overlap"): part = add_partition(disk.format, all_free[1], parted.PARTITION_NORMAL, Size("10 MiB"), all_free[1].start)
def testAddPartition(self): with sparsetmpfile("addparttest", Size("50 MiB")) as disk_file: disk = DiskFile(disk_file) disk.format = getFormat("disklabel", device=disk.path, exists=False) free = disk.format.partedDisk.getFreeSpaceRegions()[0] # # add a partition with an unaligned size # self.assertEqual(len(disk.format.partitions), 0) part = addPartition(disk.format, free, parted.PARTITION_NORMAL, Size("10 MiB") - Size(37)) self.assertEqual(len(disk.format.partitions), 1) # an unaligned size still yields an aligned partition alignment = disk.format.alignment geom = part.geometry sector_size = Size(geom.device.sectorSize) self.assertEqual(alignment.isAligned(free, geom.start), True) self.assertEqual(alignment.isAligned(free, geom.end + 1), True) self.assertEqual(part.geometry.length, int(Size("10 MiB") // sector_size)) disk.format.removePartition(part) self.assertEqual(len(disk.format.partitions), 0) # # add a partition with an unaligned start sector # start_sector = 5003 end_sector = 15001 part = addPartition(disk.format, free, parted.PARTITION_NORMAL, None, start_sector, end_sector) self.assertEqual(len(disk.format.partitions), 1) # start and end sectors are exactly as specified self.assertEqual(part.geometry.start, start_sector) self.assertEqual(part.geometry.end, end_sector) disk.format.removePartition(part) self.assertEqual(len(disk.format.partitions), 0) # # fail: add a logical partition to a primary free region # with self.assertRaisesRegex(parted.PartitionException, "no extended partition"): part = addPartition(disk.format, free, parted.PARTITION_LOGICAL, Size("10 MiB")) ## add an extended partition to the disk placeholder = addPartition(disk.format, free, parted.PARTITION_NORMAL, Size("10 MiB")) all_free = disk.format.partedDisk.getFreeSpaceRegions() addPartition(disk.format, all_free[1], parted.PARTITION_EXTENDED, Size("30 MiB"), alignment.alignUp(all_free[1], placeholder.geometry.end)) disk.format.removePartition(placeholder) self.assertEqual(len(disk.format.partitions), 1) all_free = disk.format.partedDisk.getFreeSpaceRegions() # # add a logical partition to an extended free regions # part = addPartition(disk.format, all_free[1], parted.PARTITION_LOGICAL, Size("10 MiB"), all_free[1].start) self.assertEqual(part.type, parted.PARTITION_LOGICAL) disk.format.removePartition(part) self.assertEqual(len(disk.format.partitions), 1) # # fail: add a primary partition to an extended free region # with self.assertRaisesRegex(parted.PartitionException, "overlap"): part = addPartition(disk.format, all_free[1], parted.PARTITION_NORMAL, Size("10 MiB"), all_free[1].start)