7 NAME
=$
(basename "${0}")
49 # Recent tor client require a Chutney network with tor >= 0.4.4.6 (#18190)
50 MINIMUM_TOR_VERSION
=0.4.4.6
53 echo "Usage: $NAME [OPTION]... [--] [CUCUMBER_ARGS]...
54 Sets up an appropriate environment and invokes cucumber. Note that this script
55 must be run from the Tails source directory root.
57 Options for '@product' features:
58 --allow-non-root Normally the test suite must be run as root, but if you
59 really know what you are doing this option allows any
61 --artifacts-base-uri URI
62 Pretend that the artifact is located at URI when printing
63 its location during a scenario failure. This is useful if
64 you intend to serve the artifacts via the web, for
66 --capture Captures failed scenarios into videos stored in the
67 temporary directory (see --tmpdir below) using x264
68 encoding. Requires x264.
69 --capture-all Keep videos for all scenarios, including those that
70 succeed (implies --capture).
71 --interactive-debugging
72 On failure, pause test suite until pressing Enter. Also
73 offer the option to open an interactive Ruby shell (pry)
74 in the Cucumber world's context.
76 When any image matching fails, enter an interactive mode
77 that allows to update the image. If run from a graphical
78 environment, any found candidate image will be displayed
80 --keep-chutney Don't ever clean Chutney data directory.
81 This can be a big time saver when debugging steps
82 when --keep-snapshots is not an option.
83 --keep-snapshots Don't ever delete any snapshots (including ones marked as
84 temporary). This can be a big time saver when debugging new
85 features. Implies --keep-chutney.
86 --disable-chutney EXPERIMENTAL: All tests will be run using the real Tor
87 network, not a simulated one.
88 Expect this to break many test cases.
89 --late-patch FILE Copies files into the VM before running the test suite.
90 This often can avoid a rebuild.
91 FILE is a text file where each line contains tab-separated
92 source and destination.
93 lines without a tab are ignored.
94 lines with a leading \"#\" are ignored.
95 --early-patch Boots the system with the \"early_patch=umount\" cmdline option.
96 See wiki/src/contribute/build/early-patch.mdwn for details
97 This is useful when you need something to be patched early
98 in the boot process; or if you need to run arbitrary
99 commands, not just copying files
100 --tmpdir Directory where various temporary files are written
101 during a test, e.g. VM snapshots and memory dumps,
102 failure screenshots, pcap files and disk images
103 (default is TMPDIR in the environment, and if unset,
105 --view Shows the test session in a windows. Requires x11vnc
107 --view-interact The test session can be \"touched\". For debugging purposes
109 --vnc-server-only Starts a VNC server for the test session. Requires x11vnc.
110 --iso IMAGE Test '@product' features using IMAGE.
111 --old-iso IMAGE For some '@product' features (e.g. usb_install) we need
112 an older version of Tails, which this options sets to
113 IMAGE. If none is given, it defaults to the same IMAGE
114 given by --iso, which will be good enough for most testing
117 Note that '@source' features has no relevant options.
119 CUCUMBER_ARGS can be used to specify which features to be run, but also any
120 cucumber option, although then you must pass \`--\` first to let this wrapper
121 script know that we're done with *its* options. For debugging purposes, a
122 'debug' formatter has been added so pretty debugging can be enabled with
123 \`--format debug\`. You could even combine the default (pretty) formatter with
124 pretty debugging printed to a file with \`--format pretty --format debug
130 echo "${NAME}: error: ${*}" >&2
134 package_installed
() {
137 if dpkg
-s "${1}" 2>/dev
/null |
grep -q "^Status:.*installed"; then
146 check_dependencies
() {
147 while [ -n "${1:-}" ]; do
148 if ! command -v "${1}" >/dev
/null
&& ! package_installed
"${1}" ; then
149 error
"'${1}' is missing, please install it and run again."
155 check_tor_version
() {
157 tor_version
=$
(tor
--version |
grep -Po '^Tor version \K.*' |
sed --regexp-extended 's,[.]$,,')
158 echo "tor version: $tor_version"
159 if dpkg
--compare-versions "$tor_version" lt
"$MINIMUM_TOR_VERSION"; then
160 error
"Please upgrade to tor ${MINIMUM_TOR_VERSION} or newer."
165 [ -e "/tmp/.X${1#:}-lock" ] ||
[ -e "/tmp/.X11-unix/X${1#:}" ]
168 next_free_display
() {
170 while display_in_use
":${display_nr}"; do
171 display_nr
=$
((display_nr
+1))
173 echo ":${display_nr}"
176 test_suite_cleanup
() {
177 if [ -n "${XVFB_PID:-}" ]; then
178 (kill -0 "${XVFB_PID}" 2>/dev
/null
&& kill "${XVFB_PID}") ||
/bin
/true
184 Xvfb
"$TARGET_DISPLAY" -screen 0 1024x768x24
+32 -noreset >/dev
/null
2>&1 &
186 # Wait for Xvfb to run on TARGET_DISPLAY
187 until display_in_use
"$TARGET_DISPLAY"; do
190 echo "Virtual X framebuffer started on display ${TARGET_DISPLAY}"
191 # Hide the mouse cursor so it won't be in the way when we are
192 # trying to match images.
193 unclutter
-display "$TARGET_DISPLAY" -root -idle 0.1 >/dev
/null
2>&1 &
197 check_dependencies x11vnc
198 VNC_SERVER_PORT
="$(x11vnc -listen localhost -display "${TARGET_DISPLAY}" \
199 -bg -nopw -forever 2>&1 | \
200 grep -m 1 "^PORT
=[0-9]\
+" | sed 's/^PORT=//')"
201 echo "VNC server running on: localhost:${VNC_SERVER_PORT}"
206 if [[ "${VNC_VIEWER_VIEWONLY}" = yes ]]; then
209 check_dependencies tigervnc-viewer
217 "localhost:${VNC_SERVER_PORT}" 1>/dev
/null
2>&1 &
222 # Unset all environment variables used by this script to pass options
223 # to cucumber, except TMPDIR since we explicitly want to support
224 # setting it that way.
230 VNC_VIEWER_VIEWONLY
=yes
232 INTERACTIVE_DEBUGGING
=
240 LONGOPTS
="allow-non-root,artifacts-base-uri:,view,view-interact,vnc-server-only,capture,capture-all,help,tmpdir:,keep-chutney,keep-snapshots,disable-chutney,late-patch:,early-patch,iso:,old-iso:,interactive-debugging,image-bumping-mode"
241 OPTS
=$
(getopt
-o "" --longoptions $LONGOPTS -n "${NAME}" -- "$@")
243 while [ $# -gt 0 ]; do
246 if ! /sbin
/getcap
/usr
/bin
/tcpdump |
grep -q 'cap_net_raw=eip'; then
247 error
"/usr/bin/tcpdump lacks cap_net_raw=eip"
251 --artifacts-base-uri)
253 export ARTIFACTS_BASE_URI
="${1}"
257 VNC_VIEWER_VIEWONLY
=yes
270 check_dependencies x264
274 check_dependencies x264
276 export CAPTURE_ALL
="yes"
278 --interactive-debugging)
279 export INTERACTIVE_DEBUGGING
="yes"
281 --image-bumping-mode)
282 export IMAGE_BUMPING_MODE
="yes"
285 export KEEP_CHUTNEY
="yes"
288 export KEEP_CHUTNEY
="yes"
289 export KEEP_SNAPSHOTS
="yes"
292 export DISABLE_CHUTNEY
="yes"
296 LATE_PATCH
="$(realpath -s "$1")"
297 if ! [[ -f "$LATE_PATCH" ]]; then
298 echo "--late-patch requires a valid FILE as argument"
304 export EARLY_PATCH
="yes"
308 TMPDIR
="$(readlink -f "$1")"
313 TAILS_ISO
="$(realpath -s "$1")"
318 OLD_TAILS_ISO
="$(realpath -s "$1")"
333 trap "test_suite_cleanup" EXIT HUP INT QUIT TERM
335 if [ "${EUID}" -ne 0 ] && [ -z "${ALLOW_NON_ROOT}" ]; then
336 error
"you are not running as root; if you really know what you are" \
337 "doing, see the --allow-non-root option"
340 # shellcheck disable=SC2086
341 check_dependencies
${GENERAL_DEPENDENCIES}
344 TARGET_DISPLAY
=$
(next_free_display
)
348 if [ -n "${VNC_SERVER:-}" ]; then
351 if [ -n "${VNC_VIEWER:-}" ]; then
356 if [ -n "${JENKINS_URL:-}" ]; then
357 . auto
/scripts
/utils.sh
359 if echo "${GIT_BRANCH}" |
grep -q -E '[+-]real-Tor$'; then
360 export DISABLE_CHUTNEY
="yes"
361 TAGS_ARGS
="--tag @supports_real_tor"
362 # The current Git state may not reflect the state at the time the
363 # upstream job was started (e.g. since then we git fetch + git
364 # reset --hard) so we trust the Git state described in Jenkins'
365 # environment variables instead.
366 elif echo "${GIT_BRANCH}" |
grep -q -E '[+-]force-all-tests$' \
368 ||
[ "${GIT_BRANCH#origin/}" = feature
/bullseye
] \
369 ||
[ "${GIT_BRANCH#origin/}" = testing
] \
370 ||
[ "${GIT_BRANCH#origin/}" = devel
] ; then
373 TAGS_ARGS
="${TAGS_ARGS} --tag ~@fragile --tag ~@skip_by_default"
375 if [ "${UPSTREAMJOB_GIT_COMMIT}" != "${UPSTREAMJOB_GIT_BASE_BRANCH_HEAD}" ] && \
376 git_only_doc_changes_since
"${UPSTREAMJOB_GIT_BASE_BRANCH_HEAD}"; then
377 TAGS_ARGS
="${TAGS_ARGS} --tag @doc"
381 export USER_DISPLAY
="${DISPLAY:-}"
382 export DISPLAY
=${TARGET_DISPLAY}
384 # shellcheck disable=SC2086
385 cucumber
--expand ${TAGS_ARGS} "${@}"