def test_dependencies_handling(self): device = StorageDevice("testdev1") self.assertTrue(device.controllable) self.assertIsNotNone(ActionCreateDevice(device)) device.exists = True self.assertIsNotNone(ActionDestroyDevice(device)) with patch.object(StorageDevice, "resizable", new_callable=PropertyMock(return_value=True)): self.assertIsNotNone(ActionResizeDevice(device, Size("1 GiB"))) # if any external dependency is missing, it should be impossible to create, destroy, setup, # teardown, or resize the device (controllable encompasses setup & teardown) with patch.object(StorageDevice, "_external_dependencies", new_callable=PropertyMock(return_value=[availability.unavailable_resource("testing")])): device = StorageDevice("testdev1") self.assertFalse(device.controllable) self.assertRaises(DependencyError, ActionCreateDevice, device) device.exists = True self.assertRaises(DependencyError, ActionDestroyDevice, device) self.assertRaises(ValueError, ActionResizeDevice, device, Size("1 GiB")) # same goes for formats, except that the properties they affect vary by format class fmt = get_format("lvmpv") fmt._plugin = availability.available_resource("lvm-testing") self.assertTrue(fmt.supported) self.assertTrue(fmt.formattable) self.assertTrue(fmt.destroyable) fmt._plugin = availability.unavailable_resource("lvm-testing") self.assertFalse(fmt.supported) self.assertFalse(fmt.formattable) self.assertFalse(fmt.destroyable)
def test_match(self): """Test boot format populator helper match method""" if self.helper_class is None: return partition = PartitionDevice("testpartitiondev") storagedev = StorageDevice("teststoragedev") storagedev.bootable = True data = dict() fmt_class = get_device_format_class(self.helper_class._type_specifier) if fmt_class is None: self.skipTest("failed to look up format class for %s" % self.helper_class._type_specifier) data["ID_FS_TYPE"] = self.helper_class._base_type_specifier partition._bootable = self.helper_class._bootable min_size = fmt_class._min_size max_size = fmt_class._max_size partition._size = min_size storagedev._size = min_size if fmt_class._name: partition._parted_partition = FakePartedPart(partition, fmt_class._name) self.assertTrue(self.helper_class.match(data, partition)) # These are only valid for partitions. self.assertFalse(self.helper_class.match(data, storagedev)) data["ID_FS_TYPE"] += "x" self.assertFalse(self.helper_class.match(data, partition)) data["ID_FS_TYPE"] = self.helper_class._base_type_specifier if self.helper_class._bootable: partition._bootable = False self.assertFalse(self.helper_class.match(data, partition)) partition._bootable = True if max_size: partition._size = max_size + 1 elif min_size: partition._size = min_size - 1 self.assertFalse(self.helper_class.match(data, partition)) partition._size = min_size # we don't always match on the parted partition name, so allow # subclasses to decide if not self.name_mismatch_ok: orig = partition._parted_partition partition._parted_partition = FakePartedPart(partition, 'dontmatchanything') self.assertFalse(self.helper_class.match(data, partition)) # shouldn't crash partition._parted_partition = None self.assertFalse(self.helper_class.match(data, partition)) partition._parted_partition = orig
def test_net_dev_setting(self): """ Verify netdev mount option setting after format assignment. """ netdev = FakeNetDev("net1") dev = StorageDevice("dev1", fmt=get_format("ext4")) self.assertFalse("_netdev" in dev.format.options.split(",")) dev.parents.append(netdev) dev.format = get_format("ext4") self.assertTrue("_netdev" in dev.format.options.split(","))
def testStorageDevice(self): # Check that / and NUL are rejected along with . and .. good_names = ['sda1', '1sda', 'good-name', 'cciss/c0d0'] bad_names = ['sda/1', 'sda\x00', '.', '..', 'cciss/..'] for name in good_names: self.assertTrue(StorageDevice.isNameValid(name)) for name in bad_names: self.assertFalse(StorageDevice.isNameValid(name))
def test_resizable(self): """ Test resizable property of unformatted devices. """ # Devices with no (or unrecognized) formatting should not be resizable. device = StorageDevice("testdev1", exists=True, size=Size("100 G"), fmt=get_format("ext4", exists=True)) device._resizable = True with patch.object(device, "_format", exists=True, resizable=True): self.assertTrue(device.resizable) device = StorageDevice("testdev1", exists=True, size=Size("100 G")) device._resizable = True self.assertFalse(device.resizable)
def test_storage_device(self): # Check that / and NUL are rejected along with . and .. good_names = ['sda1', '1sda', 'good-name', 'cciss/c0d0'] bad_names = ['sda/1', 'sda\x00', '.', '..', 'cciss/..'] sd = StorageDevice("tester") for name in good_names: self.assertTrue(sd.is_name_valid(name)) for name in bad_names: self.assertFalse(sd.is_name_valid(name))
def test_recursive_remove(self): dt = DeviceTree() dev1 = StorageDevice("dev1", exists=False, parents=[]) dev2 = StorageDevice("dev2", exists=False, parents=[dev1]) dt._add_device(dev1) dt._add_device(dev2) # normal self.assertTrue(dev1 in dt.devices) self.assertTrue(dev2 in dt.devices) self.assertEqual(dt.actions._actions, list()) dt.recursive_remove(dev1) self.assertFalse(dev1 in dt.devices) self.assertFalse(dev2 in dt.devices) self.assertNotEqual(dt.actions._actions, list()) dt.reset() dt._add_device(dev1) dt._add_device(dev2, new=False) # restore parent/child relationships # remove_device clears descendants and formatting but preserves the device dev1.format = get_format("swap") self.assertEqual(dev1.format.type, "swap") self.assertEqual(dt.actions._actions, list()) dt.recursive_remove(dev1, remove_device=False) self.assertTrue(dev1 in dt.devices) self.assertFalse(dev2 in dt.devices) self.assertEqual(dev1.format.type, None) self.assertNotEqual(dt.actions._actions, list()) dt.reset() dt._add_device(dev1) dt._add_device(dev2, new=False) # restore parent/child relationships # actions=False performs the removals without scheduling actions self.assertEqual(dt.actions._actions, list()) dt.recursive_remove(dev1, actions=False) self.assertFalse(dev1 in dt.devices) self.assertFalse(dev2 in dt.devices) self.assertEqual(dt.actions._actions, list()) dt.reset() dt._add_device(dev1) dt._add_device(dev2, new=False) # restore parent/child relationships # modparent only works when actions=False is passed with patch.object(dt, "_remove_device") as remove_device: dt.recursive_remove(dev1, actions=False) remove_device.assert_called_with(dev1, modparent=True) dt.recursive_remove(dev1, actions=False, modparent=False) remove_device.assert_called_with(dev1, modparent=False)
def test_net_dev_update(self): """ Verify netdev mount option setting after device creation. """ netdev = FakeNetDev("net1") dev = StorageDevice("dev1", fmt=get_format("ext4")) self.assertFalse("_netdev" in dev.format.options.split(",")) dev.parents.append(netdev) # these create methods shouldn't write anything to disk netdev.create() dev.create() self.assertTrue("_netdev" in dev.format.options.split(","))
def test_ctor_parted_partition_error_handling(self): disk = StorageDevice("testdisk", exists=True) disk._partitionable = True with patch.object(disk, "_format") as fmt: fmt.type = "disklabel" self.assertTrue(disk.partitioned) fmt.supported = True # Normal case, no exn. device = PartitionDevice("testpart1", exists=True, parents=[disk]) self.assertIn(device, disk.children) device.parents.remove(disk) self.assertEqual(len(disk.children), 0, msg="disk has children when it should not") # Parted doesn't find a partition, exn is raised. fmt.parted_disk.getPartitionByPath.return_value = None self.assertRaises(DeviceError, PartitionDevice, "testpart1", exists=True, parents=[disk]) self.assertEqual(len(disk.children), 0, msg="device is still attached to disk in spite of ctor error")
def test_match(self): """Test boot format populator helper match method""" if self.helper_class is None: return partition = PartitionDevice("testpartitiondev") storagedev = StorageDevice("teststoragedev") storagedev.bootable = True data = dict() fmt_class = get_device_format_class(self.helper_class._type_specifier) if fmt_class is None: self.skipTest("failed to look up format class for %s" % self.helper_class._type_specifier) data["ID_FS_TYPE"] = self.helper_class._base_type_specifier partition._bootable = self.helper_class._bootable min_size = fmt_class._min_size max_size = fmt_class._max_size partition._size = min_size storagedev._size = min_size self.assertTrue(self.helper_class.match(data, partition)) # These are only valid for partitions. self.assertFalse(self.helper_class.match(data, storagedev)) data["ID_FS_TYPE"] += "x" self.assertFalse(self.helper_class.match(data, partition)) data["ID_FS_TYPE"] = self.helper_class._base_type_specifier if self.helper_class._bootable: partition._bootable = False self.assertFalse(self.helper_class.match(data, partition)) partition._bootable = True if max_size: partition._size = max_size + 1 elif min_size: partition._size = min_size - 1 self.assertFalse(self.helper_class.match(data, partition)) partition._size = min_size
def test_get_device_by_name(self): dt = DeviceTree() dev1 = StorageDevice("dev1", exists=False, parents=[]) dev2 = StorageDevice("dev2", exists=False, parents=[dev1]) dt._add_device(dev1) dt._add_device(dev2) self.assertIsNone(dt.get_device_by_name("dev3")) self.assertEqual(dt.get_device_by_name("dev2"), dev2) self.assertEqual(dt.get_device_by_name("dev1"), dev1) dev2.complete = False self.assertEqual(dt.get_device_by_name("dev2"), None) self.assertEqual(dt.get_device_by_name("dev2", incomplete=True), dev2) dev3 = StorageDevice("dev3", exists=True, parents=[]) dt._add_device(dev3) dt.hide(dev3) self.assertIsNone(dt.get_device_by_name("dev3")) self.assertEqual(dt.get_device_by_name("dev3", hidden=True), dev3)
def test_add_device(self, *args): # pylint: disable=unused-argument dt = DeviceTree() dev1 = StorageDevice("dev1", exists=False, uuid=sentinel.dev1_uuid, parents=[]) self.assertEqual(dt.devices, list()) # things are called, updated as expected when a device is added with patch("blivet.devicetree.callbacks") as callbacks: dt._add_device(dev1) self.assertTrue(callbacks.device_added.called) self.assertEqual(dt.devices, [dev1]) self.assertTrue(dev1 in dt.devices) self.assertTrue(dev1.name in dt.names) self.assertTrue(dev1.add_hook.called) # pylint: disable=no-member # adding an already-added device fails self.assertRaisesRegex(ValueError, "already in tree", dt._add_device, dev1) dev2 = StorageDevice("dev2", exists=False, parents=[]) dev3 = StorageDevice("dev3", exists=False, parents=[dev1, dev2]) # adding a device with one or more parents not already in the tree fails self.assertRaisesRegex(DeviceTreeError, "parent.*not in tree", dt._add_device, dev3) self.assertFalse(dev2 in dt.devices) self.assertFalse(dev2.name in dt.names) dt._add_device(dev2) self.assertTrue(dev2 in dt.devices) self.assertTrue(dev2.name in dt.names) dt._add_device(dev3) self.assertTrue(dev3 in dt.devices) self.assertTrue(dev3.name in dt.names)
def generate_device_factory_request_btrfs_test(self, blockdev): dev1 = StorageDevice("dev1", fmt=get_format("btrfs"), size=Size("10 GiB")) dev2 = BTRFSVolumeDevice("dev2", data_level="single", parents=[dev1]) dev3 = BTRFSSubVolumeDevice( parents=[dev2], fmt=get_format("btrfs", mountpoint="/boot"), ) request = utils.generate_device_factory_request(self.storage, dev3) self.assertEqual( DeviceFactoryRequest.to_structure(request), { "device-spec": get_variant(Str, dev3.name), "disks": get_variant(List[Str], []), "mount-point": get_variant(Str, "/boot"), "reformat": get_variant(Bool, True), "format-type": get_variant(Str, "btrfs"), "label": get_variant(Str, ""), "luks-version": get_variant(Str, ""), "device-type": get_variant(Int, devicefactory.DEVICE_TYPE_BTRFS), "device-name": get_variant(Str, dev3.name), "device-size": get_variant(UInt64, Size("10 GiB").get_bytes()), "device-encrypted": get_variant(Bool, False), "device-raid-level": get_variant(Str, ""), "container-spec": get_variant(Str, dev2.name), "container-name": get_variant(Str, dev2.name), "container-size-policy": get_variant(Int64, Size("10 GiB").get_bytes()), "container-encrypted": get_variant(Bool, False), "container-raid-level": get_variant(Str, "single"), })
def test_volume_group(self): good_names = ['vg00', 'group-name', 'groupname-'] bad_names = ['-leading-hyphen', 'únicode', 'sp aces'] pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv]) for name in good_names: self.assertTrue(vg.is_name_valid(name)) for name in bad_names: self.assertFalse(vg.is_name_valid(name))
def test_mount_existing_system(self, mount): storage = create_storage() device = StorageDevice("dev1", fmt=get_format("ext4")) storage.devicetree._add_device(device) task = MountExistingSystemTask(storage, device, True) task.run() mount.assert_called_once_with( storage=storage, root_device=device, read_only=True )
def test_mount_device_with_options(self, mount): """Test MountDevice with options specified.""" self._add_device(StorageDevice("dev1", fmt=get_format("ext4"))) with tempfile.TemporaryDirectory() as d: self.interface.MountDevice("dev1", d, "ro,auto") mount.assert_called_once_with(mountpoint=d, options="ro,auto") mount.side_effect = FSError("Fake error.") with pytest.raises(MountFilesystemError) as cm: self.interface.MountDevice("dev1", "/path", "ro,auto") assert str(cm.value) == "Failed to mount dev1 at /path: Fake error."
def setUp(self): pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv]) self.fmt = blivet.formats.get_format("xfs") self.lv = LVMLogicalVolumeDevice("testlv", parents=[vg], fmt=self.fmt) pv2 = StorageDevice("pv2", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) pv3 = StorageDevice("pv3", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) vg2 = LVMVolumeGroupDevice("testvg2", parents=[pv2, pv3]) cache_req = LVMCacheRequest(Size("512 MiB"), [pv3], "writethrough") self.cached_lv = LVMLogicalVolumeDevice( "testcachedlv", parents=[vg2], fmt=blivet.formats.get_format("xfs"), exists=False, cache_request=cache_req)
def test_lvmcached_logical_volume_init(self): pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) pv2 = StorageDevice("pv2", fmt=blivet.formats.get_format("lvmpv"), size=Size("512 MiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv, pv2]) cache_req = LVMCacheRequest(Size("512 MiB"), [pv2], "writethrough") lv = LVMLogicalVolumeDevice("testlv", parents=[vg], fmt=blivet.formats.get_format("xfs"), exists=False, cache_request=cache_req) # the cache reserves space for its metadata from the requested size, but # it may require (and does in this case) a pmspare LV to be allocated self.assertEqual(lv.vg_space_used, Size("504 MiB")) # check that the LV behaves like a cached LV self.assertTrue(lv.cached) cache = lv.cache self.assertIsNotNone(cache) # check parameters reported by the (non-existing) cache # 512 MiB - 8 MiB (metadata) - 8 MiB (pmspare) self.assertEqual(cache.size, Size("496 MiB")) self.assertEqual(cache.md_size, Size("8 MiB")) self.assertEqual(cache.vg_space_used, Size("504 MiB")) self.assertIsInstance(cache.size, Size) self.assertIsInstance(cache.md_size, Size) self.assertIsInstance(cache.vg_space_used, Size) self.assertFalse(cache.exists) self.assertIsNone(cache.stats) self.assertEqual(cache.mode, "writethrough") self.assertIsNone(cache.backing_device_name) self.assertIsNone(cache.cache_device_name) self.assertEqual(set(cache.fast_pvs), set([pv2]))
def mount_existing_system_test(self, mount): storage = create_storage() device = StorageDevice("dev1", fmt=get_format("ext4")) storage.devicetree._add_device(device) with tempfile.TemporaryDirectory() as sysroot: task = MountExistingSystemTask(storage, sysroot, device, True) task.run() mount.assert_called_once_with(storage=storage, sysroot=sysroot, root_device=device, read_only=True)
def test_lvm_logical_volume_pv_free_cached(self): pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1025 MiB")) pv2 = StorageDevice("pv2", fmt=blivet.formats.get_format("lvmpv"), size=Size("513 MiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv, pv2]) pv_spec = LVPVSpec(pv, Size("256 MiB")) pv_spec2 = LVPVSpec(pv2, Size("256 MiB")) cache_req = LVMCacheRequest(Size("512 MiB"), [pv], "writethrough") lv = LVMLogicalVolumeDevice("testlv", parents=[vg], size=Size("512 MiB"), fmt=blivet.formats.get_format("xfs"), exists=False, cache_request=cache_req, pvs=[pv_spec, pv_spec2]) self.assertEqual(lv.seg_type, "linear") # 1024 MiB (free) - 256 MiB (LV part) - 504 MiB (cache shrank for pmspare space) self.assertEqual(pv.format.free, Size("264 MiB")) self.assertEqual(pv2.format.free, Size("256 MiB"))
def collect_containers_test(self): """Test CollectContainers.""" dev1 = StorageDevice("dev1", fmt=get_format("btrfs"), size=Size("10 GiB")) dev2 = BTRFSVolumeDevice("dev2", parents=[dev1]) self._add_device(dev1) self._add_device(dev2) self.assertEqual(self.interface.CollectContainers(DEVICE_TYPE_BTRFS), [dev2.name]) self.assertEqual(self.interface.CollectContainers(DEVICE_TYPE_LVM), [])
def test_vg_is_empty(self): pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1024 MiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv]) self.assertTrue(vg.is_empty) LVMLogicalVolumeDevice("testlv", parents=[vg], size=Size("512 MiB"), fmt=blivet.formats.get_format("xfs"), exists=False) self.assertFalse(vg.is_empty)
def test_find_unconfigured_luks(self): """Test FindUnconfiguredLUKS.""" self.assertEqual(self.interface.FindUnconfiguredLUKS(), []) dev1 = StorageDevice("dev1", fmt=get_format("ext4"), size=Size("10 GiB")) self._add_device(dev1) self.assertEqual(self.interface.FindUnconfiguredLUKS(), []) dev2 = LUKSDevice("dev2", parents=[dev1], fmt=get_format("luks"), size=Size("10 GiB")) self._add_device(dev2) self.assertEqual(self.interface.FindUnconfiguredLUKS(), ["dev2"])
def test_get_ancestors(self): """Test GetAncestors.""" dev1 = StorageDevice("dev1") self._add_device(dev1) dev2 = StorageDevice("dev2", parents=[dev1]) self._add_device(dev2) dev3 = StorageDevice("dev3", parents=[dev2]) self._add_device(dev3) dev4 = StorageDevice("dev4") self._add_device(dev4) dev5 = StorageDevice("dev5", parents=[dev4]) self._add_device(dev5) self.assertEqual(self.interface.GetAncestors(["dev1"]), []) self.assertEqual(self.interface.GetAncestors(["dev2"]), ["dev1"]) self.assertEqual(self.interface.GetAncestors(["dev3"]), ["dev1", "dev2"]) self.assertEqual(self.interface.GetAncestors(["dev2", "dev3"]), ["dev1", "dev2"]) self.assertEqual(self.interface.GetAncestors(["dev2", "dev5"]), ["dev1", "dev4"])
def generate_device_factory_request_lvm_test(self, blockdev): pv1 = StorageDevice("pv1", size=Size("1025 MiB"), fmt=get_format("lvmpv")) pv2 = StorageDevice("pv2", size=Size("513 MiB"), fmt=get_format("lvmpv")) vg = LVMVolumeGroupDevice("testvg", parents=[pv1, pv2]) lv = LVMLogicalVolumeDevice("testlv", size=Size("512 MiB"), parents=[vg], fmt=get_format("xfs"), exists=False, seg_type="raid1", pvs=[pv1, pv2]) request = utils.generate_device_factory_request(self.storage, lv) self.assertEqual( DeviceFactoryRequest.to_structure(request), { "device-spec": get_variant(Str, "testvg-testlv"), "disks": get_variant(List[Str], []), "mount-point": get_variant(Str, ""), "reformat": get_variant(Bool, True), "format-type": get_variant(Str, "xfs"), "label": get_variant(Str, ""), "luks-version": get_variant(Str, ""), "device-type": get_variant(Int, devicefactory.DEVICE_TYPE_LVM), "device-name": get_variant(Str, "testlv"), "device-size": get_variant(UInt64, Size("508 MiB").get_bytes()), "device-encrypted": get_variant(Bool, False), "device-raid-level": get_variant(Str, ""), "container-spec": get_variant(Str, "testvg"), "container-name": get_variant(Str, "testvg"), "container-size-policy": get_variant(Int64, Size("1.5 GiB")), "container-encrypted": get_variant(Bool, False), "container-raid-level": get_variant(Str, ""), })
def test_remove_device(self, *args): # pylint: disable=unused-argument dt = DeviceTree() dev1 = StorageDevice("dev1", exists=False, parents=[]) # removing a device not in the tree raises an exception six.assertRaisesRegex(self, ValueError, "not in tree", dt._remove_device, dev1) dt._add_device(dev1) with patch("blivet.devicetree.callbacks") as callbacks: dt._remove_device(dev1) self.assertTrue(callbacks.device_removed.called) self.assertFalse(dev1 in dt.devices) self.assertFalse(dev1.name in dt.names) self.assertTrue(dev1.remove_hook.called) # pylint: disable=no-member dev2 = StorageDevice("dev2", exists=False, parents=[dev1]) dt._add_device(dev1) dt._add_device(dev2) self.assertTrue(dev2 in dt.devices) self.assertTrue(dev2.name in dt.names) # removal of a non-leaf device raises an exception six.assertRaisesRegex(self, ValueError, "non-leaf device", dt._remove_device, dev1) self.assertTrue(dev1 in dt.devices) self.assertTrue(dev1.name in dt.names) self.assertTrue(dev2 in dt.devices) self.assertTrue(dev2.name in dt.names) # forcing removal of non-leaf device does not remove the children dt._remove_device(dev1, force=True) self.assertFalse(dev1 in dt.devices) self.assertFalse(dev1.name in dt.names) self.assertTrue(dev2 in dt.devices) self.assertTrue(dev2.name in dt.names)
def mount_device_test(self, mount): """Test MountDevice.""" self._add_device(StorageDevice("dev1", fmt=get_format("ext4"))) with tempfile.TemporaryDirectory() as d: self.interface.MountDevice("dev1", d) mount.assert_called_once_with(mountpoint=d) mount.side_effect = FSError("Fake error.") with self.assertRaises(MountFilesystemError) as cm: self.interface.MountDevice("dev1", "/path") self.assertEqual(str(cm.exception), "Failed to mount dev1 at /path: Fake error.")
def is_device_editable_test(self): """Test IsDeviceEditable.""" dev1 = StorageDevice("dev1", fmt=get_format("ext4"), size=Size("10 GiB")) dev2 = DiskDevice("dev2", fmt=get_format("disklabel"), size=Size("10 GiB")) self._add_device(dev1) self._add_device(dev2) self.assertEqual(self.interface.IsDeviceEditable("dev1"), False) self.assertEqual(self.interface.IsDeviceEditable("dev2"), True)
def test_lvm_logical_volume_mirror(self): pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1025 MiB")) pv2 = StorageDevice("pv2", fmt=blivet.formats.get_format("lvmpv"), size=Size("513 MiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv, pv2]) lv = LVMLogicalVolumeDevice("testlv", parents=[vg], size=Size("512 MiB"), fmt=blivet.formats.get_format("xfs"), exists=False, seg_type="mirror", pvs=[pv, pv2]) self.assertEqual(lv.seg_type, "mirror") # 512 MiB - 4 MiB (metadata) self.assertEqual(lv.size, Size("508 MiB")) self.assertEqual(lv._raid_level, raid.RAID1) self.assertTrue(lv.is_raid_lv) self.assertEqual(lv._num_raid_pvs, 2)
def test_unmount_device(self, unmount): """Test UnmountDevice.""" self._add_device(StorageDevice("dev1", fmt=get_format("ext4"))) with tempfile.TemporaryDirectory() as d: self.interface.UnmountDevice("dev1", d) unmount.assert_called_once_with(mountpoint=d) unmount.side_effect = FSError("Fake error.") with pytest.raises(MountFilesystemError) as cm: self.interface.UnmountDevice("dev1", "/path") assert str( cm.value) == "Failed to unmount dev1 from /path: Fake error."
def test_is_device_editable(self): """Test IsDeviceEditable.""" dev1 = StorageDevice("dev1", fmt=get_format("ext4"), size=Size("10 GiB")) dev2 = DiskDevice("dev2", fmt=get_format("disklabel"), size=Size("10 GiB")) self._add_device(dev1) self._add_device(dev2) assert self.interface.IsDeviceEditable("dev1") is False assert self.interface.IsDeviceEditable("dev2") is True
def test_opal_verification_old_firmware(self, mocked_arch, version_getter, xfs_mountable): """Check verify_opal_compatibility with an older firmware.""" storage = create_storage() mocked_arch.get_arch.return_value = "ppc64le" mocked_arch.is_powernv.return_value = True version_getter.return_value = "5.9.50-openpower1-p59fd803" xfs_mountable.return_value = True # No devices. self._verify_opal_compatibility(storage, message=None) # No mount points. dev1 = StorageDevice("dev1", size=Size("10 GiB")) storage.devicetree._add_device(dev1) self._verify_opal_compatibility(storage, message=None) # Different filesystem. dev1.format = get_format("ext2", mountpoint="/boot") self._verify_opal_compatibility(storage, message=None) # XFS on / dev1.format = get_format("xfs", mountpoint="/") self._verify_opal_compatibility(storage, message=( "Your firmware doesn't support XFS file system features " "on the /boot file system. The system will not be bootable. " "Please, upgrade the firmware or change the file system type." )) # XFS on /boot dev1.format = get_format("xfs", mountpoint="/boot") self._verify_opal_compatibility(storage, message=( "Your firmware doesn't support XFS file system features " "on the /boot file system. The system will not be bootable. " "Please, upgrade the firmware or change the file system type." ))
def get_raw_device_test(self): """Test GetRawDevice.""" dev1 = StorageDevice("dev1", fmt=get_format("ext4"), size=Size("10 GiB")) dev2 = LUKSDevice("dev2", parents=[dev1], fmt=get_format("luks"), size=Size("10 GiB")) self._add_device(dev1) self._add_device(dev2) self.assertEqual(self.interface.GetRawDevice("dev1"), "dev1") self.assertEqual(self.interface.GetRawDevice("dev2"), "dev1")
def test_storage_device(self, *patches): # pylint: disable=unused-argument # Check that / and NUL are rejected along with . and .. good_names = ['sda1', '1sda', 'good-name', 'cciss/c0d0'] bad_names = ['sda/1', 'sda\x00', '.', '..', 'cciss/..'] sd = StorageDevice("tester") for name in good_names: self.assertTrue(sd.is_name_valid(name)) for name in bad_names: self.assertFalse(sd.is_name_valid(name)) # Check that name validity check is omitted (only) when # device already exists # This test was added to prevent regression (see #1379145) for name in good_names: try: StorageDevice(name, exists=True) except ValueError: self.fail("Name check should not be performed nor failing") try: StorageDevice(name, exists=False) except ValueError: self.fail("Device name check failed when it shouldn't") for name in bad_names: try: StorageDevice(name, exists=True) except ValueError as e: if ' is not a valid name for this device' in str(e): self.fail("Device name checked on already existing device") with six.assertRaisesRegex(self, ValueError, ' is not a valid name for this device'): StorageDevice(name, exists=False)
def test_target_size(self): pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv]) orig_size = Size("800 MiB") lv = LVMLogicalVolumeDevice("testlv", parents=[vg], size=orig_size, fmt=blivet.formats.get_format("ext4"), exists=True) min_size = Size("200 MiB") lv.format.exists = True lv.format._min_instance_size = min_size lv.format._resizable = True # Make sure things are as expected to begin with. self.assertEqual(lv.min_size, min_size) self.assertEqual(lv.max_size, Size("1020 MiB")) self.assertEqual(lv.size, orig_size) # ValueError if size smaller than min_size with self.assertRaisesRegex(ValueError, "size.*smaller than the minimum"): lv.target_size = Size("1 MiB") # target size should be unchanged self.assertEqual(lv.target_size, orig_size) # ValueError if size larger than max_size with self.assertRaisesRegex(ValueError, "size.*larger than the maximum"): lv.target_size = Size("1 GiB") # target size should be unchanged self.assertEqual(lv.target_size, orig_size) # successful set of target size should also be reflected in size attr new_target = Size("900 MiB") lv.target_size = new_target self.assertEqual(lv.target_size, new_target) self.assertEqual(lv.size, new_target) # reset target size to original size lv.target_size = orig_size self.assertEqual(lv.target_size, orig_size) self.assertEqual(lv.size, orig_size)
def test_logical_volume(self): good_names = ['lv00', 'volume-name', 'volumename-'] bad_names = ['-leading-hyphen', 'únicode', 'sp aces', 'snapshot47', 'pvmove0', 'sub_tmetastring'] pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv]) lv = LVMLogicalVolumeDevice("testlv", parents=[vg], fmt=blivet.formats.get_format("xfs")) for name in good_names: self.assertTrue(lv.is_name_valid(name)) for name in bad_names: self.assertFalse(lv.is_name_valid(name))
def get_container_free_space_test(self): """Test GetContainerFreeSpace.""" dev1 = StorageDevice("dev1", fmt=get_format("lvmpv"), size=Size("10 GiB")) dev2 = LVMVolumeGroupDevice("dev2", parents=[dev1]) self._add_device(dev1) self._add_device(dev2) free_space = self.interface.GetContainerFreeSpace("dev1") self.assertEqual(free_space, 0) free_space = self.interface.GetContainerFreeSpace("dev2") self.assertGreater(free_space, Size("9 GiB").get_bytes()) self.assertLess(free_space, Size("10 GiB").get_bytes())
def set_device_passphrase_test(self): """Test SetDevicePassphrase.""" dev1 = StorageDevice("dev1", fmt=get_format("ext4"), size=Size("10 GiB")) self._add_device(dev1) dev2 = LUKSDevice("dev2", parents=[dev1], fmt=get_format("luks"), size=Size("10 GiB")) self._add_device(dev2) self.assertEqual(self.interface.FindUnconfiguredLUKS(), ["dev2"]) self.interface.SetDevicePassphrase("dev2", "123456") self.assertEqual(self.interface.FindUnconfiguredLUKS(), [])
def test_get_container_free_space(self): """Test GetContainerFreeSpace.""" dev1 = StorageDevice("dev1", fmt=get_format("lvmpv"), size=Size("10 GiB")) dev2 = LVMVolumeGroupDevice("dev2", parents=[dev1]) self._add_device(dev1) self._add_device(dev2) free_space = self.interface.GetContainerFreeSpace("dev1") assert free_space == 0 free_space = self.interface.GetContainerFreeSpace("dev2") assert free_space > Size("9 GiB").get_bytes() assert free_space < Size("10 GiB").get_bytes()
def test_get_devices(self): """Test GetDevices.""" self.assertEqual(self.interface.GetDevices(), []) self._add_device(DiskDevice( "dev1", fmt=get_format("ext4"), size=Size("10 GiB") )) self._add_device(StorageDevice( "dev2", fmt=get_format("ext4"), size=Size("10 GiB") )) self.assertEqual(self.interface.GetDevices(), ["dev1", "dev2"])
def test_lvmthin_snap_shot_device_init(self): pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"), size=Size("1 GiB")) vg = LVMVolumeGroupDevice("testvg", parents=[pv]) pool = LVMLogicalVolumeDevice("pool1", parents=[vg], size=Size("500 MiB"), seg_type="thin-pool") thinlv = LVMLogicalVolumeDevice("thinlv", parents=[pool], size=Size("200 MiB"), seg_type="thin") with self.assertRaisesRegex( ValueError, "lvm snapshot origin volume must already exist"): LVMLogicalVolumeDevice("snap1", parents=[pool], origin=thinlv, seg_type="thin") with self.assertRaisesRegex( ValueError, "lvm snapshot origin must be a logical volume"): LVMLogicalVolumeDevice("snap1", parents=[pool], origin=pv, seg_type="thin") # now make the constructor succeed so we can test some properties thinlv.exists = True snap1 = LVMLogicalVolumeDevice("snap1", parents=[pool], origin=thinlv, seg_type="thin") self.assertEqual(snap1.isleaf, True) self.assertEqual(snap1.direct, True) self.assertEqual(thinlv.isleaf, True) self.assertEqual(thinlv.direct, True) self.assertEqual(snap1.depends_on(thinlv), True) self.assertEqual(thinlv.depends_on(snap1), False) # existing thin snapshots do not depend on their origin snap1.exists = True self.assertEqual(snap1.depends_on(thinlv), False)