Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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)