예제 #1
0
 def test_blockdev_detects_dasd_device_id_and_unformatted_no_ptable(self):
     self.probe_data = _get_data('probert_storage_dasd.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/dasde']
     expected_dict = {
         'device_id': '0.0.2520',
         'id': 'disk-dasde',
         'path': '/dev/dasde',
         'type': 'disk'
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #2
0
 def test_blockdev_detects_dasd_device_id_and_vtoc_ptable(self):
     self.probe_data = _get_data('probert_storage_dasd.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/dasdd']
     expected_dict = {
         'device_id': '0.0.1544',
         'id': 'disk-dasdd',
         'path': '/dev/dasdd',
         'ptable': 'vtoc',
         'serial': '0X1544',
         'type': 'disk'
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #3
0
 def test_blockdev_detects_logical_partitions(self):
     self.probe_data = _get_data('probert_storage_lvm.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/vda5']
     expected_dict = {
         'id': 'partition-vda5',
         'type': 'partition',
         'device': 'disk-vda',
         'number': 5,
         'offset': 3223322624,
         'size': 2147483648,
         'flag': 'logical',
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #4
0
 def test_blockdev_detects_extended_partitions(self):
     self.probe_data = _get_data('probert_storage_lvm.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/vda2']
     expected_dict = {
         'id': 'partition-vda2',
         'type': 'partition',
         'device': 'disk-vda',
         'number': 2,
         'offset': 3222274048,
         'size': 5370806272,
         'flag': 'extended',
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #5
0
 def test_blockdev_detects_multipath(self):
     self.probe_data = _get_data('probert_storage_multipath.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/sda2']
     expected_dict = {
         'flag': 'linux',
         'id': 'partition-sda2',
         'offset': 2097152,
         'multipath': 'mpatha',
         'size': 10734272512,
         'type': 'partition',
         'device': 'disk-sda',
         'number': 2
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #6
0
 def test_blockdev_detects_dos_bootable_flag_on_logical_partitions(self):
     self.probe_data = _get_data('probert_storage_lvm.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/vda5']
     blockdev['ID_PART_ENTRY_FLAGS'] = '0x80'
     expected_dict = {
         'id': 'partition-vda5',
         'type': 'partition',
         'device': 'disk-vda',
         'number': 5,
         'offset': 3223322624,
         'size': 2147483648,
         'flag': 'boot',
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #7
0
 def test_blockdev_detects_dos_bootable_flag(self):
     self.probe_data = _get_data(
         'probert_storage_msdos_mbr_extended_v2.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/vdb1']
     expected_dict = {
         'id': 'partition-vdb1',
         'type': 'partition',
         'device': 'disk-vdb',
         'number': 1,
         'offset': 1048576,
         'size': 536870912,
         'flag': 'boot',
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #8
0
 def test_blockdev_skips_multipath_entry_if_bad_multipath_data(self):
     self.probe_data = _get_data('probert_storage_multipath.json')
     for path in self.probe_data['multipath']['paths']:
         path['multipath'] = ''
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/sda2']
     expected_dict = {
         'flag': 'linux',
         'id': 'partition-sda2',
         'offset': 2097152,
         'size': 10734272512,
         'type': 'partition',
         'device': 'disk-sda',
         'number': 2
     }
     self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))
예제 #9
0
 def test_blockdev_finds_multipath_id_from_dm_uuid(self):
     self.probe_data = _get_data('probert_storage_zlp6.json')
     self.bdevp = BlockdevParser(self.probe_data)
     blockdev = self.bdevp.blockdev_data['/dev/dm-2']
     result = self.bdevp.blockdev_to_id(blockdev)
     self.assertEqual('disk-sda', result)
예제 #10
0
 def setUp(self):
     super(TestBlockdevParser, self).setUp()
     self.probe_data = _get_data('probert_storage_diglett.json')
     self.bdevp = BlockdevParser(self.probe_data)
예제 #11
0
class TestBlockdevParser(CiTestCase):
    def setUp(self):
        super(TestBlockdevParser, self).setUp()
        self.probe_data = _get_data('probert_storage_diglett.json')
        self.bdevp = BlockdevParser(self.probe_data)

    def test_blockdev_parse(self):
        """ BlockdevParser 'blockdev_data' on instance matches input. """
        self.assertDictEqual(self.probe_data['blockdev'],
                             self.bdevp.blockdev_data)

    # XXX: Parameterize me
    def test_blockdev_ptable_uuid_flag(self):
        """ BlockdevParser maps ptable UUIDs to boot flags. """
        boot_guids = [
            'C12A7328-F81F-11D2-BA4B-00A0C93EC93B',
            'c12a7328-f81f-11d2-ba4b-00a0c93ec93b'
        ]
        expected_tuple = ('boot', 'EF00')
        for guid in boot_guids:
            self.assertEqual(expected_tuple,
                             self.bdevp.ptable_uuid_to_flag_entry(guid))

    # XXX: Parameterize me
    def test_blockdev_ptable_uuid_flag_invalid(self):
        """ BlockdevParser returns (None, None) for invalid uuids. """
        for invalid in [None, '', {}, []]:
            self.assertEqual((None, None),
                             self.bdevp.ptable_uuid_to_flag_entry(invalid))

    # XXX: Parameterize me
    def test_blockdev_ptable_uuid_flag_unknown_uuid(self):
        """ BlockdevParser returns (None, None) for unknown uuids. """
        for unknown in [self.random_string(), self.random_string()]:
            self.assertEqual((None, None),
                             self.bdevp.ptable_uuid_to_flag_entry(unknown))

    def test_get_unique_ids(self):
        """ BlockdevParser extracts uniq udev ID_ values. """
        expected_ids = {
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0'
        }
        blockdev = self.bdevp.blockdev_data['/dev/sda1']
        self.assertDictEqual(expected_ids, self.bdevp.get_unique_ids(blockdev))

    def test_partition_parent_devname(self):
        """ BlockdevParser calculate partition parent name. """
        expected_parent = '/dev/sda'
        blockdev = self.bdevp.blockdev_data['/dev/sda1']
        self.assertEqual(expected_parent,
                         self.bdevp.partition_parent_devname(blockdev))

    def test_partition_parent_devname_exception_non_partition(self):
        """ BlockdevParser raises ValueError if DEVTYPE is not partition."""
        blockdev = self.bdevp.blockdev_data['/dev/bcache0']
        with self.assertRaises(ValueError):
            self.bdevp.partition_parent_devname(blockdev)

    def test_blockdev_asdict_disk(self):
        """ BlockdevParser creates dictionary of DEVTYPE=disk. """

        blockdev = self.bdevp.blockdev_data['/dev/sda']
        expected_dict = {
            'id': 'disk-sda',
            'type': 'disk',
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0',
            'path': '/dev/sda',
            'ptable': 'gpt',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_asdict_partition(self):
        """ BlockdevParser creates dictionary of DEVTYPE=partition. """

        blockdev = self.bdevp.blockdev_data['/dev/sda1']
        expected_dict = {
            'id': 'partition-sda1',
            'type': 'partition',
            'device': 'disk-sda',
            'number': 1,
            'offset': 1048576,
            'size': 499122176,
            'flag': 'linux',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    # XXX: Parameterize me
    def test_blockdev_asdict_not_disk_or_partition(self):
        """ BlockdevParser ignores DEVTYPE not in 'disk, partition'. """
        test_value = {'DEVTYPE': self.random_string()}
        self.assertEqual(None, self.bdevp.asdict(test_value))

    # XXX: Parameterize me
    def test_blockdev_asdict_ignores_floppy(self):
        """ BlockdevParser ignores MAJOR=2 Floppy. """
        test_value = {'DEVTYPE': 'disk', 'MAJOR': '2'}
        self.assertEqual(None, self.bdevp.asdict(test_value))

    # XXX: Parameterize me
    def test_blockdev_asdict_ignores_cdrom(self):
        """ BlockdevParser ignores MAJOR=11 CDROM. """
        test_value = {'DEVTYPE': 'disk', 'MAJOR': '11'}
        self.assertEqual(None, self.bdevp.asdict(test_value))

    def test_blockdev_asdict_ignores_zero_start_value(self):
        """ BlockdevParser ignores partition with zero start value."""
        self.bdevp.blockdev_data['/dev/vda'] = {
            'DEVTYPE': 'disk',
            'DEVNAME': 'vda',
        }
        test_value = {
            'DEVTYPE': 'partition',
            'MAJOR': "252",
            'DEVNAME': 'vda1',
            "DEVPATH":
            "/devices/pci0000:00/0000:00:04.0/virtio0/block/vda/vda1",
            "ID_PART_ENTRY_TYPE": "0x0",
            'attrs': {
                'partition': "1",
                'size': "784334848",
                'start': "0"
            }
        }

        expected_dict = {
            'id': 'partition-vda1',
            'type': 'partition',
            'device': 'disk-vda',
            'number': 1,
            'size': 784334848,
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(test_value))

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_empty_name(self):
        test_value = {'DEVTYPE': 'disk', 'DEVNAME': '', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_empty_devtype(self):
        test_value = {'DEVTYPE': '', 'DEVNAME': 'bar', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_missing_name(self):
        test_value = {'DEVTYPE': 'disk', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_missing_devtype(self):
        test_value = {'DEVNAME': 'bar', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    def test_blockdev_detects_extended_partitions(self):
        self.probe_data = _get_data('probert_storage_lvm.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/vda2']
        expected_dict = {
            'id': 'partition-vda2',
            'type': 'partition',
            'device': 'disk-vda',
            'number': 2,
            'offset': 3222274048,
            'size': 5370806272,
            'flag': 'extended',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_detects_logical_partitions(self):
        self.probe_data = _get_data('probert_storage_lvm.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/vda5']
        expected_dict = {
            'id': 'partition-vda5',
            'type': 'partition',
            'device': 'disk-vda',
            'number': 5,
            'offset': 3223322624,
            'size': 2147483648,
            'flag': 'logical',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_asdict_disk_omits_ptable_if_none_present(self):
        blockdev = self.bdevp.blockdev_data['/dev/sda']
        del blockdev['ID_PART_TABLE_TYPE']
        expected_dict = {
            'id': 'disk-sda',
            'type': 'disk',
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0',
            'path': '/dev/sda',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_asdict_disk_marks_unknown_ptable_as_unspported(self):
        blockdev = self.bdevp.blockdev_data['/dev/sda']
        expected_dict = {
            'id': 'disk-sda',
            'type': 'disk',
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0',
            'ptable': 'unsupported',
            'path': '/dev/sda',
        }
        for invalid in ['mac', 'PMBR']:
            blockdev['ID_PART_TABLE_TYPE'] = invalid
            self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_detects_multipath(self):
        self.probe_data = _get_data('probert_storage_multipath.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/sda2']
        expected_dict = {
            'flag': 'linux',
            'id': 'partition-sda2',
            'offset': 2097152,
            'multipath': 'mpatha',
            'size': 10734272512,
            'type': 'partition',
            'device': 'disk-sda',
            'number': 2
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_finds_multipath_id_from_dm_uuid(self):
        self.probe_data = _get_data('probert_storage_zlp6.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/dm-2']
        result = self.bdevp.blockdev_to_id(blockdev)
        self.assertEqual('disk-sda', result)
예제 #12
0
class TestBlockdevParser(CiTestCase):
    def setUp(self):
        super(TestBlockdevParser, self).setUp()
        self.probe_data = _get_data('probert_storage_diglett.json')
        self.bdevp = BlockdevParser(self.probe_data)

    def test_blockdev_parse(self):
        """ BlockdevParser 'blockdev_data' on instance matches input. """
        self.assertDictEqual(self.probe_data['blockdev'],
                             self.bdevp.blockdev_data)

    # XXX: Parameterize me
    def test_blockdev_ptable_uuid_flag(self):
        """ BlockdevParser maps ptable UUIDs to boot flags. """
        boot_guids = [
            'C12A7328-F81F-11D2-BA4B-00A0C93EC93B',
            'c12a7328-f81f-11d2-ba4b-00a0c93ec93b'
        ]
        expected_tuple = ('boot', 'EF00')
        for guid in boot_guids:
            self.assertEqual(expected_tuple, ptable_uuid_to_flag_entry(guid))

    # XXX: Parameterize me
    def test_blockdev_ptable_uuid_flag_invalid(self):
        """ BlockdevParser returns (None, None) for invalid uuids. """
        for invalid in [None, '', {}, []]:
            self.assertEqual((None, None), ptable_uuid_to_flag_entry(invalid))

    # XXX: Parameterize me
    def test_blockdev_ptable_uuid_flag_unknown_uuid(self):
        """ BlockdevParser returns (None, None) for unknown uuids. """
        for unknown in [self.random_string(), self.random_string()]:
            self.assertEqual((None, None), ptable_uuid_to_flag_entry(unknown))

    def test_get_unique_ids(self):
        """ BlockdevParser extracts uniq udev ID_ values. """
        expected_ids = {
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0'
        }
        blockdev = self.bdevp.blockdev_data['/dev/sda1']
        self.assertDictEqual(expected_ids, self.bdevp.get_unique_ids(blockdev))

    def test_get_unique_ids_ignores_empty_wwn_values(self):
        """ BlockdevParser skips invalid ID_WWN_* values. """
        self.bdevp.blockdev_data['/dev/sda'] = {
            'DEVTYPE': 'disk',
            'DEVNAME': 'sda',
            'ID_SERIAL': 'Corsair_Force_GS_1785234921906',
            'ID_SERIAL_SHORT': '1785234921906',
            'ID_WWN': '0x0000000000000000',
            'ID_WWN_WITH_EXTENSION': '0x0000000000000000',
        }
        blockdev = self.bdevp.blockdev_data['/dev/sda']
        expected_ids = {'serial': 'Corsair_Force_GS_1785234921906'}
        self.assertEqual(expected_ids, self.bdevp.get_unique_ids(blockdev))

    def test_get_unique_ids_ignores_empty_serial_values(self):
        """ BlockdevParser skips invalid ID_SERIAL_* values. """
        self.bdevp.blockdev_data['/dev/sda'] = {
            'DEVTYPE': 'disk',
            'DEVNAME': 'sda',
            'ID_SERIAL': '                      ',
            'ID_SERIAL_SHORT': 'My Serial is My PassPort',
        }
        blockdev = self.bdevp.blockdev_data['/dev/sda']
        expected_ids = {'serial': 'My Serial is My PassPort'}
        self.assertEqual(expected_ids, self.bdevp.get_unique_ids(blockdev))

    def test_partition_parent_devname(self):
        """ BlockdevParser calculate partition parent name. """
        expected_parent = '/dev/sda'
        blockdev = self.bdevp.blockdev_data['/dev/sda1']
        self.assertEqual(expected_parent,
                         self.bdevp.partition_parent_devname(blockdev))

    def test_partition_parent_devname_exception_non_partition(self):
        """ BlockdevParser raises ValueError if DEVTYPE is not partition."""
        blockdev = self.bdevp.blockdev_data['/dev/bcache0']
        with self.assertRaises(ValueError):
            self.bdevp.partition_parent_devname(blockdev)

    def test_blockdev_asdict_disk(self):
        """ BlockdevParser creates dictionary of DEVTYPE=disk. """

        blockdev = self.bdevp.blockdev_data['/dev/sda']
        expected_dict = {
            'id': 'disk-sda',
            'type': 'disk',
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0',
            'path': '/dev/sda',
            'ptable': 'gpt',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_asdict_partition(self):
        """ BlockdevParser creates dictionary of DEVTYPE=partition. """

        blockdev = self.bdevp.blockdev_data['/dev/sda1']
        expected_dict = {
            'id': 'partition-sda1',
            'type': 'partition',
            'device': 'disk-sda',
            'number': 1,
            'offset': 1048576,
            'size': 499122176,
            'flag': 'linux',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    # XXX: Parameterize me
    def test_blockdev_asdict_not_disk_or_partition(self):
        """ BlockdevParser ignores DEVTYPE not in 'disk, partition'. """
        test_value = {'DEVTYPE': self.random_string()}
        self.assertEqual(None, self.bdevp.asdict(test_value))

    # XXX: Parameterize me
    def test_blockdev_asdict_ignores_floppy(self):
        """ BlockdevParser ignores MAJOR=2 Floppy. """
        test_value = {'DEVTYPE': 'disk', 'MAJOR': '2'}
        self.assertEqual(None, self.bdevp.asdict(test_value))

    # XXX: Parameterize me
    def test_blockdev_asdict_ignores_cdrom(self):
        """ BlockdevParser ignores MAJOR=11 CDROM. """
        test_value = {'DEVTYPE': 'disk', 'MAJOR': '11'}
        self.assertEqual(None, self.bdevp.asdict(test_value))

    def test_blockdev_asdict_ignores_zero_start_value(self):
        """ BlockdevParser ignores partition with zero start value."""
        self.bdevp.blockdev_data['/dev/vda'] = {
            'DEVTYPE': 'disk',
            'DEVNAME': 'vda',
        }
        test_value = {
            'DEVTYPE': 'partition',
            'MAJOR': "252",
            'DEVNAME': 'vda1',
            "DEVPATH":
            "/devices/pci0000:00/0000:00:04.0/virtio0/block/vda/vda1",
            "ID_PART_ENTRY_TYPE": "0x0",
            'attrs': {
                'partition': "1",
                'size': "784334848",
                'start': "0"
            }
        }

        expected_dict = {
            'id': 'partition-vda1',
            'type': 'partition',
            'device': 'disk-vda',
            'number': 1,
            'size': 784334848,
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(test_value))

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_empty_name(self):
        test_value = {'DEVTYPE': 'disk', 'DEVNAME': '', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_empty_devtype(self):
        test_value = {'DEVTYPE': '', 'DEVNAME': 'bar', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_missing_name(self):
        test_value = {'DEVTYPE': 'disk', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    # XXX: Parameterize me
    def test_blockdev_to_id_raises_valueerror_on_missing_devtype(self):
        test_value = {'DEVNAME': 'bar', 'DEVPATH': 'foobar'}
        with self.assertRaises(ValueError):
            self.bdevp.blockdev_to_id(test_value)

    # XXX: Parameterize me
    def test_blockdev_detects_extended_partitions(self):
        self.probe_data = _get_data('probert_storage_lvm.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/vda2']
        expected_dict = {
            'id': 'partition-vda2',
            'type': 'partition',
            'device': 'disk-vda',
            'number': 2,
            'offset': 3222274048,
            'size': 5370806272,
            'flag': 'extended',
        }
        for ext_part_entry in ['0xf', '0x5', '0x85', '0xc5']:
            blockdev['ID_PART_ENTRY_TYPE'] = ext_part_entry
            self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_detects_logical_partitions(self):
        self.probe_data = _get_data('probert_storage_lvm.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/vda5']
        expected_dict = {
            'id': 'partition-vda5',
            'type': 'partition',
            'device': 'disk-vda',
            'number': 5,
            'offset': 3223322624,
            'size': 2147483648,
            'flag': 'logical',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_detects_dos_bootable_flag(self):
        self.probe_data = _get_data(
            'probert_storage_msdos_mbr_extended_v2.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/vdb1']
        expected_dict = {
            'id': 'partition-vdb1',
            'type': 'partition',
            'device': 'disk-vdb',
            'number': 1,
            'offset': 1048576,
            'size': 536870912,
            'flag': 'boot',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_detects_dos_bootable_flag_on_logical_partitions(self):
        self.probe_data = _get_data('probert_storage_lvm.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/vda5']
        blockdev['ID_PART_ENTRY_FLAGS'] = '0x80'
        expected_dict = {
            'id': 'partition-vda5',
            'type': 'partition',
            'device': 'disk-vda',
            'number': 5,
            'offset': 3223322624,
            'size': 2147483648,
            'flag': 'boot',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_asdict_disk_omits_ptable_if_none_present(self):
        blockdev = self.bdevp.blockdev_data['/dev/sda']
        del blockdev['ID_PART_TABLE_TYPE']
        expected_dict = {
            'id': 'disk-sda',
            'type': 'disk',
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0',
            'path': '/dev/sda',
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_asdict_disk_marks_unknown_ptable_as_unspported(self):
        blockdev = self.bdevp.blockdev_data['/dev/sda']
        expected_dict = {
            'id': 'disk-sda',
            'type': 'disk',
            'wwn': '0x3001438034e549a0',
            'serial': '33001438034e549a0',
            'ptable': 'unsupported',
            'path': '/dev/sda',
        }
        for invalid in ['mac', 'PMBR']:
            blockdev['ID_PART_TABLE_TYPE'] = invalid
            self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_detects_multipath(self):
        self.probe_data = _get_data('probert_storage_multipath.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/sda2']
        expected_dict = {
            'flag': 'linux',
            'id': 'partition-sda2',
            'offset': 2097152,
            'multipath': 'mpatha',
            'size': 10734272512,
            'type': 'partition',
            'device': 'disk-sda',
            'number': 2
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_skips_multipath_entry_if_no_multipath_data(self):
        self.probe_data = _get_data('probert_storage_multipath.json')
        del self.probe_data['multipath']
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/sda2']
        expected_dict = {
            'flag': 'linux',
            'id': 'partition-sda2',
            'offset': 2097152,
            'size': 10734272512,
            'type': 'partition',
            'device': 'disk-sda',
            'number': 2
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_skips_multipath_entry_if_bad_multipath_data(self):
        self.probe_data = _get_data('probert_storage_multipath.json')
        for path in self.probe_data['multipath']['paths']:
            path['multipath'] = ''
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/sda2']
        expected_dict = {
            'flag': 'linux',
            'id': 'partition-sda2',
            'offset': 2097152,
            'size': 10734272512,
            'type': 'partition',
            'device': 'disk-sda',
            'number': 2
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_skips_multipath_entry_if_no_mp_paths(self):
        self.probe_data = _get_data('probert_storage_multipath.json')
        del self.probe_data['multipath']['paths']
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/sda2']
        expected_dict = {
            'flag': 'linux',
            'id': 'partition-sda2',
            'offset': 2097152,
            'size': 10734272512,
            'type': 'partition',
            'device': 'disk-sda',
            'number': 2
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_finds_multipath_id_from_dm_uuid(self):
        self.probe_data = _get_data('probert_storage_zlp6.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/dm-2']
        result = self.bdevp.blockdev_to_id(blockdev)
        self.assertEqual('disk-sda', result)

    def test_blockdev_find_mpath_members_checks_dm_name(self):
        """ BlockdevParser find_mpath_members uses dm_name if present."""
        dm14 = {
            "DEVTYPE": "disk",
            "DEVLINKS": "/dev/disk/by-id/dm-name-mpathb",
            "DEVNAME": "/dev/dm-14",
            "DEVTYPE": "disk",
            "DM_NAME": "mpathb",
            "DM_UUID": "mpath-360050768028211d8b000000000000062",
            "DM_WWN": "0x60050768028211d8b000000000000062",
            "MPATH_DEVICE_READY": "1",
            "MPATH_SBIN_PATH": "/sbin",
        }
        multipath = {
            "maps": [{
                "multipath": "360050768028211d8b000000000000061",
                "sysfs": "dm-11",
                "paths": "4"
            }, {
                "multipath": "360050768028211d8b000000000000062",
                "sysfs": "dm-14",
                "paths": "4"
            }, {
                "multipath": "360050768028211d8b000000000000063",
                "sysfs": "dm-15",
                "paths": "4"
            }],
            "paths": [{
                "device": "sdej",
                "serial": "0200a084762cXX00",
                "multipath": "mpatha",
                "host_wwnn": "0x20000024ff9127de",
                "target_wwnn": "0x5005076802065e38",
                "host_wwpn": "0x21000024ff9127de",
                "target_wwpn": "0x5005076802165e38",
                "host_adapter": "[undef]"
            }, {
                "device": "sdel",
                "serial": "0200a084762cXX00",
                "multipath": "mpathb",
                "host_wwnn": "0x20000024ff9127de",
                "target_wwnn": "0x5005076802065e38",
                "host_wwpn": "0x21000024ff9127de",
                "target_wwpn": "0x5005076802165e38",
                "host_adapter": "[undef]"
            }, {
                "device": "sdet",
                "serial": "0200a084762cXX00",
                "multipath": "mpatha",
                "host_wwnn": "0x20000024ff9127de",
                "target_wwnn": "0x5005076802065e37",
                "host_wwpn": "0x21000024ff9127de",
                "target_wwpn": "0x5005076802165e37",
                "host_adapter": "[undef]"
            }, {
                "device": "sdev",
                "serial": "0200a084762cXX00",
                "multipath": "mpathb",
                "host_wwnn": "0x20000024ff9127de",
                "target_wwnn": "0x5005076802065e37",
                "host_wwpn": "0x21000024ff9127de",
                "target_wwpn": "0x5005076802165e37",
                "host_adapter": "[undef]"
            }],
        }
        self.bdevp.blockdev_data['/dev/dm-14'] = dm14
        self.probe_data['multipath'] = multipath
        self.assertEqual('disk-sdel', self.bdevp.blockdev_to_id(dm14))

    def test_blockdev_detects_dasd_device_id_and_vtoc_ptable(self):
        self.probe_data = _get_data('probert_storage_dasd.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/dasdd']
        expected_dict = {
            'device_id': '0.0.1544',
            'id': 'disk-dasdd',
            'path': '/dev/dasdd',
            'ptable': 'vtoc',
            'serial': '0X1544',
            'type': 'disk'
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))

    def test_blockdev_detects_dasd_device_id_and_unformatted_no_ptable(self):
        self.probe_data = _get_data('probert_storage_dasd.json')
        self.bdevp = BlockdevParser(self.probe_data)
        blockdev = self.bdevp.blockdev_data['/dev/dasde']
        expected_dict = {
            'device_id': '0.0.2520',
            'id': 'disk-dasde',
            'path': '/dev/dasde',
            'type': 'disk'
        }
        self.assertDictEqual(expected_dict, self.bdevp.asdict(blockdev))