mirror of
https://github.com/qemu/qemu.git
synced 2024-12-18 09:43:38 +08:00
Python and tests (mostly acceptance) patches 2020-03-17
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEeruW64tGuU1eD+m7ZX6NM6XyCfMFAl5xaEMACgkQZX6NM6Xy CfPUDQ/+IACVcfF6LdPB/vwhBaKx8/fqpJEnyL8AFCkYrIVWw0c9zizjTobWbl8H qxDfqvM+O4ENy12ClG0LkyRN9sVs6IGlpE4f50kKqttd5GA8bBSvamv5iCxZ1fn8 IsR/uH5sQt8aqENxDiIszZH+UEATsFL916KyMre8faqEN8xzFvnFeQ+pT0s5sF9v XpXdS1D9JtI00pFmNz/4jkyzB4uG6D20NjoHOSS8IWMx9jOAQn5++VC6183lxdpK ty7adf0y0brC9BCEua4FdCHliDYgYbO5hdsk6oWWUQRvnYEFajXgV/nEdqV+rCG8 9KEKC7sdbOwkbXxwtfjMQ7QK51Xhz7P0d2j0+vn96V0MIve4GM0Z9vx87Psy+4T3 KJqM7GISDiFtMs2Zi2D+o4nyL4m4fS1AzbAeEWH1dwl7RaAb1zKr7F2hFSHIkNHh Z1cnoFhm0kXQFhFqMwjY5ackV+pYm8qSXroG3SvghPByb78LwBx5rzE37clW5HDa VO/pRnY0FIyYldOlu+XHGCwCgiaVQ0mUb9DOwpPL+WukZUY1y6bxWlamMvIBM0ko l1rYlnz0mEwpLptctlob0Vo/Js/jbyxT0XRcTbJq3FexFeEykFtFwW8hfT63xJXo En9cVkyEWzgT9Ici3HNOwLz5iJCfkWjx/ecRtA6TBeod0V/evo0= =DHn4 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/cleber/tags/python-next-pull-request' into staging Python and tests (mostly acceptance) patches 2020-03-17 # gpg: Signature made Wed 18 Mar 2020 00:16:03 GMT # gpg: using RSA key 7ABB96EB8B46B94D5E0FE9BB657E8D33A5F209F3 # gpg: Good signature from "Cleber Rosa <crosa@redhat.com>" [marginal] # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 7ABB 96EB 8B46 B94D 5E0F E9BB 657E 8D33 A5F2 09F3 * remotes/cleber/tags/python-next-pull-request: tests/docker: make "buildah bud" output similar to "docker build" tests/docker: add CentOS 8 Dockerfile Acceptance tests: add make targets to download images Acceptance test: add "boot_linux" tests Acceptance tests: introduce BUILD_DIR and SOURCE_DIR python/qemu/qmp.py: QMP debug with VM label Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
a1ba62a0f3
@ -316,7 +316,7 @@ jobs:
|
||||
- name: "GCC check-acceptance"
|
||||
dist: bionic
|
||||
env:
|
||||
- CONFIG="--target-list=aarch64-softmmu,alpha-softmmu,arm-softmmu,m68k-softmmu,microblaze-softmmu,mips-softmmu,mips64el-softmmu,nios2-softmmu,or1k-softmmu,ppc-softmmu,ppc64-softmmu,s390x-softmmu,sparc-softmmu,x86_64-softmmu,xtensa-softmmu"
|
||||
- CONFIG="--enable-tools --target-list=aarch64-softmmu,alpha-softmmu,arm-softmmu,m68k-softmmu,microblaze-softmmu,mips-softmmu,mips64el-softmmu,nios2-softmmu,or1k-softmmu,ppc-softmmu,ppc64-softmmu,s390x-softmmu,sparc-softmmu,x86_64-softmmu,xtensa-softmmu"
|
||||
- TEST_CMD="make check-acceptance"
|
||||
after_script:
|
||||
- python3 -c 'import json; r = json.load(open("tests/results/latest/results.json")); [print(t["logfile"]) for t in r["tests"] if t["status"] not in ("PASS", "SKIP")]' | xargs cat
|
||||
|
@ -270,7 +270,8 @@ class QEMUMachine(object):
|
||||
self._vm_monitor = os.path.join(self._sock_dir,
|
||||
self._name + "-monitor.sock")
|
||||
self._remove_files.append(self._vm_monitor)
|
||||
self._qmp = qmp.QEMUMonitorProtocol(self._vm_monitor, server=True)
|
||||
self._qmp = qmp.QEMUMonitorProtocol(self._vm_monitor, server=True,
|
||||
nickname=self._name)
|
||||
|
||||
def _post_launch(self):
|
||||
if self._qmp:
|
||||
|
@ -46,7 +46,7 @@ class QEMUMonitorProtocol:
|
||||
#: Logger object for debugging messages
|
||||
logger = logging.getLogger('QMP')
|
||||
|
||||
def __init__(self, address, server=False):
|
||||
def __init__(self, address, server=False, nickname=None):
|
||||
"""
|
||||
Create a QEMUMonitorProtocol class.
|
||||
|
||||
@ -62,6 +62,9 @@ class QEMUMonitorProtocol:
|
||||
self.__address = address
|
||||
self.__sock = self.__get_sock()
|
||||
self.__sockfile = None
|
||||
self._nickname = nickname
|
||||
if self._nickname:
|
||||
self.logger = logging.getLogger('QMP').getChild(self._nickname)
|
||||
if server:
|
||||
self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self.__sock.bind(self.__address)
|
||||
|
@ -20,6 +20,8 @@ check-help:
|
||||
@echo " $(MAKE) check-venv Creates a Python venv for tests"
|
||||
@echo " $(MAKE) check-clean Clean the tests and related data"
|
||||
@echo
|
||||
@echo " $(MAKE) get-vm-images Downloads all images used by acceptance tests, according to configured targets (~350 MB each, 1.5 GB max)"
|
||||
@echo
|
||||
@echo
|
||||
@echo "The variable SPEED can be set to control the gtester speed setting."
|
||||
@echo "Default options are -k and (for $(MAKE) V=1) --verbose; they can be"
|
||||
@ -890,7 +892,21 @@ $(TESTS_RESULTS_DIR):
|
||||
|
||||
check-venv: $(TESTS_VENV_DIR)
|
||||
|
||||
check-acceptance: check-venv $(TESTS_RESULTS_DIR)
|
||||
FEDORA_31_ARCHES_CANDIDATES=$(patsubst ppc64,ppc64le,$(TARGETS))
|
||||
FEDORA_31_ARCHES := x86_64 aarch64 ppc64le s390x
|
||||
FEDORA_31_DOWNLOAD=$(filter $(FEDORA_31_ARCHES),$(FEDORA_31_ARCHES_CANDIDATES))
|
||||
|
||||
# download one specific Fedora 31 image
|
||||
get-vm-image-fedora-31-%: check-venv
|
||||
$(call quiet-command, \
|
||||
$(TESTS_VENV_DIR)/bin/python -m avocado vmimage get \
|
||||
--distro=fedora --distro-version=31 --arch=$*, \
|
||||
"AVOCADO", "Downloading acceptance tests VM image for $*")
|
||||
|
||||
# download all vm images, according to defined targets
|
||||
get-vm-images: check-venv $(patsubst %,get-vm-image-fedora-31-%, $(FEDORA_31_DOWNLOAD))
|
||||
|
||||
check-acceptance: check-venv $(TESTS_RESULTS_DIR) get-vm-images
|
||||
$(call quiet-command, \
|
||||
$(TESTS_VENV_DIR)/bin/python -m avocado \
|
||||
--show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) \
|
||||
@ -901,7 +917,7 @@ check-acceptance: check-venv $(TESTS_RESULTS_DIR)
|
||||
|
||||
# Consolidated targets
|
||||
|
||||
.PHONY: check-block check-qapi-schema check-qtest check-unit check check-clean
|
||||
.PHONY: check-block check-qapi-schema check-qtest check-unit check check-clean get-vm-images
|
||||
check-qapi-schema: check-tests/qapi-schema/frontend check-tests/qapi-schema/doc-good.texi
|
||||
check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
|
||||
ifeq ($(CONFIG_TOOLS),y)
|
||||
|
@ -16,8 +16,21 @@ import tempfile
|
||||
|
||||
import avocado
|
||||
|
||||
SRC_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..', '..')
|
||||
sys.path.append(os.path.join(SRC_ROOT_DIR, 'python'))
|
||||
#: The QEMU build root directory. It may also be the source directory
|
||||
#: if building from the source dir, but it's safer to use BUILD_DIR for
|
||||
#: that purpose. Be aware that if this code is moved outside of a source
|
||||
#: and build tree, it will not be accurate.
|
||||
BUILD_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
||||
|
||||
if os.path.islink(os.path.dirname(os.path.dirname(__file__))):
|
||||
# The link to the acceptance tests dir in the source code directory
|
||||
lnk = os.path.dirname(os.path.dirname(__file__))
|
||||
#: The QEMU root source directory
|
||||
SOURCE_DIR = os.path.dirname(os.path.dirname(os.readlink(lnk)))
|
||||
else:
|
||||
SOURCE_DIR = BUILD_DIR
|
||||
|
||||
sys.path.append(os.path.join(SOURCE_DIR, 'python'))
|
||||
|
||||
from qemu.machine import QEMUMachine
|
||||
|
||||
@ -49,10 +62,10 @@ def pick_default_qemu_bin(arch=None):
|
||||
if is_readable_executable_file(qemu_bin_relative_path):
|
||||
return qemu_bin_relative_path
|
||||
|
||||
qemu_bin_from_src_dir_path = os.path.join(SRC_ROOT_DIR,
|
||||
qemu_bin_from_bld_dir_path = os.path.join(BUILD_DIR,
|
||||
qemu_bin_relative_path)
|
||||
if is_readable_executable_file(qemu_bin_from_src_dir_path):
|
||||
return qemu_bin_from_src_dir_path
|
||||
if is_readable_executable_file(qemu_bin_from_bld_dir_path):
|
||||
return qemu_bin_from_bld_dir_path
|
||||
|
||||
|
||||
def _console_interaction(test, success_message, failure_message,
|
||||
@ -153,7 +166,7 @@ class Test(avocado.Test):
|
||||
self.qemu_bin = self.params.get('qemu_bin',
|
||||
default=default_qemu_bin)
|
||||
if self.qemu_bin is None:
|
||||
self.cancel("No QEMU binary defined or found in the source tree")
|
||||
self.cancel("No QEMU binary defined or found in the build tree")
|
||||
|
||||
def _new_vm(self, *args):
|
||||
vm = QEMUMachine(self.qemu_bin, sock_dir=tempfile.mkdtemp())
|
||||
|
222
tests/acceptance/boot_linux.py
Normal file
222
tests/acceptance/boot_linux.py
Normal file
@ -0,0 +1,222 @@
|
||||
# Functional test that boots a complete Linux system via a cloud image
|
||||
#
|
||||
# Copyright (c) 2018-2020 Red Hat, Inc.
|
||||
#
|
||||
# Author:
|
||||
# Cleber Rosa <crosa@redhat.com>
|
||||
#
|
||||
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||
# later. See the COPYING file in the top-level directory.
|
||||
|
||||
import os
|
||||
|
||||
from avocado_qemu import Test, BUILD_DIR
|
||||
|
||||
from qemu.accel import kvm_available
|
||||
from qemu.accel import tcg_available
|
||||
|
||||
from avocado.utils import cloudinit
|
||||
from avocado.utils import network
|
||||
from avocado.utils import vmimage
|
||||
from avocado.utils import datadrainer
|
||||
from avocado.utils.path import find_command
|
||||
|
||||
ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
|
||||
KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
|
||||
TCG_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "TCG"
|
||||
|
||||
|
||||
class BootLinux(Test):
|
||||
"""
|
||||
Boots a Linux system, checking for a successful initialization
|
||||
"""
|
||||
|
||||
timeout = 900
|
||||
chksum = None
|
||||
|
||||
def setUp(self):
|
||||
super(BootLinux, self).setUp()
|
||||
self.vm.add_args('-smp', '2')
|
||||
self.vm.add_args('-m', '1024')
|
||||
self.prepare_boot()
|
||||
self.prepare_cloudinit()
|
||||
|
||||
def prepare_boot(self):
|
||||
self.log.debug('Looking for and selecting a qemu-img binary to be '
|
||||
'used to create the bootable snapshot image')
|
||||
# If qemu-img has been built, use it, otherwise the system wide one
|
||||
# will be used. If none is available, the test will cancel.
|
||||
qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
|
||||
if not os.path.exists(qemu_img):
|
||||
qemu_img = find_command('qemu-img', False)
|
||||
if qemu_img is False:
|
||||
self.cancel('Could not find "qemu-img", which is required to '
|
||||
'create the bootable image')
|
||||
vmimage.QEMU_IMG = qemu_img
|
||||
|
||||
self.log.info('Downloading/preparing boot image')
|
||||
# Fedora 31 only provides ppc64le images
|
||||
image_arch = self.arch
|
||||
if image_arch == 'ppc64':
|
||||
image_arch = 'ppc64le'
|
||||
try:
|
||||
self.boot = vmimage.get(
|
||||
'fedora', arch=image_arch, version='31',
|
||||
checksum=self.chksum,
|
||||
algorithm='sha256',
|
||||
cache_dir=self.cache_dirs[0],
|
||||
snapshot_dir=self.workdir)
|
||||
self.vm.add_args('-drive', 'file=%s' % self.boot.path)
|
||||
except:
|
||||
self.cancel('Failed to download/prepare boot image')
|
||||
|
||||
def prepare_cloudinit(self):
|
||||
self.log.info('Preparing cloudinit image')
|
||||
try:
|
||||
cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
|
||||
self.phone_home_port = network.find_free_port()
|
||||
cloudinit.iso(cloudinit_iso, self.name,
|
||||
username='root',
|
||||
password='password',
|
||||
# QEMU's hard coded usermode router address
|
||||
phone_home_host='10.0.2.2',
|
||||
phone_home_port=self.phone_home_port)
|
||||
self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
|
||||
except Exception:
|
||||
self.cancel('Failed to prepared cloudinit image')
|
||||
|
||||
def launch_and_wait(self):
|
||||
self.vm.set_console()
|
||||
self.vm.launch()
|
||||
console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
|
||||
logger=self.log.getChild('console'))
|
||||
console_drainer.start()
|
||||
self.log.info('VM launched, waiting for boot confirmation from guest')
|
||||
cloudinit.wait_for_phone_home(('0.0.0.0', self.phone_home_port), self.name)
|
||||
|
||||
|
||||
class BootLinuxX8664(BootLinux):
|
||||
"""
|
||||
:avocado: tags=arch:x86_64
|
||||
"""
|
||||
|
||||
chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
|
||||
|
||||
def test_pc_i440fx_tcg(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
if not tcg_available(self.qemu_bin):
|
||||
self.cancel(TCG_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "tcg")
|
||||
self.launch_and_wait()
|
||||
|
||||
def test_pc_i440fx_kvm(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc
|
||||
:avocado: tags=accel:kvm
|
||||
"""
|
||||
if not kvm_available(self.arch, self.qemu_bin):
|
||||
self.cancel(KVM_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "kvm")
|
||||
self.launch_and_wait()
|
||||
|
||||
def test_pc_q35_tcg(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
if not tcg_available(self.qemu_bin):
|
||||
self.cancel(TCG_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "tcg")
|
||||
self.launch_and_wait()
|
||||
|
||||
def test_pc_q35_kvm(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=accel:kvm
|
||||
"""
|
||||
if not kvm_available(self.arch, self.qemu_bin):
|
||||
self.cancel(KVM_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "kvm")
|
||||
self.launch_and_wait()
|
||||
|
||||
|
||||
class BootLinuxAarch64(BootLinux):
|
||||
"""
|
||||
:avocado: tags=arch:aarch64
|
||||
:avocado: tags=machine:virt
|
||||
:avocado: tags=machine:gic-version=2
|
||||
"""
|
||||
|
||||
chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49'
|
||||
|
||||
def add_common_args(self):
|
||||
self.vm.add_args('-bios',
|
||||
os.path.join(BUILD_DIR, 'pc-bios',
|
||||
'edk2-aarch64-code.fd'))
|
||||
self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
|
||||
self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
|
||||
|
||||
def test_virt_tcg(self):
|
||||
"""
|
||||
:avocado: tags=accel:tcg
|
||||
:avocado: tags=cpu:max
|
||||
"""
|
||||
if not tcg_available(self.qemu_bin):
|
||||
self.cancel(TCG_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "tcg")
|
||||
self.vm.add_args("-cpu", "max")
|
||||
self.vm.add_args("-machine", "virt,gic-version=2")
|
||||
self.add_common_args()
|
||||
self.launch_and_wait()
|
||||
|
||||
def test_virt_kvm(self):
|
||||
"""
|
||||
:avocado: tags=accel:kvm
|
||||
:avocado: tags=cpu:host
|
||||
"""
|
||||
if not kvm_available(self.arch, self.qemu_bin):
|
||||
self.cancel(KVM_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "kvm")
|
||||
self.vm.add_args("-cpu", "host")
|
||||
self.vm.add_args("-machine", "virt,gic-version=2")
|
||||
self.add_common_args()
|
||||
self.launch_and_wait()
|
||||
|
||||
|
||||
class BootLinuxPPC64(BootLinux):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
"""
|
||||
|
||||
chksum = '7c3528b85a3df4b2306e892199a9e1e43f991c506f2cc390dc4efa2026ad2f58'
|
||||
|
||||
def test_pseries_tcg(self):
|
||||
"""
|
||||
:avocado: tags=machine:pseries
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
if not tcg_available(self.qemu_bin):
|
||||
self.cancel(TCG_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "tcg")
|
||||
self.launch_and_wait()
|
||||
|
||||
|
||||
class BootLinuxS390X(BootLinux):
|
||||
"""
|
||||
:avocado: tags=arch:s390x
|
||||
"""
|
||||
|
||||
chksum = '4caaab5a434fd4d1079149a072fdc7891e354f834d355069ca982fdcaf5a122d'
|
||||
|
||||
def test_s390_ccw_virtio_tcg(self):
|
||||
"""
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
if not tcg_available(self.qemu_bin):
|
||||
self.cancel(TCG_NOT_AVAILABLE)
|
||||
self.vm.add_args("-accel", "tcg")
|
||||
self.launch_and_wait()
|
32
tests/docker/dockerfiles/centos8.docker
Normal file
32
tests/docker/dockerfiles/centos8.docker
Normal file
@ -0,0 +1,32 @@
|
||||
FROM centos:8.1.1911
|
||||
|
||||
RUN dnf -y update
|
||||
ENV PACKAGES \
|
||||
SDL-devel \
|
||||
bison \
|
||||
bzip2 \
|
||||
bzip2-devel \
|
||||
dbus-daemon \
|
||||
flex \
|
||||
gcc \
|
||||
gcc-c++ \
|
||||
gettext \
|
||||
git \
|
||||
glib2-devel \
|
||||
libaio-devel \
|
||||
libepoxy-devel \
|
||||
lzo-devel \
|
||||
make \
|
||||
mesa-libEGL-devel \
|
||||
nettle-devel \
|
||||
perl-Test-Harness \
|
||||
pixman-devel \
|
||||
python36 \
|
||||
rdma-core-devel \
|
||||
spice-glib-devel \
|
||||
spice-server \
|
||||
tar \
|
||||
zlib-devel
|
||||
|
||||
RUN dnf install -y $PACKAGES
|
||||
RUN rpm -q $PACKAGES | sort > /packages.txt
|
@ -9,7 +9,7 @@ MAINTAINER Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
|
||||
ENV TARGET i686
|
||||
|
||||
ENV PATH $PATH:/usr/lib/mxe/usr/$TARGET-w64-mingw32.shared/bin
|
||||
ENV PATH $PATH:/usr/lib/mxe/usr/bin:/usr/lib/mxe/usr/$TARGET-w64-mingw32.shared/bin
|
||||
|
||||
ENV PKG_CONFIG_PATH \
|
||||
$PKG_CONFIG_PATH:/usr/lib/mxe/usr/$TARGET-w64-mingw32.shared/lib/pkgconfig
|
||||
|
@ -2,3 +2,4 @@
|
||||
# in the tests/venv Python virtual environment. For more info,
|
||||
# refer to: https://pip.pypa.io/en/stable/user_guide/#id1
|
||||
avocado-framework==76.0
|
||||
pycdlib==1.9.0
|
||||
|
Loading…
Reference in New Issue
Block a user