def test_nic_hotunplug_timeout(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)) assert len(vm._devices[hwclass.NIC]) == 2
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.set_initial_downtime() dt.start() dt.join() return dom.getDowntimes()
def test_create_cache(self): with namedTemporaryDir() as dir: with MonkeyPatchScope([(vdsmapi, "VDSM_CACHE_DIR", dir)]): vdsmapi.create_cache() vdsm_api_yml = "../lib/vdsm/api/vdsm-api.yml" vdsm_api_cache = os.path.join(dir, "vdsm-api.pickle") self.assertEqual(round(os.stat(vdsm_api_yml).st_mtime, 2), round(os.stat(vdsm_api_cache).st_mtime, 2)) vdsm_events_yml = "../lib/vdsm/api/vdsm-events.yml" vdsm_events_cache = os.path.join(dir, "vdsm-events.pickle") self.assertEqual(round(os.stat(vdsm_events_yml).st_mtime, 2), round(os.stat(vdsm_events_cache).st_mtime, 2))
def test_getNetInfo(self): """Test if getNetInfo marks non-VDSM devices as a part of persistent network. """ with _fake_ifcfgs() as ifcfgs_dir: FAKE_NET_CONF_PREF = ifcfgs_dir + '/ifcfg-' with MonkeyPatchScope([(unified_persistence.netswitch, 'netinfo', lambda: FAKE_NETINFO), (misc, 'NET_CONF_PREF', FAKE_NET_CONF_PREF) ]): networks, bonds = unified_persistence._getNetInfo() self.assertEquals(set(networks), set([NETWORK_NAME])) self.assertEquals(set(bonds), set([BOND_NAME]))
def test_qcow2_compat_unsupported(self): def convert(cmd, **kw): expected = [ QEMU_IMG, 'convert', '-t', 'none', 'src', '-O', 'qcow2', 'dst' ] self.assertEqual(cmd, expected) return 0, '', '' with MonkeyPatchScope([(qemuimg, '_supports_qcow2_compat', self.supported('convert', False)), (qemuimg, '_supports_src_cache', self.supported('convert', False)), (utils, 'watchCmd', convert)]): qemuimg.convert('src', 'dst', True, dstFormat='qcow2')
def test_qemu2_backing_no_cluster(self): def call(cmd, **kw): out = [ "image: leaf.img", "file format: qcow2", "virtual size: 1.0G (1073741824 bytes)", "disk size: 196K", "backing file: base.img (actual path: /tmp/base.img)", "Format specific information:", " compat: 1.1", " lazy refcounts: false" ] return 0, out, [] with MonkeyPatchScope([(utils, "execCmd", call)]): info = qemuimg.info('leaf.img') self.assertEquals('base.img', info['backingfile'])
def testGetIfaceCfg(self): deviceName = "___This_could_never_be_a_device_name___" ifcfg = ('GATEWAY0=1.1.1.1\n' 'NETMASK=255.255.0.0\n') with namedTemporaryDir() as tempDir: ifcfgPrefix = os.path.join(tempDir, 'ifcfg-') filePath = ifcfgPrefix + deviceName with MonkeyPatchScope([(netinfo, 'NET_CONF_PREF', ifcfgPrefix)]): with open(filePath, 'w') as ifcfgFile: ifcfgFile.write(ifcfg) self.assertEqual( netinfo.getIfaceCfg(deviceName)['GATEWAY'], '1.1.1.1') self.assertEqual( netinfo.getIfaceCfg(deviceName)['NETMASK'], '255.255.0.0')
def test_console_pty_not_cleanup_path(self): def _fake_cleanup(path): self._cleaned_path = path with MonkeyPatchScope([(vmdevices.core, 'cleanup_guest_socket', _fake_cleanup)]): dev = { 'device': 'console', 'vmId': self.cfg['vmId'], } con = vmdevices.core.Console(self.log, **dev) con.cleanup() self.assertEqual(self._cleaned_path, None)
def test_legacy_conf_conversion(self, xml_model, conf_model): xml = self.NIC_HOTPLUG.replace('virtio', xml_model) vm = self.vm params = {'xml': xml} with MonkeyPatchScope([(vdsm.common.supervdsm, 'getProxy', self.supervdsm.getProxy)]): vm.hotplugNic(params) dev_conf = vm.status()['devices'] for conf in dev_conf: if conf.get('macAddr') == '66:55:44:33:22:11': self.assertEqual(conf.get('nicModel'), conf_model) break else: raise Exception("Hot plugged device not found")
def test_untrusted_image_call(self): command = [] def call(cmd, *args, **kwargs): command.extend(cmd) out = json.dumps(self._fake_info()).encode("utf-8") return 0, out, b"" with MonkeyPatchScope([(commands, "execCmd", call)]): qemuimg.info('unused', trusted_image=False) assert command[:3] == [constants.EXT_PRLIMIT, '--cpu=30', '--as=1073741824']
def test_legacy_nic_hotunplug_port_mirroring(self): vm = self.vm port_mirroring = ['network1', 'network2'] params = { 'nic': { 'macAddr': '66:55:44:33:22:11', 'network': 'test', 'device': 'bridge', 'type': 'interface', 'portMirroring': port_mirroring, } } with MonkeyPatchScope([(vdsm.common.supervdsm, 'getProxy', self.supervdsm.getProxy)]): vm.hotplugNic(params) with MonkeyPatchScope([(vdsm.common.supervdsm, 'getProxy', self.supervdsm.getProxy)]): vm.hotunplugNic(params) self.assertEqual(len(vm._devices[hwclass.NIC]), 1) dev = vm._devices[hwclass.NIC][0] self.assertEqual(dev.macAddr, "11:22:33:44:55:66") self.assertEqual(dev.network, "ovirtmgmt") self.assertEqual(self.supervdsm.mirrored_networks, [])
def setUp(self): self.uuid = API.VM.BLANK_UUID self.cif = FakeClientIF() self.vmParams = { 'vmId': self.uuid, 'memSize': 8 * 1024, 'vmType': 'kvm', 'display': 'qxl', 'kvmEnable': 'true', } with MonkeyPatchScope([(API, 'clientIF', self.cif)]): self.vm = API.VM(self.uuid) # to make testing easier self.vm._getHibernationPaths = lambda handle: (True, handle)
def testAllVmStats(self): with fake.VM(_VM_PARAMS) as testvm: with MonkeyPatchScope([(clientIF, 'getInstance', lambda _: testvm.cif)]): api = API.Global() # here is where clientIF will be used. response = api.getAllVmStats() self.assertEqual(response['status']['code'], 0) for stat in response['statsList']: self.assertVmStatsSchemaCompliancy( 'RunningVmStats', stat)
def test_qcow2_backing_file(self): def convert(cmd, **kw): expected = [ QEMU_IMG, 'convert', '-p', '-t', 'none', 'src', '-O', 'qcow2', '-o', 'compat=0.10,backing_file=bak', 'dst' ] self.assertEqual(cmd, expected) with MonkeyPatchScope([(qemuimg, '_supports_qcow2_compat', self.supported('convert', True)), (qemuimg, '_supports_src_cache', self.supported('convert', False)), (qemuimg, 'QemuImgOperation', convert)]): qemuimg.convert('src', 'dst', dstFormat='qcow2', backing='bak')
def test_disabled_compat_raises(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() with pytest.raises(se.ImageVerificationError): h.verify_untrusted_volume( 'sp', vol.sdUUID, vol.imgUUID, vol.volUUID)
def fake_file_env(obj=None, sd_version=3): with namedTemporaryDir() as tmpdir: sd_manifest = make_filesd_manifest(tmpdir, sd_version=sd_version) fake_sdc = FakeStorageDomainCache() with MonkeyPatchScope([ [sd, 'storage_repository', tmpdir], [volume, 'sdCache', fake_sdc], [hsm, 'sdCache', fake_sdc], ]): fake_sdc.domains[sd_manifest.sdUUID] = FakeSD(sd_manifest) try: yield FakeFileEnv(tmpdir, sd_manifest, fake_sdc) finally: oop.stop()
def _updateGraphicsDevice(self, testvm, device_type, graphics_params): def _check_ticket_params(domXML, conf, params): self.assertEqual(params, _TICKET_PARAMS) def _fake_set_vnc_pwd(username, pwd): pass with MonkeyPatchScope([ (hooks, 'before_vm_set_ticket', _check_ticket_params), (saslpasswd2, 'set_vnc_password', _fake_set_vnc_pwd) ]): params = {'graphicsType': device_type} params.update(graphics_params) return testvm.updateDevice(params)
def test_qcow2_backing_format(self): def convert(cmd, **kw): expected = [ QEMU_IMG, 'convert', '-p', '-t', 'none', '-T', 'none', 'src', '-O', 'qcow2', '-o', 'compat=0.10', 'dst' ] self.assertEqual(cmd, expected) with MonkeyPatchScope([(qemuimg, 'config', CONFIG), (qemuimg, 'QemuImgOperation', convert)]): qemuimg.convert('src', 'dst', dstFormat='qcow2', backingFormat='qcow2')
def VM(params=None, devices=None, runCpu=False, arch=cpuarch.X86_64, status=None, cif=None, create_device_objects=False, post_copy=None, recover=False, vmid=None, resume_behavior=None, pause_time_offset=None): with namedTemporaryDir() as tmpDir: with MonkeyPatchScope([(constants, 'P_VDSM_RUN', tmpDir), (libvirtconnection, 'get', Connection), (containersconnection, 'get', Connection), ]): if params and 'xml' in params: vmParams = {} else: if vmid is None: vmid = 'TESTING' vmParams = {'vmId': vmid, 'vmName': 'n%s' % vmid} vmParams.update({} if params is None else params) cif = ClientIF() if cif is None else cif fake = vm.Vm(cif, vmParams, recover=recover) cif.vmContainer[fake.id] = fake fake._update_metadata = lambda: None fake._sync_metadata = lambda: None fake.send_status_event = lambda **kwargs: None fake._waitForDeviceRemoval = lambda device: None fake.arch = arch fake.guestAgent = GuestAgent() fake.conf['devices'] = [] if devices is None else devices if create_device_objects: fake._devices = common.dev_map_from_dev_spec_map( fake._devSpecMapFromConf(), fake.log ) fake._guestCpuRunning = runCpu if status is not None: fake._lastStatus = status if post_copy is not None: fake._post_copy = post_copy if resume_behavior is not None: fake._resume_behavior = resume_behavior if pause_time_offset is not None: fake._pause_time = (vdsm.common.time.monotonic_time() - pause_time_offset) sampling.stats_cache.add(fake.id) def _updateDomainDescriptor(_=None): fake._domain = DomainDescriptor(fake._buildDomainXML()) fake._updateDomainDescriptor = _updateDomainDescriptor yield fake
def test_logical_volume_list(self): data = { "report": [{ "lv": [{ "lv_size": "52613349376", "data_percent": "0.06", "lv_name": "internal_pool", "vg_name": "INTERNAL", "pool_lv": "" }, { "lv_size": "10737418240", "data_percent": "0.16", "lv_name": "vdodistr", "vg_name": "INTERNAL", "pool_lv": "internal_pool" }, { "lv_size": "53687091200", "data_percent": "", "lv_name": "engine", "vg_name": "vg0", "pool_lv": "" }] }] } expected = [{ "lv_size": 52613349376, "lv_free": 52581781366, "lv_name": "internal_pool", "vg_name": "INTERNAL", "pool_lv": "" }, { "lv_size": 10737418240, "lv_free": 0, "lv_name": "vdodistr", "vg_name": "INTERNAL", "pool_lv": "internal_pool" }, { "lv_size": 53687091200, "lv_free": 0, "lv_name": "engine", "vg_name": "vg0", "pool_lv": "" }] with MonkeyPatchScope([(commands, "execCmd", partial(fake_json_call, data))]): actual = thinstorage.logicalVolumeList() self.assertEqual(expected, actual)
def testSetNumberOfVcpusFailed(self, virt_error, vdsm_error, error_message): def _fail(*args): raise_libvirt_error(virt_error, error_message) with MonkeyPatchScope([(hooks, 'before_set_num_of_cpus', lambda: None) ]): with fake.VM() as testvm: dom = fake.Domain() dom.setVcpusFlags = _fail testvm._dom = dom res = testvm.setNumberOfCpus(4) # random value assert res == response.error(vdsm_error)
def test_delayed_nic_hotunplug(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.vm.onDeviceRemoved('ua-nic-hotplugged') self.assertEqual(len(vm._devices[hwclass.NIC]), 1)
def test_console_usock_prepare_path(self): supervdsm = fake.SuperVdsm() with MonkeyPatchScope([(vmdevices.core, 'supervdsm', supervdsm)]): dev = { 'device': 'console', 'specParams': {'enableSocket': True}, 'vmid': self.cfg['vmId'], } con = vmdevices.core.Console(self.log, **dev) con.prepare() self.assertEqual(supervdsm.prepared_path, self._expected_path) self.assertEqual(supervdsm.prepared_path_group, constants.OVIRT_VMCONSOLE_GROUP)
def test_disabled_compat_raises(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.assertRaises(se.ImageVerificationError, h.verify_untrusted_volume, 'sp', vol.sdUUID, vol.imgUUID, vol.volUUID)
def test_console_pty_not_cleanup_path(self): def _fake_cleanup(path): self._cleaned_path = path with MonkeyPatchScope([(vmdevices.core, 'cleanup_guest_socket', _fake_cleanup)]): dom = xmlutils.fromstring(""" <console type="pty"> <source path="/abc/def"/> <target port="0" type="serial"/> <alias name="ua-1234"/> </console> """) vmdevices.core.cleanup_console(dom, self.cfg['vmId']) self.assertEqual(self._cleaned_path, None)
def testXenBlockDevice(self): def _connect(uri, username, passwd): self._vms[0].setDiskType('block') conn = MockVirConnect(vms=self._vms) conn.setType('Xen') return conn with MonkeyPatchScope([(libvirtconnection, 'open_connection', _connect) ]): vms = v2v.get_external_vms(self.xen_url, 'user', ProtectedPassword('password'), None)['vmList'] self.assertEqual(len(vms), len(VM_SPECS) - 1) self.assertTrue(self._vms[0] not in vms)
def testGetExternalVMs(self): def _connect(uri, username, passwd): return MockVirConnect(vms=self._vms) with MonkeyPatchScope([(libvirtconnection, 'open_connection', _connect) ]): vms = v2v.get_external_vms('esx://mydomain', 'user', ProtectedPassword('password'), None)['vmList'] self.assertEqual(len(vms), len(VM_SPECS)) for vm, spec in zip(vms, VM_SPECS): self._assertVmMatchesSpec(vm, spec) self._assertVmDisksMatchSpec(vm, spec)
def testLookupFailure(self, methodname, fakemethod, active): def _connect(uri, username, passwd): mock = MockVirConnect(vms=self._vms) mock.listAllDomains = legacylistAllDomains setattr(mock, methodname, fakemethod) return mock with MonkeyPatchScope([(libvirtconnection, 'open_connection', _connect) ]): vms = v2v.get_external_vms('esx://mydomain', 'user', ProtectedPassword('password'), None)['vmList'] assert sorted(vm['vmName'] for vm in vms) == \ sorted(spec.name for spec in VM_SPECS if spec.active == active)
def __init__(self): irs = None log = logging.getLogger('test.ClientIF') scheduler = None fake_start = mock.Mock() with MonkeyPatchScope([ (clientIF, '_glusterEnabled', False), (clientIF, 'secret', {}), (clientIF, 'MomClient', lambda *args: mock.Mock()), (clientIF, 'QemuGuestAgentPoller', lambda *args: fake_start), (clientIF, 'Listener', lambda *args: mock.Mock()), (clientIF.concurrent, 'thread', lambda *args, **kwargs: fake_start), ]): super(NotSoFakeClientIF, self).__init__(irs, log, scheduler)
def test_create_fail_writing_metadata(self): # If we fail to write metadata we will be left with a garbage LV and an # allocated metadata slot which is not freed until the LV is removed. with self.fake_env() as env: slot_before = self.get_next_free_slot(env) artifacts = env.sd_manifest.get_volume_artifacts( self.img_id, self.vol_id) with MonkeyPatchScope([ [blockVolume.BlockVolumeManifest, 'newMetadata', failure] ]): self.assertRaises(ExpectedFailure, artifacts.create, *BASE_PARAMS[sc.RAW_FORMAT]) self.validate_invisibility(env, artifacts, is_garbage=True) self.validate_domain_has_garbage(env.sd_manifest) self.assertNotEqual(slot_before, self.get_next_free_slot(env))