You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ibus/SOURCES/ibus-HEAD.patch

3977 lines
132 KiB

From a1a2fe5d13ad76956a94c0695af15d76e3edfdca Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 18 Jul 2024 01:25:41 +0900
Subject: [PATCH] Fix memory leaks in error handlings
- bus/ibusimpl: Free keys not in case of TYPE_IME_SWITCHER
- src/ibuscomposetable: Correct handling G_MAXSIZE * G_MAXSIZE
- src/ibuscomposetable: Fee ibus_compose_seqs in error handlings
---
bus/ibusimpl.c | 3 ++-
src/ibuscomposetable.c | 6 +++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index 31a095f3..445c062b 100644
--- a/bus/ibusimpl.c
+++ b/bus/ibusimpl.c
@@ -1986,7 +1986,8 @@ _ibus_set_global_shortcut_keys (BusIBusImpl *ibus,
}
ibus->ime_switcher_keys = keys;
break;
- default:;
+ default:
+ g_slice_free1 (sizeof (IBusProcessKeyEventData) * (size + 1), keys);
}
return TRUE;
}
diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
index 7531a4b2..a8e41a33 100644
--- a/src/ibuscomposetable.c
+++ b/src/ibuscomposetable.c
@@ -849,7 +849,7 @@ compose_data_to_variant (gconstpointer compose_data,
g_assert (compose_data);
if (error)
*error = NULL;
- if ((index_stride * n_seqs) > G_MAXUINT64) {
+ if (n_seqs == 0 || index_stride > (G_MAXSIZE / n_seqs)) {
if (error) {
g_set_error (error, IBUS_ERROR, IBUS_ERROR_FAILED,
"Length %u x %lu is too long",
@@ -1404,6 +1404,7 @@ ibus_compose_table_new_with_list (GList *compose_list,
(G_MAXSIZE / sizeof (guint16)))) {
g_warning ("Too long allocation %lu x %u",
s_size_total - s_size_16bit, n_index_stride);
+ g_free (ibus_compose_seqs);
return NULL;
}
rawdata = (gpointer)g_new (
@@ -1416,6 +1417,8 @@ ibus_compose_table_new_with_list (GList *compose_list,
s_size_total - s_size_16bit,
n_index_stride,
v_size_32bit);
+ g_free (ibus_compose_seqs);
+ g_free (rawdata);
return NULL;
}
if (G_LIKELY (rawdata)) {
@@ -1432,6 +1435,7 @@ ibus_compose_table_new_with_list (GList *compose_list,
}
if (!ibus_compose_seqs_32bit_first || !ibus_compose_seqs_32bit_second) {
g_warning ("Failed g_new");
+ g_free (ibus_compose_seqs);
g_free (rawdata);
return NULL;
}
--
2.45.0
From a52861385bb5d15598f6c3c3d86c7a9ee19f140a Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Sat, 27 Jul 2024 19:00:53 +0900
Subject: [PATCH 1/6] src/tests: Enable CI in GNOME Wayland
- Implement headless desktop to test Wayland sessions
- Implement ibus-desktop-testing-autostart to be executed in XDG
autostart in GNOME Wayland
- Move shared codes to ibus-desktop-testing-module between
ibus-desktop-testing-runner and ibus-desktop-testing-autostart
- Add --no-systemd option to enable the previous testing frame with running
gnome-session directly
- Rename --desktop option to --session
- Move save_screen() from runner to module
- Copy gnome-shell service file to user home for headless & virtual-monitor
- Add --delete-tests option to clean up tests
- Add AutostartCondition=if-exists in XDG autostart desktop file
- Add 60 secs in ibus-compose-locales for systemd desktop sessions
- Quote file names as much as possible.
- Check file existant and not to use "rm -f" as much as possible
- Do not set GTK_IM_MODULE=ibus for Wayland
BUG=https://github.com/ibus/ibus/pull/2657
---
src/tests/Makefile.am | 23 +-
src/tests/ibus-compose-locales.in | 16 +-
src/tests/ibus-desktop-testing-autostart | 57 --
src/tests/ibus-desktop-testing-autostart.in | 83 ++
src/tests/ibus-desktop-testing-module | 876 ++++++++++++++++++++
src/tests/ibus-desktop-testing-runner.in | 495 +----------
src/tests/ibus-desktop-testing.desktop.in | 2 +-
7 files changed, 1034 insertions(+), 518 deletions(-)
delete mode 100755 src/tests/ibus-desktop-testing-autostart
create mode 100755 src/tests/ibus-desktop-testing-autostart.in
create mode 100755 src/tests/ibus-desktop-testing-module
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index b30a39fb..6c4c86cf 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -106,6 +106,7 @@ test_sourcesdir = $(datadir)/installed-tests/ibus
CLEANFILES += \
$(test_metas) \
+ ibus-desktop-testing-autostart \
ibus-desktop-testing-runner \
org.freedesktop.IBus.Desktop.Testing.desktop \
$(NULL)
@@ -119,7 +120,10 @@ CLEANFILES += \
$(NULL)
endif
test_execsdir = $(libexecdir)/installed-tests/ibus
-libexec_SCRIPTS = ibus-desktop-testing-autostart
+libexec_SCRIPTS = \
+ ibus-desktop-testing-autostart \
+ ibus-desktop-testing-module \
+ $(NULL)
test_frame_DATA = org.freedesktop.IBus.Desktop.Testing.desktop
test_framedir = $(pkgdatadir)/tests
@@ -142,9 +146,21 @@ ibus-compose-locales: ibus-compose-locales.in
mv $@.tmp $@; \
$(NULL)
+ibus-desktop-testing-autostart: ibus-desktop-testing-autostart.in
+ INSTALLEDDIR=$(datadir)/installed-tests; \
+ sed -e "s|@DATADIR[@]|$(datadir)|g" \
+ -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" \
+ -e "s|@LIBEXECDIR[@]|$(libexecdir)|g" \
+ $< > $@.tmp; \
+ mv $@.tmp $@; \
+ $(NULL)
+
ibus-desktop-testing-runner: ibus-desktop-testing-runner.in
INSTALLEDDIR=$(datadir)/installed-tests; \
- sed -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" $< > $@.tmp; \
+ sed -e "s|@DATADIR[@]|$(datadir)|g" \
+ -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" \
+ -e "s|@LIBEXECDIR[@]|$(libexecdir)|g" \
+ $< > $@.tmp; \
mv $@.tmp $@; \
$(NULL)
@@ -157,7 +173,8 @@ EXTRA_DIST = \
ibus-compose.env \
ibus-compose-locales.in \
ibus-desktop-testing.desktop.in \
- ibus-desktop-testing-autostart \
+ ibus-desktop-testing-autostart.in \
+ ibus-desktop-testing-module \
ibus-desktop-testing-runner.in \
$(NULL)
diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in
index b36165fe..7a133ce0 100755
--- a/src/tests/ibus-compose-locales.in
+++ b/src/tests/ibus-compose-locales.in
@@ -6,7 +6,8 @@ BUILDDIR=`dirname $0`
export IBUS_COMPOSE_CACHE_DIR=$PWD
-retval=0
+RETVAL=0
+INITED=0
# Deleted for var in `cat *.env` because IFS=$'\n' is not supported in POSIX sh
while read var
do
@@ -14,19 +15,26 @@ do
if [ "x$IS_COMMENT" != x ] ; then
continue
fi
+ while [ x"$IBUS_DAEMON_WITH_SYSTEMD" != x ] && [ $INITED -lt 6 ] ; do
+ echo "Waiting for ${INITED}0 secs till 60 secs"
+ sleep 10
+ INITED=`expr $INITED + 1`
+ done
# Use $* instead of $@ not to mix strings and integers
echo "# Starting $var $BUILDDIR/ibus-compose $SRCDIR $*"
# Need to enclose $@ with double quotes not to split the array.
env $var $BUILDDIR/ibus-compose $SRCDIR "$@"
- retval=`expr $retval + $?`
- echo "# Finished $var $BUILDDIR/ibus-compose $SRCDIR $* with $retval"
+ RETVAL=`expr $RETVAL + $?`
+ echo "# Finished $var $BUILDDIR/ibus-compose $SRCDIR $* with $RETVAL"
CACHE_FILES=`ls *.cache`
if [ x"$CACHE_FILES" != x ] ; then
echo "Clean $CACHE_FILES"
rm $CACHE_FILES
fi
+ # Need to wait for 1 sec not to be freezed with gnome-shell in Wayland
+ sleep 1
done << EOF_ENVS
`cat $SRCDIR/ibus-compose.env`
EOF_ENVS
-exit $retval
+exit $RETVAL
diff --git a/src/tests/ibus-desktop-testing-autostart b/src/tests/ibus-desktop-testing-autostart
deleted file mode 100755
index 1e1eb180..00000000
--- a/src/tests/ibus-desktop-testing-autostart
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-# -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*-
-# vim:set noet ts=4:
-#
-# ibus - The Input Bus
-#
-# Copyright (c) 2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-# Copyright (c) 2021 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-TEST_LOG=
-COMMANDS='
-id
-echo $DISPLAY
-pwd
-pstree -asp $$
-gsettings list-recursively org.gnome.shell
-rpm -q gnome-shell-extension-no-overview gnome-shell gnome-session
-ps -ef | grep ibus | grep -v grep
-ibus address
-'
-
-if [ $# -gt 0 ] ; then
- TEST_LOG=$1
-fi
-
-run_test()
-{
-while read cmd ; do
- if [ x"$cmd" = x ] ; then
- continue
- fi
- echo "# $cmd"
- eval "$cmd"
-done << EOF_COMMANDS
-`echo "$COMMANDS"`
-EOF_COMMANDS
-}
-
-if [ x"$TEST_LOG" = x ] ; then
- run_test
-else
- run_test 2>>$TEST_LOG 1>>$TEST_LOG
-fi
diff --git a/src/tests/ibus-desktop-testing-autostart.in b/src/tests/ibus-desktop-testing-autostart.in
new file mode 100755
index 00000000..d50354df
--- /dev/null
+++ b/src/tests/ibus-desktop-testing-autostart.in
@@ -0,0 +1,83 @@
+#!/bin/sh
+# -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2021-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+PROGNAME=`basename $0`
+TEST_CASE_DIR="@INSTALLEDDIR@"
+MODULE_SH='ibus-desktop-testing-module'
+MODULE_SH_PATH="@LIBEXECDIR@/$MODULE_SH"
+TEST_LOG="test-autostart.log"
+TESTING_RUNNER=""
+
+
+if test -f $MODULE_SH_PATH ; then
+ . $MODULE_SH_PATH
+elif test -f $(dirname $0)/$MODULE_SH ; then
+ . $(dirname $0)/$MODULE_SH
+else
+ echo "Not found $MODULE_SH"
+ exit 1
+fi
+
+
+usage()
+{
+ $ECHO -e \
+"This test suite is called from /etc/xdg/autostart for systemd sessions\n" \
+"$PROGNAME [OPTIONS…]\n" \
+"\n" \
+"OPTIONS:\n" \
+"-h, --help This help\n" \
+"-v, --version Show version\n" \
+"-b, --builddir=BUILDDIR Set the BUILDDIR\n" \
+"-s, --srcdir=SOURCEDIR Set the SOURCEDIR\n" \
+"-V, --verbose Verbose log for ibus-daemon\n" \
+"-t, --tests=\"TESTS...\" Run TESTS programs which is separated by space\n" \
+"-r, --runner=RUNNER Run TESTS programs with a test RUNNER.\n" \
+" RUNNDER = 'gnome', 'default' or ''.\n" \
+" 'default' is an embedded runner.\n" \
+" '' is no tests.\n" \
+"-T, --timeout=TIMEOUT Set timeout (default TIMEOUT is 300 sec).\n" \
+"-o, --output=OUTPUT_FILE Output the log to OUTPUT_FILE\n" \
+" default is $TEST_LOG\n" \
+"-O, --result=RESULT_FILE Output the result to RESULT_FILE\n" \
+" default is stdout\n" \
+"-S, --screendump=DUMP_FILE Output the screen to DUMP_FILE ('STDOUT' can be stdout)\n" \
+"-e, --envcheck Retrieve environment variables\n" \
+""
+}
+
+
+main()
+{
+ parse_args "$@"
+ init_session
+ check_env
+ save_screen
+ run_test_suite
+ finit
+}
+
+
+# Need to enclose $@ with double quotes not to split the array.
+main "$@"
diff --git a/src/tests/ibus-desktop-testing-module b/src/tests/ibus-desktop-testing-module
new file mode 100755
index 00000000..2d686813
--- /dev/null
+++ b/src/tests/ibus-desktop-testing-module
@@ -0,0 +1,876 @@
+#!/bin/sh
+# -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2018-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
+# Copyright (c) 2018 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+# POSIX sh has no 'echo -e'
+: ${ECHO:='/usr/bin/echo'}
+# POSIX sh has $UID
+# DASH saves the graves in '``' as characters not to be extracted
+: ${UID:=`id -u`}
+: ${TEST_CASE_DIR='/usr/share/installed-tests'}
+: ${AUTOSTART_DESKTOP_DIR='/usr/share/ibus/tests'}
+
+
+VERSION=0.4
+BUILDDIR="."
+SRCDIR="."
+TEST_LOG_STDOUT=0
+RESULT_LOG=""
+SCREEN_LOG=""
+HAVE_GRAPHICS=1
+VERBOSE=0
+SESSION_COMMAND="dbus-launch --exit-with-session gnome-session"
+SESSION_LANG=
+SESSION_IS_GNOME=1
+GNOME_SHELL_WAYLAND_COMMAND="gnome-shell --wayland --headless --virtual-monitor 1024x768"
+SYSTEMD_SYSTEM_DIR="/usr/lib/systemd/user"
+PID_XORG=0
+PID_GNOME_SESSION=0
+ENABLED_SYSTEMD=1
+TEST_USER=itestuser
+TEST_USER_HOME=/export/home/$TEST_USER
+GDM_CONF=/run/gdm/custom.conf
+AUTOSTART_DESKTOP_FILE="org.freedesktop.IBus.Desktop.Testing.desktop"
+TESTS=""
+TIMEOUT=300
+GREEN='\033[0;32m'
+RED='\033[0;31m'
+NC='\033[0m'
+ENV_CHECK=0
+ENV_COMMANDS='
+id
+pwd
+pstree -asp $$
+gsettings list-recursively org.gnome.shell
+rpm -q gnome-shell-extension-no-overview gnome-shell gnome-session
+ps -ef | grep ibus | grep -v grep
+ibus address
+env
+#dbus-send --session --print-reply --dest=org.gnome.Shell.Introspect /org/gnome/Shell/Introspect org.gnome.Shell.Introspect.GetWindows
+'
+
+
+print_log()
+{
+ if [ x"$RESULT_LOG" != x ] ; then
+ # avoid 'echo -e' before call 'sed'.
+ if [ x"$1" = x'-e' ] ; then
+ shift
+ fi
+ NO_ESCAPE=`echo "$@" | sed -e 's/\\\033\\[0;3.m//g' -e 's/\\\033\\[0m//g'`
+ $ECHO $NO_ESCAPE >> $RESULT_LOG
+ else
+ $ECHO "$@"
+ fi
+}
+
+
+parse_args()
+{
+ # This is GNU getopt. "sudo port getopt" in BSD?
+ ARGS=`getopt -o hvb:s:cVd:t:r:iT:o:O:S:el:D --long \
+help,version,builddir:,srcdir:,no-graphics,verbose,desktop:,session:,tests:,\
+runner:,no-systemd,timeout:,output:,result:,screendump:,envcheck,lang:,\
+delete-tests\
+ -- "$@"`;
+ eval set -- "$ARGS"
+ while [ 1 ] ; do
+ case "$1" in
+ -h | --help ) usage; exit 0;;
+ -v | --version ) $ECHO -e "$VERSION"; exit 0;;
+ -b | --builddir ) BUILDDIR="$2"; shift 2;;
+ -s | --srcdir ) SRCDIR="$2"; shift 2;;
+ -c | --no-graphics ) HAVE_GRAPHICS=0; shift;;
+ -V | --verbose ) VERBOSE=1; shift;;
+ --desktop ) SESSION_COMMAND="$2"
+ print_log -e "--desktop is deprecated. Use --session instead"
+ shift 2;;
+ -d | --session ) SESSION_COMMAND="$2"; shift 2;;
+ -t | --tests ) TESTS="$2"; shift 2;;
+ -r | --runner ) TESTING_RUNNER="$2"; shift 2;;
+ -i | --no-systemd ) ENABLED_SYSTEMD=0; shift;;
+ -T | --timeout ) TIMEOUT="$2"; shift 2;;
+ -o | --output ) TEST_LOG="$2"; shift 2;;
+ -O | --result ) RESULT_LOG="$2"; shift 2;;
+ -S | --screendump ) SCREEN_LOG="$2"; shift 2;;
+ -e | --envcheck ) ENV_CHECK=1; shift;;
+ -l | --lang ) SESSION_LANG="$2"; shift 2;;
+ -D | --delete-tests ) delete_test_user; exit 0;;
+ -- ) shift; break;;
+ * ) usage; exit 1;;
+ esac
+ done
+ DL='$'
+ if echo "$SESSION_COMMAND" | grep -q -E ".*-with-dbus$DL" ; then
+ SESSION_COMMAND=`echo "$SESSION_COMMAND" | sed -e 's/-with-dbus$//'`
+ SESSION_COMMAND="dbus-launch --exit-with-session $SESSION_COMMAND"
+ fi
+}
+
+
+check_tty()
+{
+ TTY=`tty`
+ if echo $PROGNAME | grep -q runner ; then
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ if echo "$TTY" | grep -E 'tty|console' ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Changing runlevel does not support console. Please log into the host with ssh."
+ exit 1
+ fi
+ fi
+ if [ $ENABLED_SYSTEMD -eq 0 ] ; then
+ if echo "$TTY" | grep -E 'pts' ; then
+ print_log -e "Running session with ssh. It might be good to use console instead."
+ fi
+ fi
+ SESSION=`ps -ef | grep session | grep -v grep`
+ if [ x"$SESSION" != x ] ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Session is running: $SESSION"
+ exit 1
+ fi
+ fi
+}
+
+
+check_env()
+{
+ if test $ENV_CHECK -eq 0 ; then
+ return
+ fi
+ while read cmd ; do
+ if test x"$cmd" = x ; then
+ continue
+ fi
+ if echo "$cmd" | grep -q "^#"; then
+ continue
+ fi
+ echo "# $cmd" 2>>$TEST_LOG 1>>$TEST_LOG
+ eval "$cmd" 2>>$TEST_LOG 1>>$TEST_LOG
+ done << EOF_ENV_COMMANDS
+`echo "$ENV_COMMANDS"`
+EOF_ENV_COMMANDS
+}
+
+
+save_screen_real()
+{
+ SCREEN_PNG="`date '+%Y%m%d%H%M%S'`.png"
+ gnome-screenshot --file=$SCREEN_PNG
+ if test x"$SCREEN_LOG" = xSTDOUT ; then
+ base64 $SCREEN_PNG
+ touch /var/tmp/STDOUT.log
+ else
+ base64 $SCREEN_PNG > $SCREEN_LOG
+ fi
+}
+
+
+save_screen()
+{
+ if test x"$SCREEN_LOG" = x ; then
+ return
+ fi
+ if test x"$SCREEN_LOG" = xSTDOUT ; then
+ if test -f /var/tmp/STDOUT.log ; then
+ rm /var/tmp/STDOUT.log
+ fi
+ else
+ if test -f "$SCREEN_LOG" ; then
+ rm "$SCREEN_LOG"
+ fi
+ fi
+ save_screen_real &
+ while test 1 ; do
+ if test x"$SCREEN_LOG" = xSTDOUT ; then
+ if test -f /var/tmp/STDOUT.log ; then
+ break
+ fi
+ else
+ if test -f "$SCREEN_LOG" ; then
+ break
+ fi
+ fi
+ sleep 1
+ done
+}
+
+
+create_test_user()
+{
+ if grep -q $TEST_USER /etc/passwd; then
+ return;
+ fi
+ useradd -d $TEST_USER_HOME -m -s /bin/bash $TEST_USER
+ pwconv
+ passwd -d $TEST_USER
+}
+
+
+create_autologin_gdm()
+{
+ if test -f $GDM_CONF && grep -q $TEST_USER $GDM_CONF; then
+ return;
+ fi
+ cat > $GDM_CONF << _EOF_GDM_CONF
+[daemon]
+AutomaticLoginEnable=true
+AutomaticLogin=$TEST_USER
+_EOF_GDM_CONF
+}
+
+
+create_xdg_autostart()
+{
+ if test -f "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE" ; then
+ return
+ fi
+ if test ! -d "$TEST_USER_HOME" ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $TEST_USER_HOME"
+ exit 1
+ fi
+ desktop_file="$AUTOSTART_DESKTOP_DIR/$AUTOSTART_DESKTOP_FILE"
+ if test ! -f $desktop_file ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $desktop_file"
+ exit 1
+ fi
+ mkdir -p "$TEST_USER_HOME/.config/autostart"
+ cp "$desktop_file" "$TEST_USER_HOME/.config/autostart"
+ LINE="AutostartCondition=if-exists $TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
+ echo "$LINE" >> "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
+ chown -R "$TEST_USER" "$TEST_USER_HOME/.config"
+}
+
+
+delete_test_user()
+{
+ print_log "Deleting $TEST_USER"
+ pkill -u $TEST_USER
+ if grep -q $TEST_USER /etc/passwd; then
+ userdel -r $TEST_USER
+ fi
+ if test -f $GDM_CONF && grep -q $TEST_USER $GDM_CONF; then
+ rm $GDM_CONF
+ fi
+
+ if echo "$SESSION_COMMAND" | grep -q gnome-session ; then
+ SESSION_IS_GNOME=1
+ else
+ SESSION_IS_GNOME=0
+ fi
+
+ LOGIN_USER=$USER
+ LOGIN_HOME=$HOME
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ LOGIN_USER=$TEST_USER
+ LOGIN_HOME=$TEST_USER_HOME
+ fi
+
+ print_log "Deleting $LOGIN_USER environments"
+ if test -f "$LOGIN_HOME/.config/gnome-initial-setup-done" ; then
+ rm "$LOGIN_HOME/.config/gnome-initial-setup-done"
+ fi
+ if test -f "$LOGIN_HOME/.config/user-dirs.locale" ; then
+ rm "$LOGIN_HOME/.config/user-dirs.locale"
+ fi
+ if test -f /var/lib/AccountsService/users/$LOGIN_USER ; then
+ rm /var/lib/AccountsService/users/$LOGIN_USER
+ fi
+ sync
+}
+
+
+init_session()
+{
+ if [ "$RESULT_LOG" != "" ] ; then
+ if [ -f $RESULT_LOG ] ; then
+ rm $RESULT_LOG
+ fi
+ fi
+ echo "$TEST_LOG" | grep ':stdout' > /dev/null
+ HAS_STDOUT=$?
+ if [ $HAS_STDOUT -eq 0 ] ; then
+ TEST_LOG=`echo "$TEST_LOG" | sed -e 's|:stdout||'`
+ TEST_LOG_STDOUT=1
+ fi
+ if [ "$TEST_LOG" = "" ] ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: a log file is required to get return value with 'read' command"
+ exit 1
+ elif [ -f $TEST_LOG ] ; then
+ rm $TEST_LOG
+ fi
+
+ if echo "$SESSION_COMMAND" | grep -q gnome-session ; then
+ SESSION_IS_GNOME=1
+ else
+ SESSION_IS_GNOME=0
+ fi
+
+ LOGIN_USER=$USER
+ LOGIN_HOME=$HOME
+ check_tty
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ SESSION_FILE1="/usr/lib/systemd/system/gnome-headless-session@.service"
+ SESSION_FILE2="/usr/lib/systemd/system/graphical.target"
+ if [ $HAVE_GRAPHICS -eq 0 ] && [ ! -f "$SESSION_FILE1" ] ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $SESSION_FILE1: You need to install 'gdm' and 'systemd' package"
+ exit 1
+ fi
+ if [ $HAVE_GRAPHICS -eq 1 ] ; then
+ if [ ! -f "$SESSION_FILE2" ] ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $SESSION_FILE2: You need to install 'systemd' package"
+ exit 1
+ fi
+ if [ ! -f /usr/sbin/gdm ] ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No /usr/sbin/gdm: Currently only gdm is supported for auto login."
+ exit 1
+ fi
+ fi
+ create_test_user
+ create_autologin_gdm
+ create_xdg_autostart
+ LOGIN_USER=$TEST_USER
+ LOGIN_HOME=$TEST_USER_HOME
+ else
+ rm -f $TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE
+ fi
+
+ if [ ! -f $LOGIN_HOME/.config/gnome-initial-setup-done ] ; then
+ mkdir -p $LOGIN_HOME/.config
+ touch $LOGIN_HOME/.config/gnome-initial-setup-done
+ chown -R $LOGIN_USER $LOGIN_HOME/.config
+ fi
+ IS_SYSTEM_ACCOUNT=false
+ if [ "$LOGIN_USER" = "root" ] ; then
+ IS_SYSTEM_ACCOUNT=true
+ fi
+ if test x"$SESSION_LANG" = x ; then
+ SESSION_LANG=$LANG
+ fi
+ if test -f /var/lib/AccountsService/users/$LOGIN_USER; then
+ sed -i -e "s/\(Language=\).*/\1$SESSION_LANG/" \
+ /var/lib/AccountsService/users/$LOGIN_USER
+ else
+ mkdir -p /var/lib/AccountsService/users
+ cat > /var/lib/AccountsService/users/$LOGIN_USER << _EOF_AS_CONF
+[User]
+Language=$SESSION_LANG
+XSession=gnome
+SystemAccount=$IS_SYSTEM_ACCOUNT
+_EOF_AS_CONF
+ fi
+
+ # Prevent from launching a XDG dialog
+ XDG_LOCALE_FILE="$LOGIN_HOME/.config/user-dirs.locale"
+ if [ -f $XDG_LOCALE_FILE ] ; then
+ XDG_LANG_ORIG=`cat $XDG_LOCALE_FILE`
+ XDG_LANG_NEW=`echo $SESSION_LANG | sed -e 's/\(.*\)\..*/\1/'`
+ if [ "$XDG_LANG_ORIG" != "$XDG_LANG_NEW" ] ; then
+ echo "# Overriding XDG locale $XDG_LANG_ORIG with $XDG_LANG_NEW"
+ echo "$XDG_LANG_NEW" > $XDG_LOCALE_FILE
+ fi
+ fi
+
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ return
+ fi
+ # `su` command does not run loginctl
+ export XDG_SESSION_TYPE='x11'
+ export XDG_SESSION_CLASS=user
+ # `su` command does not get focus in events without this variable.
+ # Need to restart sshd after set "PermitRootLogin yes" in sshd_config
+ if [ "x$XDG_RUNTIME_DIR" = x ] ; then
+ export XDG_RUNTIME_DIR="/run/user/$UID"
+ is_root_login=`grep "^PermitRootLogin" /etc/ssh/sshd_config | grep yes`
+ if [ "x$ANSIBLE" != x ] && [ "x$is_root_login" = x ] ; then
+ print_log -e "${RED}FAIL${NC}: No permission to get focus-in events in GtkWindow with ansible"
+ echo "su command does not configure necessary login info " \
+ "with systemd and GtkWindow cannot receive focus-events " \
+ "when ibus-desktop-testing-runner is executed by " \
+ "ansible-playbook." >> $TEST_LOG
+ echo "Enabling root login via sshd, restarting sshd, set " \
+ "XDG_RUNTIME_DIR can resolve the problem under " \
+ "ansible-playbook." >> $TEST_LOG
+ exit 1
+ fi
+ fi
+ # Do we need XDG_SESSION_ID and XDG_SEAT?
+ #export XDG_CONFIG_DIRS=/etc/xdg
+ #export XDG_SESSION_ID=10
+ #export XDG_SESSION_DESKTOP=gnome
+ #export XDG_SEAT=seat0
+}
+
+
+run_dbus_daemon()
+{
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ return
+ fi
+ # Use dbus-launch --exit-with-session later instead of --sh-syntax
+ # GNOME uses a unix:abstract address and it effects gsettings set values
+ # in each test case.
+ # TODO: Should we comment out this line?
+ export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus"
+}
+
+
+init_gnome()
+{
+ if test $SESSION_IS_GNOME -ne 1 ; then
+ print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Should not be called"
+ exit 1
+ fi
+ LOGIN_USER=$USER
+ if test $ENABLED_SYSTEMD -eq 1 ; then
+ LOGIN_USER=$TEST_USER
+ fi
+ # gsettings set command needs dconf-service with the same $DISPLAY
+ pkill dconf-service
+ # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append
+ # debug messages to gsettings output and could not get the result correctly.
+ backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG"
+ unset G_MESSAGES_DEBUG
+ # Disable Tour dialog to get focus
+ GET_WELCOME_DIALOG="gsettings get org.gnome.shell welcome-dialog-last-shown-version"
+ if test $LOGIN_USER = $USER ; then
+ V=`dbus-run-session $GET_WELCOME_DIALOG`
+ else
+ V=`sudo -u $LOGIN_USER dbus-run-session $GET_WELCOME_DIALOG`
+ fi
+ if [ x"$V" = x"''" ] ; then
+ SET_WELCOME_DIALOG="gsettings set org.gnome.shell welcome-dialog-last-shown-version '100'"
+ if test $LOGIN_USER = $USER ; then
+ dbus-run-session $SET_WELCOME_DIALOG
+ else
+ sudo -u $LOGIN_USER dbus-run-session $SET_WELCOME_DIALOG
+ fi
+ fi
+ # gnome-shell now starts overview mode by login.
+ # https://extensions.gnome.org/extension/4099/no-overview/
+ NO_SYS_DIR=/usr/share/gnome-shell/extensions/no-overview@fthx
+ if test $LOGIN_USER = $USER ; then
+ NO_USER_DIR=$HOME/.local/share/gnome-shell/extensions/no-overview@fthx
+ else
+ NO_USER_DIR=$TEST_USER_HOME/.local/share/gnome-shell/extensions/no-overview@fthx
+ fi
+ if [ ! -d $NO_SYS_DIR ] && [ ! -d $NO_USER_DIR ] ; then
+ mkdir -p "`dirname $NO_USER_DIR`"
+ cp -R "no-overview@fthx" "`dirname $NO_USER_DIR`"
+ if test $LOGIN_USER = $USER ; then
+ chown -R $LOGIN_USER $HOME/.local
+ else
+ chown -R $LOGIN_USER $TEST_USER_HOME/.local
+ fi
+ fi
+ if [ $LOGIN_USER != $USER ] ; then
+ SHELL_SERVICE_FILE="org.gnome.Shell@wayland.service"
+ SYSTEMD_USER_DIR="$TEST_USER_HOME/.config/systemd/user"
+ if test $HAVE_GRAPHICS -ne 1 ; then
+ if test ! -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
+ mkdir -p "$SYSTEMD_USER_DIR"
+ pushd "$SYSTEMD_USER_DIR"
+ sed -e "s|^ExecStart=.*|ExecStart=$GNOME_SHELL_WAYLAND_COMMAND|" \
+ $SYSTEMD_SYSTEM_DIR/$SHELL_SERVICE_FILE \
+ > $SHELL_SERVICE_FILE
+ diff $SYSTEMD_SYSTEM_DIR/$SHELL_SERVICE_FILE $SHELL_SERVICE_FILE
+ popd
+ chown -R $LOGIN_USER "$TEST_USER_HOME/.config"
+ fi
+ else
+ if test -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
+ rm "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE"
+ fi
+ fi
+ fi
+ GET_DISABLE_USER_EX="gsettings get org.gnome.shell disable-user-extensions"
+ if test $LOGIN_USER = $USER ; then
+ V=`dbus-run-session $GET_DISABLE_USER_EX`
+ else
+ V=`sudo -u $LOGIN_USER dbus-run-session $GET_DISABLE_USER_EX`
+ fi
+ if [ x"$V" = x"true" ] ; then
+ SET_DISABLE_USER_EX="gsettings set org.gnome.shell disable-user-extensions false"
+ if test $LOGIN_USER = $USER ; then
+ dbus-run-session $SET_DISABLE_USER_EX
+ else
+ sudo -u $LOGIN_USER dbus-run-session $SET_DISABLE_USER_EX
+ fi
+ fi
+ GET_ENABLED_EXS="gsettings get org.gnome.shell enabled-extensions"
+ if test $LOGIN_USER = $USER ; then
+ V=`dbus-run-session $GET_ENABLED_EXS`
+ else
+ V=`sudo -u $LOGIN_USER dbus-run-session $GET_ENABLED_EXS`
+ fi
+ echo "$V" | grep "no-overview" > /dev/null
+ V2=$?
+ if [ $V2 -ne 0 ] ; then
+ V3=`echo "$V" | sed -e 's/@as //' -e 's/\[//' -e 's/\]//'`
+ if [ x"$V3" = x"''" ] || [ x"$V3" = x"" ]; then
+ V4="['no-overview@fthx']"
+ else
+ V4="[$V3,'no-overview@fthx']"
+ fi
+ SET_ENABLED_EXS="gsettings set org.gnome.shell enabled-extensions \"$V4\""
+ if test $LOGIN_USER = $USER ; then
+ eval dbus-run-session $SET_ENABLED_EXS
+ else
+ eval sudo -u $LOGIN_USER dbus-run-session $SET_ENABLED_EXS
+ fi
+ fi
+ # Disable notify dialog when the disk usage is low.
+ SET_NOTIFY_DISK="gsettings set org.gnome.settings-daemon.plugins.housekeeping free-size-gb-no-notify 0"
+ if test $LOGIN_USER = $USER ; then
+ eval dbus-run-session $SET_NOTIFY_DISK
+ else
+ eval sudo -u $LOGIN_USER dbus-run-session $SET_NOTIFY_DISK
+ fi
+ if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then
+ export G_MESSAGES_DEBUG="$backup_G_MESSAGES_DEBUG"
+ fi
+}
+
+
+operate_desktop_with_systemd()
+{
+ SESSION=gnome-headless-session
+ COMMAND="$1"
+
+ #if test $HAVE_GRAPHICS -eq 1 ; then
+ case "$COMMAND" in
+ "start") systemctl isolate graphical.target
+ echo ""
+ ;;
+ "stop") init 3;;
+ "") print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Wrong command $COMMAND"
+ exit 1;;
+ esac
+ #else
+ # setenforce 0
+ # systemctl $COMMAND ${SESSION}@${TEST_USER}
+ #fi
+ case "$COMMAND" in
+ "start") sleep 30;;
+ "") ;;
+ esac
+ #if test $HAVE_GRAPHICS -eq 1 ; then
+ systemctl status --no-pager graphical.target
+ #else
+ # systemctl status --no-pager ${SESSION}@${TEST_USER}
+ #fi
+ ps -ef | grep X
+ ps -ef | grep session
+ ps -ef | grep ibus
+}
+
+
+run_session()
+{
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ init_gnome
+ operate_desktop_with_systemd "start"
+ return
+ fi
+ export DISPLAY=:99.0
+ if test $HAVE_GRAPHICS -eq 1 ; then
+ /usr/libexec/Xorg.wrap -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . $DISPLAY &
+ else
+ /usr/bin/Xvfb $DISPLAY -noreset +extension GLX +extension RANDR +extension RENDER -screen 0 1280x1024x24 &
+ fi
+ PID_XORG=$!
+ sleep 1
+ # init_gnome need to be called with $DISPLAY before gnome-session is called
+ if [ $SESSION_IS_GNOME -eq 1 ] ; then
+ init_gnome
+ fi
+ echo "Running $SESSION_COMMAND with $USER and LANG=$SESSION_LANG in `tty`"
+ if test x"$SESSION_LANG" = x ; then
+ $SESSION_COMMAND &
+ else
+ env LANG=$SESSION_LANG $SESSION_COMMAND &
+ fi
+ PID_GNOME_SESSION=$!
+ sleep 30
+
+ IBUS_ARGS="--verbose --panel disable"
+ # gnome-shell 42 checks if org.freedesktop.IBus.session.GNOME.service
+ # systemd file is available with org.freedesktop.systemd1.Manager.GetUnit
+ # D-Bus method, which is provided by IBus 1.5.26, and if the file
+ # is available, gnome-shell no longer launch ibus-daemon
+ # because gnome-shell assumes gnome-session would launch ibus-daemon
+ # with org.freedesktop.systemd1.Manager.StartUnit D-Bus method.
+ # But actually gnome-session failed to launch ibus-daemon
+ # because the IBus systemd file depends on gnome-session.target
+ # but this CI launches gnome-session directly.
+ #
+ # So ibus-dameon is now always called here after gnome-shell fails to
+ # launch ibus-daemon.
+ # It may be better this CI launches GDM autologin to run gnome-session
+ # with gnome-session.target systemd file.
+ # But `systemctl start gdm` terminates the parent script forcibly
+ # and the script cannot get the CI result.
+ if test $VERBOSE -eq 1 ; then
+ ibus-daemon $IBUS_ARGS &
+ else
+ ibus-daemon $IBUS_ARGS --daemonize
+ fi
+ sleep 3
+ ps -ef | grep ibus
+}
+
+
+count_case_result()
+{
+ retval=$1
+ pass=$2
+ fail=$3
+
+ if test $retval -eq 0 ; then
+ pass=`expr $pass + 1`
+ else
+ fail=`expr $fail + 1`
+ fi
+ echo $pass $fail
+}
+
+
+echo_case_result()
+{
+ retval=$1
+ tst=$2
+ subtst=${3:-''}
+
+ if test $retval -eq 0 ; then
+ echo "PASS: $tst $subtst" >>$TEST_LOG
+ else
+ echo "FAIL: $tst $subtst" >>$TEST_LOG
+ fi
+}
+
+
+wait_for_systemd_autostart()
+{
+ PS_IBUS="ps -ef | grep ibus-desktop-testing | grep autostart | grep -v grep"
+ i=0
+ while test 1 ; do
+ R=`eval "$PS_IBUS"`
+ if test x"$R" != x ; then
+ break;
+ fi
+ if test $i -ge 12 ; then
+ print_log -e "${RED}FAIL${NC}: Timeout to run ibus-desktop-testing-autostart"
+ return
+ fi
+ i=`expr $i + 1`
+ sleep 5
+ done
+ print_log -e "Start ibus-desktop-testing-autostart"
+ i=0
+ while test 1 ; do
+ R=`eval "$PS_IBUS"`
+ if test x"$R" = x ; then
+ break;
+ fi
+ if test $i -ge $TIMEOUT ; then
+ print_log -e "${RED}FAIL${NC}: Timeout to exit ibus-desktop-testing-autostart"
+ return
+ fi
+ i=`expr $i + 1`
+ sleep 5
+ done
+ print_log -e "Exit ibus-desktop-testing-autostart"
+}
+
+run_direct_test_cases()
+{
+ pass=0
+ fail=0
+ for tst in $TESTS; do
+ ENVS=
+ if test -f $SRCDIR/${tst}.env ; then
+ ENVS="`cat $SRCDIR/${tst}.env`"
+ fi
+ if test x"$ENVS" = x ; then
+ $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
+ retval=$?
+ read pass fail << EOF_COUNT
+ `count_case_result $retval $pass $fail`
+EOF_COUNT
+ echo_case_result $retval $tst
+ CACHE_FILES=`ls *.cache`
+ if [ x"$CACHE_FILES" != x ] ; then
+ echo "# Clean $CACHE_FILES" >>$TEST_LOG
+ rm $CACHE_FILES
+ fi
+ else
+ i=1
+ # Deleted for var in "$ENVS" because IFS=$'\n' is not supported
+ # in POSIX sh
+ while read e ; do
+ first=`echo "$e" | grep '^#'`
+ if test x"$first" = x"#" ; then
+ continue
+ fi
+ echo "# Starting $e $BUILDDIR/$tst $SRCDIR" >>$TEST_LOG
+ env $e $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
+ retval=$?
+ echo "# Finished $e $BUILDDIR/$tst $SRCDIR with $retval" >>$TEST_LOG
+ read pass fail << EOF_COUNT
+ `count_case_result $retval $pass $fail`
+EOF_COUNT
+ echo_case_result $retval $tst $e
+ CACHE_FILES=`ls *.cache`
+ if [ x"$CACHE_FILES" != x ] ; then
+ echo "# Clean $CACHE_FILES" >>$TEST_LOG
+ rm $CACHE_FILES
+ fi
+ i=`expr $i + 1`
+ done << EOF_ENVS
+ `echo "$ENVS"`
+EOF_ENVS
+ fi
+ done
+ echo $pass $fail
+}
+
+
+run_gnome_desktop_testing_runner()
+{
+ pass=0
+ fail=0
+ if [ x"$TESTS" = x ] ; then
+ TESTS='ibus'
+ fi
+ if echo $PROGNAME | grep -q autostart ; then
+ export IBUS_DAEMON_WITH_SYSTEMD=1
+ fi
+ for tst in $TESTS; do
+ tst_dir="$TEST_CASE_DIR/$tst"
+ if [ ! -d "$tst_dir" ] ; then
+ print_log -e "${RED}FAIL${NC}: Not found %tst_dir"
+ fail=1
+ continue
+ fi
+ gnome-desktop-testing-runner --timeout=$TIMEOUT $tst \
+ 2>>$TEST_LOG 1>>$TEST_LOG
+ retval=$?
+ read pass fail << EOF
+ `count_case_result $retval $pass $fail`
+EOF
+ done
+ child_pass=`grep '^PASS:' $TEST_LOG | wc -l`
+ child_fail=`grep '^FAIL:' $TEST_LOG | wc -l`
+ if [ $child_pass -ne 0 ] || [ $child_fail -ne 0 ] ; then
+ pass=$child_pass
+ if [ $child_fail -ne 0 ] ; then
+ fail=`expr $child_fail / 2`
+ else
+ fail=0
+ fi
+ fi
+ echo $pass $fail
+}
+
+
+run_test_suite()
+{
+ print_log -e "Start test suite `date '+%F %H:%M:%S:%N'`"
+ if echo $PROGNAME | grep -q runner ; then
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ wait_for_systemd_autostart
+ return
+ fi
+ if ps -ef | grep X | grep -q wayland ; then
+ # Expect GTK_IM_MODULE=wayland by default
+ :
+ else
+ export GTK_IM_MODULE=ibus
+ fi
+ else
+ if test x"$XDG_SESSION_TYPE" = xwayland ; then
+ :
+ else
+ export GTK_IM_MODULE=ibus
+ fi
+ fi
+ pass=0
+ fail=0
+ export IBUS_COMPOSE_CACHE_DIR=$PWD
+ if test x"$TESTING_RUNNER" = x ; then
+ return
+ fi
+ case $TESTING_RUNNER in
+ default)
+ # Get only the last value with do-while.
+ read pass fail << EOF_RUNNER
+ `run_direct_test_cases`
+EOF_RUNNER
+ ;;
+ gnome)
+ read pass fail << EOF_RUNNER
+ `run_gnome_desktop_testing_runner`
+EOF_RUNNER
+ ;;
+ esac
+ echo ""
+ print_log -e "End test suite `date '+%F %H:%M:%S:%N'`"
+ # Fedora CI assumes the test is failed even if $fail is 0.
+ if [ $pass -ne 0 ] ; then
+ print_log -e "${GREEN}PASS${NC}: $pass"
+ fi
+ if [ $fail -ne 0 ] ; then
+ print_log -e "${RED}FAIL${NC}: $fail"
+ fi
+}
+
+
+finit()
+{
+ if test $PID_XORG -ne 0 ; then
+ echo "# Killing left gnome-session and Xorg"
+ kill $PID_GNOME_SESSION $PID_XORG
+ ibus exit
+ SUSER=`echo "$USER" | cut -c 1-7`
+ LEFT_CALENDAR=`ps -ef | grep gnome-shell-calendar-server | grep $SUSER | grep -v grep`
+ if test x"$LEFT_CALENDAR" != x ; then
+ echo "# Killing left gnome-shell-calendar-server"
+ echo "$LEFT_CALENDAR"
+ echo "$LEFT_CALENDAR" | awk '{print $2}' | xargs kill
+ fi
+ fi
+ if echo $PROGNAME | grep -q runner ; then
+ if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
+ operate_desktop_with_systemd "stop"
+ fi
+ fi
+
+ echo ""
+ if test -f $TEST_LOG ; then
+ if [ $TEST_LOG_STDOUT -eq 1 ] ; then
+ cat $TEST_LOG
+ else
+ echo "# See $TEST_LOG"
+ fi
+ fi
+ echo "# Finished $PROGNAME testing"
+}
diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in
index 1ac2dfc8..1d82bc76 100755
--- a/src/tests/ibus-desktop-testing-runner.in
+++ b/src/tests/ibus-desktop-testing-runner.in
@@ -4,7 +4,7 @@
#
# ibus - The Input Bus
#
-# Copyright (c) 2018-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
+# Copyright (c) 2018-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
# Copyright (c) 2018 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
@@ -22,58 +22,39 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# This test runs /usr/bin/ibus-daemon after install ibus
-#
-# # init 3
-# Login as root
-# # /root/ibus/tests/test-console.sh --tests ibus-compose \
-# --builddir /root/ibus/src/tests --srcdir /root/ibus/src/tests
-
-# POSIX sh has no 'echo -e'
-: ${ECHO:='/usr/bin/echo'}
-# POSIX sh has $UID
-# DASH saves the graves in '``' as characters not to be extracted
-: ${UID:=`id -u`}
PROGNAME=`basename $0`
-VERSION=0.3
-DISPLAY=:99.0
-BUILDDIR="."
-SRCDIR="."
+TEST_CASE_DIR="@INSTALLEDDIR@"
+MODULE_SH='ibus-desktop-testing-module'
+MODULE_SH_PATH="@LIBEXECDIR@/$MODULE_SH"
+AUTOSTART_DESKTOP_DIR="@DATADIR@/ibus/tests"
TEST_LOG="test-suite.log"
-TEST_LOG_STDOUT=0
-RESULT_LOG=""
-SCREEN_LOG=""
-HAVE_GRAPHICS=1
-VERBOSE=0
-DESKTOP_COMMAND="dbus-launch --exit-with-session gnome-session"
-PID_XORG=0
-PID_GNOME_SESSION=0
TESTING_RUNNER="default"
-TESTS=""
-TIMEOUT=300
-GREEN='\033[0;32m'
-RED='\033[0;31m'
-NC='\033[0m'
-print_log()
-{
- if [ x"$RESULT_LOG" != x ] ; then
- # avoid 'echo -e' before call 'sed'.
- if [ x"$1" = x'-e' ] ; then
- shift
- fi
- NO_ESCAPE=`echo "$@" | sed -e 's/\\\033\\[0;3.m//g' -e 's/\\\033\\[0m//g'`
- $ECHO $NO_ESCAPE >> $RESULT_LOG
- else
- $ECHO "$@"
- fi
-}
+if test -f $MODULE_SH_PATH ; then
+ . $MODULE_SH_PATH
+elif test -f $(dirname $0)/$MODULE_SH ; then
+ . $(dirname $0)/$MODULE_SH
+else
+ echo "Not found $MODULE_SH"
+ exit 1
+fi
usage()
{
+ command=""
+ for element in $SESSION_COMMAND; do
+ if test x"$element" = x; then
+ continue
+ fi
+ if echo "$element" | grep -q -E "^-" ; then
+ continue
+ fi
+ command="$element"
+ done
$ECHO -e \
"This test runs /usr/bin/ibus-daemon after install ibus\n" \
"$PROGNAME [OPTIONS…]\n" \
@@ -83,429 +64,37 @@ usage()
"-v, --version Show version\n" \
"-b, --builddir=BUILDDIR Set the BUILDDIR\n" \
"-s, --srcdir=SOURCEDIR Set the SOURCEDIR\n" \
-"-c, --no-graphics Use Xvfb instead of Xorg\n" \
+"-c, --no-graphics Use Xvfb instead of Xorg or Wayland\n" \
"-V, --verbose Verbose log for ibus-daemon\n" \
-"-d, --desktop=DESKTOP Run DESTKTOP. The default is gnome-session.\n" \
-" Suffix '-with-dbus' can run DESKTOP with dbus session." \
-" E.g. --desktop=mutter-with-dbus" \
+"-d, --session=SESSION Run SESSION. The default is ${command}.\n" \
+" Suffix '-with-dbus' can run SESSION with dbus session.\n" \
+" E.g. --session=${command}-with-dbus\n" \
+"-l, --lang=LANG Run SESSION with LANG\n" \
"-t, --tests=\"TESTS...\" Run TESTS programs which is separated by space\n" \
"-r, --runner=RUNNER Run TESTS programs with a test RUNNER.\n" \
-" RUNNDER = gnome or default.\n" \
-" default is an embedded runner.\n" \
+" RUNNDER = 'gnome' or 'default'.\n" \
+" 'default' is an embedded runner.\n" \
+"-i, --no-systemd Run gnome-seesion directly withoout systemd\n" \
+" and login manager for legacy GNOME and this\n" \
+" mode does not support Wayland.\n" \
"-T, --timeout=TIMEOUT Set timeout (default TIMEOUT is 300 sec).\n" \
-"-o, --output=OUTPUT_FILE OUtput the log to OUTPUT_FILE\n" \
-"-O, --result=RESULT_FILE OUtput the result to RESULT_FILE\n" \
-"-S, --screendump=DUMP_FILE OUtput the screen to DUMP_FILE ('STDOUT' can be stdout)\n" \
+"-o, --output=OUTPUT_FILE Output the log to OUTPUT_FILE\n" \
+" default is $TEST_LOG\n" \
+"-O, --result=RESULT_FILE Output the result to RESULT_FILE\n" \
+" default is stdout\n" \
+"-S, --screendump=DUMP_FILE Output the screen to DUMP_FILE ('STDOUT' can be stdout)\n" \
+"-D, --delete-tests Delete test enviroments and user $TEST_USER\n" \
""
}
-parse_args()
-{
- # This is GNU getopt. "sudo port getopt" in BSD?
- ARGS=`getopt -o hvb:s:cVd:t:r:T:o:O:S: --long \
- help,version,builddir:,srcdir:,no-graphics,verbose,desktop:,tests:,runner:,timeout:,output:,result:,screendump:\
- -- "$@"`;
- eval set -- "$ARGS"
- while [ 1 ] ; do
- case "$1" in
- -h | --help ) usage; exit 0;;
- -v | --version ) $ECHO -e "$VERSION"; exit 0;;
- -b | --builddir ) BUILDDIR="$2"; shift 2;;
- -s | --srcdir ) SRCDIR="$2"; shift 2;;
- -c | --no-graphics ) HAVE_GRAPHICS=0; shift;;
- -V | --verbose ) VERBOSE=1; shift;;
- -d | --desktop ) DESKTOP_COMMAND="$2"; shift 2;;
- -t | --tests ) TESTS="$2"; shift 2;;
- -r | --runner ) TESTING_RUNNER="$2"; shift 2;;
- -T | --timeout ) TIMEOUT="$2"; shift 2;;
- -o | --output ) TEST_LOG="$2"; shift 2;;
- -O | --result ) RESULT_LOG="$2"; shift 2;;
- -S | --screendump ) SCREEN_LOG="$2"; shift 2;;
- -- ) shift; break;;
- * ) usage; exit 1;;
- esac
- done
- DL='$'
- echo "$DESKTOP_COMMAND" | grep "\-with\-dbus$DL" > /dev/null
- HAS_DBUS_SUFFIX=$?
- if [ $HAS_DBUS_SUFFIX -eq 0 ] ; then
- DESKTOP_COMMAND=`echo "$DESKTOP_COMMAND" | sed -e 's/-with-dbus$//'`
- DESKTOP_COMMAND="dbus-launch --exit-with-session $DESKTOP_COMMAND"
- fi
-}
-
-
-init_desktop()
-{
- if [ "$RESULT_LOG" != "" ] ; then
- if [ -f $RESULT_LOG ] ; then
- rm $RESULT_LOG
- fi
- fi
- echo "$TEST_LOG" | grep ':stdout' > /dev/null
- HAS_STDOUT=$?
- if [ $HAS_STDOUT -eq 0 ] ; then
- TEST_LOG=`echo "$TEST_LOG" | sed -e 's|:stdout||'`
- TEST_LOG_STDOUT=1
- fi
- if [ "$TEST_LOG" = "" ] ; then
- print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: a log file is required to get return value with 'read' command"
- exit 255
- elif [ -f $TEST_LOG ] ; then
- rm $TEST_LOG
- fi
- if [ x$FORCE_TEST != x ] ; then
- RUN_ARGS="$RUN_ARGS --force"
- fi
-
- if [ ! -f $HOME/.config/gnome-initial-setup-done ] ; then
- IS_SYSTEM_ACCOUNT=false
- if [ "$USER" = "root" ] ; then
- IS_SYSTEM_ACCOUNT=true
- fi
- if test ! -f /var/lib/AccountsService/users/$USER ; then
- mkdir -p /var/lib/AccountsService/users
- cat >> /var/lib/AccountsService/users/$USER << _EOF
-[User]
-Language=ja_JP.UTF-8
-XSession=gnome
-SystemAccount=$IS_SYSTEM_ACCOUNT
-_EOF
- fi
- mkdir -p $HOME/.config
- touch $HOME/.config/gnome-initial-setup-done
- fi
-
- # Prevent from launching a XDG dialog
- XDG_LOCALE_FILE="$HOME/.config/user-dirs.locale"
- if [ -f $XDG_LOCALE_FILE ] ; then
- XDG_LANG_ORIG=`cat $XDG_LOCALE_FILE`
- XDG_LANG_NEW=`echo $LANG | sed -e 's/\(.*\)\..*/\1/'`
- if [ "$XDG_LANG_ORIG" != "$XDG_LANG_NEW" ] ; then
- echo "# Overriding XDG locale $XDG_LANG_ORIG with $XDG_LANG_NEW"
- echo "$XDG_LANG_NEW" > $XDG_LOCALE_FILE
- fi
- fi
- # `su` command does not run loginctl
- export XDG_SESSION_TYPE='x11'
- export XDG_SESSION_CLASS=user
- # `su` command does not get focus in events without this variable.
- # Need to restart sshd after set "PermitRootLogin yes" in sshd_config
- if [ "x$XDG_RUNTIME_DIR" = x ] ; then
- export XDG_RUNTIME_DIR="/run/user/$UID"
- is_root_login=`grep "^PermitRootLogin" /etc/ssh/sshd_config | grep yes`
- if [ "x$ANSIBLE" != x ] && [ "x$is_root_login" = x ] ; then
- print_log -e "${RED}FAIL${NC}: No permission to get focus-in events in GtkWindow with ansible"
- echo "su command does not configure necessary login info " \
- "with systemd and GtkWindow cannot receive focus-events " \
- "when ibus-desktop-testing-runner is executed by " \
- "ansible-playbook." >> $TEST_LOG
- echo "Enabling root login via sshd, restarting sshd, set " \
- "XDG_RUNTIME_DIR can resolve the problem under " \
- "ansible-playbook." >> $TEST_LOG
- exit 255
- fi
- fi
- # Do we need XDG_SESSION_ID and XDG_SEAT?
- #export XDG_CONFIG_DIRS=/etc/xdg
- #export XDG_SESSION_ID=10
- #export XDG_SESSION_DESKTOP=gnome
- #export XDG_SEAT=seat0
-}
-
-
-run_dbus_daemon()
-{
- # Use dbus-launch --exit-with-session later instead of --sh-syntax
- # GNOME uses a unix:abstract address and it effects gsettings set values
- # in each test case.
- # TODO: Should we comment out this line?
- export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus"
-}
-
-
-init_gnome()
-{
- # gsettings set command needs dconf-service with the same $DISPLAY
- pkill dconf-service
- # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append
- # debug messages to gsettings output and could not get the result correctly.
- backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG"
- unset G_MESSAGES_DEBUG
- # Disable Tour dialog to get focus
- V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version`
- if [ x"$V" = x"''" ] ; then
- gsettings set org.gnome.shell welcome-dialog-last-shown-version '100'
- fi
- # gnome-shell now starts overview mode by login.
- # https://extensions.gnome.org/extension/4099/no-overview/
- NO_SYS_DIR=/usr/share/gnome-shell/extensions/no-overview@fthx
- NO_USER_DIR=$HOME/.local/share/gnome-shell/extensions/no-overview@fthx
- if [ ! -d $NO_SYS_DIR ] && [ ! -d $NO_USER_DIR ] ; then
- mkdir -p "`dirname $NO_USER_DIR`"
- cp -R "no-overview@fthx" "`dirname $NO_USER_DIR`"
- fi
- V=`gsettings get org.gnome.shell disable-user-extensions`
- if [ x"$V" = x"true" ] ; then
- gsettings set org.gnome.shell disable-user-extensions false
- fi
- V=`gsettings get org.gnome.shell enabled-extensions`
- echo "$V" | grep "no-overview" > /dev/null
- V2=$?
- if [ $V2 -ne 0 ] ; then
- V3=`echo "$V" | sed -e 's/@as //' -e 's/\[//' -e 's/\]//'`
- if [ x"$V3" = x"''" ] || [ x"$V3" = x"" ]; then
- V4="['no-overview@fthx']"
- else
- V4="[$V3, 'no-overview@fthx']"
- fi
- gsettings set org.gnome.shell enabled-extensions "$V4"
- fi
- if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then
- export G_MESSAGES_DEBUG="$backup_G_MESSAGES_DEBUG"
- fi
-}
-
-
-run_desktop()
-{
- echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null
- HAS_GNOME=$?
- export DISPLAY=$DISPLAY
- if test $HAVE_GRAPHICS -eq 1 ; then
- /usr/libexec/Xorg.wrap -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . $DISPLAY &
- else
- /usr/bin/Xvfb $DISPLAY -noreset +extension GLX +extension RANDR +extension RENDER -screen 0 1280x1024x24 &
- fi
- PID_XORG=$!
- sleep 1
- # init_gnome need to be called with $DISPLAY before gnome-session is called
- if [ $HAS_GNOME -eq 0 ] ; then
- init_gnome
- fi
- echo "Running $DESKTOP_COMMAND with $USER in `tty`"
- $DESKTOP_COMMAND &
- PID_GNOME_SESSION=$!
- sleep 30
-
- IBUS_ARGS="--verbose --panel disable"
- # gnome-shell 42 checks if org.freedesktop.IBus.session.GNOME.service
- # systemd file is available with org.freedesktop.systemd1.Manager.GetUnit
- # D-Bus method, which is provided by IBus 1.5.26, and if the file
- # is available, gnome-shell no longer launch ibus-daemon
- # because gnome-shell assumes gnome-session would launch ibus-daemon
- # with org.freedesktop.systemd1.Manager.StartUnit D-Bus method.
- # But actually gnome-session failed to launch ibus-daemon
- # because the IBus systemd file depends on gnome-session.target
- # but this CI launches gnome-session directly.
- #
- # So ibus-dameon is now always called here after gnome-shell fails to
- # launch ibus-daemon.
- # It may be better this CI launches GDM autologin to run gnome-session
- # with gnome-session.target systemd file.
- # But `systemctl start gdm` terminates the parent script forcibly
- # and the script cannot get the CI result.
- if test $VERBOSE -eq 1 ; then
- ibus-daemon $IBUS_ARGS &
- else
- ibus-daemon $IBUS_ARGS --daemonize
- fi
- sleep 3
- if test $VERBOSE -eq 1 ; then
- ps -ef | grep ibus
- fi
-}
-
-
-count_case_result()
-{
- retval=$1
- pass=$2
- fail=$3
-
- if test $retval -eq 0 ; then
- pass=`expr $pass + 1`
- else
- fail=`expr $fail + 1`
- fi
- echo $pass $fail
-}
-
-
-echo_case_result()
-{
- retval=$1
- tst=$2
- subtst=${3:-''}
-
- if test $retval -eq 0 ; then
- echo "PASS: $tst $subtst" >>$TEST_LOG
- else
- echo "FAIL: $tst $subtst" >>$TEST_LOG
- fi
-}
-
-
-run_direct_test_cases()
-{
- pass=0
- fail=0
- for tst in $TESTS; do
- ENVS=
- if test -f $SRCDIR/${tst}.env ; then
- ENVS="`cat $SRCDIR/${tst}.env`"
- fi
- if test x"$ENVS" = x ; then
- $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
- retval=$?
- read pass fail << EOF_COUNT
- `count_case_result $retval $pass $fail`
-EOF_COUNT
- echo_case_result $retval $tst
- CACHE_FILES=`ls *.cache`
- if [ x"$CACHE_FILES" != x ] ; then
- echo "# Clean $CACHE_FILES" >>$TEST_LOG
- rm $CACHE_FILES
- fi
- else
- i=1
- # Deleted for var in "$ENVS" because IFS=$'\n' is not supported
- # in POSIX sh
- while read e ; do
- first=`echo "$e" | grep '^#'`
- if test x"$first" = x"#" ; then
- continue
- fi
- echo "# Starting $e $BUILDDIR/$tst $SRCDIR" >>$TEST_LOG
- env $e $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
- retval=$?
- echo "# Finished $e $BUILDDIR/$tst $SRCDIR with $retval" >>$TEST_LOG
- read pass fail << EOF_COUNT
- `count_case_result $retval $pass $fail`
-EOF_COUNT
- echo_case_result $retval $tst $e
- CACHE_FILES=`ls *.cache`
- if [ x"$CACHE_FILES" != x ] ; then
- echo "# Clean $CACHE_FILES" >>$TEST_LOG
- rm $CACHE_FILES
- fi
- i=`expr $i + 1`
- done << EOF_ENVS
- `echo "$ENVS"`
-EOF_ENVS
- fi
- done
- echo $pass $fail
-}
-
-
-run_gnome_desktop_testing_runner()
-{
- pass=0
- fail=0
- if [ x"$TESTS" = x ] ; then
- TESTS='ibus'
- fi
- for tst in $TESTS; do
- tst_dir="@INSTALLEDDIR@/$tst"
- if [ ! -d "$tst_dir" ] ; then
- print_log -e "${RED}FAIL${NC}: Not found %tst_dir"
- fail=1
- continue
- fi
- gnome-desktop-testing-runner --timeout=$TIMEOUT $tst \
- 2>>$TEST_LOG 1>>$TEST_LOG
- retval=$?
- read pass fail << EOF
- `count_case_result $retval $pass $fail`
-EOF
- done
- child_pass=`grep '^PASS:' $TEST_LOG | wc -l`
- child_fail=`grep '^FAIL:' $TEST_LOG | wc -l`
- if [ $child_pass -ne 0 ] || [ $child_fail -ne 0 ] ; then
- pass=$child_pass
- if [ $child_fail -ne 0 ] ; then
- fail=`expr $child_fail / 2`
- else
- fail=0
- fi
- fi
- echo $pass $fail
-}
-
-
-run_test_suite()
-{
- pass=0
- fail=0
- export GTK_IM_MODULE=ibus
- export IBUS_COMPOSE_CACHE_DIR=$PWD
- if [ x"$TESTING_RUNNER" = x ] ; then
- TESTING_RUNNER="default"
- fi
- case $TESTING_RUNNER in
- default)
- # Get only the last value with do-while.
- read pass fail << EOF_RUNNER
- `run_direct_test_cases`
-EOF_RUNNER
- ;;
- gnome)
- read pass fail << EOF_RUNNER
- `run_gnome_desktop_testing_runner`
-EOF_RUNNER
- ;;
- esac
- echo ""
- # Fedora CI assumes the test is failed even if $fail is 0.
- if [ $pass -ne 0 ] ; then
- print_log -e "${GREEN}PASS${NC}: $pass"
- fi
- if [ $fail -ne 0 ] ; then
- print_log -e "${RED}FAIL${NC}: $fail"
- fi
- echo ""
- if [ $TEST_LOG_STDOUT -eq 1 ] ; then
- cat $TEST_LOG
- else
- echo "# See $TEST_LOG"
- fi
-}
-
-
-finit()
-{
- echo "# Killing left gnome-session and Xorg"
- kill $PID_GNOME_SESSION $PID_XORG
- ibus exit
- SUSER=`echo "$USER" | cut -c 1-7`
- LEFT_CALENDAR=`ps -ef | grep gnome-shell-calendar-server | grep $SUSER | grep -v grep`
- if [ x"$LEFT_CALENDAR" != x ] ; then
- echo "# Killing left gnome-shell-calendar-server"
- echo "$LEFT_CALENDAR"
- echo "$LEFT_CALENDAR" | awk '{print $2}' | xargs kill
- fi
-
- echo "# Finished $PROGNAME testing"
-}
-
-
main()
{
parse_args "$@"
- init_desktop
+ init_session
run_dbus_daemon 2>>$TEST_LOG 1>>$TEST_LOG
- run_desktop 2>>$TEST_LOG 1>>$TEST_LOG
- if [ x"$SCREEN_LOG" != x ] ; then
- SCREEN_PNG="`date '+%Y%m%d%H%M%S'`.png"
- gnome-screenshot --file=$SCREEN_PNG
- if [ x"$SCREEN_LOG" = xSTDOUT ] ; then
- base64 $SCREEN_PNG
- else
- base64 $SCREEN_PNG > $SCREEN_LOG
- fi
- fi
+ run_session 2>>$TEST_LOG 1>>$TEST_LOG
+ save_screen
run_test_suite
finit
}
diff --git a/src/tests/ibus-desktop-testing.desktop.in b/src/tests/ibus-desktop-testing.desktop.in
index 1b815345..e91900ed 100644
--- a/src/tests/ibus-desktop-testing.desktop.in
+++ b/src/tests/ibus-desktop-testing.desktop.in
@@ -2,7 +2,7 @@
Name=IBus Desktop Testing Runner
GenericName=Input Method Desktop Testing Runner
Comment=Test plugin for IBus Desktop Testing
-Exec=@libexecdir@/ibus-desktop-testing-autostart /var/tmp/ibus-ci-autostart.log
+Exec=sh -c 'exec @libexecdir@/ibus-desktop-testing-autostart --envcheck --output $HOME/test-autostart.log --result $HOME/test.log --runner gnome --screendump $HOME/screen.log --tests ibus'
Terminal=false
Type=Application
Encoding=UTF-8
--
2.45.0
From 039fcb16f18d341a244362c3e797eeaa5c51010e Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Sat, 27 Jul 2024 19:02:09 +0900
Subject: [PATCH 2/6] Fix tests cases to be run in Wayland
- Fix ibus-bus since ibus_bus_exit_async() does not work ibus-daemon
with systemd and run `ibus restart` instead.
- Fix ibus-compose-locales to wait for 1 sec between key event test cases
to reset gnome-shell/mutter.
- Fix ibus-compose to wait for commit-text event since the gnome-shell/mutter
process is a bit slow and can reset the previous commit-text events
before the previous events are not committed.
- Fix counts in ibus-engine-switch.
- Unref IBusEngineDesc in ibus-engine-switch.
- Fix ibusimpl not to change the engine of the context when global-engine
is enabled.
- Check DISPLAY and setxkbmap in xkb-latin-layouts for Wayland
BUG=https://github.com/ibus/ibus/pull/2657
---
bus/ibusimpl.c | 8 ++
bus/ibusimpl.h | 3 +-
bus/inputcontext.c | 9 +++
src/ibusshare.c | 2 +-
src/tests/ibus-bus.c | 92 +++++++++++++++++++---
src/tests/ibus-compose.c | 139 ++++++++++++++++++++++++---------
src/tests/ibus-engine-switch.c | 45 ++++++++++-
src/tests/xkb-latin-layouts | 9 +++
8 files changed, 254 insertions(+), 53 deletions(-)
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index 445c062b..4bed9bc0 100644
--- a/bus/ibusimpl.c
+++ b/bus/ibusimpl.c
@@ -2463,6 +2463,14 @@ bus_ibus_impl_is_embed_preedit_text (BusIBusImpl *ibus)
return ibus->embed_preedit_text;
}
+gboolean
+bus_ibus_impl_is_use_global_engine (BusIBusImpl *ibus)
+{
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
+
+ return ibus->use_global_engine;
+}
+
BusInputContext *
bus_ibus_impl_get_focused_input_context (BusIBusImpl *ibus)
{
diff --git a/bus/ibusimpl.h b/bus/ibusimpl.h
index e3b43f87..428b773b 100644
--- a/bus/ibusimpl.h
+++ b/bus/ibusimpl.h
@@ -2,7 +2,7 @@
/* vim:set et sts=4: */
/* bus - The Input Bus
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2022-2023 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2022-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
* Copyright (C) 2008-2022 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -94,6 +94,7 @@ BusComponent *bus_ibus_impl_lookup_component_by_name
gboolean bus_ibus_impl_is_use_sys_layout (BusIBusImpl *ibus);
gboolean bus_ibus_impl_is_embed_preedit_text
(BusIBusImpl *ibus);
+gboolean bus_ibus_impl_is_use_global_engine (BusIBusImpl *ibus);
BusInputContext *bus_ibus_impl_get_focused_input_context
(BusIBusImpl *ibus);
GHashTable *bus_ibus_impl_get_engine_focus_id_table
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
index 1e795733..85358241 100644
--- a/bus/inputcontext.c
+++ b/bus/inputcontext.c
@@ -1289,6 +1289,15 @@ _ic_set_engine (BusInputContext *context,
GDBusMethodInvocation *invocation)
{
gchar *engine_name = NULL;
+ BusIBusImpl *ibus = bus_ibus_impl_get_default ();
+
+ if (bus_ibus_impl_is_use_global_engine (ibus)) {
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Cannot set engines when use-global-engine is enabled.");
+ return;
+ }
+
g_variant_get (parameters, "(&s)", &engine_name);
if (!bus_input_context_has_focus (context)) {
diff --git a/src/ibusshare.c b/src/ibusshare.c
index 5ab6e889..57e3ef14 100644
--- a/src/ibusshare.c
+++ b/src/ibusshare.c
@@ -2,7 +2,7 @@
/* vim:set et sts=4: */
/* ibus - The Input Bus
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2015-2023 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2015-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
* Copyright (C) 2008-2018 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
diff --git a/src/tests/ibus-bus.c b/src/tests/ibus-bus.c
index d6b105cf..76120354 100644
--- a/src/tests/ibus-bus.c
+++ b/src/tests/ibus-bus.c
@@ -802,20 +802,29 @@ start_set_preload_engines_async (void)
NULL); /* user_data */
}
+typedef struct _ExitAsyncData {
+ gboolean has_socket_path;
+ gboolean exited;
+ guint timeout_id;
+} ExitAsyncData;
+
static void
_socket_changed_cb (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event_type,
- IBusBus *bus)
+ ExitAsyncData *data)
{
switch (event_type) {
case G_FILE_MONITOR_EVENT_CHANGED:
g_debug ("IBus socket file is changed");
call_next_async_function ();
+ data->exited = TRUE;
g_signal_handlers_disconnect_by_func (monitor,
G_CALLBACK (_socket_changed_cb),
- NULL);
+ data);
+ if (data->timeout_id)
+ g_source_remove (data->timeout_id);
g_object_unref (monitor);
break;
case G_FILE_MONITOR_EVENT_CREATED:
@@ -829,6 +838,33 @@ _socket_changed_cb (GFileMonitor *monitor,
}
}
+static gboolean
+_exit_timeout (gpointer user_data)
+{
+ g_error ("start_exit_async() is timeout. You might run ibus-daemon " \
+ "with systemd under GNOME and the exit API does not work. " \
+ "You need to export IBUS_DAEMON_WITH_SYSTEMD=1 .\n");
+ return G_SOURCE_REMOVE;
+}
+
+static void
+finish_ibus_restart_async (GPid pid,
+ gint status,
+ gpointer *user_data)
+{
+ ExitAsyncData *data = (ExitAsyncData *)user_data;
+ g_spawn_close_pid (pid);
+ if (data->has_socket_path == FALSE) {
+ g_debug ("ibus_bus_exit_finish: OK socket file: none");
+ g_usleep (G_USEC_PER_SEC);
+ call_next_async_function ();
+ } else {
+ g_debug ("ibus_bus_exit_finish: OK socket file: monitored");
+ if (!data->exited)
+ data->timeout_id = g_timeout_add_seconds (10, _exit_timeout, NULL);
+ }
+}
+
static void
finish_exit_async (GObject *source_object,
GAsyncResult *res,
@@ -838,25 +874,32 @@ finish_exit_async (GObject *source_object,
gboolean result = ibus_bus_exit_async_finish (bus,
res,
&error);
- gboolean has_socket_path = GPOINTER_TO_INT (user_data);
+ ExitAsyncData *data = (ExitAsyncData *)user_data;
if (error) {
g_warning ("Failed to ibus_bus_exit(): %s", error->message);
g_error_free (error);
}
g_assert (result);
- if (has_socket_path == FALSE) {
+ g_assert (data);
+ if (data->has_socket_path == FALSE) {
g_debug ("ibus_bus_exit_finish: OK socket file: none");
g_usleep (G_USEC_PER_SEC);
call_next_async_function ();
} else {
g_debug ("ibus_bus_exit_finish: OK socket file: monitored");
+ if (!data->exited)
+ data->timeout_id = g_timeout_add_seconds (10, _exit_timeout, NULL);
}
}
static void
start_exit_async (void)
{
- gboolean has_socket_path = FALSE;
+ static ExitAsyncData data = {
+ .has_socket_path = FALSE,
+ .exited = FALSE,
+ .timeout_id = 0
+ };
/* When `./runtest ibus-bus` runs, ibus-daemon sometimes failed to
* restart because closing a file descriptor was failed in
* bus/server.c:_restart_server() with a following error:
@@ -879,7 +922,7 @@ start_exit_async (void)
g_assert (address_path);
file = g_file_new_for_path (address_path);
g_assert (file);
- has_socket_path = TRUE;
+ data.has_socket_path = TRUE;
monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, &error);
if (error) {
g_warning ("Failed to monitor socket file: %s", error->message);
@@ -887,15 +930,38 @@ start_exit_async (void)
}
g_assert (monitor);
g_signal_connect (monitor, "changed",
- G_CALLBACK (_socket_changed_cb), NULL);
+ G_CALLBACK (_socket_changed_cb),
+ &data);
g_object_unref (file);
}
- ibus_bus_exit_async (bus,
- TRUE, /* restart */
- -1, /* timeout */
- NULL, /* cancellable */
- finish_exit_async,
- GINT_TO_POINTER (has_socket_path)); /* user_data */
+ /* When ibus-daemon runs with systemd, restarting the daemon with
+ * ibus_bus_exit_async() does not work so runs `ibus restart` command
+ * with IBUS_DAEMON_WITH_SYSTEMD variable instead.
+ */
+ if (g_getenv ("IBUS_DAEMON_WITH_SYSTEMD")) {
+ gchar *argv[] = { "ibus", "restart", NULL };
+ GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD \
+ | G_SPAWN_SEARCH_PATH \
+ | G_SPAWN_STDOUT_TO_DEV_NULL \
+ | G_SPAWN_STDERR_TO_DEV_NULL;
+ GPid pid = 0;
+ GError *error = NULL;
+ g_spawn_async (NULL, argv, NULL, flags, NULL, NULL, &pid, &error);
+ if (error) {
+ g_warning ("Failed to call ibus restart: %s", error->message);
+ g_error_free (error);
+ }
+ g_child_watch_add (pid,
+ (GChildWatchFunc)finish_ibus_restart_async,
+ &data);
+ } else {
+ ibus_bus_exit_async (bus,
+ TRUE, /* restart */
+ -1, /* timeout */
+ NULL, /* cancellable */
+ finish_exit_async,
+ &data); /* user_data */
+ }
}
static gboolean
diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
index 21de7a22..660aee7f 100644
--- a/src/tests/ibus-compose.c
+++ b/src/tests/ibus-compose.c
@@ -7,19 +7,28 @@
#define RED "\033[0;31m"
#define NC "\033[0m"
-IBusBus *m_bus;
-gchar *m_compose_file;
-IBusComposeTableEx *m_compose_table;
-IBusEngine *m_engine;
-gchar *m_srcdir;
-
-guint ibus_compose_key_flag (guint key);
-
+static IBusBus *m_bus;
+static gchar *m_compose_file;
+static IBusComposeTableEx *m_compose_table;
+static IBusEngine *m_engine;
+static gchar *m_srcdir;
+static GMainLoop *m_loop;
+
+typedef enum {
+ TEST_CREATE_ENGINE,
+ TEST_COMMIT_TEXT
+} TestIDleCategory;
+
+typedef struct _TestIdleData {
+ TestIDleCategory category;
+ guint idle_id;
+} TestIdleData;
+
+extern guint ibus_compose_key_flag (guint key);
static gboolean window_focus_in_event_cb (GtkWidget *entry,
GdkEventFocus *event,
gpointer data);
-
static gchar *
get_compose_path ()
{
@@ -51,17 +60,50 @@ get_compose_path ()
}
+gboolean
+idle_cb (gpointer user_data)
+{
+ TestIdleData *data = (TestIdleData *)user_data;
+ g_assert (data);
+ switch (data->category) {
+ case TEST_CREATE_ENGINE:
+ g_test_fail_printf ("\"create-engine\" signal is timeout.");
+ break;
+ case TEST_COMMIT_TEXT:
+ if (data->idle_id)
+ g_test_fail_printf ("Commiting composed chars is timeout.");
+ if (m_loop) {
+ if (g_main_loop_is_running (m_loop))
+ g_main_loop_quit (m_loop);
+ g_clear_pointer (&m_loop, g_main_loop_unref);
+ gtk_main_quit ();
+ }
+ data->idle_id = 0;
+ break;
+ default:
+ g_test_fail_printf ("Idle func is called by wrong category:%d.",
+ data->category);
+ break;
+ }
+ return G_SOURCE_REMOVE;
+}
+
+
static IBusEngine *
create_engine_cb (IBusFactory *factory,
const gchar *name,
- gpointer data)
+ gpointer user_data)
{
static int i = 1;
gchar *engine_path =
g_strdup_printf ("/org/freedesktop/IBus/engine/simpletest/%d",
i++);
gchar *compose_path;
+ TestIdleData *data = (TestIdleData *)user_data;
+ g_assert (data);
+ /* Don't reset idle_id to avoid duplicated register_ibus_engine(). */
+ g_source_remove (data->idle_id);
m_engine = ibus_engine_new_with_type (IBUS_TYPE_ENGINE_SIMPLE,
name,
engine_path,
@@ -75,28 +117,33 @@ create_engine_cb (IBusFactory *factory,
ibus_engine_simple_add_compose_file (IBUS_ENGINE_SIMPLE (m_engine),
compose_path);
m_compose_table = ibus_compose_table_load_cache (compose_path);
- if (m_compose_table == NULL)
- g_warning ("Your locale uses en_US compose table.");
}
g_free (compose_path);
return m_engine;
}
+
static gboolean
register_ibus_engine ()
{
+ static TestIdleData data = { .category = TEST_CREATE_ENGINE, .idle_id = 0 };
IBusFactory *factory;
IBusComponent *component;
IBusEngineDesc *desc;
+ if (data.idle_id) {
+ g_test_incomplete ("Test is called twice due to a timeout.");
+ return TRUE;
+ }
m_bus = ibus_bus_new ();
if (!ibus_bus_is_connected (m_bus)) {
- g_critical ("ibus-daemon is not running.");
+ g_test_fail_printf ("ibus-daemon is not running.");
return FALSE;
}
factory = ibus_factory_new (ibus_bus_get_connection (m_bus));
+ data.idle_id = g_timeout_add_seconds (20, idle_cb, &data);
g_signal_connect (factory, "create-engine",
- G_CALLBACK (create_engine_cb), NULL);
+ G_CALLBACK (create_engine_cb), &data);
component = ibus_component_new (
"org.freedesktop.IBus.SimpleTest",
@@ -122,34 +169,29 @@ register_ibus_engine ()
return TRUE;
}
-static gboolean
-finit (gpointer data)
-{
- g_test_incomplete ("time out");
- gtk_main_quit ();
- return FALSE;
-}
static void
-set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
+set_engine_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
{
IBusBus *bus = IBUS_BUS (object);
- GtkWidget *entry = GTK_WIDGET (data);
+ GtkWidget *entry = GTK_WIDGET (user_data);
GError *error = NULL;
+ static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
int i, j;
int index_stride;
IBusComposeTablePrivate *priv;
if (!ibus_bus_set_global_engine_async_finish (bus, res, &error)) {
- gchar *msg = g_strdup_printf ("set engine failed: %s", error->message);
- g_test_incomplete (msg);
- g_free (msg);
+ g_test_fail_printf ("set engine failed: %s", error->message);
g_error_free (error);
return;
}
if (m_compose_table == NULL) {
- gtk_main_quit ();
+ g_test_skip ("Your locale uses en_US compose table.");
+ idle_cb (&data);
return;
}
@@ -157,6 +199,7 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
for (i = 0;
i < (m_compose_table->n_seqs * index_stride);
i += index_stride) {
+ data.idle_id = g_timeout_add_seconds (20, idle_cb, &data);
for (j = i; j < i + (index_stride - 2); j++) {
guint keyval = m_compose_table->data[j];
guint keycode = 0;
@@ -172,12 +215,22 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
g_signal_emit_by_name (m_engine, "process-key-event",
keyval, keycode, modifiers, &retval);
}
+ /* Need to wait for calling window_inserted_text_cb() with
+ * g_main_loop_run() because the commit-text event could be cancelled
+ * by the next commit-text event with gnome-shell in Wayland.
+ */
+ g_main_loop_run (m_loop);
+ if (data.idle_id) {
+ g_source_remove (data.idle_id);
+ data.idle_id = 0;
+ }
}
priv = m_compose_table->priv;
if (priv) {
for (i = 0;
i < (priv->first_n_seqs * index_stride);
i += index_stride) {
+ data.idle_id = g_timeout_add_seconds (20, idle_cb, &data);
for (j = i; j < i + (index_stride - 2); j++) {
guint keyval = priv->data_first[j];
guint keycode = 0;
@@ -193,13 +246,18 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
g_signal_emit_by_name (m_engine, "process-key-event",
keyval, keycode, modifiers, &retval);
}
+ g_main_loop_run (m_loop);
+ if (data.idle_id) {
+ g_source_remove (data.idle_id);
+ data.idle_id = 0;
+ }
}
}
g_signal_handlers_disconnect_by_func (entry,
G_CALLBACK (window_focus_in_event_cb),
NULL);
- g_timeout_add_seconds (10, finit, NULL);
+ data.idle_id = g_timeout_add_seconds (10, idle_cb, &data);
}
static gboolean
@@ -215,12 +273,13 @@ window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
return FALSE;
}
+
static void
window_inserted_text_cb (GtkEntryBuffer *buffer,
guint position,
const gchar *chars,
guint nchars,
- gpointer data)
+ gpointer user_data)
{
/* https://gitlab.gnome.org/GNOME/gtk/commit/9981f46e0b
* The latest GTK does not emit "inserted-text" when the text is "".
@@ -234,8 +293,9 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
int seq;
gunichar code = g_utf8_get_char (chars);
const gchar *test;
- GtkEntry *entry = GTK_ENTRY (data);
+ GtkEntry *entry = GTK_ENTRY (user_data);
IBusComposeTablePrivate *priv;
+ static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
g_assert (m_compose_table != NULL);
@@ -302,21 +362,26 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
stride = 0;
seq = 0;
} else {
- gtk_main_quit ();
+ /* Finish tests */
+ idle_cb (&data);
return;
}
}
if (enable_32bit && seq == priv->first_n_seqs) {
- gtk_main_quit ();
+ /* Finish tests */
+ idle_cb (&data);
return;
}
#if !GTK_CHECK_VERSION (3, 22, 16)
n_loop++;
#endif
+
gtk_entry_set_text (entry, "");
+ g_main_loop_quit (m_loop);
}
+
static void
create_window ()
{
@@ -335,14 +400,13 @@ create_window ()
gtk_widget_show_all (window);
}
+
static void
test_compose (void)
{
GLogLevelFlags flags;
- if (!register_ibus_engine ()) {
- g_test_fail ();
+ if (!register_ibus_engine ())
return;
- }
create_window ();
/* FIXME:
@@ -357,6 +421,7 @@ test_compose (void)
g_log_set_always_fatal (flags);
}
+
int
main (int argc, char *argv[])
{
@@ -380,10 +445,12 @@ main (int argc, char *argv[])
#else
test_name = g_strdup (g_getenv ("LANG"));
#endif
- if (!test_name || !g_ascii_strncasecmp (test_name, "en_US", 5)) {
+ if (m_compose_file &&
+ (!test_name || !g_ascii_strncasecmp (test_name, "en_US", 5))) {
g_free (test_name);
test_name = g_path_get_basename (m_compose_file);
}
+ m_loop = g_main_loop_new (NULL, TRUE);
test_path = g_build_filename ("/ibus-compose", test_name, NULL);
g_test_add_func (test_path, test_compose);
g_free (test_path);
diff --git a/src/tests/ibus-engine-switch.c b/src/tests/ibus-engine-switch.c
index a1eeba2a..b50bac59 100644
--- a/src/tests/ibus-engine-switch.c
+++ b/src/tests/ibus-engine-switch.c
@@ -1,6 +1,7 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
#include <string.h>
+#include <unistd.h>
#include "ibus.h"
static IBusBus *bus;
@@ -47,6 +48,7 @@ change_context_engine (IBusInputContext *context)
g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc),
==,
engine_names[i]);
+ g_object_unref (engine_desc);
}
}
@@ -61,7 +63,7 @@ static void
global_engine_changed_cb (IBusBus *bus, gchar *name, gpointer user_data)
{
GlobalEngineChangedData *data = (GlobalEngineChangedData *) user_data;
- if (data->count++ == 0)
+ if (data->count++ == 1)
ibus_quit ();
}
@@ -84,6 +86,35 @@ change_global_engine_cb (gpointer user_data)
return FALSE;
}
+gboolean
+_wait_for_key_release_cb (gpointer user_data)
+{
+ GMainLoop *loop = (GMainLoop *)user_data;
+ /* If this program is invoked by manual with Enter key in GNOME
+ * Wayland session, ibus_input_context_focus_in() can be called in
+ * test_context_engine_set_by_global() before the key release of
+ * the Enter key so ibus/bus/inputcontext.c:_ic_process_key_event()
+ * could call another bus_input_context_focus_in() in that test case
+ * and fail.
+ */
+ g_test_message ("Wait for 3 seconds for key release event");
+ g_main_loop_quit (loop);
+ return G_SOURCE_REMOVE;
+}
+
+static void
+test_init (void)
+{
+ char *tty_name = ttyname (STDIN_FILENO);
+ GMainLoop *loop = g_main_loop_new (NULL, TRUE);
+ g_test_message ("Test on %s", tty_name ? tty_name : "(null)");
+ if (tty_name && g_strstr_len (tty_name, -1, "pts")) {
+ g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
+ g_main_loop_run (loop);
+ }
+ g_main_loop_unref (loop);
+}
+
static void
test_global_engine (void)
{
@@ -105,6 +136,10 @@ test_global_engine (void)
} else {
data.reverse = FALSE;
}
+ g_test_message ("Initial engine name: %s",
+ desc ? ibus_engine_desc_get_name (desc) : "(null)");
+ if (desc)
+ g_object_unref (desc);
data.count = 0;
@@ -112,7 +147,7 @@ test_global_engine (void)
"global-engine-changed",
G_CALLBACK (global_engine_changed_cb),
&data);
- data.timeout_id = g_timeout_add_seconds (1, timeout_cb, &data);
+ data.timeout_id = g_timeout_add_seconds (3, timeout_cb, &data);
data.idle_id = g_idle_add ((GSourceFunc) change_global_engine_cb, &data);
ibus_main ();
@@ -144,6 +179,7 @@ test_context_engine (void)
change_context_engine (context);
engine_desc = ibus_input_context_get_engine (context);
g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE);
+ g_object_unref (engine_desc);
g_object_unref (context);
}
@@ -171,6 +207,7 @@ test_context_engine_set_by_global (void)
engine_desc = ibus_input_context_get_engine (context);
g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE);
+ g_object_unref (engine_desc);
g_object_unref (context);
}
@@ -199,9 +236,11 @@ test_context_engine_set_by_focus (void)
engine_desc = ibus_input_context_get_engine (context);
g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, "dummy");
+ g_object_unref (engine_desc);
engine_desc = ibus_input_context_get_engine (another_context);
g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE);
+ g_object_unref (engine_desc);
g_object_unref (context);
g_object_unref (another_context);
@@ -220,6 +259,8 @@ main (gint argc,
ibus_bus_set_watch_ibus_signal (bus, TRUE);
+ g_test_add_func ("/ibus/engine-switch/test-init",
+ test_init);
g_test_add_func ("/ibus/engine-switch/global-engine",
test_global_engine);
g_test_add_func ("/ibus/engine-switch/context-engine",
diff --git a/src/tests/xkb-latin-layouts b/src/tests/xkb-latin-layouts
index 92464234..45c99358 100755
--- a/src/tests/xkb-latin-layouts
+++ b/src/tests/xkb-latin-layouts
@@ -120,6 +120,15 @@ EOF_READ_XKB
main()
{
+ if [ x"$DISPLAY" = x ] ; then
+ echo "skip: No display. Maybe headless mode."
+ exit 77
+ fi
+ if ! which setxkbmap > /dev/null ; then
+ echo "skip: No setxkbmap"
+ exit 77
+ fi
+
parse_args "$@"
if [ x"$INSTALLED_SCHEMAS_DIR" != x ] ; then
--
2.45.0
From 44f9a5957e4c53b4a6e6b3f42b56f2d20d58a21c Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Sat, 27 Jul 2024 19:04:39 +0900
Subject: [PATCH 3/6] src/tests: Enable GTK4
Seems GTK3 does not work in GNOME Wayland headless session to get
GdkMonitor in gtk_init() and trying to migrate the test cases to
GTK4.
Calling ibus_init() twice with g_static_resource_init() causes a
memory error and fix it.
BUG=https://github.com/ibus/ibus/pull/2657
---
src/tests/Makefile.am | 8 +--
src/tests/ibus-compose.c | 147 ++++++++++++++++++++++++++++++++------
src/tests/ibus-keypress.c | 146 ++++++++++++++++++++++++++++++-------
3 files changed, 251 insertions(+), 50 deletions(-)
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 6c4c86cf..10acd0a7 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -182,8 +182,8 @@ ibus_bus_SOURCES = ibus-bus.c
ibus_bus_LDADD = $(prog_ldadd)
ibus_compose_SOURCES = ibus-compose.c
-ibus_compose_CFLAGS = @GTK3_CFLAGS@
-ibus_compose_LDADD = $(prog_ldadd) @GTK3_LIBS@
+ibus_compose_CFLAGS = @GTK4_CFLAGS@
+ibus_compose_LDADD = $(prog_ldadd) @GTK4_LIBS@
ibus_config_SOURCES = ibus-config.c
ibus_config_LDADD = $(prog_ldadd)
@@ -207,8 +207,8 @@ ibus_keynames_SOURCES = ibus-keynames.c
ibus_keynames_LDADD = $(prog_ldadd)
ibus_keypress_SOURCES = ibus-keypress.c
-ibus_keypress_CFLAGS = @GTK3_CFLAGS@ @XTEST_CFLAGS@
-ibus_keypress_LDADD = $(prog_ldadd) @GTK3_LIBS@ @XTEST_LIBS@
+ibus_keypress_CFLAGS = @GTK4_CFLAGS@ @XTEST_CFLAGS@
+ibus_keypress_LDADD = $(prog_ldadd) @GTK4_LIBS@ @XTEST_LIBS@
ibus_registry_SOURCES = ibus-registry.c
ibus_registry_LDADD = $(prog_ldadd)
diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
index 660aee7f..57851b0a 100644
--- a/src/tests/ibus-compose.c
+++ b/src/tests/ibus-compose.c
@@ -13,6 +13,9 @@ static IBusComposeTableEx *m_compose_table;
static IBusEngine *m_engine;
static gchar *m_srcdir;
static GMainLoop *m_loop;
+#if GTK_CHECK_VERSION (4, 0, 0)
+static gboolean m_list_toplevel;
+#endif
typedef enum {
TEST_CREATE_ENGINE,
@@ -25,9 +28,16 @@ typedef struct _TestIdleData {
} TestIdleData;
extern guint ibus_compose_key_flag (guint key);
+
+#if GTK_CHECK_VERSION (4, 0, 0)
+static void event_controller_enter_cb (GtkEventController *controller,
+ gpointer user_data);
+#else
static gboolean window_focus_in_event_cb (GtkWidget *entry,
GdkEventFocus *event,
gpointer data);
+#endif
+
static gchar *
get_compose_path ()
@@ -76,7 +86,11 @@ idle_cb (gpointer user_data)
if (g_main_loop_is_running (m_loop))
g_main_loop_quit (m_loop);
g_clear_pointer (&m_loop, g_main_loop_unref);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = FALSE;
+#else
gtk_main_quit ();
+#endif
}
data->idle_id = 0;
break;
@@ -170,13 +184,28 @@ register_ibus_engine ()
}
+static void
+window_destroy_cb (void)
+{
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = FALSE;
+#else
+ gtk_main_quit ();
+#endif
+}
+
+
static void
set_engine_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
IBusBus *bus = IBUS_BUS (object);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ GtkEventController *controller = GTK_EVENT_CONTROLLER (user_data);
+#else
GtkWidget *entry = GTK_WIDGET (user_data);
+#endif
GError *error = NULL;
static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
int i, j;
@@ -254,24 +283,55 @@ set_engine_cb (GObject *object,
}
}
+#if GTK_CHECK_VERSION (4, 0, 0)
+ g_signal_handlers_disconnect_by_func (
+ controller,
+ G_CALLBACK (event_controller_enter_cb),
+ NULL);
+#else
g_signal_handlers_disconnect_by_func (entry,
G_CALLBACK (window_focus_in_event_cb),
NULL);
+#endif
data.idle_id = g_timeout_add_seconds (10, idle_cb, &data);
}
-static gboolean
-window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
+
+static void
+set_engine (gpointer user_data)
{
+ g_test_message ("set_engine() is calling");
g_assert (m_bus != NULL);
ibus_bus_set_global_engine_async (m_bus,
"xkbtest:us::eng",
-1,
NULL,
set_engine_cb,
- entry);
+ user_data);
+}
+
+
+#if GTK_CHECK_VERSION (4, 0, 0)
+static void
+event_controller_enter_cb (GtkEventController *controller,
+ gpointer user_data)
+{
+ g_test_message ("EventController emits \"enter\" signal");
+ set_engine (controller);
+}
+
+#else
+
+static gboolean
+window_focus_in_event_cb (GtkWidget *entry,
+ GdkEventFocus *event,
+ gpointer data)
+{
+ g_test_message ("Entry emits \"focus-in-event\" signal");
+ set_engine (entry);
return FALSE;
}
+#endif
static void
@@ -293,7 +353,9 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
int seq;
gunichar code = g_utf8_get_char (chars);
const gchar *test;
+#if ! GTK_CHECK_VERSION (4, 0, 0)
GtkEntry *entry = GTK_ENTRY (user_data);
+#endif
IBusComposeTablePrivate *priv;
static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
@@ -306,6 +368,10 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
n_loop = 0;
return;
}
+#endif
+#if GTK_CHECK_VERSION (4, 0, 0)
+ if (code == 0)
+ return;
#endif
i = stride + (m_compose_table->max_seq_len + 2) - 2;
seq = (i + 2) / (m_compose_table->max_seq_len + 2);
@@ -318,12 +384,12 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
test = RED "FAIL" NC;
g_test_fail ();
}
- g_print ("%05d/%05d %s expected: %04X typed: %04X\n",
- seq,
- m_compose_table->n_seqs,
- test,
- m_compose_table->data[i],
- code);
+ g_test_message ("%05d/%05d %s expected: %04X typed: %04X",
+ seq,
+ m_compose_table->n_seqs,
+ test,
+ m_compose_table->data[i],
+ code);
} else {
const gchar *p = chars;
guint num = priv->data_first[i];
@@ -344,14 +410,14 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
test = RED "FAIL" NC;
g_test_fail ();
}
- g_print ("%05d/%05ld %s expected: %04X[%d] typed: %04X\n",
- seq,
- priv->first_n_seqs,
- test,
- valid_output ? priv->data_second[index]
- : priv->data_second[index + j],
- valid_output ? index + num : index + j,
- valid_output ? g_utf8_get_char (chars) : code);
+ g_test_message ("%05d/%05ld %s expected: %04X[%d] typed: %04X",
+ seq,
+ priv->first_n_seqs,
+ test,
+ valid_output ? priv->data_second[index]
+ : priv->data_second[index + j],
+ valid_output ? index + num : index + j,
+ valid_output ? g_utf8_get_char (chars) : code);
}
stride += m_compose_table->max_seq_len + 2;
@@ -377,7 +443,11 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
n_loop++;
#endif
+#if GTK_CHECK_VERSION (4, 0, 0)
+ gtk_entry_buffer_set_text (buffer, "", 0);
+#else
gtk_entry_set_text (entry, "");
+#endif
g_main_loop_quit (m_loop);
}
@@ -385,19 +455,43 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
static void
create_window ()
{
- GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- GtkWidget *entry = gtk_entry_new ();
+ GtkWidget *window;
+ GtkWidget *entry;
GtkEntryBuffer *buffer;
+#if GTK_CHECK_VERSION (4, 0, 0)
+ GtkEventController *controller;
+ GtkEditable *text;
+
+ window = gtk_window_new ();
+#else
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+#endif
+ entry = gtk_entry_new ();
g_signal_connect (window, "destroy",
- G_CALLBACK (gtk_main_quit), NULL);
+ G_CALLBACK (window_destroy_cb), NULL);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ controller = gtk_event_controller_focus_new ();
+ text = gtk_editable_get_delegate (GTK_EDITABLE (entry));
+ g_signal_connect (controller, "enter",
+ G_CALLBACK (event_controller_enter_cb), NULL);
+ gtk_widget_add_controller (GTK_WIDGET (text), controller);
+#else
g_signal_connect (entry, "focus-in-event",
G_CALLBACK (window_focus_in_event_cb), NULL);
+#endif
buffer = gtk_entry_get_buffer (GTK_ENTRY (entry));
g_signal_connect (buffer, "inserted-text",
G_CALLBACK (window_inserted_text_cb), entry);
+
+#if GTK_CHECK_VERSION (4, 0, 0)
+ gtk_window_set_child (GTK_WINDOW (window), entry);
+ gtk_window_set_focus (GTK_WINDOW (window), entry);
+ gtk_window_present (GTK_WINDOW (window));
+#else
gtk_container_add (GTK_CONTAINER (window), entry);
gtk_widget_show_all (window);
+#endif
}
@@ -408,6 +502,9 @@ test_compose (void)
if (!register_ibus_engine ())
return;
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = TRUE;
+#endif
create_window ();
/* FIXME:
* IBusIMContext opens GtkIMContextSimple as the slave and
@@ -417,7 +514,13 @@ test_compose (void)
" "GTK+ supports to output one char only: "
*/
flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ gtk_window_list_toplevels ();
+ while (m_list_toplevel)
+ g_main_context_iteration (NULL, TRUE);
+#else
gtk_main ();
+#endif
g_log_set_always_fatal (flags);
}
@@ -435,7 +538,11 @@ main (int argc, char *argv[])
if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE))
g_message ("Failed setenv NO_AT_BRIDGE\n");
g_test_init (&argc, &argv, NULL);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ gtk_init ();
+#else
gtk_init (&argc, &argv);
+#endif
m_srcdir = (argc > 1 && strlen (argv[1]) < FILENAME_MAX)
? g_strdup (argv[1]) : g_strdup (".");
diff --git a/src/tests/ibus-keypress.c b/src/tests/ibus-keypress.c
index d44f39b2..a9288260 100644
--- a/src/tests/ibus-keypress.c
+++ b/src/tests/ibus-keypress.c
@@ -1,12 +1,16 @@
#include <gtk/gtk.h>
+#if GTK_CHECK_VERSION (4, 0, 0)
+#include <gdk/x11/gdkx.h>
+#else
#include <gdk/gdkx.h>
+#endif
#include "ibus.h"
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#ifdef GDK_WINDOWING_WAYLAND
-#if GTK_CHECK_VERSION (3, 98, 4)
+#if GTK_CHECK_VERSION (4, 0, 0)
#include <gdk/wayland/gdkwayland.h>
#else
#include <gdk/gdkwayland.h>
@@ -51,12 +55,18 @@ static const gunichar test_results[][60] = {
};
-IBusBus *m_bus;
-IBusEngine *m_engine;
+static IBusBus *m_bus;
+static IBusEngine *m_engine;
+#if GTK_CHECK_VERSION (4, 0, 0)
+static gboolean m_list_toplevel;
+static gboolean event_controller_enter_cb (GtkEventController *controller,
+ gpointer user_data);
+#else
static gboolean window_focus_in_event_cb (GtkWidget *entry,
GdkEventFocus *event,
gpointer data);
+#endif
static IBusEngine *
create_engine_cb (IBusFactory *factory, const gchar *name, gpointer data)
@@ -118,7 +128,11 @@ static gboolean
finit (gpointer data)
{
g_critical ("time out");
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = FALSE;
+#else
gtk_main_quit ();
+#endif
return FALSE;
}
@@ -173,27 +187,41 @@ send_key_event (Display *xdisplay,
}
}
+static void
+window_destroy_cb (void)
+{
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = FALSE;
+#else
+ gtk_main_quit ();
+#endif
+}
+
static void
set_engine_cb (GObject *object,
GAsyncResult *res,
- gpointer data)
+ gpointer user_data)
{
IBusBus *bus = IBUS_BUS (object);
- GtkWidget *entry = GTK_WIDGET (data);
+#if ! GTK_CHECK_VERSION (4, 0, 0)
+ GtkWidget *entry = GTK_WIDGET (user_data);
+#endif
GdkDisplay *display;
Display *xdisplay = NULL;
GError *error = NULL;
int i, j;
- g_assert (GTK_IS_ENTRY (entry));
-
if (!ibus_bus_set_global_engine_async_finish (bus, res, &error)) {
g_critical ("set engine failed: %s", error->message);
g_error_free (error);
return;
}
+#if GTK_CHECK_VERSION (4, 0, 0)
+ display = gdk_display_get_default ();
+#else
display = gtk_widget_get_display (entry);
+#endif
g_assert (GDK_IS_X11_DISPLAY (display));
xdisplay = gdk_x11_display_get_xdisplay (display);
g_return_if_fail (xdisplay);
@@ -210,8 +238,8 @@ set_engine_cb (GObject *object,
g_timeout_add_seconds (10, finit, NULL);
}
-static gboolean
-window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
+static void
+set_engine (gpointer user_data)
{
g_assert (m_bus != NULL);
ibus_bus_set_global_engine_async (m_bus,
@@ -219,18 +247,40 @@ window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
-1,
NULL,
set_engine_cb,
- entry);
+ user_data);
+}
+
+#if GTK_CHECK_VERSION (4, 0, 0)
+static gboolean
+event_controller_enter_cb (GtkEventController *controller,
+ gpointer user_data)
+{
+ set_engine (controller);
+ return FALSE;
+}
+
+#else
+
+static gboolean
+window_focus_in_event_cb (GtkWidget *entry,
+ GdkEventFocus *event,
+ gpointer user_data)
+{
+ set_engine (entry);
return FALSE;
}
+#endif
static void
window_inserted_text_cb (GtkEntryBuffer *buffer,
guint position,
const gchar *chars,
guint nchars,
- gpointer data)
+ gpointer user_data)
{
- GtkWidget *entry = data;
+#if ! GTK_CHECK_VERSION (4, 0, 0)
+ GtkWidget *entry = user_data;
+#endif
static int i = 0;
static int j = 0;
@@ -242,10 +292,19 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
g_print ("\n");
i++;
j = 0;
- if (test_results[i][0] == 0)
+ if (test_results[i][0] == 0) {
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = FALSE;
+#else
gtk_main_quit ();
- else
+#endif
+ } else {
+#if GTK_CHECK_VERSION (4, 0, 0)
+ gtk_entry_buffer_set_text (buffer, "", 1);
+#else
gtk_entry_set_text (GTK_ENTRY (entry), "");
+#endif
+ }
return;
}
g_assert (g_utf8_get_char (chars) == test_results[i][j]);
@@ -255,19 +314,39 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
static void
create_window ()
{
- GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ GtkWidget *window;
GtkWidget *entry = gtk_entry_new ();
GtkEntryBuffer *buffer;
+#if GTK_CHECK_VERSION (4, 0, 0)
+ GtkEventController *controller;
+
+ window = gtk_window_new ();
+#else
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+#endif
g_signal_connect (window, "destroy",
- G_CALLBACK (gtk_main_quit), NULL);
+ G_CALLBACK (window_destroy_cb), NULL);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ controller = gtk_event_controller_focus_new ();
+ g_signal_connect (controller, "enter",
+ G_CALLBACK (event_controller_enter_cb), NULL);
+ gtk_widget_add_controller (window, controller);
+#else
g_signal_connect (entry, "focus-in-event",
G_CALLBACK (window_focus_in_event_cb), NULL);
+#endif
buffer = gtk_entry_get_buffer (GTK_ENTRY (entry));
g_signal_connect (buffer, "inserted-text",
G_CALLBACK (window_inserted_text_cb), entry);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ gtk_window_set_child (GTK_WINDOW (window), entry);
+ gtk_window_set_focus (GTK_WINDOW (window), entry);
+ gtk_window_present (GTK_WINDOW (window));
+#else
gtk_container_add (GTK_CONTAINER (window), entry);
gtk_widget_show_all (window);
+#endif
}
static void
@@ -277,6 +356,16 @@ test_keypress (void)
int status = 0;
GError *error = NULL;
+#ifdef GDK_WINDOWING_WAYLAND
+ {
+ GdkDisplay *display = gdk_display_get_default ();
+ if (GDK_IS_WAYLAND_DISPLAY (display)) {
+ g_test_skip_printf ("setxkbmap and XTEST do not work in Wayland.");
+ return;
+ }
+ }
+#endif
+
/* localectl does not change the session keymap. */
path = g_find_program_in_path ("setxkbmap");
if (path) {
@@ -287,33 +376,38 @@ test_keypress (void)
g_free (path);
g_assert (register_ibus_engine ());
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = TRUE;
+#endif
create_window ();
+#if GTK_CHECK_VERSION (4, 0, 0)
+ while (m_list_toplevel)
+ g_main_context_iteration (NULL, TRUE);
+#else
gtk_main ();
+#endif
}
int
main (int argc, char *argv[])
{
- ibus_init ();
+ /* ibus_init() should not be called here because
+ * ibus_init() is called from IBus Gtk4 IM module even if
+ * GTK_IM_MODULE=wayland is exported.
+ */
/* Avoid a warning of "AT-SPI: Could not obtain desktop path or name"
* with gtk_main().
*/
if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE))
g_message ("Failed setenv NO_AT_BRIDGE\n");
g_test_init (&argc, &argv, NULL);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ gtk_init ();
+#else
gtk_init (&argc, &argv);
-#ifdef GDK_WINDOWING_WAYLAND
- {
- GdkDisplay *display = gdk_display_get_default ();
- if (GDK_IS_WAYLAND_DISPLAY (display)) {
- g_print ("setxkbmap and XTEST do not work in Wayland.\n");
- return 0;
- }
- }
#endif
g_test_add_func ("/ibus/keyrepss", test_keypress);
-
return g_test_run ();
}
--
2.45.0
From a2689c4d66d1f5ae73d2ddbbb94374c98914a029 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Sat, 27 Jul 2024 19:07:58 +0900
Subject: [PATCH 4/6] src/tests: Fix test cases in GNOME Xorg in ibus-compose
"focus-in" signal is sent to IBus GtkIMModule with a delay in GNOME
desktop session and the signal order is not fixed with GTK_PHASE_TARGET
also "focus-in" signal is also sent with GtkText "realize"' signal.
Now the test cases wait for GtkText 'realize' signal.
This fixes the test cases in GNOME Xorg but there are still sone issues
in GNOME Wayland.
BUG=https://github.com/ibus/ibus/pull/2657
---
src/tests/ibus-compose.c | 71 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 68 insertions(+), 3 deletions(-)
diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
index 57851b0a..e9f102a1 100644
--- a/src/tests/ibus-compose.c
+++ b/src/tests/ibus-compose.c
@@ -39,6 +39,23 @@ static gboolean window_focus_in_event_cb (GtkWidget *entry,
#endif
+gboolean
+_wait_for_key_release_cb (gpointer user_data)
+{
+ GMainLoop *loop = (GMainLoop *)user_data;
+ /* If this program is invoked by manual with Enter key in GNOME
+ * Wayland session, ibus_input_context_focus_in() can be called in
+ * test_context_engine_set_by_global() before the key release of
+ * the Enter key so ibus/bus/inputcontext.c:_ic_process_key_event()
+ * could call another bus_input_context_focus_in() in that test case
+ * and fail.
+ */
+ g_test_message ("Wait for 3 seconds for key release event");
+ g_main_loop_quit (loop);
+ return G_SOURCE_REMOVE;
+}
+
+
static gchar *
get_compose_path ()
{
@@ -312,12 +329,45 @@ set_engine (gpointer user_data)
#if GTK_CHECK_VERSION (4, 0, 0)
+static gboolean
+event_controller_enter_delay (gpointer user_data)
+{
+ GtkEventController *controller = (GtkEventController *)user_data;
+ GtkWidget *text = gtk_event_controller_get_widget (controller);
+ static int i = 0;
+
+ /* Wait for gtk_text_realize() which calls gtk_text_im_set_focus_in()
+ * while gtk_text_focus_changed() also calls gtk_text_im_set_focus_in()
+ * in GNOME Xorg.
+ */
+ if (gtk_widget_get_realized (text)) {
+ set_engine (user_data);
+ return G_SOURCE_REMOVE;
+ }
+ if (i++ == 10) {
+ g_test_fail_printf ("Window is not realized with %d times", i);
+ return G_SOURCE_REMOVE;
+ }
+ g_test_message ("event_controller_enter_delay %d", i);
+ return G_SOURCE_CONTINUE;
+}
+
+
static void
event_controller_enter_cb (GtkEventController *controller,
gpointer user_data)
{
+ static guint id = 0;
+
g_test_message ("EventController emits \"enter\" signal");
- set_engine (controller);
+ /* Call an idle function because gtk_widget_add_controller()
+ * calls g_list_prepend() for event_controllers and this controller is
+ * always called before "gtk-text-focus-controller"
+ * is caleld and the IM context does not receive the focus-in yet.
+ */
+ if (id)
+ return;
+ id = g_idle_add (event_controller_enter_delay, controller);
}
#else
@@ -473,8 +523,9 @@ create_window ()
#if GTK_CHECK_VERSION (4, 0, 0)
controller = gtk_event_controller_focus_new ();
text = gtk_editable_get_delegate (GTK_EDITABLE (entry));
- g_signal_connect (controller, "enter",
- G_CALLBACK (event_controller_enter_cb), NULL);
+ gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
+ g_signal_connect_after (controller, "enter",
+ G_CALLBACK (event_controller_enter_cb), NULL);
gtk_widget_add_controller (GTK_WIDGET (text), controller);
#else
g_signal_connect (entry, "focus-in-event",
@@ -495,6 +546,19 @@ create_window ()
}
+static void
+test_init (void)
+{
+ char *tty_name = ttyname (STDIN_FILENO);
+ GMainLoop *loop = g_main_loop_new (NULL, TRUE);
+ g_test_message ("Test on %s", tty_name ? tty_name : "(null)");
+ if (tty_name && g_strstr_len (tty_name, -1, "pts")) {
+ g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
+ g_main_loop_run (loop);
+ }
+ g_main_loop_unref (loop);
+}
+
static void
test_compose (void)
{
@@ -557,6 +621,7 @@ main (int argc, char *argv[])
g_free (test_name);
test_name = g_path_get_basename (m_compose_file);
}
+ g_test_add_func ("/ibus-compose/test-init", test_init);
m_loop = g_main_loop_new (NULL, TRUE);
test_path = g_build_filename ("/ibus-compose", test_name, NULL);
g_test_add_func (test_path, test_compose);
--
2.45.0
From e65110a9bed03c981884e28ff44e2ac1f639df45 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Sat, 27 Jul 2024 19:09:10 +0900
Subject: [PATCH 5/6] src/tests: Fix ibus-compose for GNOME Wayland
mutter calls meta_wayland_text_input_set_focus() after meta_window_show()
and the delayed focus-in/out events are sent to IBusEngine.
Now sleep() is added in ibus-compose because MetaWaylandInputMethod
cannot know the application status while GTK application is already
realized.
Also GTK4 compose table supports 16bit compose keys only and it
causes a warning with pt-BR and fi-FI compose tables but the warning
is treated as a failure with g_test_init().
Set LANG=en_US.UTF-8 for thw workaround to test pt-BR and fi-FI IBus
compose tables.
BUG=https://github.com/ibus/ibus/pull/2657
---
src/tests/ibus-compose.c | 223 ++++++++++++++++++++++++++++++++++-----
1 file changed, 195 insertions(+), 28 deletions(-)
diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
index e9f102a1..0679c259 100644
--- a/src/tests/ibus-compose.c
+++ b/src/tests/ibus-compose.c
@@ -7,19 +7,24 @@
#define RED "\033[0;31m"
#define NC "\033[0m"
+static gchar *m_test_name;
+static gchar *m_session_name;
static IBusBus *m_bus;
static gchar *m_compose_file;
static IBusComposeTableEx *m_compose_table;
static IBusEngine *m_engine;
static gchar *m_srcdir;
+static gboolean m_is_gtk_32bit_compose_error;
static GMainLoop *m_loop;
+static char *m_engine_is_focused;
#if GTK_CHECK_VERSION (4, 0, 0)
static gboolean m_list_toplevel;
#endif
typedef enum {
+ TEST_COMMIT_TEXT,
TEST_CREATE_ENGINE,
- TEST_COMMIT_TEXT
+ TEST_DELAYED_FOCUS_IN
} TestIDleCategory;
typedef struct _TestIdleData {
@@ -39,6 +44,19 @@ static gboolean window_focus_in_event_cb (GtkWidget *entry,
#endif
+gboolean
+is_integrated_desktop ()
+{
+ if (!m_session_name)
+ m_session_name = g_strdup (g_getenv ("XDG_SESSION_DESKTOP"));
+ if (!m_session_name)
+ return FALSE;
+ if (!g_ascii_strncasecmp (m_session_name, "gnome", strlen ("gnome")))
+ return TRUE;
+ return FALSE;
+}
+
+
gboolean
_wait_for_key_release_cb (gpointer user_data)
{
@@ -63,11 +81,15 @@ get_compose_path ()
const gchar * const *l;
gchar *compose_path = NULL;
+ if (m_is_gtk_32bit_compose_error)
+ g_assert (g_setenv ("LANG", m_test_name, TRUE));
#if GLIB_CHECK_VERSION (2, 58, 0)
langs = g_get_language_names_with_category ("LC_CTYPE");
#else
langs = g_get_language_names ();
#endif
+ if (m_is_gtk_32bit_compose_error)
+ g_assert (g_setenv ("LANG", "en_US.UTF-8", TRUE));
for (l = langs; *l; l++) {
if (g_str_has_prefix (*l, "en_US"))
break;
@@ -91,6 +113,9 @@ gboolean
idle_cb (gpointer user_data)
{
TestIdleData *data = (TestIdleData *)user_data;
+ static int n = 0;
+ gboolean terminate_program = FALSE;
+
g_assert (data);
switch (data->category) {
case TEST_CREATE_ENGINE:
@@ -103,23 +128,75 @@ idle_cb (gpointer user_data)
if (g_main_loop_is_running (m_loop))
g_main_loop_quit (m_loop);
g_clear_pointer (&m_loop, g_main_loop_unref);
-#if GTK_CHECK_VERSION (4, 0, 0)
- m_list_toplevel = FALSE;
-#else
- gtk_main_quit ();
-#endif
+ terminate_program = TRUE;
}
data->idle_id = 0;
break;
+ case TEST_DELAYED_FOCUS_IN:
+ if (m_engine_is_focused) {
+ data->idle_id = 0;
+ n = 0;
+ g_main_loop_quit (m_loop);
+ return G_SOURCE_REMOVE;
+ }
+ if (n++ < 10) {
+ g_test_message ("Waiting for \"focus-in\" signal %dth times", n);
+ return G_SOURCE_CONTINUE;
+ }
+ g_test_fail_printf ("\"focus-in\" signal is timeout.");
+ g_main_loop_quit (m_loop);
+ terminate_program = TRUE;
+ n = 0;
+ break;
default:
g_test_fail_printf ("Idle func is called by wrong category:%d.",
data->category);
break;
}
+ if (terminate_program) {
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = FALSE;
+#else
+ gtk_main_quit ();
+#endif
+ }
return G_SOURCE_REMOVE;
}
+static void
+engine_focus_in_cb (IBusEngine *engine,
+#ifdef IBUS_FOCUS_IN_ID
+ gchar *object_path,
+ gchar *client,
+#endif
+ gpointer user_data)
+{
+#ifdef IBUS_FOCUS_IN_ID
+ g_test_message ("engine_focus_in_cb %s %s", object_path, client);
+ m_engine_is_focused = g_strdup (client);
+#else
+ g_test_message ("engine_focus_in_cb");
+ m_engine_is_focused = g_strdup ("No named");
+#endif
+}
+
+static void
+engine_focus_out_cb (IBusEngine *engine,
+#ifdef IBUS_FOCUS_IN_ID
+ gchar *object_path,
+#endif
+ gpointer user_data)
+{
+#ifdef IBUS_FOCUS_IN_ID
+ g_test_message ("engine_focus_out_cb %s", object_path);
+#else
+ g_test_message ("engine_focus_out_cb");
+#endif
+ g_clear_pointer (&m_engine_is_focused, g_free);
+}
+
+
static IBusEngine *
create_engine_cb (IBusFactory *factory,
const gchar *name,
@@ -135,11 +212,30 @@ create_engine_cb (IBusFactory *factory,
g_assert (data);
/* Don't reset idle_id to avoid duplicated register_ibus_engine(). */
g_source_remove (data->idle_id);
- m_engine = ibus_engine_new_with_type (IBUS_TYPE_ENGINE_SIMPLE,
- name,
- engine_path,
- ibus_bus_get_connection (m_bus));
+ m_engine = (IBusEngine *)g_object_new (
+ IBUS_TYPE_ENGINE_SIMPLE,
+ "engine-name", name,
+ "object-path", engine_path,
+ "connection", ibus_bus_get_connection (m_bus),
+#ifdef IBUS_FOCUS_IN_ID
+ "has-focus-id", TRUE,
+#endif
+ NULL);
g_free (engine_path);
+
+ m_engine_is_focused = NULL;
+#ifdef IBUS_FOCUS_IN_ID
+ g_signal_connect (m_engine, "focus-in-id",
+#else
+ g_signal_connect (m_engine, "focus-in",
+#endif
+ G_CALLBACK (engine_focus_in_cb), NULL);
+#ifdef IBUS_FOCUS_IN_ID
+ g_signal_connect (m_engine, "focus-out-id",
+#else
+ g_signal_connect (m_engine, "focus-out",
+#endif
+ G_CALLBACK (engine_focus_out_cb), NULL);
if (m_compose_file)
compose_path = g_build_filename (m_srcdir, m_compose_file, NULL);
else
@@ -235,6 +331,13 @@ set_engine_cb (GObject *object,
return;
}
+ /* ibus_im_context_focus_in() is called after GlboalEngine is set. */
+ if (is_integrated_desktop () && !m_engine_is_focused) {
+ data.category = TEST_DELAYED_FOCUS_IN;
+ data.idle_id = g_timeout_add_seconds (1, idle_cb, &data);
+ g_main_loop_run (m_loop);
+ if (data.idle_id != 0)
+ return;
if (m_compose_table == NULL) {
g_test_skip ("Your locale uses en_US compose table.");
idle_cb (&data);
@@ -319,6 +422,7 @@ set_engine (gpointer user_data)
{
g_test_message ("set_engine() is calling");
g_assert (m_bus != NULL);
+
ibus_bus_set_global_engine_async (m_bus,
"xkbtest:us::eng",
-1,
@@ -346,6 +450,11 @@ event_controller_enter_delay (gpointer user_data)
}
if (i++ == 10) {
g_test_fail_printf ("Window is not realized with %d times", i);
+#if GTK_CHECK_VERSION (4, 0, 0)
+ m_list_toplevel = FALSE;
+#else
+ gtk_main_quit ();
+#endif
return G_SOURCE_REMOVE;
}
g_test_message ("event_controller_enter_delay %d", i);
@@ -360,16 +469,43 @@ event_controller_enter_cb (GtkEventController *controller,
static guint id = 0;
g_test_message ("EventController emits \"enter\" signal");
- /* Call an idle function because gtk_widget_add_controller()
- * calls g_list_prepend() for event_controllers and this controller is
- * always called before "gtk-text-focus-controller"
- * is caleld and the IM context does not receive the focus-in yet.
- */
if (id)
return;
- id = g_idle_add (event_controller_enter_delay, controller);
+ if (is_integrated_desktop ()) {
+ /* Wait for 3 seconds in GNOME Wayland because there is a long time lag
+ * between the "enter" signal on the event controller in GtkText
+ * and the "FocusIn" D-Bus signal in BusInputContext of ibus-daemon
+ * because mutter/core/window.c:meta_window_show() calls
+ * mutter/core/window.c:meta_window_focus() ->
+ * mutter/wayland/meta-wayland-text-input.c:
+ * meta_wayland_text_input_set_focus() ->
+ * mutter/clutter/clutter/clutter-input-method.c:
+ * clutter_input_method_focus_out()
+ * I.e. "FocusOut" and "FocusIn" D-Bus methods are always delayed
+ * against the window present in GNOME Wayland.
+ * If "FocusOut" and "FocusIn" D-Bus signals would be called after
+ * "SetGlobalEngine" D-BUs signal was called in ibus-daemon,
+ * the following functions could be called:
+ * engine_focus_out_cb() for the "gnome-shell" context
+ * engine_focus_in_cb() for the "fake" context
+ * engine_focus_out_cb() for the "fake" context
+ * engine_focus_in_cb() for the "gnome-shell" context
+ * and ibus_engine_commit_text() would not work.
+ * This assume the focus-in/out signals are called within the timeout
+ * seconds.
+ */
+ id = g_timeout_add_seconds (3,
+ event_controller_enter_delay,
+ controller);
+ } else {
+ /* Call an idle function in Xorg because gtk_widget_add_controller()
+ * calls g_list_prepend() for event_controllers and this controller is
+ * always called before "gtk-text-focus-controller"
+ * is caleld and the IM context does not receive the focus-in yet.
+ */
+ id = g_idle_add (event_controller_enter_delay, controller);
+ }
}
-
#else
static gboolean
@@ -550,10 +686,18 @@ static void
test_init (void)
{
char *tty_name = ttyname (STDIN_FILENO);
- GMainLoop *loop = g_main_loop_new (NULL, TRUE);
+ GMainLoop *loop;
+ static guint idle_id = 0;
+
+ if (idle_id) {
+ g_test_incomplete ("Test is called twice due to a timeout.");
+ return;
+ }
+
+ loop = g_main_loop_new (NULL, TRUE);
g_test_message ("Test on %s", tty_name ? tty_name : "(null)");
if (tty_name && g_strstr_len (tty_name, -1, "pts")) {
- g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
+ idle_id = g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
g_main_loop_run (loop);
}
g_main_loop_unref (loop);
@@ -586,14 +730,16 @@ test_compose (void)
gtk_main ();
#endif
g_log_set_always_fatal (flags);
+ g_clear_pointer (&m_engine_is_focused, g_free);
+ g_clear_pointer (&m_session_name, g_free);
}
int
main (int argc, char *argv[])
{
- gchar *test_name;
gchar *test_path;
+ int retval;
ibus_init ();
/* Avoid a warning of "AT-SPI: Could not obtain desktop path or name"
@@ -612,21 +758,42 @@ main (int argc, char *argv[])
? g_strdup (argv[1]) : g_strdup (".");
m_compose_file = g_strdup (g_getenv ("COMPOSE_FILE"));
#if GLIB_CHECK_VERSION (2, 58, 0)
- test_name = g_strdup (g_get_language_names_with_category ("LC_CTYPE")[0]);
+ m_test_name = g_strdup (g_get_language_names_with_category ("LC_CTYPE")[0]);
#else
- test_name = g_strdup (g_getenv ("LANG"));
+ m_test_name = g_strdup (g_getenv ("LANG"));
#endif
if (m_compose_file &&
- (!test_name || !g_ascii_strncasecmp (test_name, "en_US", 5))) {
- g_free (test_name);
- test_name = g_path_get_basename (m_compose_file);
+ (!m_test_name || !g_ascii_strncasecmp (m_test_name, "en_US", 5))) {
+ g_free (m_test_name);
+ m_test_name = g_path_get_basename (m_compose_file);
+ }
+ /* The parent of GtkIMContextWayland is GtkIMContextSimple and
+ * it outputs a warning of "Can't handle >16bit keyvals" in
+ * gtk/gtkcomposetable.c:parse_compose_sequence() in pt-BR locales
+ * and any warnings are treated as errors with g_test_run()
+ * So export LANG=en_US.UTF-8 for GNOME Wayland as a workaround.
+ */
+ if (m_test_name && (!g_ascii_strncasecmp (m_test_name, "pt_BR", 5) ||
+ !g_ascii_strncasecmp (m_test_name, "fi_FI", 5)
+ )) {
+ m_is_gtk_32bit_compose_error = TRUE;
+ }
+ if (m_is_gtk_32bit_compose_error) {
+#if 1
+ g_assert (g_setenv ("LANG", "en_US.UTF-8", TRUE));
+#else
+ /* FIXME: Use expected_messages in g_log_structured() */
+ g_test_expect_message ("Gtk", G_LOG_LEVEL_WARNING,
+ "Can't handle >16bit keyvals");
+#endif
}
g_test_add_func ("/ibus-compose/test-init", test_init);
m_loop = g_main_loop_new (NULL, TRUE);
- test_path = g_build_filename ("/ibus-compose", test_name, NULL);
+ test_path = g_build_filename ("/ibus-compose", m_test_name, NULL);
g_test_add_func (test_path, test_compose);
g_free (test_path);
- g_free (test_name);
- return g_test_run ();
+ retval = g_test_run ();
+ g_free (m_test_name);
+ return retval;
}
--
2.45.0
From 23785e6c8150aceda7f9665a3335f1e4baecd1cc Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 1 Aug 2024 08:23:09 +0900
Subject: [PATCH 6/6] src/tests: Fix some CI issues with busy TMT virtual session
- Increase waiting time in ibus-compose-locales.
- Wait for 3 secs after set-engine in ibus-compose to wait for the delayed
focus-in/out events.
- delete screendump option in ibus-desktop-testing.desktop not to
support no display.
- setlocale in ibus-engine-switch to get UTF-8 warnings.
- Quote file names as shell syntax as much as possible.
- Check file existent and do not use "rm -f" as much as possible.
- Do not set GTK_IM_MODULE=ibus for Wayland.
- Exclude sshd-session to check existent sessions.
BUG=https://github.com/ibus/ibus/pull/2657
---
src/tests/ibus-compose-locales.in | 4 +-
src/tests/ibus-compose.c | 23 ++++--
src/tests/ibus-desktop-testing-autostart.in | 1 +
src/tests/ibus-desktop-testing-module | 79 ++++++++++++++++-----
src/tests/ibus-desktop-testing.desktop.in | 2 +-
src/tests/ibus-engine-switch.c | 3 +
6 files changed, 85 insertions(+), 27 deletions(-)
diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in
index 7a133ce0..485204c0 100755
--- a/src/tests/ibus-compose-locales.in
+++ b/src/tests/ibus-compose-locales.in
@@ -15,8 +15,8 @@ do
if [ "x$IS_COMMENT" != x ] ; then
continue
fi
- while [ x"$IBUS_DAEMON_WITH_SYSTEMD" != x ] && [ $INITED -lt 6 ] ; do
- echo "Waiting for ${INITED}0 secs till 60 secs"
+ while [ x"$IBUS_DAEMON_WITH_SYSTEMD" != x ] && [ $INITED -lt 12 ] ; do
+ echo "Waiting for ${INITED}0 secs till 120 secs"
sleep 10
INITED=`expr $INITED + 1`
done
diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
index 0679c259..326d3b90 100644
--- a/src/tests/ibus-compose.c
+++ b/src/tests/ibus-compose.c
@@ -331,13 +331,22 @@ set_engine_cb (GObject *object,
return;
}
- /* ibus_im_context_focus_in() is called after GlboalEngine is set. */
- if (is_integrated_desktop () && !m_engine_is_focused) {
- data.category = TEST_DELAYED_FOCUS_IN;
- data.idle_id = g_timeout_add_seconds (1, idle_cb, &data);
- g_main_loop_run (m_loop);
- if (data.idle_id != 0)
- return;
+ /* ibus_im_context_focus_in() is called after GlboalEngine is set.
+ * The focus-in/out events happen more slowly in a busy system
+ * likes with a TMT tool.
+ */
+ if (is_integrated_desktop () && g_getenv ("IBUS_DAEMON_WITH_SYSTEMD")) {
+ g_test_message ("Start tiny \"focus-in\" signal test");
+ for (i = 0; i < 3; i++) {
+ data.category = TEST_DELAYED_FOCUS_IN;
+ data.idle_id = g_timeout_add_seconds (1, idle_cb, &data);
+ g_main_loop_run (m_loop);
+ if (data.idle_id != 0)
+ return;
+ }
+ g_test_message ("End tiny \"focus-in\" signal test");
+ data.category = TEST_COMMIT_TEXT;
+ }
if (m_compose_table == NULL) {
g_test_skip ("Your locale uses en_US compose table.");
idle_cb (&data);
diff --git a/src/tests/ibus-desktop-testing-autostart.in b/src/tests/ibus-desktop-testing-autostart.in
index d50354df..9ecc8c27 100755
--- a/src/tests/ibus-desktop-testing-autostart.in
+++ b/src/tests/ibus-desktop-testing-autostart.in
@@ -73,6 +73,7 @@ main()
parse_args "$@"
init_session
check_env
+ #run_monitor
save_screen
run_test_suite
finit
diff --git a/src/tests/ibus-desktop-testing-module b/src/tests/ibus-desktop-testing-module
index 2d686813..55eb248e 100755
--- a/src/tests/ibus-desktop-testing-module
+++ b/src/tests/ibus-desktop-testing-module
@@ -63,8 +63,9 @@ pwd
pstree -asp $$
gsettings list-recursively org.gnome.shell
rpm -q gnome-shell-extension-no-overview gnome-shell gnome-session
-ps -ef | grep ibus | grep -v grep
+ps -ef | grep ibus | grep -v TMT | grep -v grep
ibus address
+locale
env
#dbus-send --session --print-reply --dest=org.gnome.Shell.Introspect /org/gnome/Shell/Introspect org.gnome.Shell.Introspect.GetWindows
'
@@ -133,7 +134,8 @@ check_tty()
TTY=`tty`
if echo $PROGNAME | grep -q runner ; then
if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
- if echo "$TTY" | grep -E 'tty|console' ; then
+ # "not a tty" is correct with TMT tool
+ if echo "$TTY" | grep -E 'tty|console' | grep -v "not a tty" ; then
print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Changing runlevel does not support console. Please log into the host with ssh."
exit 1
fi
@@ -143,7 +145,7 @@ check_tty()
print_log -e "Running session with ssh. It might be good to use console instead."
fi
fi
- SESSION=`ps -ef | grep session | grep -v grep`
+ SESSION=`ps -ef | grep session | grep -v TMT | grep -v sshd-session | grep -v grep`
if [ x"$SESSION" != x ] ; then
print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Session is running: $SESSION"
exit 1
@@ -254,7 +256,8 @@ create_xdg_autostart()
exit 1
fi
mkdir -p "$TEST_USER_HOME/.config/autostart"
- cp "$desktop_file" "$TEST_USER_HOME/.config/autostart"
+ sed -e "s/\(^Exec=.*\)tests ibus\(.*\)/\1tests $TESTS\2/" "$desktop_file" \
+ > "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
LINE="AutostartCondition=if-exists $TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
echo "$LINE" >> "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
chown -R "$TEST_USER" "$TEST_USER_HOME/.config"
@@ -327,6 +330,9 @@ init_session()
LOGIN_USER=$USER
LOGIN_HOME=$HOME
+ if [ x"$TESTS" = x ] ; then
+ TESTS='ibus'
+ fi
check_tty
if [ $ENABLED_SYSTEMD -eq 1 ] && [ $SESSION_IS_GNOME -eq 1 ] ; then
SESSION_FILE1="/usr/lib/systemd/system/gnome-headless-session@.service"
@@ -482,9 +488,25 @@ init_gnome()
chown -R $LOGIN_USER $TEST_USER_HOME/.local
fi
fi
+
+ ## Use gnome-headless-session for the no-graphics option because currently
+ ## GDM itself cannot run the login screen(greeter) without a display so
+ ## the no-graphics option does not work with GDM and the TMT tool
+ ## while GDM can invoke the headless GNOME Wayland sessions.
+ ##
+ ## Use GNOME_SHELL_WAYLAND_COMMAND for the no-graphics option to add a
+ ## virtual monitor since gnome-headless-session provides a headless mode
+ ## but no monitor and IBus focus-in/out events does not work without
+ ## any monitors.
+ ##
+ ## Use the systemd locale configuration for the no-graphcis mode since
+ ## gnome-headless-session does not pull LANG from AccountsService.
+ ##
if [ $LOGIN_USER != $USER ] ; then
SHELL_SERVICE_FILE="org.gnome.Shell@wayland.service"
SYSTEMD_USER_DIR="$TEST_USER_HOME/.config/systemd/user"
+ ENV_USER_DIR="$TEST_USER_HOME/.config/environment.d"
+ LOCALE_CONF="$ENV_USER_DIR/ibus.conf"
if test $HAVE_GRAPHICS -ne 1 ; then
if test ! -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
mkdir -p "$SYSTEMD_USER_DIR"
@@ -494,12 +516,19 @@ init_gnome()
> $SHELL_SERVICE_FILE
diff $SYSTEMD_SYSTEM_DIR/$SHELL_SERVICE_FILE $SHELL_SERVICE_FILE
popd
- chown -R $LOGIN_USER "$TEST_USER_HOME/.config"
fi
+ mkdir -p "$ENV_USER_DIR"
+ cat > "$LOCALE_CONF" << _EOF_LOCALE_CONF
+LANG=$SESSION_LANG
+_EOF_LOCALE_CONF
+ chown -R $LOGIN_USER "$TEST_USER_HOME/.config"
else
if test -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
rm "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE"
fi
+ if test -f "$LOCALE_CONF" ; then
+ rm "$LOCALE_CONF"
+ fi
fi
fi
GET_DISABLE_USER_EX="gsettings get org.gnome.shell disable-user-extensions"
@@ -556,7 +585,7 @@ operate_desktop_with_systemd()
SESSION=gnome-headless-session
COMMAND="$1"
- #if test $HAVE_GRAPHICS -eq 1 ; then
+ if test $HAVE_GRAPHICS -eq 1 ; then
case "$COMMAND" in
"start") systemctl isolate graphical.target
echo ""
@@ -565,22 +594,24 @@ operate_desktop_with_systemd()
"") print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Wrong command $COMMAND"
exit 1;;
esac
- #else
- # setenforce 0
- # systemctl $COMMAND ${SESSION}@${TEST_USER}
- #fi
+ else
+ setenforce 0
+ systemctl $COMMAND ${SESSION}@${TEST_USER}
+ fi
case "$COMMAND" in
"start") sleep 30;;
"") ;;
esac
- #if test $HAVE_GRAPHICS -eq 1 ; then
+ if test $HAVE_GRAPHICS -eq 1 ; then
systemctl status --no-pager graphical.target
- #else
- # systemctl status --no-pager ${SESSION}@${TEST_USER}
- #fi
+ else
+ systemctl status --no-pager ${SESSION}@${TEST_USER}
+ fi
ps -ef | grep X
ps -ef | grep session
ps -ef | grep ibus
+ SUSER=`echo "$LOGIN_USER" | cut -c 1-7`
+ ps -ef | grep $SUSER
}
@@ -639,6 +670,23 @@ run_session()
}
+run_monitor()
+{
+ if ! which gnome-monitor-config > /dev/null ; then
+ print_log -e "${RED}FAIL${NC}: No gnome-monitor-config"
+ return
+ fi
+ if [ $ENABLED_SYSTEMD -ne 1 ] || [ $SESSION_IS_GNOME -ne 1 ] \
+ || [ $HAVE_GRAPHICS -ne 1 ] ; then
+ return
+ fi
+ /usr/libexec/gnome-screen-cast.py -v 1024 768 &
+ sleep 3
+ gnome-monitor-config list
+ #gnome-monitor-config set -LpM Virtual-1 -t normal -m 1024x768@60.004
+}
+
+
count_case_result()
{
retval=$1
@@ -758,9 +806,6 @@ run_gnome_desktop_testing_runner()
{
pass=0
fail=0
- if [ x"$TESTS" = x ] ; then
- TESTS='ibus'
- fi
if echo $PROGNAME | grep -q autostart ; then
export IBUS_DAEMON_WITH_SYSTEMD=1
fi
diff --git a/src/tests/ibus-desktop-testing.desktop.in b/src/tests/ibus-desktop-testing.desktop.in
index e91900ed..fe9356ad 100644
--- a/src/tests/ibus-desktop-testing.desktop.in
+++ b/src/tests/ibus-desktop-testing.desktop.in
@@ -2,7 +2,7 @@
Name=IBus Desktop Testing Runner
GenericName=Input Method Desktop Testing Runner
Comment=Test plugin for IBus Desktop Testing
-Exec=sh -c 'exec @libexecdir@/ibus-desktop-testing-autostart --envcheck --output $HOME/test-autostart.log --result $HOME/test.log --runner gnome --screendump $HOME/screen.log --tests ibus'
+Exec=sh -c 'exec @libexecdir@/ibus-desktop-testing-autostart --envcheck --output $HOME/test-autostart.log --result $HOME/test.log --runner gnome --tests ibus'
Terminal=false
Type=Application
Encoding=UTF-8
diff --git a/src/tests/ibus-engine-switch.c b/src/tests/ibus-engine-switch.c
index b50bac59..7359e125 100644
--- a/src/tests/ibus-engine-switch.c
+++ b/src/tests/ibus-engine-switch.c
@@ -1,5 +1,6 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+#include <locale.h>
#include <string.h>
#include <unistd.h>
#include "ibus.h"
@@ -251,6 +252,8 @@ main (gint argc,
gchar **argv)
{
gint result;
+ /* To get UTF-8 error messages with glib2 */
+ setlocale (LC_ALL, "");
ibus_init ();
g_test_init (&argc, &argv, NULL);
bus = ibus_bus_new ();
--
2.45.0