def setUp(self): self.vm = None self.qemu_bin = self.params.get('qemu_bin', default=pick_default_qemu_bin()) if self.qemu_bin is None: self.cancel("No QEMU binary defined or found in the source tree") self.vm = QEMUMachine(self.qemu_bin)
def boot(self, img, extra_args=[]): args = self._args + [ "-device", "VGA", "-drive", "file=%s,if=none,id=drive0,cache=writeback" % img, "-device", "virtio-blk,drive=drive0,bootindex=0"] args += self._data_args + extra_args logging.debug("QEMU args: %s", " ".join(args)) qemu_bin = os.environ.get("QEMU", "qemu-system-x86_64") guest = QEMUMachine(binary=qemu_bin, args=args) try: guest.launch() except: logging.error("Failed to launch QEMU, command line:") logging.error(" ".join([qemu_bin] + args)) logging.error("Log:") logging.error(guest.get_log()) logging.error("QEMU version >= 2.10 is required") raise atexit.register(self.shutdown) self._guest = guest usernet_info = guest.qmp("human-monitor-command", command_line="info usernet") self.ssh_port = None for l in usernet_info["return"].splitlines(): fields = l.split() if "TCP[HOST_FORWARD]" in fields and "22" in fields: self.ssh_port = l.split()[3] if not self.ssh_port: raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \ usernet_info)
def setUp(self): self.jobdir = os.path.dirname(self.logdir) self.log.info("### jobdir: %s", self.jobdir) self.kernel = os.path.join(self.jobdir, "drminfo.kernel") self.initrd = os.path.join(self.jobdir, "drminfo.initrd") self.qemu_binary = self.find_qemu_binary() self.log.info("### using qemu binary: %s", self.qemu_binary) self.vm = QEMUMachine(self.qemu_binary)
class Test(avocado.Test): def setUp(self): self.vm = None self.qemu_bin = self.params.get('qemu_bin', default=pick_default_qemu_bin()) if self.qemu_bin is None: self.cancel("No QEMU binary defined or found in the source tree") self.vm = QEMUMachine(self.qemu_bin) def tearDown(self): if self.vm is not None: self.vm.shutdown()
def boot(self, img, extra_args=[]): args = self._args + [ "-device", "VGA", "-drive", "file=%s,if=none,id=drive0,cache=writeback" % img, "-device", "virtio-blk,drive=drive0,bootindex=0" ] args += self._data_args + extra_args logging.debug("QEMU args: %s", " ".join(args)) qemu_bin = os.environ.get("QEMU", "qemu-system-" + self.arch) guest = QEMUMachine(binary=qemu_bin, args=args) try: guest.launch() except: logging.error("Failed to launch QEMU, command line:") logging.error(" ".join([qemu_bin] + args)) logging.error("Log:") logging.error(guest.get_log()) logging.error("QEMU version >= 2.10 is required") raise atexit.register(self.shutdown) self._guest = guest usernet_info = guest.qmp("human-monitor-command", command_line="info usernet") self.ssh_port = None for l in usernet_info["return"].splitlines(): fields = l.split() if "TCP[HOST_FORWARD]" in fields and "22" in fields: self.ssh_port = l.split()[3] if not self.ssh_port: raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \ usernet_info)
def migrate_vm(self, vga, display = None): self.log.info("### live migration: start ...") dest_uri = 'tcp:localhost:%u' % self._get_free_port() dest_vm = QEMUMachine(self.qemu_binary) self.boot_gfx_vm(vga, display, dest_vm, dest_uri); self.vm.qmp('migrate_set_speed', value = "1G") self.vm.qmp('migrate', uri=dest_uri) wait.wait_for( self.migration_finished, timeout=self.timeout, step=0.1, args=(self.vm,) ) self.assertEqual(dest_vm.command('query-migrate')['status'], 'completed') self.assertEqual(self.vm.command('query-migrate')['status'], 'completed') self.assertEqual(dest_vm.command('query-status')['status'], 'running') self.assertEqual(self.vm.command('query-status')['status'], 'postmigrate') self.log.info("### live migration: OK") # swap vm and console handles, so we can talk to the new vm ... self.vm.shutdown() self.vm = dest_vm self.rconsole = self.vm.console_socket.makefile('r') self.wconsole = self.vm.console_socket.makefile('w')
def run_device(self, devtype, opts=None, machine='pc'): """ Run QEMU with `-device DEVTYPE`, return device info from `query-pci` """ with QEMUMachine(self.qemu_bin) as vm: vm.set_machine(machine) if opts: devtype += ',' + opts vm.add_args('-device', '%s,id=devfortest' % (devtype)) vm.add_args('-S') vm.launch() pcibuses = vm.command('query-pci') alldevs = [dev for bus in pcibuses for dev in bus['devices']] devfortest = [dev for dev in alldevs if dev['qdev_id'] == 'devfortest'] return devfortest[0], get_pci_interfaces(vm, devtype)
def _new_vm(self, *args): vm = QEMUMachine(self.qemu_bin) if args: vm.add_args(*args) return vm
class TestDRM(avocado.Test): rconsole = None wconsole = None def find_qemu_binary(self): """ Picks the path of a QEMU binary, starting either in the current working directory or in the source tree root directory. """ arch = os.uname()[4] qemu_path = [ "/usr/local/bin/qemu-system-%s" % arch, "/usr/bin/qemu-system-%s" % arch, "/usr/bin/qemu-kvm", "/usr/libexec/qemu-kvm", ] if not QEMU_BUILD_DIR is None: qemu_build = os.path.join(QEMU_BUILD_DIR, "%s-softmmu" % arch, "qemu-system-%s" % arch) qemu_path.insert(0, qemu_build) if not QEMU_BINARY is None: qemu_path.insert(0, QEMU_BINARY) for item in qemu_path: if os.path.isfile(item): return item return None def prepare_kernel_initrd(self): if LINUX_BUILD_DIR is None: kmoddir = None kversion = os.uname()[2] copyfile("/boot/vmlinuz-%s" % kversion, self.kernel) else: self.log.info("### install kernel modules (%s) for initrd" % LINUX_BUILD_DIR) cmdline = "make -C %s" % LINUX_BUILD_DIR cmdline += " INSTALL_MOD_PATH=%s" % self.workdir cmdline += " modules_install" run(cmdline) kmoddir = glob("%s/lib/modules/*" % self.workdir)[0] kversion = os.path.basename(kmoddir) copyfile("%s/arch/x86/boot/bzImage" % LINUX_BUILD_DIR, self.kernel) drivers = [ "cirrus", "bochs-drm", "qxl", "virtio-pci", "virtio-gpu", "vgem", "vkms", ] modules = [ "base", "systemd", "systemd-initrd", "dracut-systemd", "bash", "drm", "rootfs-block", ] files = [ "/usr/bin/drminfo", "/usr/bin/drmtest", "/usr/bin/fbinfo", "/usr/bin/fbtest", "/usr/bin/virtiotest", "/usr/bin/egltest", "/usr/bin/prime", "/usr/bin/edid-decode", "/usr/bin/strace", "/etc/fonts/fonts.conf", "/etc/fonts/conf.d/59-liberation-mono.conf", "/usr/share/fontconfig/conf.avail/59-liberation-mono.conf", "/usr/share/fonts/liberation/LiberationMono-Regular.ttf", "/usr/share/fonts/liberation-mono/LiberationMono-Regular.ttf", ] rpms = [ "mesa-libGL", "mesa-libEGL", "mesa-dri-drivers", ] # drop non-existing modules all_modules = run("dracut --list-modules").stdout.decode().split() module_list = [] for module in modules: if module in all_modules: module_list.append(module) # add files from rpms for rpm in rpms: rpmfiles = run("rpm -ql %s" % rpm) for item in rpmfiles.stdout.decode().split(): files.append(item) self.log.info("### create initrd for %s" % kversion) cmdline = "dracut" cmdline += " --no-hostonly" cmdline += " --force" if not kmoddir is None: cmdline += " --kmoddir \"%s\"" % kmoddir cmdline += " --modules \"%s\"" % " ".join(module_list) cmdline += " --drivers \"%s\"" % " ".join(drivers) for item in files: cmdline += " --install %s" % item cmdline += " \"%s\" \"%s\"" % (self.initrd, kversion) run(cmdline) def boot_gfx_vm(self, vga, display=None, vm=None, incoming=None, iommu=False, append=""): append += " console=ttyS0" append += " rd.shell" append += " rd.break" self.log.info("### boot kernel with display device \"%s\"" % vga) if vm is None: vm = self.vm if iommu: vm.set_machine('q35,kernel-irqchip=split') else: vm.set_machine('pc') vm.set_console() vm.add_args('-enable-kvm') vm.add_args('-m', '1G') vm.add_args('-kernel', self.kernel) vm.add_args('-initrd', self.initrd) vm.add_args('-append', append) vm.add_args('-device', vga) if iommu: vm.add_args('-device', 'intel-iommu,intremap=on,device-iotlb=on') vm.add_args('-global', 'virtio-pci.iommu_platform=on') if not display is None: vm.add_args('-display', display) if not incoming is None: vm.add_args('-incoming', incoming) vm.launch() if self.rconsole is None: self.rconsole = vm.console_socket.makefile('r') if self.wconsole is None: self.wconsole = vm.console_socket.makefile('w') def console_prepare(self): self.lconsole = logging.getLogger('console') self.lcommand = logging.getLogger('command') self.console_wait('Entering emergency mode') self.console_wait_char('continue): ') self.console_send() self.console_wait_char('# ') self.console_send('PS1=---\\\\u---\\\\n') self.console_wait('---root---') self.console_run('udevadm settle') self.console_wait('---root---') def console_send(self, line=""): self.wconsole.write(line) self.wconsole.write('\n') self.wconsole.flush() def console_run(self, command): self.lcommand.debug(command) self.console_send(command) self.rconsole.readline() # newline self.rconsole.readline() # command line echo def console_trace(self, name): while True: msg = self.rconsole.readline() self.lconsole.debug("%s: %s" % (name, msg.rstrip())) if '--[ end trace' in msg: break def console_wait_char(self, good): msg = "" counter = 1 while True: char = self.rconsole.read(1) if char == '\n': if len(msg) != 0: self.lconsole.debug("%3d: %s [line]" % (counter, msg)) counter += 1 msg = "" else: msg += char if good in msg: break if len(msg) != 0: self.lconsole.debug("%3d: %s [match]" % (counter, msg)) def console_wait(self, good, bad=None, errmsg=None): output = "" counter = 1 while True: msg = self.rconsole.readline() self.lconsole.debug("%3d: %s" % (counter, msg.rstrip())) counter += 1 if good in msg: break if not bad is None: if bad in msg: if errmsg is None: errmsg = "unexpected output (%s)" % bad self.fail(errmsg) if 'Kernel panic - not syncing' in msg: self.fail("kernel panic") if 'Oops: ' in msg: self.console_trace("oops") self.fail("kernel oops") if 'WARNING: ' in msg: self.console_trace("warn") self.fail("kernel warn") if 'BUG ' in msg: #self.console_trace("bug") self.fail("kernel bug") if re.search('drm:.*ERROR', msg): self.fail("kernel drm error") if len(msg) == 0: if not self.vm.is_running(): self.fail("unexpected qemu exit %d" % self.vm.exitcode()) else: self.fail("unexpected console eof") if counter > 1000: self.fail("too much output") output += msg return output def html_append(self, html): outfile = '%s/_checkdata.html' % self.outputdir f = open(outfile, "a") f.write("<hr>\n") f.write(html) f.close() def screen_dump(self, vga, name, expected=None): if vga == 'qxl-vga' or vga == 'qxl': self.vm.qmp('screendump', filename='/dev/null') time.sleep(0.1) out_ppm = '%s/%s-%s.ppm' % (self.outputdir, name, vga) out_jpg = '%s/%s-%s.jpg' % (self.outputdir, name, vga) self.vm.qmp('screendump', filename=out_ppm) self.wconsole.write('\n') self.wconsole.flush() checksum = run("md5sum %s" % out_ppm).stdout.decode().split()[0] self.log.debug("checksum: %s" % checksum) if not expected is None: self.log.debug("expected: %s" % expected) if checksum != expected: self.log.warning("checksum mismatch") if os.path.isfile("/usr/bin/convert"): run("/usr/bin/convert %s %s" % (out_ppm, out_jpg)) os.remove(out_ppm) img = "<h3>%s-%s</h3>\n" % (name, vga) img += "<img src='%s-%s.jpg'>\n" % (name, vga) self.html_append(img) def write_text(self, vga, name, content): outfile = '%s/%s-%s.txt' % (self.outputdir, name, vga) f = open(outfile, "w") f.write(content) f.close() div = "<h3>%s-%s</h3>\n" % (name, vga) div += "<pre>%s</pre>" % content self.html_append(div) def setUp(self): self.jobdir = os.path.dirname(self.logdir) self.log.info("### jobdir: %s", self.jobdir) self.kernel = os.path.join(self.jobdir, "drminfo.kernel") self.initrd = os.path.join(self.jobdir, "drminfo.initrd") self.qemu_binary = self.find_qemu_binary() self.log.info("### using qemu binary: %s", self.qemu_binary) self.vm = QEMUMachine(self.qemu_binary) def tearDown(self): self.vm.shutdown()