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_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 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_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)