tests: Run KMS tests inside a QEMU virtual machine
This commit makes it possible to run test executables in a test environment constructed of a virtual machine running the Linux kernel with the virtual KMS driver enabled, and a mocked system environment using meta-dbus-runner.py/python-dbusmock. The qemu machine is configured to use 256M of memory, as the default 128M was not enough for the tests to pass. Using qemu is also only made possible on x86_64; more changes are needed for it to be runnable on aarch64, so add a warning if it was enabled on any other architecture. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2151>
This commit is contained in:
parent
b5284e5ccc
commit
06eb27d503
11
meson.build
11
meson.build
@ -57,6 +57,7 @@ sysprof_req = '>= 3.37.2'
|
|||||||
gnome = import('gnome')
|
gnome = import('gnome')
|
||||||
pkg = import('pkgconfig')
|
pkg = import('pkgconfig')
|
||||||
i18n = import('i18n')
|
i18n = import('i18n')
|
||||||
|
fs = import('fs')
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
|
|
||||||
prefix = get_option('prefix')
|
prefix = get_option('prefix')
|
||||||
@ -269,6 +270,7 @@ have_core_tests = false
|
|||||||
have_cogl_tests = false
|
have_cogl_tests = false
|
||||||
have_clutter_tests = false
|
have_clutter_tests = false
|
||||||
have_native_tests = false
|
have_native_tests = false
|
||||||
|
have_kvm_tests = false
|
||||||
have_installed_tests = false
|
have_installed_tests = false
|
||||||
|
|
||||||
if have_tests
|
if have_tests
|
||||||
@ -287,6 +289,15 @@ if have_tests
|
|||||||
error('Native tests require remote desktop')
|
error('Native tests require remote desktop')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
have_kvm_tests = get_option('kvm_tests')
|
||||||
|
if have_kvm_tests
|
||||||
|
if not have_native_backend
|
||||||
|
error('KVM tests need the native backend tests')
|
||||||
|
endif
|
||||||
|
if host_machine.cpu_family() != 'x86_64'
|
||||||
|
error('KVM tests are only supported on x86_64')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
have_cogl_tests = get_option('cogl_tests')
|
have_cogl_tests = get_option('cogl_tests')
|
||||||
have_clutter_tests = get_option('clutter_tests')
|
have_clutter_tests = get_option('clutter_tests')
|
||||||
|
@ -141,6 +141,18 @@ option('tests',
|
|||||||
description: 'Enable tests globally. Specific test suites can be controlled with core_tests, clutter_tests, and cogl_tests'
|
description: 'Enable tests globally. Specific test suites can be controlled with core_tests, clutter_tests, and cogl_tests'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
option('kvm_tests',
|
||||||
|
type: 'boolean',
|
||||||
|
value: false,
|
||||||
|
description: 'Enable running certain tests in a virtual machine with a custom built kernel'
|
||||||
|
)
|
||||||
|
|
||||||
|
option('kvm_kernel_image',
|
||||||
|
type: 'string',
|
||||||
|
value: '',
|
||||||
|
description: 'Path to a Linux kernel image to be used for KVM testing'
|
||||||
|
)
|
||||||
|
|
||||||
option('profiler',
|
option('profiler',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: true,
|
value: true,
|
||||||
|
29
src/tests/kvm/README.md
Normal file
29
src/tests/kvm/README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
## High level description of the files in this directory.
|
||||||
|
|
||||||
|
### build-linux.sh
|
||||||
|
|
||||||
|
Builds a Linux kernel image meant to be launched using qemu. Doesn't make any
|
||||||
|
assumptions about configuration other than that. It uses the drm kernel tree.
|
||||||
|
It's used from meson.build.
|
||||||
|
|
||||||
|
### kernel-version.txt
|
||||||
|
|
||||||
|
Describes the version of the Linux kernel to use; usually a tag. It's a
|
||||||
|
separate file so that changing the version will make meson build a new kernel
|
||||||
|
image.
|
||||||
|
|
||||||
|
### virtme-run.sh
|
||||||
|
|
||||||
|
A helper script that uses 'virtme' to launch a qemu virtual machine with the
|
||||||
|
host filesystem exposed inside the virtual machine.
|
||||||
|
|
||||||
|
### run-kvm-test.sh
|
||||||
|
|
||||||
|
Runs the passed test executable in a mocked environment using
|
||||||
|
'meta-dbus-runner.py' (which uses python-dbusmock to create a mocked system
|
||||||
|
environment.
|
||||||
|
|
||||||
|
### meson.build
|
||||||
|
|
||||||
|
Contains one rule for building the Linux kernel image, and meson test cases
|
||||||
|
that launches tests inside virtual machines.
|
74
src/tests/kvm/build-linux.sh
Executable file
74
src/tests/kvm/build-linux.sh
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Script for building the Linux kernel from git. It aims to build a kernel image
|
||||||
|
# that is suitable for running in a virtual machine and is aimed to used for
|
||||||
|
# testing.
|
||||||
|
#
|
||||||
|
# Usage: build-linux.sh [REPO-URL] [BRANCH|TAG] [OUTPUT-FILE] [...CONFIGS]
|
||||||
|
#
|
||||||
|
# Where [..CONFIGS] can be any number of configuration options, e.g.
|
||||||
|
# --enable CONFIG_DRM_VKMS
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# From scripts/subarch.include in linux
|
||||||
|
function get-subarch()
|
||||||
|
{
|
||||||
|
uname -m | sed -e s/i.86/x86/ \
|
||||||
|
-e s/x86_64/x86/ \
|
||||||
|
-e s/sun4u/sparc64/ \
|
||||||
|
-e s/arm.*/arm/ -e s/sa110/arm/ \
|
||||||
|
-e s/s390x/s390/ -e s/parisc64/parisc/ \
|
||||||
|
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
|
||||||
|
-e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
|
||||||
|
-e s/riscv.*/riscv/
|
||||||
|
}
|
||||||
|
|
||||||
|
REPO="$1"
|
||||||
|
BRANCH_OR_TAG="$(cat $2)"
|
||||||
|
IMAGE="$3"
|
||||||
|
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
SUBARCH=$(get-subarch)
|
||||||
|
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
|
||||||
|
# ./scripts/config --enable CONFIG_DRM_VKMS
|
||||||
|
CONFIGS=()
|
||||||
|
while [[ "x$1" != "x" ]]; do
|
||||||
|
CONFIGS+=( "$1" )
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
echo Building Linux for $ARCH \($SUBARCH\)...
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [ -d linux ]; then
|
||||||
|
pushd linux
|
||||||
|
git fetch $REPO $BRANCH_OR_TAG
|
||||||
|
git checkout FETCH_HEAD
|
||||||
|
else
|
||||||
|
git clone --depth=1 --branch=$BRANCH_OR_TAG $REPO linux
|
||||||
|
pushd linux
|
||||||
|
fi
|
||||||
|
|
||||||
|
make defconfig
|
||||||
|
sync
|
||||||
|
make kvm_guest.config
|
||||||
|
|
||||||
|
echo Enabling ${CONFIGS[@]}...
|
||||||
|
./scripts/config ${CONFIGS[@]/#/--enable }
|
||||||
|
|
||||||
|
make oldconfig
|
||||||
|
make -j8
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
TARGET_DIR="$(dirname "$IMAGE")"
|
||||||
|
mkdir -p "$TARGET_DIR"
|
||||||
|
mv linux/arch/$SUBARCH/boot/bzImage "$IMAGE"
|
||||||
|
mv linux/.config $TARGET_DIR/.config
|
||||||
|
#rm -rf linux
|
1
src/tests/kvm/kernel-version.txt
Normal file
1
src/tests/kvm/kernel-version.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
drm-next-2021-11-12
|
48
src/tests/kvm/meson.build
Normal file
48
src/tests/kvm/meson.build
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
build_linux = find_program('build-linux.sh')
|
||||||
|
|
||||||
|
kernel_image_path = get_option('kvm_kernel_image')
|
||||||
|
if kernel_image_path != ''
|
||||||
|
if not fs.is_absolute(kernel_image_path)
|
||||||
|
error('Kernel image path @0@ must be absolute'.format(kernel_image_path))
|
||||||
|
endif
|
||||||
|
if not fs.is_file(kernel_image_path)
|
||||||
|
error('Kernel image @0@ does not exist'.format(kernel_image_path))
|
||||||
|
endif
|
||||||
|
kernel_image_target = []
|
||||||
|
else
|
||||||
|
kernel_image_target = custom_target('linux-kernel',
|
||||||
|
output: 'bzImage',
|
||||||
|
input: 'kernel-version.txt',
|
||||||
|
console: true,
|
||||||
|
command: [
|
||||||
|
build_linux,
|
||||||
|
'https://anongit.freedesktop.org/git/drm/drm.git',
|
||||||
|
'@INPUT@',
|
||||||
|
'@OUTPUT@',
|
||||||
|
'--enable', 'CONFIG_DRM_VKMS',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
kernel_image_path = kernel_image_target.full_path()
|
||||||
|
endif
|
||||||
|
|
||||||
|
virtme_run = find_program('virtme-run.sh')
|
||||||
|
|
||||||
|
foreach test: privileged_tests
|
||||||
|
test_name = test[0]
|
||||||
|
test_executable = test[1]
|
||||||
|
|
||||||
|
test('kvm-' + test_name, virtme_run,
|
||||||
|
suite: ['core', 'mutter/native/kvm'],
|
||||||
|
depends: [
|
||||||
|
kernel_image_target,
|
||||||
|
],
|
||||||
|
workdir: mutter_srcdir,
|
||||||
|
args: [
|
||||||
|
kernel_image_path,
|
||||||
|
meta_dbus_runner.full_path(),
|
||||||
|
'--kvm',
|
||||||
|
test_executable.full_path(),
|
||||||
|
meson.current_build_dir(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
endforeach
|
23
src/tests/kvm/run-kvm-test.sh
Executable file
23
src/tests/kvm/run-kvm-test.sh
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
WRAPPER="$1"
|
||||||
|
WRAPPER_ARGS="$2"
|
||||||
|
TEST_EXECUTABLE="$3"
|
||||||
|
TEST_RESULT="$4"
|
||||||
|
|
||||||
|
export XDG_RUNTIME_DIR="/tmp/sub-runtime-dir-$UID"
|
||||||
|
export GSETTINGS_SCHEMA_DIR="$PWD/build/data"
|
||||||
|
export G_SLICE="always-malloc"
|
||||||
|
export MALLOC_CHECK_="3"
|
||||||
|
export NO_AT_BRIDGE="1"
|
||||||
|
export MALLOC_PERTURB_="123"
|
||||||
|
|
||||||
|
mkdir -p -m 700 $XDG_RUNTIME_DIR
|
||||||
|
|
||||||
|
glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||||
|
|
||||||
|
"$WRAPPER" $WRAPPER_ARGS "$TEST_EXECUTABLE"
|
||||||
|
|
||||||
|
echo $? > $TEST_RESULT
|
25
src/tests/kvm/virtme-run.sh
Executable file
25
src/tests/kvm/virtme-run.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIRNAME="$(dirname "$0")"
|
||||||
|
IMAGE="$1"
|
||||||
|
WRAPPER="$2"
|
||||||
|
WRAPPER_ARGS="$3"
|
||||||
|
TEST_EXECUTABLE="$4"
|
||||||
|
TEST_BUILD_DIR="$5"
|
||||||
|
|
||||||
|
TEST_RESULT_FILE=$(mktemp -p "$TEST_BUILD_DIR" -t test-result-XXXXXX)
|
||||||
|
echo 1 > "$TEST_RESULT_FILE"
|
||||||
|
|
||||||
|
virtme-run \
|
||||||
|
--memory=256M \
|
||||||
|
--rw \
|
||||||
|
--pwd \
|
||||||
|
--kimg "$IMAGE" \
|
||||||
|
--script-sh "sh -c \"env HOME=$HOME $DIRNAME/run-kvm-test.sh \\\"$WRAPPER\\\" \\\"$WRAPPER_ARGS\\\" \\\"$TEST_EXECUTABLE\\\" \\\"$TEST_RESULT_FILE\\\"\""
|
||||||
|
|
||||||
|
TEST_RESULT="$(cat "$TEST_RESULT_FILE")"
|
||||||
|
rm "$TEST_RESULT_FILE"
|
||||||
|
|
||||||
|
exit "$TEST_RESULT"
|
@ -117,6 +117,8 @@ test_runner = executable('mutter-test-runner',
|
|||||||
install_dir: mutter_installed_tests_libexecdir,
|
install_dir: mutter_installed_tests_libexecdir,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
meta_dbus_runner = find_program('meta-dbus-runner.py')
|
||||||
|
|
||||||
if have_installed_tests
|
if have_installed_tests
|
||||||
install_data('meta-dbus-runner.py',
|
install_data('meta-dbus-runner.py',
|
||||||
install_dir: mutter_installed_tests_libexecdir,
|
install_dir: mutter_installed_tests_libexecdir,
|
||||||
@ -391,11 +393,14 @@ if have_native_tests
|
|||||||
is_parallel: false,
|
is_parallel: false,
|
||||||
timeout: 60,
|
timeout: 60,
|
||||||
)
|
)
|
||||||
|
endif
|
||||||
test('native-kms-render', native_kms_render_tests,
|
|
||||||
suite: ['core', 'mutter/native/kms/render'],
|
if have_kvm_tests
|
||||||
env: test_env,
|
privileged_tests = [
|
||||||
is_parallel: false,
|
[ 'kms-render', native_kms_render_tests ],
|
||||||
timeout: 60,
|
]
|
||||||
)
|
|
||||||
|
if have_kvm_tests
|
||||||
|
subdir('kvm')
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
Loading…
Reference in New Issue
Block a user