Пример #1
0
    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)
Пример #2
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"}

            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))
Пример #3
0
    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)
Пример #4
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)
Пример #5
0
    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)
Пример #6
0
    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)
Пример #7
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)
Пример #8
0
    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)
Пример #9
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)
Пример #10
0
    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)