mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-18 14:27:43 +00:00
This change suppresses the output of ending the processes started for the test run. The output doesn't help much but clutters the overall output and shows up as warnings on TC.
452 lines
14 KiB
Bash
Executable file
452 lines
14 KiB
Bash
Executable file
# shellcheck shell=bash
|
|
|
|
function can_run_wayland() {
|
|
local MUTTER_VERSION
|
|
MUTTER_VERSION=$(mutter --version | head -1 | cut -f2 -d' ' | cut -f1 -d'.')
|
|
if (( MUTTER_VERSION < 40 )); then
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function _generate_kmpjson() {
|
|
local TESTDIR
|
|
TESTDIR="$1"
|
|
pushd "${TESTDIR}" > /dev/null || exit
|
|
KMPFILE="${TESTDIR}/kmp.json"
|
|
cat <<-EOF > "${KMPFILE}"
|
|
{
|
|
"system": {
|
|
"keymanDeveloperVersion": "10.0.1099.0",
|
|
"fileVersion": "7.0"
|
|
},
|
|
"info": {
|
|
"name": {
|
|
"description": "Test Keyboards"
|
|
},
|
|
"version": {
|
|
"description": "0.0"
|
|
}
|
|
},
|
|
"files": [
|
|
{
|
|
"name": "kmp.json",
|
|
"description": "Package information (JSON)"
|
|
}
|
|
EOF
|
|
for f in k_*.kmx; do
|
|
keyboard=$(basename "${f}")
|
|
keyboard="${keyboard%.*}"
|
|
echo " ," >> "${KMPFILE}"
|
|
cat <<-EOF >> "${KMPFILE}"
|
|
{
|
|
"name": "${keyboard}",
|
|
"description": "${keyboard}"
|
|
}
|
|
EOF
|
|
done
|
|
cat <<-EOF >> "${KMPFILE}"
|
|
],
|
|
"keyboards": [
|
|
EOF
|
|
FIRST=true
|
|
for f in k_*.kmx; do
|
|
keyboard=$(basename "${f}")
|
|
keyboard="${keyboard%.*}"
|
|
if ${FIRST}; then
|
|
FIRST=false
|
|
else
|
|
echo " ," >> "${KMPFILE}"
|
|
fi
|
|
cat <<-EOF >> "${KMPFILE}"
|
|
{
|
|
"name": "${keyboard}",
|
|
"id": "${keyboard}",
|
|
"version": "0.0",
|
|
"languages": [
|
|
{
|
|
"name": "Undetermined",
|
|
"id": "und"
|
|
}
|
|
]
|
|
}
|
|
EOF
|
|
done
|
|
echo " ]" >> "${KMPFILE}"
|
|
echo "}" >> "${KMPFILE}"
|
|
popd > /dev/null || exit
|
|
}
|
|
|
|
function _link_test_keyboards() {
|
|
KMX_TEST_DIR=$1
|
|
TESTDIR=$2
|
|
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}"
|
|
else
|
|
echo "Can't find test kmx files in ${KMX_TEST_DIR}"
|
|
exit 3
|
|
fi
|
|
}
|
|
|
|
function _setup_init() {
|
|
local ENV_FILE CLEANUP_FILE PID_FILE DISPLAY_SERVER
|
|
ENV_FILE=$1
|
|
CLEANUP_FILE=$2
|
|
PID_FILE=$3
|
|
DISPLAY_SERVER=$4
|
|
|
|
if [[ -z "${TOP_SRCDIR:-}" ]]; then
|
|
TOP_SRCDIR=${G_TEST_SRCDIR:-$(realpath "$(dirname "$0")/..")}/..
|
|
fi
|
|
if [[ -z "${TOP_BINDIR:-}" ]]; then
|
|
TOP_BINDIR=${G_TEST_BUILDDIR:-$(realpath "$(dirname "$0/..")")}/..
|
|
fi
|
|
|
|
echo > "${ENV_FILE}"
|
|
|
|
if [[ -f "${CLEANUP_FILE}" ]]; then
|
|
# kill previous instances
|
|
"$(dirname "$0")"/teardown-tests.sh "${CLEANUP_FILE}" "${DISPLAY_SERVER}" || true
|
|
fi
|
|
|
|
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
|
|
|
|
if [[ -d "${COMMON_ARCH_DIR}"/release ]]; then
|
|
COMMON_ARCH_DIR=${COMMON_ARCH_DIR}/release
|
|
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"
|
|
exit 2
|
|
fi
|
|
|
|
export LD_LIBRARY_PATH=${COMMON_ARCH_DIR}/src:${LD_LIBRARY_PATH-}
|
|
echo "export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >> "${ENV_FILE}"
|
|
}
|
|
|
|
function _setup_dbus_session() {
|
|
local ENV_FILE CLEANUP_FILE
|
|
ENV_FILE="$1"
|
|
CLEANUP_FILE="$2"
|
|
|
|
if [[ -z "${DOCKER_RUNNING:-}" ]] && [[ -z "${TEAMCITY_GIT_PATH:-}" ]] && ! pgrep -f jetbrains.buildServer.agent.AgentMain > /dev/null; then
|
|
return
|
|
fi
|
|
|
|
if [[ ! -d "/run/user/${UID:-$(id -u)}" ]]; then
|
|
# /run/user/$UID usually gets created by the session, but since we
|
|
# don't start the regular UI we don't have a session. Therefore we
|
|
# call the setupRuntimeDir.sh script to create the directory. The
|
|
# script should contain the following commands:
|
|
# mkdir -p "/run/user/${SUDO_UID:-$(id -u)}"
|
|
# chmod 0700 "/run/user/${SUDO_UID:-$(id -u)}"
|
|
# chown "${SUDO_USER:-$(whoami)}" "/run/user/${SUDO_UID:-$(id -u)}"
|
|
if [[ -f "/usr/local/bin/setupRuntimeDir.sh" ]]; then
|
|
echo "# Creating /run/user/${UID:-$(id -u)}..."
|
|
sudo /usr/local/bin/setupRuntimeDir.sh
|
|
else
|
|
echo "# WARNING: /run/user/${UID:-$(id -u)} is missing without having /usr/local/bin/setupRuntimeDir.sh, tests will likely fail"
|
|
fi
|
|
fi
|
|
|
|
if [[ -z "${XDG_RUNTIME_DIR:-}" ]]; then
|
|
export XDG_RUNTIME_DIR=/run/user/${UID:-$(id -u)}
|
|
echo "export XDG_RUNTIME_DIR=/run/user/${UID:-$(id -u)}" >> "${ENV_FILE}"
|
|
fi
|
|
if [[ ! -d "${XDG_RUNTIME_DIR}" ]]; then
|
|
echo "${XDG_RUNTIME_DIR} is missing, please create it"
|
|
exit 1
|
|
fi
|
|
|
|
export NO_AT_BRIDGE=1
|
|
echo "export NO_AT_BRIDGE=1" >> "${ENV_FILE}"
|
|
|
|
if pgrep -u "${USER:-$(whoami)}" dbus-daemon > /dev/null; then
|
|
# dbus-daemon is already running, skipping setup
|
|
return
|
|
fi
|
|
|
|
echo "# Starting dbus session..."
|
|
dbus-launch --auto-syntax >> "${ENV_FILE}"
|
|
PID=$(pidof dbus-daemon)
|
|
echo "kill -9 ${PID} || true # dbus-daemon" >> "${CLEANUP_FILE}"
|
|
}
|
|
|
|
function _setup_test_dbus_server() {
|
|
local ENV_FILE CLEANUP_FILE
|
|
ENV_FILE=$1
|
|
CLEANUP_FILE=$2
|
|
|
|
# Start test dbus server. This will create `/tmp/km-test-server.env`.
|
|
"${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}"
|
|
|
|
# shellcheck disable=SC1091
|
|
source /tmp/km-test-server.env
|
|
# shellcheck disable=SC2154
|
|
echo "# DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}"
|
|
}
|
|
|
|
function _setup_display_server() {
|
|
local DISPLAY_SERVER ENV_FILE CLEANUP_FILE PID_FILE PID DISP_XVFB DISP_XEPHYR
|
|
ENV_FILE=$1
|
|
CLEANUP_FILE=$2
|
|
PID_FILE=$3
|
|
DISPLAY_SERVER=$4
|
|
|
|
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."
|
|
exit 7
|
|
fi
|
|
echo "Running on Wayland:"
|
|
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}" &
|
|
PID=$!
|
|
echo "kill -9 ${PID} &> /dev/null || true # mutter" >> "${CLEANUP_FILE}"
|
|
echo "${PID} mutter" >> "${PID_FILE}"
|
|
sleep 1s
|
|
WAYLAND_DISPLAY=$(grep "Using Wayland display" "${TMPFILE}" | cut -d"'" -f2)
|
|
export WAYLAND_DISPLAY
|
|
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 &
|
|
PID=$!
|
|
sleep 1
|
|
if ps --no-headers --pid="${PID}" > /dev/null; then
|
|
break
|
|
fi
|
|
done
|
|
echo "kill -9 ${PID} &> /dev/null || 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 &
|
|
PID=$!
|
|
sleep 1
|
|
if ps --no-headers --pid="${PID}" > /dev/null; then
|
|
break
|
|
fi
|
|
done
|
|
echo "kill -9 ${PID} &> /dev/null || true # Xephyr" >> "${CLEANUP_FILE}"
|
|
echo "${PID} Xephyr" >> "${PID_FILE}"
|
|
echo "Starting metacity"
|
|
metacity --display=":${DISP_XEPHYR}" &> /dev/null &
|
|
PID=$!
|
|
echo "kill -9 ${PID} &> /dev/null || true # metacity" >> "${CLEANUP_FILE}"
|
|
echo "${PID} metacity" >> "${PID_FILE}"
|
|
|
|
export DISPLAY=:${DISP_XEPHYR}
|
|
echo "export DISPLAY=\"${DISPLAY}\"" >> "${ENV_FILE}"
|
|
fi
|
|
}
|
|
|
|
function _setup_schema_and_gsettings() {
|
|
local ENV_FILE
|
|
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}"
|
|
|
|
export GSETTINGS_SCHEMA_DIR=${SCHEMA_DIR}
|
|
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}"
|
|
|
|
# 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
|
|
export GSETTINGS_BACKEND=keyfile
|
|
echo "export GSETTINGS_BACKEND=\"${GSETTINGS_BACKEND}\"" >> "${ENV_FILE}"
|
|
IBUS_CONFIG=--config=/usr/libexec/ibus-memconf
|
|
fi
|
|
}
|
|
|
|
function _setup_ibus() {
|
|
local ENV_FILE CLEANUP_FILE PID_FILE PID STANDALONE
|
|
ENV_FILE=$1
|
|
CLEANUP_FILE=$2
|
|
PID_FILE=$3
|
|
STANDALONE=${4:-}
|
|
|
|
echo "Starting ibus-daemon..."
|
|
#shellcheck disable=SC2086
|
|
ibus-daemon ${ARG_VERBOSE-} --daemonize --panel=disable --address=unix:abstract="${TEMP_DATA_DIR}/test-ibus" ${IBUS_CONFIG-} &> /tmp/ibus-daemon.log
|
|
|
|
PID=$(pgrep -f "${TEMP_DATA_DIR}/test-ibus")
|
|
if [[ "${STANDALONE}" == "--standalone" ]] && [[ "${DOCKER_RUNNING:-false}" != "true" ]] && [[ -z "${TEAMCITY_GIT_PATH:-}" ]]; then
|
|
# manual test run
|
|
echo "if kill -9 ${PID} &> /dev/null; then ibus restart || ibus start -d; fi # ibus-daemon" >> "${CLEANUP_FILE}"
|
|
else
|
|
# test run as part of the build
|
|
echo "kill -9 ${PID} &> /dev/null || true # ibus-daemon" >> "${CLEANUP_FILE}"
|
|
fi
|
|
echo "${PID} ibus-daemon" >> "${PID_FILE}"
|
|
sleep 1s
|
|
|
|
IBUS_ADDRESS=$(ibus address)
|
|
export IBUS_ADDRESS
|
|
|
|
echo "export IBUS_ADDRESS=\"${IBUS_ADDRESS}\"" >> "${ENV_FILE}"
|
|
|
|
echo "Starting ibus-engine-keyman..."
|
|
#shellcheck disable=SC2086
|
|
"${TOP_BINDIR}/src/ibus-engine-keyman" --testing ${ARG_VERBOSE-} &> /tmp/ibus-engine-keyman.log &
|
|
PID=$!
|
|
echo "kill -9 ${PID} &> /dev/null || true # ibus-engine-keyman" >> "${CLEANUP_FILE}"
|
|
echo "${PID} ibus-engine-keyman" >> "${PID_FILE}"
|
|
sleep 1s
|
|
}
|
|
|
|
function setup() {
|
|
local DISPLAY_SERVER ENV_FILE CLEANUP_FILE PID_FILE TESTBASEDIR TESTDIR STANDALONE
|
|
DISPLAY_SERVER=$1
|
|
ENV_FILE=$2
|
|
CLEANUP_FILE=$3
|
|
PID_FILE=$4
|
|
STANDALONE=${5:-}
|
|
|
|
_setup_init "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" "${DISPLAY_SERVER}"
|
|
|
|
TESTBASEDIR=${XDG_DATA_HOME:-${HOME}/.local/share}/keyman
|
|
TESTDIR=${TESTBASEDIR}/test_kmx
|
|
|
|
_link_test_keyboards "${TOP_SRCDIR}/../../common/test/keyboards/baseline" "${TESTDIR}" "${TESTBASEDIR}"
|
|
|
|
_generate_kmpjson "${TESTDIR}"
|
|
|
|
_setup_dbus_session "${ENV_FILE}" "${CLEANUP_FILE}"
|
|
_setup_test_dbus_server "${ENV_FILE}" "${CLEANUP_FILE}"
|
|
_setup_display_server "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" "${DISPLAY_SERVER}"
|
|
_setup_schema_and_gsettings "${ENV_FILE}"
|
|
_setup_ibus "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" "${STANDALONE}"
|
|
}
|
|
|
|
function setup_display_server_only() {
|
|
local DISPLAY_SERVER ENV_FILE CLEANUP_FILE PID_FILE TESTBASEDIR TESTDIR
|
|
DISPLAY_SERVER=$1
|
|
ENV_FILE=$2
|
|
CLEANUP_FILE=$3
|
|
PID_FILE=$4
|
|
|
|
_setup_init "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" "${DISPLAY_SERVER}"
|
|
_setup_display_server "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" "${DISPLAY_SERVER}"
|
|
_setup_schema_and_gsettings "${ENV_FILE}"
|
|
}
|
|
|
|
function cleanup() {
|
|
local CLEANUP_FILE DISPLAY_SERVER
|
|
CLEANUP_FILE=$1
|
|
DISPLAY_SERVER=$2
|
|
|
|
if [[ -f "${CLEANUP_FILE}" ]]; then
|
|
echo
|
|
echo "# Shutting down processes..."
|
|
bash "${CLEANUP_FILE}" # &> /dev/null
|
|
rm "${CLEANUP_FILE}"
|
|
echo "# Finished shutdown of processes."
|
|
fi
|
|
|
|
if [[ "${DOCKER_RUNNING:-false}" == "true" ]]; then
|
|
echo "# Copying log files..."
|
|
# Note: build/tmp is build/docker-linux/<distro>/tmp on the host!
|
|
BUILD_TMP="$(dirname "$0")/../../../build/tmp"
|
|
mkdir -p "${BUILD_TMP}"
|
|
[[ -f /tmp/ibus-engine-keyman.log ]] && mv /tmp/ibus-engine-keyman.log "${BUILD_TMP}/ibus-engine-keyman${DISPLAY_SERVER}.log"
|
|
[[ -f /tmp/ibus-daemon.log ]] && mv /tmp/ibus-daemon.log "${BUILD_TMP}/ibus-daemon${DISPLAY_SERVER}.log"
|
|
[[ -f /tmp/km-test-server.log ]] && mv /tmp/km-test-server.log "${BUILD_TMP}/km-test-server${DISPLAY_SERVER}.log"
|
|
echo "# Finished copying log files"
|
|
fi
|
|
|
|
if [[ -z "${DOCKER_RUNNING:-}" ]] && [[ -z "${TEAMCITY_GIT_PATH:-}" ]] && ! pgrep -f jetbrains.buildServer.agent.AgentMain > /dev/null; then
|
|
# Not running in Docker or TeamCity:
|
|
# Killing the ibus-daemon that we started for testing might have caused
|
|
# some other ibus processes that belong to the real ibus daemon to
|
|
# be killed as well, leaving us with no way to type.
|
|
# So we kill the remaining lonely ibus-daemon and start ibus again.
|
|
if [[ "$(ibus engine)" == "" ]]; then
|
|
echo "# Killing and restarting ibus-daemon"
|
|
kill -9 "$(pgrep -u "${USER:-$(whoami)}" ibus-daemon)"
|
|
ibus start -d
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function exit_on_package_build() {
|
|
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
|
|
fi
|
|
}
|
|
|
|
function _get_missing_processes() {
|
|
local PID_FILE MISSING_PROCS PID LINE
|
|
PID_FILE=$1
|
|
MISSING_PROCS=""
|
|
|
|
while read -r LINE; do
|
|
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)"
|
|
break
|
|
fi
|
|
done < "${PID_FILE}"
|
|
}
|
|
|
|
function check_processes_running() {
|
|
local DISPLAY_SERVER ENV_FILE CLEANUP_FILE PID_FILE MISSING_PROCS TEST_NAME
|
|
DISPLAY_SERVER=$1
|
|
ENV_FILE=$2
|
|
CLEANUP_FILE=$3
|
|
PID_FILE=$4
|
|
TEST_NAME=$5
|
|
MISSING_PROCS=$(_get_missing_processes "${PID_FILE}")
|
|
|
|
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 "Restarting..." ; } >> /tmp/debug.output
|
|
mv /tmp/ibus-engine-keyman.log{,"-${TEST_NAME}-$(date -Iseconds)"}
|
|
cleanup "${CLEANUP_FILE}" "${DISPLAY_SERVER}" &> /dev/null
|
|
setup "${DISPLAY_SERVER}" "${ENV_FILE}" "${CLEANUP_FILE}" "${PID_FILE}" &> /dev/null
|
|
fi
|
|
|
|
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
|
|
}
|