class TestRescanTimeout(VdsmTestCase): @contextmanager def assertMaxDuration(self, maxtime): start = time.monotonic_time() try: yield finally: elapsed = time.monotonic_time() - start if maxtime < elapsed: self.fail("Operation was too slow %.2fs > %.2fs" % (elapsed, maxtime)) @MonkeyPatch(iscsiadm, 'session_rescan', fake_rescan(0.1)) @MonkeyPatch(iscsi, 'config', make_config([("irs", "scsi_rescan_maximal_timeout", "1")])) def testWait(self): with self.assertMaxDuration(0.3): iscsi.rescan() @MonkeyPatch(iscsiadm, 'session_rescan', fake_rescan(2)) @MonkeyPatch(iscsi, 'config', make_config([("irs", "scsi_rescan_maximal_timeout", "1")])) def testTimeout(self): with self.assertMaxDuration(1.2): iscsi.rescan()
def test_disabled_compat_raises(self, qemu_compat, hsm_compat): with self.fake_volume(sc.COW_FORMAT) as vol: create_conf = make_config([('irs', 'qcow2_compat', qemu_compat)]) check_conf = make_config([('irs', 'qcow2_compat', hsm_compat)]) with MonkeyPatchScope([(qemuimg, 'config', create_conf), (hsm, 'config', check_conf)]): qemuimg.create(vol.volumePath, size=self.SIZE, format=qemuimg.FORMAT.QCOW2) h = FakeHSM() self.assertRaises(se.ImageVerificationError, h.verify_untrusted_volume, 'sp', vol.sdUUID, vol.imgUUID, vol.volUUID)
class TestMigrationTimeout: CONFIG = make_config([('vars', 'migration_listener_timeout', '30'), ('vars', 'max_migration_listener_timeout', '5')]) def test_disk_timeout_needed(self): with fake.VM(xmldevices=read_data('disk_devices.xml')) as testvm: timeout = testvm._disk_preparation_timeout() assert timeout == 10.0 def test_no_disks(self): with fake.VM() as testvm: timeout = testvm._disk_preparation_timeout() assert timeout == 0.0 def test_overall_timeout(self): with fake.VM(xmldevices=read_data('disk_devices.xml')) as testvm: timeout = testvm._migration_destination_prepare_timeout() assert timeout == 46.0 def test_max_timeout(self, monkeypatch): monkeypatch.setattr(vdsm.virt.vm, 'config', self.CONFIG) with fake.VM() as testvm: timeout = testvm._migration_destination_prepare_timeout() assert timeout == 5
def test_autodelete_when_finished(self, error): cfg = make_config([('jobs', 'autodelete_delay', '10')]) job = AutodeleteJob(exception=error) jobs.add(job) with MonkeyPatchScope([(jobs, 'config', cfg)]): self.run_job(job) self._verify_autodelete(job, 10)
def test_autodelete_when_aborted(self): cfg = make_config([('jobs', 'autodelete_delay', '10')]) job = AutodeleteJob() jobs.add(job) with MonkeyPatchScope([(jobs, 'config', cfg)]): job.abort() self._verify_autodelete(job, 10)
def test_invalid_config(self): config = make_config([('irs', 'qcow2_compat', '1.2')]) with MonkeyPatchScope([(qemuimg, '_supports_qcow2_compat', self.supported('create', True)), (qemuimg, 'config', config)]): with self.assertRaises(exception.InvalidConfiguration): qemuimg.create('image', format='qcow2')
def test_autodelete_disabled(self): cfg = make_config([('jobs', 'autodelete_delay', '-1')]) job = AutodeleteJob() jobs.add(job) with MonkeyPatchScope([(jobs, 'config', cfg)]): self.run_job(job) self.assertEqual(0, len(self.scheduler.calls))
def setUp(self): self._test_dir = tempfile.mkdtemp() self.test_env['VDSM_CONF'] = self._test_dir + '/vdsm.conf' self.test_env['LCONF'] = self._test_dir + '/libvirtd.conf' self.test_env['QCONF'] = self._test_dir + '/qemu.conf' self.test_env['LDCONF'] = self._test_dir + '/qemu-sanlock.conf' self.test_env['QLCONF'] = self._test_dir + '/libvirtd' self.test_env['QNETWORK'] = 'NON_EXISTENT' for key, val in self.test_env.items(): if not key == 'VDSM_CONF': FakeFiles[key]['path'] = val self._setConfig( ('QLCONF', 'libvirtd'), ('LDCONF', 'qemu_sanlock'), ) self.vdsm_cfg = make_config(()) self.patch = monkeypatch.Patch([(os, 'getuid', lambda: 0), (libvirt, 'config', self.vdsm_cfg), (libvirt, 'FILES', FakeFiles), (utils, 'isOvirtNode', lambda: False)]) self.patch.apply()
def setUp(self): self._test_dir = tempfile.mkdtemp() self.test_env['VDSM_CONF'] = self._test_dir + '/vdsm.conf' self.test_env['LCONF'] = self._test_dir + '/libvirtd.conf' self.test_env['QCONF'] = self._test_dir + '/qemu.conf' self.test_env['LDCONF'] = self._test_dir + '/qemu-sanlock.conf' self.test_env['QLCONF'] = self._test_dir + '/libvirtd' self.test_env['QNETWORK'] = 'NON_EXISTENT' for key, val in self.test_env.items(): if not key == 'VDSM_CONF': FakeLibvirtFiles[key]['path'] = val _setConfig( self, ('QLCONF', 'libvirtd'), ('LDCONF', 'qemu_sanlock'), ) self.vdsm_cfg = make_config(()) self.patch = monkeypatch.Patch([ (os, 'getuid', lambda: 0), (libvirt, 'config', self.vdsm_cfg), (libvirt, 'FILES', FakeLibvirtFiles), (cpuarch, 'real', lambda: cpuarch.X86_64), (cpuinfo, 'flags', lambda: ['pdpe1gb']), ]) self.patch.apply()
def test_get_refreshable_device_classes(self, whitelist, expected): with MonkeyPatchScope([ (common, 'config', make_config([('devel', 'device_xml_refresh_enable', whitelist)])) ]): self.assertEqual( common.get_refreshable_device_classes(), expected )
def make_env(events_enabled): vm = FakeVM() vm._dom = FakeDomain() cfg = make_config([('irs', 'enable_block_threshold_event', 'true' if events_enabled else 'false')]) with MonkeyPatchScope([(drivemonitor, 'config', cfg)]): mon = drivemonitor.DriveMonitor(vm, vm.log) yield mon, vm
def make_env(events_enabled): vm = FakeVM() vm._dom = FakeDomain() cfg = make_config([ ('irs', 'enable_block_threshold_event', 'true' if events_enabled else 'false')]) with MonkeyPatchScope([(drivemonitor, 'config', cfg)]): mon = drivemonitor.DriveMonitor(vm, vm.log) yield mon, vm
def test_retry_on_limit_exceeded(self, failures): serv = FakeServer(initial_failures=failures, exc=exception.MigrationLimitExceeded()) dom, src = make_env() src._destServer = serv cfg = make_config([('vars', 'migration_retry_timeout', '0')]) with MonkeyPatchScope([(migration, 'config', cfg)]): src.run() self.assertEqual(serv.attempts, failures + 1) # +1 for success self.assertEqual(dom.migrations, 1)
def env(enable='true', format='pstat', clock='cpu', builtins='false'): with temporaryPath() as filename: config = make_config([ ('devel', 'cpu_profile_enable', enable), ('devel', 'cpu_profile_filename', filename), ('devel', 'cpu_profile_format', format), ('devel', 'cpu_profile_clock', clock), ('devel', 'cpu_profile_builtins', builtins), ]) with MonkeyPatchScope([(cpu, 'config', config)]): yield filename
def test_retry_on_limit_exceeded(self, failures): serv = FakeServer(initial_failures=failures, exc=exception.MigrationLimitExceeded()) dom, src = make_env() src._destServer = serv cfg = make_config([('vars', 'migration_retry_timeout', '0')]) with MonkeyPatchScope([(migration, 'config', cfg)]): src.run() assert serv.attempts == failures + 1 # +1 for success assert dom.migrations == 1
def test_valid_qcow2_compat(self, hsm_compat, config_compat, sd_version): with self.fake_volume(vol_fmt=sc.COW_FORMAT, sd_version=sd_version) as vol: create_conf = make_config([('irs', 'qcow2_compat', config_compat)]) with MonkeyPatchScope([(qemuimg, 'config', create_conf)]): op = qemuimg.create(vol.volumePath, size=self.SIZE, format=qemuimg.FORMAT.QCOW2, qcow2Compat=hsm_compat) op.run() h = FakeHSM() h.verify_untrusted_volume( 'sp', vol.sdUUID, vol.imgUUID, vol.volUUID)
def test_valid_qcow2_compat(self, hsm_compat, config_compat, sd_version): with self.fake_volume(vol_fmt=sc.COW_FORMAT, sd_version=sd_version) as vol: create_conf = make_config([('irs', 'qcow2_compat', config_compat)]) info = {"format": qemuimg.FORMAT.QCOW2, "compat": hsm_compat} with MonkeyPatchScope([(qemuimg, 'config', create_conf), (qemuimg, 'info', lambda unused: info)]): qemuimg.create(vol.volumePath, size=self.SIZE, format=qemuimg.FORMAT.QCOW2) h = FakeHSM() self.assertNotRaises(h.verify_untrusted_volume, 'sp', vol.sdUUID, vol.imgUUID, vol.volUUID)
def _update_downtime_repeatedly(downtime, steps): dom = fake.Domain() with fake.VM({'memSize': 1024}) as testvm: testvm._dom = dom cfg = make_config([('vars', 'migration_downtime_delay', '0')]) with MonkeyPatchScope([(migration, 'config', cfg)]): dt = migration.DowntimeThread(testvm, downtime, steps) dt.start() dt.join() return dom.getDowntimes()
def test_nic_hotunplug_timeout(self): vm = self.vm self.test_nic_hotplug() self.assertEqual(len(vm._devices[hwclass.NIC]), 2) params = {'xml': self.NIC_HOTPLUG} with MonkeyPatchScope([ (vdsm.common.supervdsm, 'getProxy', self.supervdsm.getProxy), (vdsm.virt.vm, 'config', make_config([('vars', 'hotunplug_timeout', '0'), ('vars', 'hotunplug_check_interval', '0.01')])), ]): self.vm._dom.vm = None self.assertTrue(response.is_error(vm.hotunplugNic(params))) self.assertEqual(len(vm._devices[hwclass.NIC]), 2)
def monitor_env(shutdown=False, refresh=300): config = make_config([("irs", "repo_stats_cache_refresh_timeout", str(refresh))]) with MonkeyPatchScope([(monitor, "sdCache", FakeStorageDomainCache()), (monitor, "config", config)]): event = FakeEvent() checker = FakeCheckService() thread = monitor.MonitorThread("uuid", "host_id", MONITOR_INTERVAL, event, checker) try: yield MonitorEnv(thread, event, checker) finally: thread.stop(shutdown=shutdown) try: thread.join() except RuntimeError as e: log.error("Error joining thread: %s", e)
def setUp(self): self._test_dir = tempfile.mkdtemp() self.test_env['VDSM_CONF'] = self._test_dir + '/vdsm.conf' self.test_env['LCONF'] = self._test_dir + '/libvirtd.conf' self.test_env['QCONF'] = self._test_dir + '/qemu.conf' self.test_env['LDCONF'] = self._test_dir + '/qemu-sanlock.conf' self.test_env['QLCONF'] = self._test_dir + '/libvirtd' self.test_env['QNETWORK'] = 'NON_EXISTENT' for key, val in self.test_env.items(): if not key == 'VDSM_CONF': FakeLibvirtFiles[key]['path'] = val _setConfig(self, ('QLCONF', 'libvirtd'), ('LDCONF', 'qemu_sanlock'), ) self.vdsm_cfg = make_config(()) self.patch = monkeypatch.Patch([ ( os, 'getuid', lambda: 0 ), ( libvirt, 'config', self.vdsm_cfg ), ( libvirt, 'FILES', FakeLibvirtFiles ), ( cpuarch, 'real', lambda: cpuarch.X86_64 ), ( cpuinfo, 'flags', lambda: ['pdpe1gb'] ), ]) self.patch.apply()
def test_delayed_nic_hotunplug(self): vm = self.vm self.test_nic_hotplug() assert len(vm._devices[hwclass.NIC]) == 2 params = {'xml': self.NIC_HOTPLUG} with MonkeyPatchScope([ (vdsm.common.supervdsm, 'getProxy', self.supervdsm.getProxy), (vdsm.virt.vm, 'config', make_config([('vars', 'hotunplug_timeout', '0'), ('vars', 'hotunplug_check_interval', '0.01')])), ]): self.vm._dom.vm = None assert response.is_error(vm.hotunplugNic(params)) self.vm.onDeviceRemoved('ua-nic-hotplugged') assert len(vm._devices[hwclass.NIC]) == 1
def setUp(self): self._test_dir = tempfile.mkdtemp() self.test_env['VDSM_CONF'] = self._test_dir + '/vdsm.conf' self.test_env['LCONF'] = self._test_dir + '/libvirtd.conf' self.test_env['QCONF'] = self._test_dir + '/qemu.conf' self.test_env['LDCONF'] = self._test_dir + '/qemu-sanlock.conf' self.test_env['QLCONF'] = self._test_dir + '/libvirtd' self.test_env['QNETWORK'] = 'NON_EXISTENT' for key, val in self.test_env.items(): if not key == 'VDSM_CONF': FakeFiles[key]['path'] = val self._setConfig( ('QLCONF', 'libvirtd'), ('LDCONF', 'qemu_sanlock'), ) self.vdsm_cfg = make_config(()) self.patch = monkeypatch.Patch([ ( os, 'getuid', lambda: 0 ), ( libvirt, 'config', self.vdsm_cfg ), ( libvirt, 'FILES', FakeFiles ), ( utils, 'isOvirtNode', lambda: False ) ]) self.patch.apply()
def test_start_with_invalid_operation(self): """ periodic.start() should swallow any error that periodic.Operation.start() may raise, and keep starting the other operations after the failed one. """ lock = threading.Lock() done = threading.Event() def _work(): with lock: self.tasks -= 1 if not self.tasks: done.set() ops = [ periodic.Operation(_work, period=1.0, scheduler=self.sched, executor=self.exc), # will raise periodic.InvalidValue periodic.Operation(lambda: None, period=0, scheduler=self.sched, executor=self.exc), periodic.Operation(_work, period=1.0, scheduler=self.sched, executor=self.exc), ] with MonkeyPatchScope([ (periodic, 'config', make_config([('sampling', 'enable', 'false')])), (periodic, '_create', lambda cif, sched: ops), ]): # Don't assume operations are started in order, # we just know all of them will be start()ed. # See the documentation of periodic.start() periodic.start(fake.ClientIF(), self.sched) done.wait(0.5) self.assertTrue(done.is_set())
def monitor_env(shutdown=False, refresh=300): config = make_config([("irs", "repo_stats_cache_refresh_timeout", str(refresh))]) with MonkeyPatchScope([ (monitor, "sdCache", FakeStorageDomainCache()), (monitor, 'config', config), ]): event = FakeEvent() checker = FakeCheckService() thread = monitor.MonitorThread('uuid', 'host_id', MONITOR_INTERVAL, event, checker) try: yield MonitorEnv(thread, event, checker) finally: thread.stop(shutdown=shutdown) try: thread.join() except RuntimeError as e: log.error("Error joining thread: %s", e)
def test_roundtrip_events_disabled(self, mboxfiles, monkeypatch): config = make_config([("mailbox", "events_enable", "false")]) monkeypatch.setattr(sm, "config", config) delay = 0.05 messages = 8 times = self.roundtrip(mboxfiles, delay, messages) best = times[0] worst = times[-1] average = sum(times) / len(times) log.info( "stats: messages=%d delay=%.3f best=%.3f average=%.3f worst=%.3f", messages, delay, best, average, worst) # Running locally takes: # stats: messages=8 delay=0.050 best=0.847 average=1.064 worst=1.243 # Using larger timeout to avoid failures on slower environment. assert best < 5 * MONITOR_INTERVAL assert average < 6 * MONITOR_INTERVAL assert worst < 7 * MONITOR_INTERVAL
def test_graphics(self, graphics_xml, display_ip, meta, src_ports, expected_ports): meta['vmid'] = 'VMID' ovs_bridge = None bridge_name = meta.get('display_network') if bridge_name is not None: ovs_bridge = {'name': bridge_name, 'dpdk_enabled': False} with MonkeyPatchScope([ (vmdevices.graphics, 'supervdsm', FakeSupervdsm(ovs_bridge)), (vmdevices.graphics, '_getNetworkIp', lambda net: display_ip), (vmdevices.graphics.libvirtnetwork, 'create_network', lambda net, vmid: None), (vmdevices.graphics.libvirtnetwork, 'delete_network', lambda net, vmid: None), (vmdevices.graphics, 'config', make_config([('vars', 'ssl', 'true')])), ]): self._check_roundtrip( vmdevices.graphics.Graphics, graphics_xml.format(**src_ports), meta=meta, expected_xml=graphics_xml.format(**expected_ports))
def make_env(events_enabled, drive_infos): log = logging.getLogger('test') cfg = make_config([('irs', 'enable_block_threshold_event', 'true' if events_enabled else 'false')]) # the Drive class use those two tunables as class constants. with MonkeyPatchScope([ (Drive, 'VOLWM_CHUNK_SIZE', CHUNK_SIZE), (Drive, 'VOLWM_FREE_PCT', CHUNK_PCT), (drivemonitor, 'config', cfg), ]): dom = FakeDomain() irs = FakeIRS() drives = [ make_drive(log, dom, irs, index, drive_conf, info) for index, (drive_conf, info) in enumerate(drive_infos) ] cif = FakeClientIF() cif.irs = irs yield FakeVM(cif, dom, drives), dom, drives
def make_env(events_enabled, drive_infos): log = logging.getLogger('test') cfg = make_config([ ('irs', 'enable_block_threshold_event', 'true' if events_enabled else 'false')]) # the Drive class use those two tunables as class constants. with MonkeyPatchScope([ (Drive, 'VOLWM_CHUNK_SIZE', CHUNK_SIZE), (Drive, 'VOLWM_FREE_PCT', CHUNK_PCT), (drivemonitor, 'config', cfg), ]): dom = FakeDomain() irs = FakeIRS() drives = [ make_drive(log, dom, irs, index, drive_conf, info) for index, (drive_conf, info) in enumerate(drive_infos) ] cif = FakeClientIF() cif.irs = irs yield FakeVM(cif, dom, drives), dom, drives
def api_strict_mode(): return MonkeyPatch(vdsmapi, 'config', make_config( [('devel', 'api_strict_mode', 'true')]))
from monkeypatch import MonkeyPatch from monkeypatch import MonkeyPatchScope from storage.storagetestlib import ( fake_env, make_qemu_chain, ) from . import qemuio from testlib import make_config from testlib import make_uuid from testlib import permutations, expandPermutations from testlib import VdsmTestCase CONFIG = make_config([('irs', 'volume_utilization_chunk_mb', '1024')]) GIB_IN_BLOCKS = GIB // sc.BLOCK_SIZE @expandPermutations class TestBlockVolumeSize(VdsmTestCase): @permutations([ # (preallocate, capacity in blocks, initial size in blocks), # allocation size in MB # Preallocate, capacity 2048 blocks, No initial size. # Expected 1 Mb allocated [(sc.PREALLOCATED_VOL, 2048, None), 1], # Preallocate, capacity 2049 blocks, No initial size. # Expected 2 Mb allocated [(sc.PREALLOCATED_VOL, 2049, None), 2],
class TestDriveLeases(XMLTestCase): """ To have leases, drive must have a non-empty volumeChain, shared="exclusive", or shared="false" and irs:use_volume_leases=True. Any other setting results in no leases. """ # Drive without leases @MonkeyPatch(storage, 'config', make_config([("irs", "use_volume_leases", "false")])) @permutations([ ["true"], ["True"], ["TRUE"], ["false"], ["False"], ["FALSE"], [DRIVE_SHARED_TYPE.NONE], [DRIVE_SHARED_TYPE.EXCLUSIVE], [DRIVE_SHARED_TYPE.SHARED], [DRIVE_SHARED_TYPE.TRANSIENT], ]) def test_shared_no_volume_leases_no_chain(self, shared): conf = drive_config(shared=shared, volumeChain=[]) self.check_no_leases(conf) @MonkeyPatch(storage, 'config', make_config([("irs", "use_volume_leases", "true")])) @permutations([ ["true"], ["True"], ["TRUE"], ["false"], ["False"], ["FALSE"], [DRIVE_SHARED_TYPE.NONE], [DRIVE_SHARED_TYPE.EXCLUSIVE], [DRIVE_SHARED_TYPE.SHARED], [DRIVE_SHARED_TYPE.TRANSIENT], ]) def test_shared_use_volume_leases_no_chain(self, shared): conf = drive_config(shared=shared, volumeChain=[]) self.check_no_leases(conf) # Drive with leases @MonkeyPatch(storage, 'config', make_config([("irs", "use_volume_leases", "true")])) @permutations([ ["false"], [DRIVE_SHARED_TYPE.EXCLUSIVE], ]) def test_use_volume_leases(self, shared): conf = drive_config(shared=shared, volumeChain=make_volume_chain()) self.check_leases(conf) @MonkeyPatch(storage, 'config', make_config([("irs", "use_volume_leases", "false")])) @permutations([ [DRIVE_SHARED_TYPE.EXCLUSIVE], ]) def test_no_volume_leases(self, shared): conf = drive_config(shared=shared, volumeChain=make_volume_chain()) self.check_leases(conf) # Helpers def check_no_leases(self, conf): drive = Drive({}, self.log, **conf) leases = list(drive.getLeasesXML()) self.assertEqual([], leases) def check_leases(self, conf): drive = Drive({}, self.log, **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)
from testlib import make_config from testlib import namedTemporaryDir from vdsm.common import cmdutils from vdsm.common import commands from vdsm.common import constants from testlib import temporaryPath from vdsm.common import exception from vdsm.common.constants import GIB from vdsm.common.constants import MEGAB from vdsm.storage import qemuimg CLUSTER_SIZE = 64 * 1024 QEMU_IMG = qemuimg._qemuimg.cmd CONFIG = make_config([('irs', 'qcow2_compat', '0.10')]) def fake_json_call(data, cmd, **kw): return 0, json.dumps(data).encode("utf-8"), [] class TestCompat: @pytest.mark.parametrize("compat,result", [ ("0.10", True), ("1.1", True), ("10.1", False), ]) def test_supports_compat(self, compat, result): assert result == qemuimg.supports_compat(compat)
def test_invalid_config(self): config = make_config([('irs', 'qcow2_compat', '1.2')]) with MonkeyPatchScope([(qemuimg, 'config', config)]): with pytest.raises(exception.InvalidConfiguration): qemuimg.create('image', format='qcow2')
def api_strict_mode(): return MonkeyPatch(vdsmapi, 'config', make_config([('devel', 'api_strict_mode', 'true')]))
class TestTransient(VdsmTestCase): def test_not_transient_drive(self): drive = { 'diskType': DISK_TYPE.FILE, 'format': 'cow', 'path': '/original/path', } testvm = FakeVM() testvm._prepareTransientDisks([drive]) self.assertEqual(drive['diskType'], DISK_TYPE.FILE) self.assertEqual(drive['path'], '/original/path') self.assertEqual(drive['format'], 'cow') @MonkeyPatch(vm, 'config', make_config([])) @MonkeyPatch(sdc, 'sdCache', FakeSDCache()) @permutations([['raw'], ['cow']]) def test_transient(self, img_format): with namedTemporaryDir() as tmpdir: original_path = os.path.join(tmpdir, 'base') self.create_image(original_path, img_format) drive = { 'diskType': DISK_TYPE.BLOCK, 'domainID': 'domainid', 'format': img_format, 'path': original_path, 'shared': DRIVE_SHARED_TYPE.TRANSIENT, 'volumeID': 'volumeid', } vm.config.set('vars', 'transient_disks_repository', tmpdir) testvm = FakeVM() testvm._prepareTransientDisks([drive]) self.check_drive(drive, original_path, tmpdir) def check_drive(self, drive, original_path, tmpdir): self.assertEqual(drive['diskType'], DISK_TYPE.FILE) self.assertEqual(drive['format'], 'cow') self.assertTrue(drive['path'].startswith(tmpdir), "%s does not start with %s" % (drive['path'], tmpdir)) file_stat = os.stat(drive['path']) self.assertEqual(stat.S_IMODE(file_stat.st_mode), 0o660) transient_info = qemuimg.info(drive['path']) self.assertEqual(transient_info['format'], qemuimg.FORMAT.QCOW2) self.assertEqual(transient_info['virtualsize'], VIRTUAL_SIZE) self.assertEqual(transient_info['compat'], QCOW2_COMPAT) self.assertEqual(transient_info['backingfile'], original_path) def create_image(self, img_path, img_format): if img_format == 'raw': with open(img_path, 'w') as f: f.truncate(VIRTUAL_SIZE) elif img_format == 'cow': op = qemuimg.create(img_path, size=VIRTUAL_SIZE, format=qemuimg.FORMAT.QCOW2, qcow2Compat=QCOW2_COMPAT) op.run() else: raise AssertionError("invalid format: %s" % img_format)
def qemu_agent_command(self, command, timeout, flags): return libvirt_qemu.qemuAgentCommand(self._dom, command, timeout, flags) @contextmanager def qga_context(self, timeout=-1): yield def _dom_guestInfo(self, types, flags): return self._vm._dom.guestInfo(types, flags) @MonkeyClass(libvirt_qemu, "qemuAgentCommand", _fake_qemuAgentCommand) @MonkeyClass(qemuguestagent, 'config', make_config([('guest_agent', 'periodic_workers', '1')])) @MonkeyClass(qemuguestagent.QemuGuestAgentDomain, 'guestInfo', _dom_guestInfo) class QemuGuestAgentTests(TestCaseBase): def setUp(self): self.cif = fake.ClientIF() self.qga_poller = self.cif.qga_poller self.vm = FakeVM() self.qga_poller.update_caps( self.vm.id, { 'version': '0.0-test', 'commands': [ qemuguestagent._QEMU_ACTIVE_USERS_COMMAND, qemuguestagent._QEMU_DEVICES_COMMAND, qemuguestagent._QEMU_GUEST_INFO_COMMAND, qemuguestagent._QEMU_FSINFO_COMMAND,
class ApplicationProfileTests(ProfileTests): @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) @MonkeyPatch(cpu, '_FILENAME', FILENAME) @MonkeyPatch(cpu, '_FORMAT', 'pstat') def test_pstats_format(self): requires_yappi() cpu.start() cpu.is_running() # Let if profile something cpu.stop() self.assertNotRaises(pstats.Stats, FILENAME) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) @MonkeyPatch(cpu, '_FILENAME', FILENAME) @MonkeyPatch(cpu, '_FORMAT', 'ystat') def test_ystats_format(self): requires_yappi() cpu.start() cpu.is_running() # Let if profile something cpu.stop() self.assertNotRaises(open_ystats, FILENAME) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) @MonkeyPatch(cpu, '_FILENAME', FILENAME) @MonkeyPatch(cpu, '_FORMAT', 'ystat') @MonkeyPatch(cpu, '_BUILTINS', True) def test_with_builtins(self): requires_yappi() cpu.start() dict() cpu.stop() stats = open_ystats(FILENAME) self.assertTrue(find_module(stats, '__builtin__')) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) @MonkeyPatch(cpu, '_FILENAME', FILENAME) @MonkeyPatch(cpu, '_FORMAT', 'ystat') @MonkeyPatch(cpu, '_BUILTINS', False) def test_without_builtins(self): requires_yappi() cpu.start() dict() cpu.stop() stats = open_ystats(FILENAME) self.assertFalse(find_module(stats, '__builtin__')) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) @MonkeyPatch(cpu, '_FILENAME', FILENAME) @MonkeyPatch(cpu, '_FORMAT', 'ystat') @MonkeyPatch(cpu, '_CLOCK', 'cpu') def test_cpu_clock(self): requires_yappi() cpu.start() self.sleep(0.1) cpu.stop() stats = open_ystats(FILENAME) name = function_name(self.sleep) func = find_function(stats, __file__, name) self.assertTrue(func.ttot < 0.1) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) @MonkeyPatch(cpu, '_FILENAME', FILENAME) @MonkeyPatch(cpu, '_FORMAT', 'ystat') @MonkeyPatch(cpu, '_CLOCK', 'wall') def test_wall_clock(self): requires_yappi() cpu.start() self.sleep(0.1) cpu.stop() stats = open_ystats(FILENAME) name = function_name(self.sleep) func = find_function(stats, __file__, name) self.assertTrue(func.ttot > 0.1) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) @MonkeyPatch(cpu, '_FILENAME', FILENAME) def test_is_running(self): requires_yappi() self.assertFalse(cpu.is_running()) cpu.start() try: self.assertTrue(cpu.is_running()) finally: cpu.stop() self.assertFalse(cpu.is_running()) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'true')])) def test_is_enabled(self): requires_yappi() self.assertTrue(cpu.is_enabled()) # This must succeed even if yappi is not installed @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'false')])) def test_disabled(self): cpu.start() try: self.assertFalse(cpu.is_running()) finally: cpu.stop() def sleep(self, seconds): time.sleep(seconds)
class ThreadsProfileTests(ProfileTests): def setUp(self): self.thread = None self.ready = threading.Event() self.resume = threading.Event() @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'false')])) def test_new_threads(self): # The easy case - threads started after yappi was started requires_yappi() self.new_threads() stats = open_ystats(FILENAME) name = function_name(self.worker_function) func = find_function(stats, __file__, name) self.assertEquals(func.ncall, 1) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'false')])) def test_running_threads(self): # The harder case - threads started before yappi was started requires_yappi() self.start_thread() self.running_threads() stats = open_ystats(FILENAME) name = function_name(self.worker_function) func = find_function(stats, __file__, name) self.assertEquals(func.ncall, 1) @MonkeyPatch(cpu, 'config', make_config([('devel', 'profile_enable', 'false')])) def test_without_threads(self): requires_yappi() self.without_threads() stats = open_ystats(FILENAME) name = function_name(self.worker_function) self.assertRaises(NotFound, find_function, stats, __file__, name) @cpu.profile(FILENAME, format="ystat", threads=True) def new_threads(self): self.start_thread() self.join_thread() @cpu.profile(FILENAME, format="ystat", threads=True) def running_threads(self): self.join_thread() @cpu.profile(FILENAME, format="ystat", threads=False) def without_threads(self): self.start_thread() self.join_thread() def start_thread(self): self.thread = threading.Thread(target=self.worker) self.thread.daemon = True self.thread.start() self.ready.wait() def join_thread(self): self.resume.set() self.thread.join() def worker(self): self.ready.set() self.resume.wait() self.worker_function() def worker_function(self): pass
def test_zero_block_size_invalid(self, block_size_mb, monkeypatch): cfg = make_config([('irs', 'zero_block_size_mb', block_size_mb)]) monkeypatch.setattr(blockdev, "config", cfg) with pytest.raises(exception.InvalidConfiguration): blockdev.zero_block_size()
class TestVmDevices(XMLTestCase): PCI_ADDR = \ 'bus="0x00" domain="0x0000" function="0x0" slot="0x03" type="pci"' PCI_ADDR_DICT = {'slot': '0x03', 'bus': '0x00', 'domain': '0x0000', 'function': '0x0', 'type': 'pci'} GRAPHICS_XMLS = [ """ <graphics autoport="yes" defaultMode="secure" keymap="en-us" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" type="vnc"> <listen network="vdsm-vmDisplay" type="network"/> </graphics>""", """ <graphics autoport="yes" defaultMode="secure" listen="0" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice"> <channel mode="secure" name="main"/> <channel mode="secure" name="inputs"/> <channel mode="secure" name="cursor"/> <channel mode="secure" name="playback"/> <channel mode="secure" name="record"/> <channel mode="secure" name="display"/> </graphics>""", """ <graphics autoport="yes" defaultMode="secure" listen="0" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice"> <channel mode="secure" name="main"/> </graphics>""", """ <graphics autoport="yes" defaultMode="secure" listen="0" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice"> <clipboard copypaste="no"/> </graphics>""", """ <graphics autoport="yes" defaultMode="secure" listen="0" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice"> <filetransfer enable="no"/> </graphics>"""] def setUp(self): self.conf = { 'vmName': 'testVm', 'vmId': '9ffe28b6-6134-4b1e-8804-1185f49c436f', 'smp': '8', 'maxVCpus': '160', 'memSize': '1024', 'memGuaranteedSize': '512', } self.confDeviceGraphicsVnc = ( ({'type': 'graphics', 'device': 'vnc'},), ({'type': 'graphics', 'device': 'vnc', 'port': '-1', 'specParams': { 'displayNetwork': 'vmDisplay', 'keyMap': 'en-us'}},)) self.confDeviceGraphicsSpice = ( ({'type': 'graphics', 'device': 'spice'},), ({'type': 'graphics', 'device': 'spice', 'port': '-1', 'tlsPort': '-1', 'specParams': { 'spiceSecureChannels': 'smain,sinputs,scursor,splayback,srecord,sdisplay'}},)) self.confDeviceGraphics = (self.confDeviceGraphicsVnc + self.confDeviceGraphicsSpice) def test_createXmlElem(self): dev = {'type': 'graphics', 'device': 'spice'} expected_xml = '''<?xml version=\'1.0\' encoding=\'utf-8\'?> <graphics device="spice" type="test" />''' with fake.VM(self.conf, devices=(dev,), create_device_objects=True) as testvm: graphics = testvm._devices[hwclass.GRAPHICS][0] element = graphics.createXmlElem('graphics', 'test', attributes=('device', 'foo',)) result = xmlutils.tostring(element) self.assertXMLEqual(result, expected_xml) def testGraphicsDevice(self): for dev in self.confDeviceGraphics: with fake.VM(self.conf, dev) as testvm: devs = testvm._devSpecMapFromConf() self.assertTrue(devs['graphics']) def testGraphicDeviceHeadless(self): with fake.VM(self.conf) as testvm: devs = testvm._devSpecMapFromConf() self.assertFalse(devs['graphics']) def testGraphicDeviceHeadlessSupported(self): conf = {} conf.update(self.conf) self.assertTrue(vmdevices.graphics.isSupportedDisplayType(conf)) def testHasSpiceEngineXML(self): conf = {} conf.update(self.conf) conf['xml'] = read_data('domain.xml') with fake.VM(conf) as testvm: self.assertTrue(testvm.hasSpice) @permutations([['vnc', 'spice'], ['spice', 'vnc']]) def testGraphicsDeviceMultiple(self, primary, secondary): devices = [{'type': 'graphics', 'device': primary}, {'type': 'graphics', 'device': secondary}] with fake.VM(self.conf, devices) as testvm: devs = testvm._devSpecMapFromConf() self.assertEqual(len(devs['graphics']), 2) @permutations([['vnc'], ['spice']]) def testGraphicsDeviceDuplicated(self, devType): devices = [{'type': 'graphics', 'device': devType}, {'type': 'graphics', 'device': devType}] with fake.VM(self.conf, devices) as testvm: self.assertRaises(ValueError, testvm._devSpecMapFromConf) @permutations([ # alias, memballoonXML (None, "<memballoon model='none'/>"), ('balloon0', "<memballoon model='none'><alias name='balloon0'/></memballoon>"), ]) def testBalloonDeviceAliasUpdateConfig(self, alias, memballoonXML): domainXML = """<domain> <devices> %s </devices> </domain>""" % memballoonXML dev = {'device': 'memballoon', 'type': 'none', 'specParams': {}} with fake.VM(self.conf, [dev]) as testvm: testvm._domain = DomainDescriptor(domainXML) devs = testvm._devSpecMapFromConf() testvm._updateDevices(devs) testvm._devices = vmdevices.common.dev_map_from_dev_spec_map( devs, testvm.log ) self.assertNotRaises( vmdevices.core.Balloon.update_device_info, testvm, testvm._devices[hwclass.BALLOON], ) dev = testvm._devices[hwclass.BALLOON][0] if alias is None: self.assertFalse(hasattr(dev, 'alias')) else: self.assertEqual(dev.alias, alias) @MonkeyPatch(vmdevices.network.supervdsm, 'getProxy', lambda: MockedProxy()) def testInterfaceXMLBandwidthUpdate(self): originalBwidthXML = """ <bandwidth> <inbound average="1000" burst="1024" peak="5000"/> <outbound average="128" burst="256"/> </bandwidth>""" NEW_OUT = {'outbound': {'average': 1042, 'burst': 128, 'peak': 500}} updatedBwidthXML = """ <bandwidth> <inbound average="1000" burst="1024" peak="5000"/> <outbound average="%(average)s" burst="%(burst)s" peak="%(peak)s"/> </bandwidth>""" % NEW_OUT['outbound'] dev = {'nicModel': 'virtio', 'macAddr': '52:54:00:59:F5:3F', 'network': 'ovirtmgmt', 'address': self.PCI_ADDR_DICT, 'device': 'bridge', 'type': 'interface', 'bootOrder': '1', 'filter': 'no-mac-spoofing', 'specParams': {'inbound': {'average': 1000, 'peak': 5000, 'burst': 1024}, 'outbound': {'average': 128, 'burst': 256}}, 'custom': {'queues': '7'}, 'vm_custom': {'vhost': 'ovirtmgmt:true', 'sndbuf': '0'}, } iface = vmdevices.network.Interface(self.log, **dev) orig_bandwidth = iface.getXML().findall('bandwidth')[0] self.assert_dom_xml_equal(orig_bandwidth, originalBwidthXML) bandwith = iface.get_bandwidth_xml(NEW_OUT, orig_bandwidth) self.assert_dom_xml_equal(bandwith, updatedBwidthXML) @MonkeyPatch(vmdevices.network.supervdsm, 'getProxy', lambda: MockedProxy( ovs_bridge={'name': 'ovirtmgmt', 'dpdk_enabled': False})) def test_interface_update(self): devices = [{'nicModel': 'virtio', 'network': 'ovirtmgmt', 'macAddr': '52:54:00:59:F5:3F', 'device': 'bridge', 'type': 'interface', 'alias': 'net1', 'name': 'net1', 'linkActive': 'true', 'specParams': {'inbound': {'average': 1000, 'peak': 5000, 'burst': 1024}, 'outbound': {'average': 128, 'burst': 256}}, }] params = {'linkActive': 'true', 'alias': 'net1', 'deviceType': 'interface', 'network': 'ovirtmgmt2', 'specParams': {'inbound': {}, 'outbound': {}}} updated_xml = ''' <interface type="bridge"> <mac address="52:54:00:59:F5:3F"/> <model type="virtio"/> <source bridge="ovirtmgmt2"/> <virtualport type="openvswitch"/> <link state="up"/> <alias name="net1"/> <bandwidth/> </interface> ''' with fake.VM(devices=devices, create_device_objects=True) as testvm: testvm._dom = fake.Domain() res = testvm.updateDevice(params) self.assertIn('vmList', res) self.assertXMLEqual(testvm._dom.devXml, updated_xml) def testUpdateDriverInSriovInterface(self): interface_xml = """<?xml version="1.0" encoding="utf-8"?> <domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"> <devices> <interface type='hostdev' managed='no'> <source> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </source> <driver name='vfio' queues='10'/> <mac address='ff:ff:ff:ff:ff:ff'/> <vlan> <tag id='3'/> </vlan> <boot order='9'/> </interface> </devices> </domain>""" with fake.VM() as testvm: interface_conf = { 'type': hwclass.NIC, 'device': 'hostdev', 'hostdev': 'pci_0000_05_00_1', 'macAddr': 'ff:ff:ff:ff:ff:ff', 'specParams': {'vlanid': 3}, 'bootOrder': '9'} interface_dev = vmdevices.network.Interface( testvm.log, **interface_conf) testvm.conf['devices'] = [interface_conf] device_conf = [interface_dev] testvm._domain = DomainDescriptor(interface_xml) vmdevices.network.Interface.update_device_info( testvm, device_conf) self.assertEqual(interface_dev.driver, {'queues': '10', 'name': 'vfio'}) def test_interface_update_disappear_queues(self): interface_xml = """<interface type="bridge"> <model type="virtio" /> <link state="up" /> <source bridge="ovirtmgmt" /> <driver name="vhost" queues="1" /> <alias name="ua-604c7957-9aaf-4e86-bcaa-87e12571449b" /> <mac address="00:1a:4a:16:01:50" /> <mtu size="1500" /> <filterref filter="vdsm-no-mac-spoofing" /> <bandwidth /> </interface> """ updated_xml = """<?xml version="1.0" encoding="utf-8"?> <domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"> <devices> <interface type='bridge'> <mac address='00:1a:4a:16:01:50'/> <source bridge='ovirtmgmt'/> <target dev='vnet0'/> <model type='virtio'/> <driver name='vhost'/> <filterref filter='vdsm-no-mac-spoofing'/> <link state='up'/> <mtu size='1500'/> <alias name='ua-604c7957-9aaf-4e86-bcaa-87e12571449b'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> </devices> </domain>""" meta = {'vmid': 'VMID'} # noone cares about the actual ID with fake.VM() as testvm: nic = vmdevices.network.Interface.from_xml_tree( self.log, xmlutils.fromstring(interface_xml), meta=meta ) saved_driver = nic.driver.copy() testvm._devices[hwclass.NIC].append(nic) testvm._domain = DomainDescriptor(updated_xml) vmdevices.network.Interface.update_device_info( testvm, testvm._devices[hwclass.NIC] ) self.assertEqual(nic.driver, saved_driver) @MonkeyPatch(vmdevices.network.supervdsm, 'getProxy', lambda: MockedProxy(ovs_bridge={'name': 'test', 'dpdk_enabled': True})) def test_vhostuser_interface(self): interfaceXML = """ <interface type="vhostuser"> <address {pciaddr}/> <mac address="52:54:00:59:F5:3F"/> <model type="virtio"/> <source mode="server" path="{rundir}vhostuser/{vmid}" type="unix" /> <filterref filter="no-mac-spoofing"/> <link state="up"/> <boot order="1"/> </interface>""".format( pciaddr=self.PCI_ADDR, rundir=constants.P_VDSM_RUN, vmid='f773dff7-0e9c-3bc3-9e36-9713415446df', ) dev = {'nicModel': 'virtio', 'macAddr': '52:54:00:59:F5:3F', 'network': 'test', 'address': self.PCI_ADDR_DICT, 'device': 'bridge', 'type': 'interface', 'bootOrder': '1', 'filter': 'no-mac-spoofing', 'vmid': self.conf['vmId']} iface = vmdevices.network.Interface(self.log, **dev) iface.setup() try: self.assert_dom_xml_equal(iface.getXML(), interfaceXML) finally: iface.teardown() @MonkeyPatch(vmdevices.network.supervdsm, 'getProxy', lambda: MockedProxy(ovs_bridge={'name': 'test', 'dpdk_enabled': True})) def test_vhostuser_interface_recovery(self): interfaceXML = """ <interface type="vhostuser"> <address {pciaddr}/> <mac address="52:54:00:59:F5:3F"/> <model type="virtio"/> <source mode="server" path="{rundir}vhostuser/{vmid}" type="unix" /> <filterref filter="no-mac-spoofing"/> <link state="up"/> <boot order="1"/> </interface>""".format( pciaddr=self.PCI_ADDR, rundir=constants.P_VDSM_RUN, vmid='f773dff7-0e9c-3bc3-9e36-9713415446df', ) dev = {'nicModel': 'virtio', 'macAddr': '52:54:00:59:F5:3F', 'network': 'test', 'address': self.PCI_ADDR_DICT, 'device': 'bridge', 'type': 'interface', 'bootOrder': '1', 'filter': 'no-mac-spoofing', 'vmid': self.conf['vmId']} iface = vmdevices.network.Interface(self.log, **dev) iface.recover() try: self.assert_dom_xml_equal(iface.getXML(), interfaceXML) finally: iface.teardown() def testGetUnderlyingGraphicsDeviceInfo(self): port = '6000' tlsPort = '6001' graphicsXML = """<?xml version="1.0" encoding="utf-8"?> <domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"> <devices> <graphics autoport="yes" keymap="en-us" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="%s" tlsPort="%s" type="spice"> <listen network="vdsm-vmDisplay" type="network"/> </graphics> </devices> </domain>""" % (port, tlsPort) with fake.VM() as testvm: graphConf = { 'type': hwclass.GRAPHICS, 'device': 'spice', 'port': '-1', 'tlsPort': '-1'} graphDev = vmdevices.graphics.Graphics( testvm.log, device='spice', port='-1', tlsPort='-1') testvm.conf['devices'] = [graphConf] device_conf = [graphDev] testvm._domain = DomainDescriptor(graphicsXML) vmdevices.graphics.Graphics.update_device_info(testvm, device_conf) self.assertEqual(graphDev.port, port) self.assertEqual(graphDev.tlsPort, tlsPort) self.assertEqual(graphDev.port, graphConf['port']) self.assertEqual(graphDev.tlsPort, graphConf['tlsPort']) @MonkeyPatch(graphics, 'config', make_config([('vars', 'ssl', 'true')])) def testGraphicsDeviceXML(self): vmConfs = [ {'devices': [{ 'type': 'graphics', 'device': 'vnc', 'port': '-1', 'specParams': { 'displayNetwork': 'vmDisplay', 'keyMap': 'en-us'}}]}, {'devices': [{ 'type': 'graphics', 'device': 'spice', 'port': '-1', 'tlsPort': '-1', 'specParams': { 'spiceSecureChannels': 'smain,sinputs,scursor,splayback,srecord,sdisplay'}}]}, {'devices': [{ 'type': 'graphics', 'device': 'spice', 'port': '-1', 'tlsPort': '-1', 'specParams': { 'spiceSecureChannels': 'smain'}}]}, {'devices': [{ 'type': 'graphics', 'device': 'spice', 'port': '-1', 'tlsPort': '-1', 'specParams': { 'copyPasteEnable': 'false'}}]}, {'devices': [{ 'type': 'graphics', 'device': 'spice', 'port': '-1', 'tlsPort': '-1', 'specParams': { 'fileTransferEnable': 'false'}}]}] for vmConf, xml in zip(vmConfs, self.GRAPHICS_XMLS): self._verifyGraphicsXML(vmConf, xml) def _verifyGraphicsXML(self, vmConf, xml): spiceChannelXML = """ <channel type="spicevmc"> <target name="com.redhat.spice.0" type="virtio"/> </channel>""" vmConf.update(self.conf) with fake.VM() as testvm: dev = testvm._dev_spec_update_with_vm_conf(vmConf['devices'][0]) with MonkeyPatchScope([ (vmdevices.graphics.libvirtnetwork, 'networks', lambda: {}) ]): graph = vmdevices.graphics.Graphics(self.log, **dev) self.assert_dom_xml_equal(graph.getXML(), xml) if graph.device == 'spice': self.assert_dom_xml_equal(graph.getSpiceVmcChannelsXML(), spiceChannelXML) @permutations([['''<hostdev managed="no" mode="subsystem" type="usb"> <alias name="testusb"/> <source> <address bus="1" device="2"/> </source> </hostdev>''', {'type': hwclass.HOSTDEV, 'device': 'usb_1_1'}], ['''<hostdev managed="no" mode="subsystem" type="pci"> <alias name="testpci"/> <source> <address bus="0" domain="0" function="0" slot="2"/> </source> <address bus="0" domain="0" function="0" slot="3"/> </hostdev>''', {'type': hwclass.HOSTDEV, 'device': 'pci_0000_00_02_0'}]]) def testGetUpdateHostDeviceInfo(self, device_xml, conf): xml = """<?xml version="1.0" encoding="utf-8"?> <domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"> <devices> %s </devices> </domain>""" % (device_xml,) with fake.VM() as testvm: device = vmdevices.hostdevice.HostDevice(testvm.log, **conf) testvm.conf['devices'] = [conf] device_conf = [device] testvm._domain = DomainDescriptor(xml) vmdevices.hostdevice.HostDevice.update_device_info(testvm, device_conf) def test_mdev_details_(self): details = hostdev._mdev_type_details('graphics-card-1', '/nonexistent') for f in hostdev._MDEV_FIELDS: self.assertEqual(getattr(details, f), 'graphics-card-1' if f == 'name' else '') def testGraphicsNoDisplayNetwork(self): with fake.VM() as testvm: graphDev = vmdevices.graphics.Graphics(testvm.log) self.assertNotIn('displayNetwork', graphDev.specParams) def testGraphicsDisplayNetworkFromSpecParams(self): with fake.VM() as testvm: graphDev = vmdevices.graphics.Graphics( testvm.log, specParams={'displayNetwork': 'vmDisplaySpecParams'}) self.assertEqual(graphDev.specParams['displayNetwork'], 'vmDisplaySpecParams')
def test_zero_block_size_valid(self, block_size_mb, monkeypatch): cfg = make_config([('irs', 'zero_block_size_mb', block_size_mb)]) monkeypatch.setattr(blockdev, "config", cfg) block_size = int(block_size_mb) * constants.MEGAB assert blockdev.zero_block_size() == block_size
'hwaddr': '00:00:00:00:00:00'}} return ifdata class FakeVM(object): def __init__(self): self._dom = FakeDomain() @property def id(self): return "00000000-0000-0000-0000-000000000001" @MonkeyClass(libvirt_qemu, "qemuAgentCommand", _fake_qemuAgentCommand) @MonkeyClass(qemuguestagent, 'config', make_config([ ('guest_agent', 'periodic_workers', '1') ])) class QemuGuestAgentTests(TestCaseBase): def setUp(self): self.cif = fake.ClientIF() self.scheduler = schedule.Scheduler(name="test.Scheduler", clock=monotonic_time) self.scheduler.start() self.log = logging.getLogger("test") self.qga_poller = qemuguestagent.QemuGuestAgentPoller( self.cif, self.log, self.scheduler) self.vm = FakeVM() self.qga_poller.update_caps( self.vm.id, { 'version': '0.0-test',
def zero_method(request, monkeypatch): cfg = make_config([('irs', 'zero_method', request.param)]) monkeypatch.setattr(blockdev, "config", cfg) return request.param