def test_recursive_remove(self): devicetree = DeviceTree() devicetree._add_device(self.disk1) devicetree._add_device(self.partition1) devicetree._add_device(self.partition2) devicetree._add_device(self.disk2) devicetree._add_device(self.vg) devicetree._add_device(self.lv) self.assertIn(self.disk1, devicetree.devices) self.assertIn(self.partition1, devicetree.devices) self.assertIn(self.lv, devicetree.devices) self.assertEqual(devicetree.get_device_by_name(self.disk1.name), self.disk1) self.assertIsNotNone(devicetree.get_device_by_name(self.partition1.name)) self.assertIsNotNone(devicetree.get_device_by_name(self.partition1.name, hidden=True)) self.assertIsNotNone(devicetree.get_device_by_name(self.lv.name, hidden=True)) self.assertIsNotNone(devicetree.get_device_by_path(self.lv.path, hidden=True)) self.assertIsNotNone(devicetree.get_device_by_id(self.partition2.id, hidden=True, incomplete=True)) self.assertEqual(len(devicetree.get_dependent_devices(self.disk1)), 4) with patch('blivet.devicetree.ActionDestroyFormat.apply'): devicetree.recursive_remove(self.disk1) self.assertTrue(self.disk1 in devicetree.devices) self.assertFalse(self.partition1 in devicetree.devices) self.assertFalse(self.partition2 in devicetree.devices) self.assertFalse(self.vg in devicetree.devices) self.assertFalse(self.lv in devicetree.devices)
def test_get_related_disks(self): tree = DeviceTree() sda = DiskDevice("sda", size=Size('300g')) sdb = DiskDevice("sdb", size=Size('300g')) sdc = DiskDevice("sdc", size=Size('300G')) tree._add_device(sda) tree._add_device(sdb) tree._add_device(sdc) self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) sda.format = get_format("lvmpv", device=sda.path) sdb.format = get_format("lvmpv", device=sdb.path) vg = LVMVolumeGroupDevice("relvg", parents=[sda, sdb]) tree._add_device(vg) self.assertEqual(tree.get_related_disks(sda), set([sda, sdb])) self.assertEqual(tree.get_related_disks(sdb), set([sda, sdb])) self.assertEqual(tree.get_related_disks(sdc), set()) tree.hide(sda) self.assertEqual(tree.get_related_disks(sda), set([sda, sdb])) self.assertEqual(tree.get_related_disks(sdb), set([sda, sdb])) tree.hide(sdb) self.assertEqual(tree.get_related_disks(sda), set([sda, sdb])) self.assertEqual(tree.get_related_disks(sdb), set([sda, sdb])) tree.unhide(sda) self.assertEqual(tree.get_related_disks(sda), set([sda, sdb])) self.assertEqual(tree.get_related_disks(sdb), set([sda, sdb]))
def test_run(self, *args): """Test partition device populator.""" device_get_partition_disk = args[0] device_get_name = args[1] get_device_by_name = args[2] devicetree = DeviceTree() data = Mock() # for every case: # 1. device(s) in tree # 2. lvm filter updated # 3. exceptions raised # base case: disk is already in the tree, normal disk fmt = get_format("disklabel", exists=True, device="/dev/xyz") disk = DiskDevice("xyz", fmt=fmt, exists=True) devicetree._add_device(disk) device_name = "xyz1" device_get_name.return_value = device_name device_get_partition_disk.return_value = "xyz" get_device_by_name.return_value = disk helper = self.helper_class(devicetree, data) device = helper.run() self.assertIsInstance(device, PartitionDevice) self.assertTrue(device.exists) self.assertEqual(device.name, device_name) self.assertTrue(device in devicetree.devices)
def test_expand_taglist(self): tree = DeviceTree() sda = DiskDevice("sda") sdb = DiskDevice("sdb") sdc = DiskDevice("sdc") sdd = DiskDevice("sdd") tree._add_device(sda) tree._add_device(sdb) tree._add_device(sdc) tree._add_device(sdd) sda.tags = {Tags.remote} sdb.tags = {Tags.ssd} sdc.tags = {Tags.local, Tags.ssd} sdd.tags = set() self.assertEqual(tree.expand_taglist(["sda", "sdb"]), {"sda", "sdb"}) self.assertEqual(tree.expand_taglist(["@local"]), {"sdc"}) self.assertEqual(tree.expand_taglist(["@ssd"]), {"sdb", "sdc"}) self.assertEqual(tree.expand_taglist(["@ssd", "sdd", "@local"]), {"sdb", "sdc", "sdd"}) with self.assertRaises(ValueError): tree.expand_taglist(["sdd", "@invalid_tag"])
def test_run(self, *args): """Test loop device populator.""" device_get_name = args[1] get_backing_file = args[2] devicetree = DeviceTree() data = Mock() # Add backing file and loop device. devicetree.get_device_by_name.return_value = None device_name = "loop3" device_get_name.return_value = device_name backing_file = "/some/file" get_backing_file.return_value = backing_file helper = self.helper_class(devicetree, data) device = helper.run() self.assertIsInstance(device, LoopDevice) self.assertTrue(device in devicetree.devices) self.assertTrue(device.exists) self.assertEqual(device.name, device_name) self.assertIsInstance(device.parents[0], FileDevice) self.assertTrue(device.parents[0].exists) self.assertEqual(devicetree.get_device_by_name.call_count, 1) # pylint: disable=no-member devicetree.get_device_by_name.assert_called_with(backing_file) # pylint: disable=no-member
def test_resolve_device(self): dt = DeviceTree() dev1_label = "dev1_label" dev1_uuid = "1234-56-7890" fmt1 = get_format("ext4", label=dev1_label, uuid=dev1_uuid) dev1 = StorageDevice("dev1", exists=True, fmt=fmt1, size=fmt1.min_size) dt._add_device(dev1) dev2_label = "dev2_label" fmt2 = get_format("swap", label=dev2_label) dev2 = StorageDevice("dev2", exists=True, fmt=fmt2) dt._add_device(dev2) dev3 = StorageDevice("sdp2", exists=True) dt._add_device(dev3) dt.edd_dict.update({"dev1": 0x81, "dev2": 0x82}) self.assertEqual(dt.resolve_device(dev1.name), dev1) self.assertEqual(dt.resolve_device("LABEL=%s" % dev1_label), dev1) self.assertEqual(dt.resolve_device("UUID=%s" % dev1_label), None) self.assertEqual(dt.resolve_device("UUID=%s" % dev1_uuid), dev1) self.assertEqual(dt.resolve_device("/dev/dev1"), dev1) self.assertEqual(dt.resolve_device("dev2"), dev2) self.assertEqual(dt.resolve_device("0x82"), dev2) self.assertEqual(dt.resolve_device(dev3.name), dev3)
def test_run(self, *args): """Test multipath device populator.""" device_get_name = args[0] add_slave_devices = args[1] devicetree = DeviceTree() data = {"DM_UUID": "1-2-3-4"} device_name = "mpathtest" device_get_name.return_value = device_name slave_1 = Mock(tags=set()) slave_1.parents = [] slave_2 = Mock(tags=set()) slave_2.parents = [] devicetree._add_device(slave_1) devicetree._add_device(slave_2) add_slave_devices.return_value = [slave_1, slave_2] helper = self.helper_class(devicetree, data) device = helper.run() self.assertIsInstance(device, MultipathDevice) self.assertTrue(device.exists) self.assertEqual(device.name, device_name) self.assertTrue(device in devicetree.devices)
def test_device_name(self): # check that devicetree.names property contains all device's names # mock lvs_info to avoid blockdev call allowing run as non-root with patch.object(LVsInfo, 'cache', new_callable=PropertyMock) as mock_lvs_cache: mock_lvs_cache.return_value = {"sdmock": "dummy"} tree = DeviceTree() dev_names = ["sda", "sdb", "sdc"] for dev_name in dev_names: dev = DiskDevice(dev_name) tree._add_device(dev) self.assertTrue(dev in tree.devices) # frobnicate a bit with the hidden status of the devices: # * hide sda # * hide and unhide again sdb # * leave sdc unchanged tree.hide(tree.get_device_by_name("sda")) tree.hide(tree.get_device_by_name("sdb")) tree.unhide(tree.get_device_by_name("sdb", hidden=True)) # some lvs names may be already present in the system (mocked) lv_info = list(lvs_info.cache.keys()) # all devices should still be present in the tree.names self.assertEqual(sorted(tree.names), sorted(lv_info + dev_names))
def test_run(self, *args): """Test multipath device populator.""" device_get_name = args[0] add_slave_devices = args[1] devicetree = DeviceTree() # set up some fake udev data to verify handling of specific entries data = Mock() _data = {"ID_WWN": "0x5000c50086fb75ca", "DM_UUID": "1-2-3-4"} def _getitem_(key, extra=None): return _data.get(key, extra) data.get = Mock(side_effect=_getitem_) data.__getitem__ = Mock(side_effect=_getitem_) device_name = "mpathtest" device_get_name.return_value = device_name slave_1 = Mock(tags=set()) slave_1.parents = [] slave_2 = Mock(tags=set()) slave_2.parents = [] devicetree._add_device(slave_1) devicetree._add_device(slave_2) add_slave_devices.return_value = [slave_1, slave_2] helper = self.helper_class(devicetree, data) device = helper.run() self.assertIsInstance(device, MultipathDevice) self.assertTrue(device.exists) self.assertEqual(device.name, device_name) self.assertEqual(device.wwn, _data["ID_WWN"]) self.assertTrue(device in devicetree.devices)
def test_hide_ignored_disks(self): tree = DeviceTree() sda = DiskDevice("sda") sdb = DiskDevice("sdb") sdc = DiskDevice("sdc") tree._add_device(sda) tree._add_device(sdb) tree._add_device(sdc) self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) # test ignored_disks tree.ignored_disks = ["sdb"] # verify hide is called as expected with patch.object(tree, "hide") as hide: tree._hide_ignored_disks() hide.assert_called_with(sdb) # verify that hide works as expected tree._hide_ignored_disks() self.assertTrue(sda in tree.devices) self.assertFalse(sdb in tree.devices) self.assertTrue(sdc in tree.devices) # unhide sdb and make sure it works tree.unhide(sdb) self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) # test exclusive_disks tree.ignored_disks = [] tree.exclusive_disks = ["sdc"] with patch.object(tree, "hide") as hide: tree._hide_ignored_disks() hide.assert_any_call(sda) hide.assert_any_call(sdb) tree._hide_ignored_disks() self.assertFalse(sda in tree.devices) self.assertFalse(sdb in tree.devices) self.assertTrue(sdc in tree.devices) tree.unhide(sda) tree.unhide(sdb) self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices)
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_run(self, *args): """Test lvm device populator.""" device_get_lv_vg_name = args[0] device_get_name = args[1] get_device_by_name = args[3] devicetree = DeviceTree() data = Mock() # Add slave/parent devices and then look up the device. device_get_name.return_value = sentinel.lv_name devicetree.get_device_by_name.return_value = None # pylint: disable=unused-argument def _get_device_by_name(name, **kwargs): if name == sentinel.lv_name: return sentinel.lv_device get_device_by_name.side_effect = _get_device_by_name device_get_lv_vg_name.return_value = sentinel.vg_name helper = self.helper_class(devicetree, data) self.assertEqual(helper.run(), sentinel.lv_device) self.assertEqual(devicetree.get_device_by_name.call_count, 3) # pylint: disable=no-member get_device_by_name.assert_has_calls([ call(sentinel.vg_name, hidden=True), call(sentinel.vg_name), call(sentinel.lv_name) ]) # Add slave/parent devices, but the device is still not in the tree get_device_by_name.side_effect = None get_device_by_name.return_value = None self.assertEqual(helper.run(), None) get_device_by_name.assert_called_with(sentinel.lv_name) # A non-vg device with the same name as the vg is already in the tree. # pylint: disable=unused-argument def _get_device_by_name2(name, **kwargs): if name == sentinel.lv_name: return sentinel.lv_device elif name == sentinel.vg_name: return sentinel.non_vg_device get_device_by_name.side_effect = _get_device_by_name2 if six.PY3: with self.assertLogs('blivet', level='WARNING') as log_cm: self.assertEqual(helper.run(), sentinel.lv_device) log_entry = "WARNING:blivet:found non-vg device with name %s" % sentinel.vg_name self.assertTrue(log_entry in log_cm.output) else: self.assertEqual(helper.run(), sentinel.lv_device)
def test_device_name(self): # check that devicetree.names property contains all device's names # mock lvs_info to avoid blockdev call allowing run as non-root with patch.object(LVsInfo, 'cache', new_callable=PropertyMock) as mock_lvs_cache: mock_lvs_cache.return_value = { "sdmock": "dummy", "testvg-testlv": "dummy" } tree = DeviceTree() dev_names = ["sda", "sdb", "sdc"] for dev_name in dev_names: dev = DiskDevice(dev_name, size=Size("1 GiB")) tree._add_device(dev) self.assertTrue(dev in tree.devices) self.assertTrue(dev.name in tree.names) dev.format = get_format("lvmpv", device=dev.path) vg = LVMVolumeGroupDevice("testvg", parents=[dev]) tree._add_device(vg) dev_names.append(vg.name) lv = LVMLogicalVolumeDevice("testlv", parents=[vg]) tree._add_device(lv) dev_names.append(lv.name) # frobnicate a bit with the hidden status of the devices: # * hide sda # * hide and unhide again sdb # * leave sdc unchanged tree.hide(tree.get_device_by_name("sda")) tree.hide(tree.get_device_by_name("sdb")) tree.unhide(tree.get_device_by_name("sdb", hidden=True)) # some lvs names may be already present in the system (mocked) lv_info = list(lvs_info.cache.keys()) # all devices should still be present in the tree.names self.assertEqual(set(tree.names), set(lv_info + dev_names)) # "remove" the LV, it should no longer be in the list tree.actions._actions.append( Mock(device=lv, type=ACTION_TYPE_DESTROY, obj=ACTION_OBJECT_DEVICE)) tree._remove_device(lv) self.assertFalse(lv.name in tree.names)
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 six.assertRaisesRegex(self, DeviceTreeError, "Trying to add already existing device.", dt._add_device, dev1) # adding a device with the same UUID dev_clone = StorageDevice("dev_clone", exists=False, uuid=sentinel.dev1_uuid, parents=[]) six.assertRaisesRegex(self, DuplicateUUIDError, "Duplicate UUID.*", dt._add_device, dev_clone) 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 six.assertRaisesRegex(self, 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 test_run(self, *args): """Test optical device populator.""" device_get_name = args[0] devicetree = DeviceTree() data = Mock() helper = self.helper_class(devicetree, data) device_name = "sr0" device_get_name.return_value = device_name device = helper.run() self.assertIsInstance(device, OpticalDevice) self.assertTrue(device.exists) self.assertEqual(device.name, device_name) self.assertTrue(device in devicetree.devices)
def test_run(self): if self.udev_type is None: return devicetree = DeviceTree() data = dict() device = Mock() with patch("blivet.udev.device_get_format", return_value=self.udev_type): helper = self.helper_class(devicetree, data, device) helper.run() self.assertEqual(device.format.type, self.blivet_type, msg="FormatPopulator.run failed for %s" % self.udev_type)
def test_run(self, *args): """Test md device populator.""" device_get_md_name = args[0] get_device_by_name = args[4] devicetree = DeviceTree() # base case: _add_slave_devices gets the array into the tree data = Mock() device = Mock() device.parents = [] device_name = "mdtest" device_get_md_name.return_value = device_name get_device_by_name.return_value = device helper = self.helper_class(devicetree, data) self.assertEqual(helper.run(), device)
def test_run(self, *args): """Test disk device populator.""" device_get_name = args[0] devicetree = DeviceTree() # set up some fake udev data to verify handling of specific entries data = {"SYS_PATH": "dummy", "ID_WWN": "0x5000c50086fb75ca"} device_name = "nop" device_get_name.return_value = device_name helper = self.helper_class(devicetree, data) device = helper.run() self.assertIsInstance(device, DiskDevice) self.assertTrue(device.exists) self.assertTrue(device.is_disk) self.assertEqual(device.wwn, data["ID_WWN"]) self.assertEqual(device.name, device_name) self.assertTrue(device in devicetree.devices)
def test_reset(self): dt = DeviceTree() names = ["fakedev1", "fakedev2"] for name in names: device = Mock(name=name, spec=StorageDevice, parents=[], exists=True) dt._devices.append(device) dt.names = names[:] dt.actions._actions.append(Mock(name="fake action")) lvm.lvm_cc_addFilterRejectRegexp("xxx") lvm.config_args_data["filterAccepts"].append("yyy") dt.ignored_disks.append(names[0]) dt.exclusive_disks.append(names[1]) dt._hidden.append(dt._devices.pop(1)) dt.edd_dict = {"a": 22} dt.reset() empty_list = list() self.assertEqual(dt._devices, empty_list) self.assertEqual(list(dt.actions), empty_list) self.assertIsInstance(dt.actions, ActionList) self.assertEqual(dt._hidden, empty_list) self.assertEqual(lvm.config_args_data["filterAccepts"], empty_list) self.assertEqual(lvm.config_args_data["filterRejects"], empty_list) self.assertEqual(dt.exclusive_disks, empty_list) self.assertEqual(dt.ignored_disks, empty_list) self.assertEqual(dt.edd_dict, dict())
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 setUp(self): self.tree = DeviceTree() self.sda = DiskDevice("sda") self.sdb = DiskDevice("sdb") self.sdc = DiskDevice("sdc") self.tree._add_device(self.sda) self.tree._add_device(self.sdb) self.tree._add_device(self.sdc) self.assertTrue(self.sda in self.tree.devices) self.assertTrue(self.sdb in self.tree.devices) self.assertTrue(self.sdc in self.tree.devices) # now test exclusive_disks special cases for multipath self.sda.format = get_format("multipath_member", exists=True) self.sdb.format = get_format("multipath_member", exists=True) self.sdc.format = get_format("multipath_member", exists=True) self.mpatha = MultipathDevice("mpatha", parents=[self.sda, self.sdb, self.sdc]) self.tree._add_device(self.mpatha)
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 test_run(self, *args): """Test dm device populator.""" device_is_dm_livecd = args[2] device_get_name = args[1] devicetree = DeviceTree() # The general case for dm devices is that adding the slave/parent devices # will result in the dm device itself being in the tree. device = Mock() devicetree.get_device_by_name.return_value = device data = {"DM_UUID": sentinel.dm_uuid} helper = self.helper_class(devicetree, data) self.assertEqual(helper.run(), device) self.assertEqual(devicetree._add_slave_devices.call_count, 1) # pylint: disable=no-member self.assertEqual(devicetree.get_device_by_name.call_count, 1) # pylint: disable=no-member # since we faked the lookup as if the device was already in the tree # the helper should not have added it, meaning it shouldn't be there self.assertFalse(device in devicetree.devices) # The other case is adding a live media image parent = Mock() parent.parents = [] devicetree._add_slave_devices.return_value = [parent] devicetree._add_device(parent) devicetree.get_device_by_name.return_value = None device_name = "livedevice" device_get_name.return_value = device_name device_is_dm_livecd.return_value = True device = helper.run() self.assertIsInstance(device, DMDevice) self.assertTrue(device in devicetree.devices) self.assertEqual(device.dm_uuid, sentinel.dm_uuid) self.assertEqual(device.name, device_name) self.assertEqual(device.sysfs_path, sentinel.sysfs_path) self.assertEqual(list(device.parents), [parent])
def test_ignored_disk_tags(self): tree = DeviceTree() fake_ssd = Mock(name="fake_ssd", spec=StorageDevice, parents=[], tags=[Tags.ssd], exists=True) fake_local = Mock(name="fake_local", spec=StorageDevice, parents=[], tags=[Tags.local], exists=True) tree._devices.extend([fake_ssd, fake_local]) self.assertFalse(tree._is_ignored_disk(fake_ssd)) self.assertFalse(tree._is_ignored_disk(fake_local)) tree.ignored_disks.append("@ssd") self.assertTrue(tree._is_ignored_disk(fake_ssd)) self.assertFalse(tree._is_ignored_disk(fake_local)) tree.exclusive_disks.append("@local") self.assertTrue(tree._is_ignored_disk(fake_ssd)) self.assertFalse(tree._is_ignored_disk(fake_local))
def setUp(self): """Set up the test.""" self.maxDiff = None self.devicetree = DeviceTree() self.fsset = FSSet(self.devicetree)
def test_run(self, *args): """Test lvm format populator.""" get_device_by_uuid = args[0] devicetree = DeviceTree() data = dict() device = Mock() device.parents = [] device.size = Size("10g") devicetree._add_device(device) # pylint: disable=attribute-defined-outside-init self._pvs = blockdev.lvm.pvs self._vgs = blockdev.lvm.vgs self._lvs = blockdev.lvm.lvs blockdev.lvm.pvs = Mock(return_value=[]) blockdev.lvm.vgs = Mock(return_value=[]) blockdev.lvm.lvs = Mock(return_value=[]) self.addCleanup(self._clean_up) # base case: pv format with no vg with patch("blivet.udev.device_get_format", return_value=self.udev_type): helper = self.helper_class(devicetree, data, device) helper.run() self.assertEqual( device.format.type, self.blivet_type, msg="Wrong format type after FormatPopulator.run on %s" % self.udev_type) # pv belongs to a valid vg which is already in the tree (no lvs) pv_info = Mock() pv_info.vg_name = "testvgname" pv_info.vg_uuid = sentinel.vg_uuid pv_info.pe_start = 0 pv_info.pv_free = 0 device.path = sentinel.pv_path vg_device = Mock() vg_device.parents = [] vg_device.lvs = [] get_device_by_uuid.return_value = vg_device with patch("blivet.static_data.lvm_info.PVsInfo.cache", new_callable=PropertyMock) as mock_pvs_cache: mock_pvs_cache.return_value = {sentinel.pv_path: pv_info} with patch("blivet.udev.device_get_format", return_value=self.udev_type): helper = self.helper_class(devicetree, data, device) self.assertFalse(device in vg_device.parents) helper.run() self.assertEqual( device.format.type, self.blivet_type, msg="Wrong format type after FormatPopulator.run on %s" % self.udev_type) self.assertEqual(get_device_by_uuid.call_count, 3) get_device_by_uuid.assert_called_with(pv_info.vg_uuid, incomplete=True) self.assertTrue(device in vg_device.parents) get_device_by_uuid.reset_mock() get_device_by_uuid.return_value = None # pv belongs to a valid vg which is not in the tree (no lvs, either) pv_info.vg_size = "10g" pv_info.vg_free = 0 pv_info.vg_extent_size = "4m" pv_info.vg_extent_count = 2500 pv_info.vg_free_count = 0 pv_info.vg_pv_count = 1 with patch("blivet.static_data.lvm_info.PVsInfo.cache", new_callable=PropertyMock) as mock_pvs_cache: mock_pvs_cache.return_value = {sentinel.pv_path: pv_info} with patch("blivet.udev.device_get_format", return_value=self.udev_type): helper = self.helper_class(devicetree, data, device) helper.run() self.assertEqual( device.format.type, self.blivet_type, msg="Wrong format type after FormatPopulator.run on %s" % self.udev_type) self.assertEqual(get_device_by_uuid.call_count, 2) get_device_by_uuid.assert_called_with(pv_info.vg_uuid, incomplete=True) vg_device = devicetree.get_device_by_name(pv_info.vg_name) self.assertTrue(vg_device is not None) devicetree._remove_device(vg_device) get_device_by_uuid.reset_mock() # pv belongs to a valid vg not in the tree with two lvs lv1 = Mock() lv1.vg_name = pv_info.vg_name lv1.lv_name = "testlv1" lv1.uuid = sentinel.lv1_uuid lv1.attr = "-wi-ao----" lv1.size = "2g" lv1.segtype = "linear" lv1_name = "%s-%s" % (pv_info.vg_name, lv1.lv_name) lv2 = Mock() lv2.vg_name = pv_info.vg_name lv2.lv_name = "testlv2" lv2.uuid = sentinel.lv2_uuid lv2.attr = "-wi-ao----" lv2.size = "7g" lv2.segtype = "linear" lv2_name = "%s-%s" % (pv_info.vg_name, lv2.lv_name) lv_info = {lv1_name: lv1, lv2_name: lv2} device.format.container_uuid = pv_info.vg_uuid def gdbu(uuid, **kwargs): # pylint: disable=unused-argument # This version doesn't check format UUIDs return next((d for d in devicetree.devices if d.uuid == uuid), None) get_device_by_uuid.side_effect = gdbu with patch("blivet.static_data.lvm_info.PVsInfo.cache", new_callable=PropertyMock) as mock_pvs_cache: mock_pvs_cache.return_value = {sentinel.pv_path: pv_info} with patch("blivet.static_data.lvm_info.LVsInfo.cache", new_callable=PropertyMock) as mock_lvs_cache: mock_lvs_cache.return_value = lv_info with patch("blivet.udev.device_get_format", return_value=self.udev_type): self.assertEqual( devicetree.get_device_by_name(pv_info.vg_name, incomplete=True), None) helper = self.helper_class(devicetree, data, device) helper.run() self.assertEqual( device.format.type, self.blivet_type, msg="Wrong format type after FormatPopulator.run on %s" % self.udev_type) self.assertEqual(get_device_by_uuid.call_count, 4, get_device_by_uuid.mock_calls ) # two for vg and one for each lv get_device_by_uuid.assert_has_calls([ call(pv_info.vg_uuid, incomplete=True), call(lv1.uuid), call(lv2.uuid) ], any_order=True) vg_device = devicetree.get_device_by_name(pv_info.vg_name) self.assertTrue(vg_device is not None) lv1_device = devicetree.get_device_by_name(lv1_name) self.assertEqual(lv1_device.uuid, lv1.uuid) lv2_device = devicetree.get_device_by_name(lv2_name) self.assertEqual(lv2_device.uuid, lv2.uuid)
def test_hide_ignored_disks(self): tree = DeviceTree() sda = DiskDevice("sda") sdb = DiskDevice("sdb") sdc = DiskDevice("sdc") tree._add_device(sda) tree._add_device(sdb) tree._add_device(sdc) self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) # test ignored_disks tree.ignored_disks = ["sdb"] # verify hide is called as expected with patch.object(tree, "hide") as hide: tree._hide_ignored_disks() hide.assert_called_with(sdb) # verify that hide works as expected tree._hide_ignored_disks() self.assertTrue(sda in tree.devices) self.assertFalse(sdb in tree.devices) self.assertTrue(sdc in tree.devices) # unhide sdb and make sure it works tree.unhide(sdb) self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) # test exclusive_disks tree.ignored_disks = [] tree.exclusive_disks = ["sdc"] with patch.object(tree, "hide") as hide: tree._hide_ignored_disks() hide.assert_any_call(sda) hide.assert_any_call(sdb) tree._hide_ignored_disks() self.assertFalse(sda in tree.devices) self.assertFalse(sdb in tree.devices) self.assertTrue(sdc in tree.devices) tree.unhide(sda) tree.unhide(sdb) self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) # now test exclusive_disks special cases for multipath sda.format = get_format("multipath_member", exists=True) sdb.format = get_format("multipath_member", exists=True) sdc.format = get_format("multipath_member", exists=True) mpatha = MultipathDevice("mpatha", parents=[sda, sdb, sdc]) tree._add_device(mpatha) tree.ignored_disks = [] tree.exclusive_disks = ["mpatha"] with patch.object(tree, "hide") as hide: tree._hide_ignored_disks() self.assertFalse(hide.called) tree._hide_ignored_disks() self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) self.assertTrue(mpatha in tree.devices) # all members in exclusive_disks implies the mpath in exclusive_disks tree.exclusive_disks = ["sda", "sdb", "sdc"] with patch.object(tree, "hide") as hide: tree._hide_ignored_disks() self.assertFalse(hide.called) tree._hide_ignored_disks() self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertTrue(sdc in tree.devices) self.assertTrue(mpatha in tree.devices) tree.exclusive_disks = ["sda", "sdb"] with patch.object(tree, "hide") as hide: tree._hide_ignored_disks() hide.assert_any_call(mpatha) hide.assert_any_call(sdc) # verify that hide works as expected tree._hide_ignored_disks() self.assertTrue(sda in tree.devices) self.assertTrue(sdb in tree.devices) self.assertFalse(sdc in tree.devices) self.assertFalse(mpatha in tree.devices)
def test_run(self, *args): """Test md format populator.""" get_device_by_uuid = args[0] get_devices = args[1] device_is_md = args[2] devicetree = DeviceTree() data = dict() device = Mock() device.name = sentinel.dev1_name device.parents = [] device.size = Size("10g") devicetree._add_device(device) # pylint: disable=attribute-defined-outside-init self._examine = blockdev.md.examine blockdev.md.examine = Mock() self.addCleanup(self._clean_up) # member belongs to a valid array which is already in the tree md_info = Mock() md_info.uuid = sentinel.md_uuid blockdev.md.examine.return_value = md_info md_device = Mock() get_device_by_uuid.return_value = md_device with patch("blivet.udev.device_get_format", return_value=self.udev_type): helper = self.helper_class(devicetree, data, device) helper.run() self.assertEqual( device.format.type, self.blivet_type, msg="Wrong format type after FormatPopulator.run on %s" % self.udev_type) self.assertEqual(get_device_by_uuid.call_count, 1) get_device_by_uuid.assert_called_with(md_info.uuid, incomplete=True) md_device.parents.append.assert_called_once_with(device) # pylint: disable=no-member get_device_by_uuid.reset_mock() get_device_by_uuid.return_value = None # first of two members belonging to a valid array which is not in the tree array_name = "mdtest" md_info.level = "raid1" md_info.num_devices = 2 md_info.metadata = "1.2" md_info.device = "/dev/md/" + array_name blockdev.md.examine.return_value = md_info device_is_md.return_value = True md_udev = { "MD_LEVEL": md_info.level, "MD_UUID": sentinel.md_uuid, "MD_DEVNAME": array_name } get_devices.return_value = [md_udev] with patch("blivet.udev.device_get_format", return_value=self.udev_type): helper = self.helper_class(devicetree, data, device) helper.run() self.assertEqual( device.format.type, self.blivet_type, msg="Wrong format type after FormatPopulator.run on %s" % self.udev_type) self.assertEqual(get_device_by_uuid.call_count, 1) get_device_by_uuid.assert_called_with(md_info.uuid, incomplete=True) array = devicetree.get_device_by_name(array_name) self.assertTrue(array is None) array = devicetree.get_device_by_name(array_name, incomplete=True) self.assertTrue(array is not None) self.assertFalse(array.complete) self.assertEqual(array.name, array_name) get_device_by_uuid.reset_mock() array = devicetree.get_device_by_name(array_name, incomplete=True) get_device_by_uuid.return_value = array # second of two members belonging to a valid array device2 = Mock() device2.name = sentinel.dev2_name device2.parents = [] device2.size = Size("10g") devicetree._add_device(device2) with patch("blivet.udev.device_get_format", return_value=self.udev_type): helper = self.helper_class(devicetree, data, device2) helper.run() self.assertEqual( device2.format.type, self.blivet_type, msg="Wrong format type after FormatPopulator.run on %s" % self.udev_type) self.assertEqual(get_device_by_uuid.call_count, 1) # one for the array get_device_by_uuid.assert_called_with(md_info.uuid, incomplete=True) array = devicetree.get_device_by_name(array_name) self.assertTrue(array is not None) self.assertTrue(array.complete) self.assertEqual(array.name, array_name)