Merge pull request #14409 from keymanapp/refactor/linux/integrtests

This commit is contained in:
Eberhard Beilharz 2025-07-28 09:25:19 +02:00 • committed by GitHub
commit fc5eacd07b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 103 additions and 96 deletions

View file

@ -1,20 +1,24 @@
#!/usr/bin/env bash
# shellcheck disable=SC2312
set -eu
# shellcheck disable=SC2034
TOP_SRCDIR=${top_srcdir:-$(realpath "$(dirname "$0")/../..")}
TESTBASEDIR=${XDG_DATA_HOME:-$HOME/.local/share}/keyman
TESTBASEDIR=${XDG_DATA_HOME:-${HOME}/.local/share}/keyman
TESTDIR=${TESTBASEDIR}/test_kmx
CLEANUP_FILE=/tmp/ibus-keyman-test-cleanup
PID_FILE=/tmp/ibus-keyman-test.pids
ENV_FILE=/tmp/keyman-env.txt
# shellcheck disable=SC1091
. "$(dirname "$0")"/test-helper.inc.sh
local_cleanup() {
cleanup "$CLEANUP_FILE"
cleanup "${CLEANUP_FILE}"
}
if [ -v KEYMAN_PKG_BUILD ]; then
if [[ -v KEYMAN_PKG_BUILD ]]; then
# During package builds we skip these tests that require to start ibus because
# ibus requires to find /var/lib/dbus/machine-id or /etc/machine-id, otherwise it fails with:
# "Bail out! IBUS-FATAL-WARNING: Unable to load /var/lib/dbus/machine-id: Failed to open file
@ -23,7 +27,7 @@ if [ -v KEYMAN_PKG_BUILD ]; then
exit 0
fi
if ! which Xvfb > /dev/null || ! which Xephyr > /dev/null || ! which metacity > /dev/null || ! which mutter > /dev/null; then
if ! command -v Xvfb > /dev/null || ! command -v Xephyr > /dev/null || ! command -v metacity > /dev/null || ! command -v mutter > /dev/null; then
echo "Please install Xvfb, Xephyr, metacity and mutter before running these tests!"
echo "sudo apt install xvfb xserver-xephyr metacity mutter"
exit 1
@ -54,9 +58,9 @@ function run_tests() {
DISPLAY_SERVER=$1
shift
if [ -d "$(dirname "$0")/../../../build/$(arch)/debug" ]; then
if [[ -d "$(dirname "$0")/../../../build/$(arch)/debug" ]]; then
CONFIG=debug
elif [ -d "$(dirname "$0")/../../../build/$(arch)/release" ]; then
elif [[ -d "$(dirname "$0")/../../../build/$(arch)/release" ]]; then
CONFIG=release
else
echo "Cannot find ../../../build/$(arch)/debug or ../../../build/$(arch)/release"
@ -74,19 +78,20 @@ function run_tests() {
fi
echo ""
if [ $# -gt 0 ]; then
if [[ $# -gt 0 ]]; then
#shellcheck disable=SC2206
TESTFILES=($@)
else
pushd "$TESTDIR" > /dev/null || exit
pushd "${TESTDIR}" > /dev/null || exit
TESTFILES=(*.kmx)
popd > /dev/null || exit
fi
echo "# Starting tests..."
# shellcheck disable=SC1090
source "$ENV_FILE"
echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS"
source "${ENV_FILE}"
# shellcheck disable=SC2154
echo "DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}"
if [[ -n ${REMOTE_DEBUG:-} ]]; then
echo "===> Now attach debugger to ${REMOTE_HOST}"
@ -97,10 +102,10 @@ function run_tests() {
#shellcheck disable=SC2086
${REMOTE_DEBUG:-} "${G_TEST_BUILDDIR:-../../build/$(arch)/${CONFIG}/tests}/ibus-keyman-tests" ${ARG_K-} ${ARG_TAP-} \
${ARG_VERBOSE-} ${ARG_DEBUG-} ${ARG_SURROUNDING_TEXT-} ${ARG_NO_SURROUNDING_TEXT-} \
--directory "$TESTDIR" "${DISPLAY_SERVER}" ${TESTFILES[@]}
--directory "${TESTDIR}" "${DISPLAY_SERVER}" ${TESTFILES[@]}
echo "# Finished tests."
cleanup "$CLEANUP_FILE"
cleanup "${CLEANUP_FILE}"
}
USE_WAYLAND=1
@ -124,34 +129,34 @@ while (( $# )); do
shift || (echo "Error: The last argument is missing a value. Exiting."; false) || exit 5
done
if ! can_run_wayland && [ "$USE_WAYLAND" == "0" ]; then
if ! can_run_wayland && [[ "${USE_WAYLAND}" == "0" ]]; then
# support for --headless got added in mutter 40.x
echo "# WARNING: mutter doesn't support running headless. Skipping Wayland tests."
USE_WAYLAND=0
if [ "$USE_X11" == "0" ]; then
if [[ "${USE_X11}" == "0" ]]; then
echo "ERROR: no tests to run. Can't run Wayland tests, and --no-x11 is specified."
exit 8
fi
fi
if [ "$USE_WAYLAND" == "0" ] && [ "$USE_X11" == "0" ]; then
if [[ "${USE_WAYLAND}" == "0" ]] && [[ "${USE_X11}" == "0" ]]; then
echo "ERROR: I'll have to run somewhere. Specifying both --no-wayland and --no-x11 is not allowed."
exit 6
fi
G_TEST_BUILDDIR="${G_TEST_BUILDDIR:-../../build/$(arch)/debug/tests}"
if [ ! -f "${G_TEST_BUILDDIR}/ibus-keyman-tests" ]; then
if [[ ! -f "${G_TEST_BUILDDIR}/ibus-keyman-tests" ]]; then
G_TEST_BUILDDIR="${G_TEST_BUILDDIR:-../../build/$(arch)/release/tests}"
fi
echo > "$CLEANUP_FILE"
echo > "$PID_FILE"
echo > "${CLEANUP_FILE}"
echo > "${PID_FILE}"
trap local_cleanup EXIT SIGINT
if [ "$USE_WAYLAND" == "1" ]; then
if [[ "${USE_WAYLAND}" == "1" ]]; then
run_tests --wayland "$@"
fi
if [ "$USE_X11" == "1" ]; then
if [[ "${USE_X11}" == "1" ]]; then
run_tests --x11 "$@"
fi

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
# shellcheck shell=bash
function can_run_wayland() {
local MUTTER_VERSION
@ -13,9 +13,9 @@ function can_run_wayland() {
function _generate_kmpjson() {
local TESTDIR
TESTDIR="$1"
pushd "$TESTDIR" > /dev/null || exit
pushd "${TESTDIR}" > /dev/null || exit
KMPFILE="${TESTDIR}/kmp.json"
cat <<-EOF > "$KMPFILE"
cat <<-EOF > "${KMPFILE}"
{
"system": {
"keymanDeveloperVersion": "10.0.1099.0",
@ -36,33 +36,33 @@ function _generate_kmpjson() {
}
EOF
for f in k_*.kmx; do
keyboard=$(basename "$f")
keyboard=$(basename "${f}")
keyboard="${keyboard%.*}"
echo " ," >> "$KMPFILE"
cat <<-EOF >> "$KMPFILE"
echo " ," >> "${KMPFILE}"
cat <<-EOF >> "${KMPFILE}"
{
"name": "$keyboard",
"description": "$keyboard"
"name": "${keyboard}",
"description": "${keyboard}"
}
EOF
done
cat <<-EOF >> "$KMPFILE"
cat <<-EOF >> "${KMPFILE}"
],
"keyboards": [
EOF
FIRST=true
for f in k_*.kmx; do
keyboard=$(basename "$f")
keyboard=$(basename "${f}")
keyboard="${keyboard%.*}"
if $FIRST; then
if ${FIRST}; then
FIRST=false
else
echo " ," >> "$KMPFILE"
echo " ," >> "${KMPFILE}"
fi
cat <<-EOF >> "$KMPFILE"
cat <<-EOF >> "${KMPFILE}"
{
"name": "$keyboard",
"id": "$keyboard",
"name": "${keyboard}",
"id": "${keyboard}",
"version": "0.0",
"languages": [
{
@ -73,8 +73,8 @@ EOF
}
EOF
done
echo " ]" >> "$KMPFILE"
echo "}" >> "$KMPFILE"
echo " ]" >> "${KMPFILE}"
echo "}" >> "${KMPFILE}"
popd > /dev/null || exit
}
@ -84,9 +84,9 @@ function _link_test_keyboards() {
TESTBASEDIR=$3
if [[ $(find "${KMX_TEST_DIR}/" -name k_\*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then
mkdir -p "$(realpath --canonicalize-missing "$TESTBASEDIR")"
rm -f "$TESTDIR"
ln -sf "$(realpath "${KMX_TEST_DIR}")" "$TESTDIR"
mkdir -p "$(realpath --canonicalize-missing "${TESTBASEDIR}")"
rm -f "${TESTDIR}"
ln -sf "$(realpath "${KMX_TEST_DIR}")" "${TESTDIR}"
else
echo "Can't find test kmx files in ${KMX_TEST_DIR}"
exit 3
@ -99,31 +99,31 @@ function _setup_init() {
CLEANUP_FILE=$2
PID_FILE=$3
if [ -z "${TOP_SRCDIR:-}" ]; then
if [[ -z "${TOP_SRCDIR:-}" ]]; then
TOP_SRCDIR=${G_TEST_SRCDIR:-$(realpath "$(dirname "$0")/..")}/..
fi
if [ -z "${TOP_BINDIR:-}" ]; then
if [[ -z "${TOP_BINDIR:-}" ]]; then
TOP_BINDIR=${G_TEST_BUILDDIR:-$(realpath "$(dirname "$0/..")")}/..
fi
echo > "$ENV_FILE"
echo > "${ENV_FILE}"
if [ -f "$CLEANUP_FILE" ]; then
if [[ -f "${CLEANUP_FILE}" ]]; then
# kill previous instances
"$(dirname "$0")"/teardown-tests.sh "$CLEANUP_FILE" || true
"$(dirname "$0")"/teardown-tests.sh "${CLEANUP_FILE}" || true
fi
echo > "$CLEANUP_FILE"
echo > "$PID_FILE"
echo > "${CLEANUP_FILE}"
echo > "${PID_FILE}"
TEMP_DATA_DIR=$(mktemp --directory)
echo "rm -rf \"${TEMP_DATA_DIR}\" || true # TEMP_DATA_DIR" >> "${CLEANUP_FILE}"
COMMON_ARCH_DIR=
[ -d "${TOP_SRCDIR}"/../../core/build/arch ] && COMMON_ARCH_DIR=${TOP_SRCDIR}/../../core/build/arch
[[ -d "${TOP_SRCDIR}"/../../core/build/arch ]] && COMMON_ARCH_DIR=${TOP_SRCDIR}/../../core/build/arch
if [ -d "${COMMON_ARCH_DIR}"/release ]; then
if [[ -d "${COMMON_ARCH_DIR}"/release ]]; then
COMMON_ARCH_DIR=${COMMON_ARCH_DIR}/release
elif [ -d "${COMMON_ARCH_DIR}"/debug ]; then
elif [[ -d "${COMMON_ARCH_DIR}"/debug ]]; then
COMMON_ARCH_DIR=${COMMON_ARCH_DIR}/debug
else
echo "Can't find neither ${COMMON_ARCH_DIR}/release nor ${COMMON_ARCH_DIR}/debug"
@ -131,7 +131,7 @@ function _setup_init() {
fi
export LD_LIBRARY_PATH=${COMMON_ARCH_DIR}/src:${LD_LIBRARY_PATH-}
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> "$ENV_FILE"
echo "export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >> "${ENV_FILE}"
}
function _setup_test_dbus_server() {
@ -143,12 +143,14 @@ function _setup_test_dbus_server() {
"${TOP_BINDIR}/tests/dbus-test-server/km-dbus-test-server" &> /tmp/km-test-server.log &
sleep 1
cat /tmp/km-test-server.env >> "$ENV_FILE"
cat /tmp/km-test-server.env >> "$CLEANUP_FILE"
echo "${TOP_BINDIR}/tests/dbus-test-server/stop-test-server" >> "$CLEANUP_FILE"
cat /tmp/km-test-server.env >> "${ENV_FILE}"
cat /tmp/km-test-server.env >> "${CLEANUP_FILE}"
echo "${TOP_BINDIR}/tests/dbus-test-server/stop-test-server" >> "${CLEANUP_FILE}"
# shellcheck disable=SC1091
source /tmp/km-test-server.env
echo "# DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS"
# shellcheck disable=SC2154
echo "# DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}"
}
function _setup_display_server() {
@ -158,7 +160,7 @@ function _setup_display_server() {
PID_FILE=$3
DISPLAY_SERVER=$4
if [ "$DISPLAY_SERVER" == "--wayland" ]; then
if [[ "${DISPLAY_SERVER}" == "--wayland" ]]; then
if ! can_run_wayland; then
# support for --headless got added in mutter 40.x
echo "ERROR: mutter doesn't support running headless. Can't run Wayland tests."
@ -168,49 +170,49 @@ function _setup_display_server() {
echo "Starting mutter..."
TMPFILE=$(mktemp)
# mutter-Message: 18:56:15.422: Using Wayland display name 'wayland-1'
mutter --wayland --headless --no-x11 --virtual-monitor 1024x768 &> "$TMPFILE" &
mutter --wayland --headless --no-x11 --virtual-monitor 1024x768 &> "${TMPFILE}" &
PID=$!
echo "kill -9 ${PID} || true # mutter" >> "$CLEANUP_FILE"
echo "kill -9 ${PID} || true # mutter" >> "${CLEANUP_FILE}"
echo "${PID} mutter" >> "${PID_FILE}"
sleep 1s
export WAYLAND_DISPLAY
WAYLAND_DISPLAY=$(grep "Using Wayland display" "$TMPFILE" | cut -d"'" -f2)
rm "$TMPFILE"
echo "export WAYLAND_DISPLAY=\"$WAYLAND_DISPLAY\"" >> "$ENV_FILE"
WAYLAND_DISPLAY=$(grep "Using Wayland display" "${TMPFILE}" | cut -d"'" -f2)
rm "${TMPFILE}"
echo "export WAYLAND_DISPLAY=\"${WAYLAND_DISPLAY}\"" >> "${ENV_FILE}"
else
echo "Running on X11:"
while true; do
echo "Starting Xvfb..."
DISP_XVFB=$RANDOM
Xvfb -screen 0 1024x768x24 :${DISP_XVFB} &> /dev/null &
DISP_XVFB=${RANDOM}
Xvfb -screen 0 1024x768x24 ":${DISP_XVFB}" &> /dev/null &
PID=$!
sleep 1
if ps --no-headers --pid="$PID" > /dev/null; then
if ps --no-headers --pid="${PID}" > /dev/null; then
break
fi
done
echo "kill -9 ${PID} || true # Xvfb" >> "$CLEANUP_FILE"
echo "kill -9 ${PID} || true # Xvfb" >> "${CLEANUP_FILE}"
echo "${PID} Xvfb" >> "${PID_FILE}"
while true; do
echo "Starting Xephyr..."
DISP_XEPHYR=$RANDOM
DISPLAY=:${DISP_XVFB} Xephyr :${DISP_XEPHYR} -screen 1024x768 &> /dev/null &
DISP_XEPHYR=${RANDOM}
DISPLAY=:${DISP_XVFB} Xephyr ":${DISP_XEPHYR}" -screen 1024x768 &> /dev/null &
PID=$!
sleep 1
if ps --no-headers --pid="$PID" > /dev/null; then
if ps --no-headers --pid="${PID}" > /dev/null; then
break
fi
done
echo "kill -9 ${PID} || true # Xephyr" >> "$CLEANUP_FILE"
echo "kill -9 ${PID} || true # Xephyr" >> "${CLEANUP_FILE}"
echo "${PID} Xephyr" >> "${PID_FILE}"
echo "Starting metacity"
metacity --display=:${DISP_XEPHYR} &> /dev/null &
metacity --display=":${DISP_XEPHYR}" &> /dev/null &
PID=$!
echo "kill -9 ${PID} || true # metacity" >> "$CLEANUP_FILE"
echo "kill -9 ${PID} || true # metacity" >> "${CLEANUP_FILE}"
echo "${PID} metacity" >> "${PID_FILE}"
export DISPLAY=:${DISP_XEPHYR}
echo "export DISPLAY=\"$DISPLAY\"" >> "$ENV_FILE"
echo "export DISPLAY=\"${DISPLAY}\"" >> "${ENV_FILE}"
fi
}
@ -219,23 +221,23 @@ function _setup_schema_and_gsettings() {
ENV_FILE=$1
# Install schema to temporary directory. This removes the build dependency on the keyman package.
SCHEMA_DIR=$TEMP_DATA_DIR/glib-2.0/schemas
export XDG_DATA_DIRS=$TEMP_DATA_DIR:${XDG_DATA_DIRS-}
echo "export XDG_DATA_DIRS=$XDG_DATA_DIRS" >> "$ENV_FILE"
SCHEMA_DIR=${TEMP_DATA_DIR}/glib-2.0/schemas
export XDG_DATA_DIRS=${TEMP_DATA_DIR}:${XDG_DATA_DIRS-}
echo "export XDG_DATA_DIRS=${XDG_DATA_DIRS}" >> "${ENV_FILE}"
export GSETTINGS_SCHEMA_DIR=${SCHEMA_DIR}
echo "export GSETTINGS_SCHEMA_DIR=\"$SCHEMA_DIR\"" >> "$ENV_FILE"
echo "export GSETTINGS_SCHEMA_DIR=\"${SCHEMA_DIR}\"" >> "${ENV_FILE}"
mkdir -p "$SCHEMA_DIR"
cp "${TOP_SRCDIR}"/../keyman-config/resources/com.keyman.gschema.xml "$SCHEMA_DIR"/
glib-compile-schemas "$SCHEMA_DIR"
mkdir -p "${SCHEMA_DIR}"
cp "${TOP_SRCDIR}"/../keyman-config/resources/com.keyman.gschema.xml "${SCHEMA_DIR}"/
glib-compile-schemas "${SCHEMA_DIR}"
# Ubuntu 18.04 Bionic doesn't have ibus-memconf, and glib is not compiled with the keyfile
# backend enabled, so we just use the default backend. Otherwise we use the keyfile
# store which interferes less when running on a dev machine.
if [ -f /usr/libexec/ibus-memconf ]; then
if [[ -f /usr/libexec/ibus-memconf ]]; then
export GSETTINGS_BACKEND=keyfile
echo "export GSETTINGS_BACKEND=\"$GSETTINGS_BACKEND\"" >> "$ENV_FILE"
echo "export GSETTINGS_BACKEND=\"${GSETTINGS_BACKEND}\"" >> "${ENV_FILE}"
IBUS_CONFIG=--config=/usr/libexec/ibus-memconf
fi
}
@ -264,7 +266,7 @@ function _setup_ibus() {
IBUS_ADDRESS=$(ibus address)
export IBUS_ADDRESS
echo "export IBUS_ADDRESS=\"$IBUS_ADDRESS\"" >> "$ENV_FILE"
echo "export IBUS_ADDRESS=\"${IBUS_ADDRESS}\"" >> "${ENV_FILE}"
echo "Starting ibus-engine-keyman..."
#shellcheck disable=SC2086
@ -285,12 +287,12 @@ function setup() {
_setup_init "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}"
TESTBASEDIR=${XDG_DATA_HOME:-$HOME/.local/share}/keyman
TESTBASEDIR=${XDG_DATA_HOME:-${HOME}/.local/share}/keyman
TESTDIR=${TESTBASEDIR}/test_kmx
_link_test_keyboards "${TOP_SRCDIR}/../../common/test/keyboards/baseline" "$TESTDIR" "$TESTBASEDIR"
_link_test_keyboards "${TOP_SRCDIR}/../../common/test/keyboards/baseline" "${TESTDIR}" "${TESTBASEDIR}"
_generate_kmpjson "$TESTDIR"
_generate_kmpjson "${TESTDIR}"
_setup_test_dbus_server "${ENV_FILE}" "${CLEANUP_FILE}"
_setup_display_server "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" "${DISPLAY_SERVER}"
@ -314,10 +316,10 @@ function cleanup() {
local CLEANUP_FILE
CLEANUP_FILE=$1
if [ -f "$CLEANUP_FILE" ]; then
if [[ -f "${CLEANUP_FILE}" ]]; then
echo
echo "# Shutting down processes..."
bash "$CLEANUP_FILE" # > /dev/null 2>&1
bash "${CLEANUP_FILE}" # > /dev/null 2>&1
rm "$CLEANUP_FILE"
echo "# Finished shutdown of processes."
fi
@ -333,7 +335,7 @@ function cleanup() {
}
function exit_on_package_build() {
if [ -v KEYMAN_PKG_BUILD ]; then
if [[ -v KEYMAN_PKG_BUILD ]]; then
# Skip setup during package builds - can't run headless and we won't
# run the other tests anyway
exit 0
@ -346,12 +348,12 @@ function _get_missing_processes() {
MISSING_PROCS=""
while read -r LINE; do
if [ -z "$LINE" ]; then
if [[ -z "${LINE}" ]]; then
continue
fi
PID=$(echo "$LINE" | cut -d' ' -f1)
if ! ps --no-headers --pid="$PID" > /dev/null; then
MISSING_PROCS="${MISSING_PROCS} $(echo "$LINE" | cut -d' ' -f2)"
PID=$(echo "${LINE}" | cut -d' ' -f1)
if ! ps --no-headers --pid="${PID}" > /dev/null; then
MISSING_PROCS="${MISSING_PROCS} $(echo "${LINE}" | cut -d' ' -f2)"
break
fi
done < "${PID_FILE}"
@ -364,19 +366,19 @@ function check_processes_running() {
CLEANUP_FILE=$3
PID_FILE=$4
TEST_NAME=$5
MISSING_PROCS=$(_get_missing_processes "$PID_FILE")
MISSING_PROCS=$(_get_missing_processes "${PID_FILE}")
if [ "$MISSING_PROCS" != "" ]; then
if [[ "${MISSING_PROCS}" != "" ]]; then
echo "# Some background processes no longer running. Restarting..."
{ echo "Some background processes no longer running (running ${TEST_NAME}):" ; \
echo "$MISSING_PROCS" ; \
echo "${MISSING_PROCS}" ; \
echo "Restarting..." ; } >> /tmp/debug.output
mv /tmp/ibus-engine-keyman.log{,"-${TEST_NAME}-$(date -Iseconds)"}
cleanup "${CLEANUP_FILE}" > /dev/null 2>&1
setup "${DISPLAY_SERVER}" "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" > /dev/null 2>&1
fi
if [ "$(_get_missing_processes "$PID_FILE")" != "" ]; then
if [[ "$(_get_missing_processes "$PID_FILE")" != "" ]]; then
echo "# WARNING: Expected background processes are still missing after restart: ${MISSING_PROCS}"
echo "# Maybe an old process is still running?"
fi