Example #1
0
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()
Example #2
0
 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)
Example #3
0
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
Example #4
0
 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)
Example #5
0
 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)
Example #6
0
 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)
Example #7
0
 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')
Example #8
0
 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))
Example #9
0
 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')
Example #10
0
 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))
Example #11
0
    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()
Example #12
0
 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)
Example #13
0
    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()
Example #14
0
 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
         )
Example #15
0
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
Example #16
0
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
Example #17
0
    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)
Example #18
0
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
Example #19
0
    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
Example #20
0
 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)
Example #21
0
 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)
Example #22
0
 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)
Example #23
0
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()
Example #24
0
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()
Example #25
0
 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)
Example #26
0
 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)
Example #27
0
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)
Example #28
0
    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()
Example #29
0
 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
Example #30
0
    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()
Example #31
0
    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())
Example #32
0
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)
Example #33
0
    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
Example #34
0
 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))
Example #35
0
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
Example #36
0
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
Example #37
0
def api_strict_mode():
        return MonkeyPatch(vdsmapi, 'config', make_config(
            [('devel', 'api_strict_mode', 'true')]))
Example #38
0
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],
Example #39
0
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)
Example #40
0
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)
Example #41
0
 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')
Example #42
0
def api_strict_mode():
    return MonkeyPatch(vdsmapi, 'config',
                       make_config([('devel', 'api_strict_mode', 'true')]))
Example #43
0
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)
Example #44
0
    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,
Example #45
0
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)
Example #46
0
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
Example #47
0
 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()
Example #48
0
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')
Example #49
0
 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
Example #50
0
                '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',
Example #51
0
def zero_method(request, monkeypatch):
    cfg = make_config([('irs', 'zero_method', request.param)])
    monkeypatch.setattr(blockdev, "config", cfg)
    return request.param