From 39399865eee69c9fa2fcc9d86804c3a46634112e Mon Sep 17 00:00:00 2001 From: Alois Mahdal Date: Wed, 15 Jun 2022 10:10:48 +0200 Subject: [PATCH] Add preexec hook to wait for accessibility On some machines, accessibility framework (normally used to enable accessibility features for GUIs, but in anabot also used to access Anaconda GUI state programatically) may take long to start. This can result in anabot failing to access the accessibility framework and crashing with gi.repository.GLib.GError like this: Traceback (most recent call last): File "/opt/launcher.py", line 6, in sys.exit(anabot.launcher.main(*sys.argv)) File "/opt/anabot/launcher.py", line 148, in main run_test("/var/run/anabot/final-recipe.xml", appname=app_name, children_required=min_children) File "/opt/anabot/runtime/run_test.py", line 27, in run_test import dogtail.tree # pylint: disable=import-error File "/opt/lib/python3.9/site-packages/dogtail/tree.py", line 1338, in children = root.children File "/opt/lib/python3.9/site-packages/dogtail/tree.py", line 236, in children if self.parent and self.parent.roleName == 'hyper link': gi.repository.GLib.GError: atspi_error: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken. (1) This hook is designed to try and connect to the accessibility bus before anabot is started, and keep trying until the connection succeeds or we run out of attempts. See the embedded comment for more details. --- .../hooks/30-wait_for_a11y-preexec.hook | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 profiles/default/hooks/30-wait_for_a11y-preexec.hook diff --git a/profiles/default/hooks/30-wait_for_a11y-preexec.hook b/profiles/default/hooks/30-wait_for_a11y-preexec.hook new file mode 100644 index 00000000..4a74bbda --- /dev/null +++ b/profiles/default/hooks/30-wait_for_a11y-preexec.hook @@ -0,0 +1,72 @@ +#!/bin/bash + +# +# Pre-exec hook to wait for accessibility framework +# +# The hook is based on "probe" that will check that the accessibility +# framework is accessible. +# +# This is to deal with flakiness of the AT-SPI interface that appears on +# machines (reportedly, more on VM's) and can cause a11y (and thus +# dogtail) appear as functional, but then fail when trying to talk to it. +# +# The hook uses an in-line script that will try to enable accessibility +# functions and dump tree of objects as seen by dogtail. If this is +# successful, the hook exits with zero status. +# +# If the check fails, the hook will re-try after 30 seconds. This repeats +# for 40 attempts---if it's not successful, the hook will exit with non-zero +# status. +# + +warn() { + # + # Print lines $@ to stderr + # + local self=${0##*/} + for line in "$@"; do + echo "$self:$line" >&2 + done + +} + +mkpy() { + # + # Print Python code for dogtail probe + # + echo 'import dogtail.utils' + echo 'dogtail.utils.enableA11y()' + echo 'import dogtail.tree' + echo 'dogtail.tree.root.dump()' +} + +verify() { + # + # True if dogtail data is available + # + PYTHONPATH="$PYTHONPATH:/opt/bundled/dogtail" \ + /usr/libexec/platform-python -c "$(mkpy)" \ + || return 3 +} + +main() { + local attempts=40 # max number of attempts + local delay=30 # delay between attempts + local togo # leftover number of attempts + togo=$attempts + while true; do + warn "checking for dogtail data, attempt #$((attempts - togo + 1))" + verify && { + warn "...success!" + return 0 + } + ((togo--)) + test "$togo" -gt 0 || break + warn "sleeping before next attempt: $delay, remaining attempts $togo/$attempts" + sleep "$delay" + done + warn "ran out of attempts, giving up" + exit 1 +} + +main "$@"