def test_migrate_from_block_to_network(self): conf = drive_config(path='/blockdomain/volume') drive = Drive(self.log, diskType=DISK_TYPE.BLOCK, **conf) # Migrate drive to network disk... drive.path = "pool/volume" drive.diskType = DISK_TYPE.NETWORK self.assertEqual(DISK_TYPE.NETWORK, drive.diskType)
def test_disk_type_unset(self): with namedTemporaryDir() as tmpdir: path = os.path.join(tmpdir, "vol") open(path, "w").close() conf = drive_config(format="cow", path=path) drive = Drive(self.log, **conf) self.assertFalse(drive.needs_monitoring(events_enabled=True))
def test_migrate_from_block_to_file(self): conf = drive_config(path='/blockdomain/volume') drive = Drive(self.log, diskType=DISK_TYPE.BLOCK, **conf) # Migrate drive to file domain... drive.diskType = DISK_TYPE.FILE drive.path = "/filedomain/volume" self.assertEqual(DISK_TYPE.FILE, drive.diskType)
def make_drive(log, dom, irs, index, conf, block_info): cfg = utils.picklecopy(conf) cfg['index'] = index cfg['path'] = '/{iface}/{index}'.format( iface=cfg['iface'], index=cfg['index'] ) add_uuids(index, cfg) if 'diskReplicate' in cfg: add_uuids(index + REPLICA_BASE_INDEX, cfg['diskReplicate']) drive = Drive(log, **cfg) dom.block_info[drive.path] = utils.picklecopy(block_info) if (drive.format == "raw" and block_info["physical"] != block_info["capacity"]): raise RuntimeError( "Invalid test data - " "raw disk capacity != physical: %s" % block_info) irs.set_drive_size(drive, block_info['physical']) return drive
def test_block_threshold_stale_path(self): conf = drive_config(diskType=DISK_TYPE.BLOCK, path='/new/path') drive = Drive(self.log, **conf) drive.threshold_state = BLOCK_THRESHOLD.SET drive.on_block_threshold('/old/path') self.assertEqual(drive.threshold_state, BLOCK_THRESHOLD.SET)
def test_parse_volume_chain_network(self): volume_chain = [{ 'path': 'server:/vol/11111111-1111-1111-1111-111111111111', 'volumeID': '11111111-1111-1111-1111-111111111111' }, { 'path': 'server:/vol/22222222-2222-2222-2222-222222222222', 'volumeID': '22222222-2222-2222-2222-222222222222' }] conf = drive_config(volumeChain=volume_chain) drive = Drive(self.log, diskType=DISK_TYPE.NETWORK, **conf) disk_xml = etree.fromstring(""" <disk> <source name='server:/vol/11111111-1111-1111-1111-111111111111'/> <backingStore type='network' index='1'> <source name='server:/vol/22222222-2222-2222-2222-222222222222'/> <backingStore/> </backingStore> </disk>""") chain = drive.parse_volume_chain(disk_xml) expected = [ storage.VolumeChainEntry( path='server:/vol/22222222-2222-2222-2222-222222222222', allocation=None, uuid='22222222-2222-2222-2222-222222222222', index=1), storage.VolumeChainEntry( path='server:/vol/11111111-1111-1111-1111-111111111111', allocation=None, uuid='11111111-1111-1111-1111-111111111111', index=None) ] self.assertEqual(chain, expected)
def test_migrate_network_to_block(self): conf = drive_config(diskType=DISK_TYPE.NETWORK, path='pool/volume') drive = Drive(self.log, **conf) # Migrate drive to block domain... drive.path = '/blockdomain/volume' drive.diskType = DISK_TYPE.BLOCK self.assertEqual(DISK_TYPE.BLOCK, drive.diskType)
def test_migrate_from_file_to_block(self): conf = drive_config(path='/filedomain/volume') drive = Drive(self.log, diskType=DISK_TYPE.FILE, **conf) # Migrate drive to block domain... drive.diskType = DISK_TYPE.BLOCK drive.path = "/blockdomain/volume" assert DISK_TYPE.BLOCK == drive.diskType
def test_migrate_network_to_block(self): conf = drive_config(diskType=DISK_TYPE.NETWORK, path='pool/volume') drive = Drive(self.log, **conf) self.assertTrue(drive.networkDev) # Migrate drive to block domain... drive.path = '/blockdomain/volume' drive.diskType = None self.assertTrue(drive.blockDev)
def test_migrate_from_block_to_network(self): conf = drive_config(path='/blockdomain/volume') drive = Drive(self.log, **conf) self.assertTrue(drive.blockDev) # Migrate drive to network disk... drive.path = "pool/volume" drive.diskType = DISK_TYPE.NETWORK self.assertFalse(drive.blockDev)
def test_invalid_name(self, interface, index): conf = drive_config(device='disk', iface=interface, index=index, diskType=DISK_TYPE.FILE) with pytest.raises(ValueError): Drive(self.log, **conf)
def test_block_threshold_set_state(self): path = '/old/path' conf = drive_config(diskType=DISK_TYPE.BLOCK, path=path) drive = Drive(self.log, **conf) drive.threshold_state = BLOCK_THRESHOLD.SET drive.on_block_threshold(path) assert drive.threshold_state == BLOCK_THRESHOLD.EXCEEDED
def test_path_change_reset_threshold_state(self): conf = drive_config(diskType=DISK_TYPE.BLOCK, path='/old/path') drive = Drive(self.log, **conf) # Simulating drive in SET state drive.threshold_state = BLOCK_THRESHOLD.SET drive.path = '/new/path' assert drive.threshold_state == BLOCK_THRESHOLD.UNSET
def test_migrate_from_block_to_file(self): conf = drive_config(path='/blockdomain/volume') drive = Drive(self.log, **conf) self.assertTrue(drive.blockDev) # Migrate drive to file domain... utils.isBlockDevice = lambda path: False drive.path = "/filedomain/volume" self.assertFalse(drive.blockDev)
def test_ide_drive(self, interface, index, expected_name): conf = drive_config(device='disk', iface=interface, index=index, diskType=DISK_TYPE.FILE) drive = Drive(self.log, **conf) assert drive.name == expected_name
def test_incorrect_protocol(self): drive = Drive(self.log, diskType=DISK_TYPE.NETWORK, protocol='gluster', **self.conf) with pytest.raises(exception.UnsupportedOperation): drive.get_snapshot_xml({'protocol': 'bad', 'diskType': 'network'})
def test_floppy_readonly(self, flag, expected): conf = drive_config( readonly=flag, device='floppy' ) drive = Drive(self.log, **conf) self.assertEqual(drive.device, 'floppy') self.assertIs(drive.readonly, expected)
def test_disk_readonly(self, flag, expected): conf = drive_config( readonly=flag, serial='54-a672-23e5b495a9ea', diskType=DISK_TYPE.FILE, ) drive = Drive(self.log, **conf) assert drive.device == 'disk' assert drive.readonly is expected
def test_disk_readonly(self, flag, expected): conf = drive_config( readonly=flag, serial='54-a672-23e5b495a9ea', diskType=DISK_TYPE.FILE, ) drive = Drive(self.log, **conf) self.assertEqual(drive.device, 'disk') self.assertIs(drive.readonly, expected)
def test_set_iotune(self, iotune): conf = drive_config( serial='54-a672-23e5b495a9ea', diskType=DISK_TYPE.BLOCK, ) drive = Drive(self.log, **conf) with pytest.raises(Exception): drive.iotune = iotune
def test_ide_drive(self, interface, index, expected_name): conf = drive_config( device='disk', iface=interface, index=index, ) drive = Drive(self.log, **conf) self.assertEqual(drive.name, expected_name)
def test_unset_disk_type(self): # Simulate legacy behavior in cluster version < 4.2, vdsm discover the # disk type by checking if the path is a block device. with namedTemporaryDir() as tmpdir: path = os.path.join(tmpdir, "vol") open(path, "w").close() conf = drive_config(device="disk", format="cow", path=path) drive = Drive(self.log, **conf) self.assertFalse(drive.chunked, "File based drive cannot be chunked")
def make_drive(log, index, **param_dict): conf = drive_config( index=str(index), domainID='domain_%s' % index, poolID='pool_%s' % index, imageID='image_%s' % index, volumeID='volume_%s' % index, **param_dict ) return Drive(log, **conf)
def test_file(self): drive = Drive(self.log, diskType=DISK_TYPE.FILE, **self.conf) expected = """ <disk name='vda' snapshot='external' type='file'> <source file='/image' type='file'/> </disk> """ snap_info = {'path': '/image', 'device': 'disk'} actual = drive.get_snapshot_xml(snap_info) self.assertXMLEqual(vmxml.format_xml(actual), expected)
def test_block(self): drive = Drive(self.log, diskType=DISK_TYPE.BLOCK, **self.conf) expected = """ <disk name='vda' snapshot='external' type='block'> <source dev='/dev/dm-1' type='block'/> </disk> """ snap_info = {'path': '/dev/dm-1', 'device': 'disk'} actual = drive.get_snapshot_xml(snap_info) self.assertXMLEqual(vmxml.format_xml(actual), expected)
def make_env(): log = logging.getLogger('test') # the Drive class use those two tunables as class constants. with MonkeyPatchScope([ (Drive, 'VOLWM_CHUNK_SIZE', CHUNK_SIZE_GB), (Drive, 'VOLWM_FREE_PCT', CHUNK_PCT), ]): # storage does not validate the UUIDs, so we use phony names # for brevity drives = [ Drive( log, **drive_config( format='cow', diskType=DISK_TYPE.BLOCK, index=0, volumeID='volume_0', poolID='pool_0', imageID='image_0', domainID='domain_0', )), Drive( log, **drive_config( format='cow', diskType=DISK_TYPE.BLOCK, index=1, volumeID='volume_1', poolID='pool_0', imageID='image_1', domainID='domain_0', )), ] # TODO: add raw/block drive and qcow2/file drive. # check we don't try to monitor or extend those drives. cif = FakeClientIF() cif.irs = FakeIRS() dom = FakeDomain() yield FakeVM(cif, dom, drives), dom, drives
def check_leases(self, conf): drive = Drive(self.log, diskType=DISK_TYPE.FILE, **conf) leases = list(drive.getLeasesXML()) self.assertEqual(1, len(leases)) xml = """ <lease> <key>vol_id</key> <lockspace>dom_id</lockspace> <target offset="0" path="path" /> </lease> """ self.assertXMLEqual(vmxml.format_xml(leases[0]), xml)
def check_leases(self, conf): drive = Drive(self.log, diskType=DISK_TYPE.FILE, **conf) leases = list(drive.getLeasesXML()) assert 1 == len(leases) xml = """ <lease> <key>vol_id</key> <lockspace>dom_id</lockspace> <target offset="0" path="path" /> </lease> """ self.assertXMLEqual(xmlutils.tostring(leases[0]), xml)
def test_block(self): drive = Drive(self.log, diskType=DISK_TYPE.BLOCK, **self.conf) expected = """ <disk name='vda' snapshot='external' type='block'> <source dev='/dev/dm-1' type='block'> <seclabel model="dac" relabel="no" type="none" /> </source> </disk> """ snap_info = {'path': '/dev/dm-1', 'device': 'disk'} actual = drive.get_snapshot_xml(snap_info) self.assertXMLEqual(xmlutils.tostring(actual), expected)
def make_env(self, disk_type): with namedTemporaryDir() as tmpdir: """ Below we imitate that behaviour by providing two different directories under /rhv/data-center root and one of those directories is a symlink to another one. We fill VolumeChain with real directory and use symlinked directory in XML, emulating libvirt reply. """ dc_base = os.path.join(tmpdir, "dc") run_base = os.path.join(tmpdir, "run") images_path = os.path.join(dc_base, "images") os.makedirs(images_path) os.symlink(dc_base, run_base) dc_top_vol = os.path.join( images_path, "11111111-1111-1111-1111-111111111111") dc_base_vol = os.path.join( images_path, "22222222-2222-2222-2222-222222222222") make_file(dc_top_vol) make_file(dc_base_vol) run_top_vol = os.path.join( run_base, "images", "11111111-1111-1111-1111-111111111111") run_base_vol = os.path.join( run_base, "images", "22222222-2222-2222-2222-222222222222") volume_chain = [ {'path': dc_top_vol, 'volumeID': '11111111-1111-1111-1111-111111111111'}, {'path': dc_base_vol, 'volumeID': '22222222-2222-2222-2222-222222222222'} ] conf = drive_config(volumeChain=volume_chain) drive = Drive(self.log, diskType=disk_type, **conf) yield VolumeChainEnv( drive, run_top_vol, run_base_vol )