Skip to content
This repository was archived by the owner on Jun 30, 2021. It is now read-only.

Commit 4f3e3f6

Browse files
committed
Zalenium: Retry via start-xvfb.sh when the DISPLAY fails
1 parent bc02531 commit 4f3e3f6

File tree

5 files changed

+139
-157
lines changed

5 files changed

+139
-157
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Note image ids also change after scm-source.json has being updated which trigger
1111
+ **Changes:** https://github.com/elgalu/docker-selenium/compare/TBD_PREV_COMM...master (TBD_DATE)
1212
+ Upgrade Ubuntu xenial to 20170517.1
1313
+ Use custom xmanager wallpaper-dosel.png or wallpaper-zalenium.png
14+
+ Zalenium: Retry via start-xvfb.sh when the DISPLAY fails
1415
+ **Image tag details:**
1516
+ Selenium version: TBD_SELENIUM_3_VERSION (TBD_SELENIUM_3_REVISION)
1617
+ Chrome stable: TBD_CHROME_STABLE

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ For pull requests or local commits:
55

66
git checkout -b tmp-`cat VERSION`
77
time (./test/bef && ./test/install && ./test/script_start && ./test/script_end)
8-
docker exec grid versions && ./test/after_script && travis lint
98
open ./images/grid3_console.png && open ./videos/mobile_emulation/*.mp4
9+
docker exec grid versions && ./test/after_script && travis lint
1010
git checkout ./images/grid3_console.png scm-source.json
1111
#git add ... git commit ... git push ... open pull request
1212

1313
For repository owners only:
1414

15-
git commit -m "Upgrade Chromedriver minor from 2.29 to 2.30"
15+
git commit -m "Zalenium: Retry via start-xvfb.sh when the DISPLAY fails"
1616
git tag -d latest; git tag -d `cat VERSION`; git push origin :`cat VERSION`; git tag `cat VERSION` && git push --force origin tmp-`cat VERSION` && git push --tags
1717

1818
-- Wait for Travis to pass OK

bin/entry.sh

Lines changed: 8 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,10 @@ echo "Setting --user-data-dir=/home/seluser/chrome-user-data-dir" > "${LOGS_DIR}
172172
echo "breaks the ability of clients to set Chrome options via the capabilities." >> "${LOGS_DIR}/chrome_browser.log"
173173
echo "Please send us a PR if you know how to set the path for the Firefox browser logs." >> "${LOGS_DIR}/chrome_browser.log"
174174
# When running for Zalenium prepare certain customizations
175-
# if [ "${ZALENIUM}" == "true" ]; then
176-
# export CHROME_ADDITIONAL_ARGS="--user-data-dir=/home/seluser/chrome-user-data-dir"
177-
# fi
175+
if [ "${ZALENIUM}" == "true" ]; then
176+
# Set proper desktop background
177+
sudo mv -f /usr/share/images/fluxbox/wallpaper-zalenium.png /usr/share/images/fluxbox/ubuntu-light.png
178+
fi
178179

179180
# TODO: Remove this duplicated logic
180181
if [ "${SELENIUM_HUB_PORT}" = "0" ]; then
@@ -362,134 +363,9 @@ fix_dirs.sh
362363
# Docker alongside docker
363364
docker_alongside_docker.sh
364365

365-
#----------------------------------------
366-
# Fix autoassigned ports
367-
#----------------------------------------
368366
# Open a new file descriptor that redirects to stdout:
369367
exec 3>&1
370368

371-
function get_free_display() {
372-
local selected_disp_num="-1"
373-
local find_display_num=-1
374-
375-
# Get a list of socket DISPLAYs already used
376-
netstat -nlp 2>/dev/null | grep -Po '(?<=\/tmp\/\.X11-unix\/X)([0-9]+)' | sort -u > /tmp/netstatX11.log
377-
# [ ! -s /tmp/netstatX11.log ] && echo "-- INFO: Emtpy file /tmp/netstatX11.log" 1>&3
378-
379-
# important: while loops are executed in a subshell
380-
# var assignments will be lost unless using <<<
381-
# using 11.0 12.3 1.8 and so on didn't work, left as a reference
382-
# local pythonCmd="from random import shuffle;list1 = list(range($MAX_DISPLAY_SEARCH));shuffle(list1);list2 = [x/10 for x in list1];str_res = ' '.join(str(e) for e in list2);print (str_res)"
383-
local pythonCmd="from random import shuffle;list1 = list(range($MAX_DISPLAY_SEARCH));shuffle(list1);print (' '.join(str(e) for e in list1))"
384-
local displayNums=$(python -c "${pythonCmd}")
385-
# Always find a free DISPLAY port starting with current DISP_N if it was provided
386-
[ "${DISP_N}" != "-1" ] && displayNums="${DISP_N} ${displayNums}"
387-
IFS=' ' read -r -a arrayDispNums <<< "$displayNums"
388-
for find_display_num in ${arrayDispNums[@]}; do
389-
# read -r Do not treat a backslash character in any special way.
390-
# Consider each backslash to be part of the input line.
391-
# -s file is not zero size
392-
if [ -s /tmp/netstatX11.log ]; then
393-
while read read_disp_num ; do
394-
if [ "${read_disp_num}" = "${find_display_num}" ]; then
395-
echo "-- WARN: DISPLAY=:${find_display_num} is taken, searching for another..." 1>&3
396-
selected_disp_num="-1"
397-
break
398-
elif [ "${selected_disp_num}" = "-1" ]; then
399-
selected_disp_num="${find_display_num}"
400-
echo "-- INFO: Possible free DISPLAY=:${find_display_num}" 1>&3
401-
# echo "-- DEBUG: Updated selected_disp_num=$selected_disp_num" 1>&3
402-
# echo "-- DEBUG: WAS read_disp_num=$read_disp_num" 1>&3
403-
fi
404-
done <<< "$(cat /tmp/netstatX11.log)"
405-
else
406-
# echo "-- INFO: Emtpy file /tmp/netstatX11.log" 1>&3
407-
# selected_disp_num="${DEFAULT_DISP_N}"
408-
selected_disp_num="${find_display_num}"
409-
fi
410-
if [ "${selected_disp_num}" != "-1" ]; then
411-
# If we can already use that display it means there is already some
412-
# Xvfb there which means we need to keep looking for a free one.
413-
export DISPLAY=":${find_display_num}"
414-
echo "${DISPLAY}" > DISPLAY
415-
if xsetroot -cursor_name left_ptr -fg white -bg black > /dev/null 2>&1; then
416-
echo "-- WARN: DISPLAY=:${find_display_num} is already being used, skip it..." 1>&3
417-
selected_disp_num="-1"
418-
fi
419-
fi
420-
if [ "${selected_disp_num}" != "-1" ]; then
421-
break
422-
elif [ ${find_display_num} -gt ${MAX_DISPLAY_SEARCH} ]; then
423-
echo "-- ERROR: Entered in an infinite loop at $0 after netstat" 1>&2 1>&3
424-
selected_disp_num="-1"
425-
break
426-
fi
427-
done
428-
[ "${selected_disp_num}" = "-1" ] #|| echo "-- INFO: Found free DISPLAY=:${selected_disp_num}" 1>&3
429-
430-
export DISPLAY=":${selected_disp_num}"
431-
echo "${DISPLAY}" > DISPLAY
432-
echo ${selected_disp_num}
433-
}
434-
435-
function start_xvfb() {
436-
# Start the X server that can run on machines with no real display
437-
# using Xvfb instead of Xdummy
438-
# echo "-- INFO: Will try to start Xvfb at DISPLAY=${DISPLAY}" 1>&3
439-
# if DEBUG = true ...
440-
# echo "Will use the following values for Xvfb"
441-
# echo " screen=${SCREEN_NUM} geometry=${GEOMETRY}"
442-
# echo " XVFB_CLI_OPTS_TCP=${XVFB_CLI_OPTS_TCP}"
443-
# echo " XVFB_CLI_OPTS_BASE=${XVFB_CLI_OPTS_BASE}"
444-
# echo " XVFB_CLI_OPTS_EXT=${XVFB_CLI_OPTS_EXT}"
445-
Xvfb ${DISPLAY} -screen ${SCREEN_NUM} ${GEOMETRY} \
446-
${XVFB_CLI_OPTS_TCP} ${XVFB_CLI_OPTS_BASE} ${XVFB_CLI_OPTS_EXT} \
447-
1> "${LOGS_DIR}/xvfb-tryouts-stdout.log" \
448-
2> "${LOGS_DIR}/xvfb-tryouts-stderr.log" &
449-
}
450-
451-
if [ ! -z "${XE_DISP_NUM}" ]; then
452-
echo "INFO: XE_DISP_NUM '${XE_DISP_NUM}' was provided so switching to that DISPLAY"
453-
echo "INFO: and skipping virtual framebuffer startup in favor of remote."
454-
export DISP_N="${XE_DISP_NUM}"
455-
export DISPLAY=":${DISP_N}"
456-
start_xvfb
457-
# elif [ "${PICK_ALL_RANDOM_PORTS}" = "true" ] || [ "${DISP_N}" = "-1" ]; then
458-
else
459-
# Find a free DISPLAY port starting with current DISP_N if any
460-
i=0
461-
while true ; do
462-
let i=${i}+1
463-
export DISP_N=$(get_free_display)
464-
export DISPLAY=":${DISP_N}"
465-
echo "${DISPLAY}" > DISPLAY
466-
export XEPHYR_DISPLAY=":${DISP_N}"
467-
if ! start_xvfb; then
468-
echo "-- WARN: start_xvfb() failed!" 1>&3
469-
fi
470-
if timeout --foreground "${WAIT_FOREGROUND_RETRY}" wait-xvfb.sh &> "${LOGS_DIR}/wait-xvfb-stdout.log"; then
471-
break
472-
else
473-
echo "-- WARN: wait-xvfb.sh failed! for DISPLAY=${DISPLAY}" 1>&3
474-
fi
475-
if [ ${i} -gt ${MAX_DISPLAY_SEARCH} ]; then
476-
echo "-- ERROR: Failed to start Xvfb at $0 after many retries." 1>&2 1>&3
477-
break
478-
fi
479-
done
480-
# else
481-
# export XEPHYR_DISPLAY=":${DISP_N}"
482-
# export DISPLAY=":${DISP_N}"
483-
# start_xvfb
484-
fi
485-
486-
487-
# Validations
488-
if [ ":$DISP_N" != "${DISPLAY}" ]; then
489-
echo "FATAL: DISP_N '${DISP_N}' doesn't match DISPLAY '${DISPLAY}'" 1>&2
490-
exit 122
491-
fi
492-
493369
#-------------------------------
494370
# Fix small tiny 64mb shm issue
495371
#-------------------------------
@@ -500,6 +376,10 @@ if [ "${SHM_TRY_MOUNT_UNMOUNT}" = "true" ]; then
500376
tmpfs /dev/shm || true
501377
fi
502378

379+
start-xvfb.sh
380+
export DISPLAY="$(cat DISPLAY)"
381+
export DISP_N="$(cat DISP_N)"
382+
503383
#-------------------------------------------
504384
# Keep updated environment vars inside files
505385
#-------------------------------------------

xmanager/bin/start-xmanager.sh

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,29 @@ elif [ "${XMANAGER}" = "fluxbox" ]; then
5151
stat_failed=false
5252
break
5353
else
54-
echo "-- WARN: wait-xmanager.sh failed! for DISPLAY=${DISPLAY}"
54+
echoerr "wait-xmanager.sh failed! for DISPLAY=${DISPLAY} during attempt ${i}"
55+
killall xsetroot || true
5556
killall fluxbox || true
57+
if [ ${i} -gt 3 ]; then
58+
echoerr "wait-xmanager.sh already failed ${i} times for DISPLAY=${DISPLAY}. Will kill Xvfb and find a new DISPLAY"
59+
killall Xvfb || true
60+
start-xvfb.sh
61+
export DISPLAY="$(cat DISPLAY)"
62+
export DISP_N="$(cat DISP_N)"
63+
fi
5664
fi
5765
if [ ${i} -gt ${FLUXBOX_START_MAX_RETRIES} ]; then
5866
echoerr "-- ERROR: Failed to start Fluxbox at $0 after many retries."
5967
break
6068
fi
69+
sleep 0.2
6170
done
62-
[ "${stat_failed}" != "true" ] && wait
63-
stat_failed=true
71+
if [ "${stat_failed}" != "true" ]; then
72+
wait
73+
else
74+
stat_failed=true
75+
fi
76+
sleep 0.2
6477
done
6578
else
6679
die "The chosen X manager is not supported: '${XMANAGER}'"

xvfb/bin/start-xvfb.sh

Lines changed: 112 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,127 @@
11
#!/usr/bin/env bash
22

3-
# DISABLED! since we always need Xvfb this file will be deprecated
4-
53
# set -e: exit asap if a command exits with a non-zero status
64
set -e
75

8-
if [ -f /tmp/xvfb.pid ]; then
9-
kill $(cat /tmp/xvfb.pid)
10-
rm -f /tmp/xvfb.pid
11-
fi
6+
# Open a new file descriptor that redirects to stdout:
7+
exec 3>&1
8+
9+
function get_free_display() {
10+
local selected_disp_num="-1"
11+
local find_display_num=-1
12+
13+
# Get a list of socket DISPLAYs already used
14+
netstat -nlp 2>/dev/null | grep -Po '(?<=\/tmp\/\.X11-unix\/X)([0-9]+)' | sort -u > /tmp/netstatX11.log
15+
# [ ! -s /tmp/netstatX11.log ] && echo "-- INFO: Emtpy file /tmp/netstatX11.log" 1>&3
16+
17+
# important: while loops are executed in a subshell
18+
# var assignments will be lost unless using <<<
19+
# using 11.0 12.3 1.8 and so on didn't work, left as a reference
20+
# local pythonCmd="from random import shuffle;list1 = list(range($MAX_DISPLAY_SEARCH));shuffle(list1);list2 = [x/10 for x in list1];str_res = ' '.join(str(e) for e in list2);print (str_res)"
21+
local pythonCmd="from random import shuffle;list1 = list(range($MAX_DISPLAY_SEARCH));shuffle(list1);print (' '.join(str(e) for e in list1))"
22+
local displayNums=$(python -c "${pythonCmd}")
23+
# Always find a free DISPLAY port starting with current DISP_N if it was provided
24+
[ "${DISP_N}" != "-1" ] && displayNums="${DISP_N} ${displayNums}"
25+
IFS=' ' read -r -a arrayDispNums <<< "$displayNums"
26+
for find_display_num in ${arrayDispNums[@]}; do
27+
# read -r Do not treat a backslash character in any special way.
28+
# Consider each backslash to be part of the input line.
29+
# -s file is not zero size
30+
if [ -s /tmp/netstatX11.log ]; then
31+
while read read_disp_num ; do
32+
if [ "${read_disp_num}" = "${find_display_num}" ]; then
33+
echo "-- WARN: DISPLAY=:${find_display_num} is taken, searching for another..." 1>&3
34+
selected_disp_num="-1"
35+
break
36+
elif [ "${selected_disp_num}" = "-1" ]; then
37+
selected_disp_num="${find_display_num}"
38+
echo "-- INFO: Possible free DISPLAY=:${find_display_num}" 1>&3
39+
# echo "-- DEBUG: Updated selected_disp_num=$selected_disp_num" 1>&3
40+
# echo "-- DEBUG: WAS read_disp_num=$read_disp_num" 1>&3
41+
fi
42+
done <<< "$(cat /tmp/netstatX11.log)"
43+
else
44+
# echo "-- INFO: Emtpy file /tmp/netstatX11.log" 1>&3
45+
# selected_disp_num="${DEFAULT_DISP_N}"
46+
selected_disp_num="${find_display_num}"
47+
fi
48+
if [ "${selected_disp_num}" != "-1" ]; then
49+
# If we can already use that display it means there is already some
50+
# Xvfb there which means we need to keep looking for a free one.
51+
export DISPLAY=":${find_display_num}"
52+
echo "${DISPLAY}" > DISPLAY
53+
echo "${DISP_N}" > DISP_N
54+
if xsetroot -cursor_name left_ptr -fg white -bg black > /dev/null 2>&1; then
55+
echo "-- WARN: DISPLAY=:${find_display_num} is already being used, skip it..." 1>&3
56+
selected_disp_num="-1"
57+
fi
58+
fi
59+
if [ "${selected_disp_num}" != "-1" ]; then
60+
break
61+
elif [ ${find_display_num} -gt ${MAX_DISPLAY_SEARCH} ]; then
62+
echo "-- ERROR: Entered in an infinite loop at $0 after netstat" 1>&2 1>&3
63+
selected_disp_num="-1"
64+
break
65+
fi
66+
done
67+
[ "${selected_disp_num}" = "-1" ] #|| echo "-- INFO: Found free DISPLAY=:${selected_disp_num}" 1>&3
68+
69+
export DISPLAY=":${selected_disp_num}"
70+
echo "${DISPLAY}" > DISPLAY
71+
echo "${DISP_N}" > DISP_N
72+
echo ${selected_disp_num}
73+
}
74+
75+
function start_xvfb() {
76+
# Start the X server that can run on machines with no real display
77+
# using Xvfb instead of Xdummy
78+
# echo "-- INFO: Will try to start Xvfb at DISPLAY=${DISPLAY}" 1>&3
79+
# if DEBUG = true ...
80+
# echo "Will use the following values for Xvfb"
81+
# echo " screen=${SCREEN_NUM} geometry=${GEOMETRY}"
82+
# echo " XVFB_CLI_OPTS_TCP=${XVFB_CLI_OPTS_TCP}"
83+
# echo " XVFB_CLI_OPTS_BASE=${XVFB_CLI_OPTS_BASE}"
84+
# echo " XVFB_CLI_OPTS_EXT=${XVFB_CLI_OPTS_EXT}"
85+
Xvfb ${DISPLAY} -screen ${SCREEN_NUM} ${GEOMETRY} \
86+
${XVFB_CLI_OPTS_TCP} ${XVFB_CLI_OPTS_BASE} ${XVFB_CLI_OPTS_EXT} \
87+
1> "${LOGS_DIR}/xvfb-tryouts-stdout.log" \
88+
2> "${LOGS_DIR}/xvfb-tryouts-stderr.log" &
89+
}
1290

1391
if [ ! -z "${XE_DISP_NUM}" ]; then
1492
echo "INFO: XE_DISP_NUM '${XE_DISP_NUM}' was provided so switching to that DISPLAY"
1593
echo "INFO: and skipping virtual framebuffer startup in favor of remote."
1694
export DISP_N="${XE_DISP_NUM}"
1795
export DISPLAY=":${DISP_N}"
96+
start_xvfb
97+
# elif [ "${PICK_ALL_RANDOM_PORTS}" = "true" ] || [ "${DISP_N}" = "-1" ]; then
1898
else
19-
if [ ":$DISP_N" != "${DISPLAY}" ]; then
20-
echo "WARN: DISP_N '${DISP_N}' doesn't match DISPLAY '${DISPLAY}'"
99+
# Find a free DISPLAY port starting with current DISP_N if any
100+
i=0
101+
while true ; do
102+
let i=${i}+1
103+
export DISP_N=$(get_free_display)
21104
export DISPLAY=":${DISP_N}"
22-
echo "WARN: so fixing it; new DISPLAY is '${DISPLAY}'"
23-
fi
24-
25-
# Start the X server that can run on machines with no real display
26-
# using Xvfb instead of Xdummy
27-
echo "Will start Xvfb with DISPLAY=${DISPLAY}"
28-
echo "Will start Xvfb with screen=${SCREEN_NUM} geometry=${GEOMETRY}"
29-
echo "Will start Xvfb with XVFB_CLI_OPTS_TCP=${XVFB_CLI_OPTS_TCP}"
30-
echo "Will start Xvfb with XVFB_CLI_OPTS_BASE=${XVFB_CLI_OPTS_BASE}"
31-
echo "Will start Xvfb with XVFB_CLI_OPTS_EXT=${XVFB_CLI_OPTS_EXT}"
32-
Xvfb ${DISPLAY} -screen ${SCREEN_NUM} ${GEOMETRY} \
33-
${XVFB_CLI_OPTS_TCP} ${XVFB_CLI_OPTS_BASE} ${XVFB_CLI_OPTS_EXT}
105+
echo "${DISPLAY}" > DISPLAY
106+
echo "${DISP_N}" > DISP_N
107+
export XEPHYR_DISPLAY=":${DISP_N}"
108+
if ! start_xvfb; then
109+
echo "-- WARN: start_xvfb() failed!" 1>&3
110+
fi
111+
if timeout --foreground "${WAIT_FOREGROUND_RETRY}" wait-xvfb.sh &> "${LOGS_DIR}/wait-xvfb-stdout.log"; then
112+
break
113+
else
114+
echo "-- WARN: wait-xvfb.sh failed! for DISPLAY=${DISPLAY}" 1>&3
115+
fi
116+
if [ ${i} -gt ${MAX_DISPLAY_SEARCH} ]; then
117+
echo "-- ERROR: Failed to start Xvfb at $0 after many retries." 1>&2 1>&3
118+
break
119+
fi
120+
done
34121
fi
35122

36-
# Note to double pipe output and keep this process logs add at the end:
37-
# 2>&1 | tee $XVFB_LOG
38-
# But is no longer required because individual logs are maintained by
39-
# supervisord right now.
123+
# Validations
124+
if [ ":$DISP_N" != "${DISPLAY}" ]; then
125+
echo "FATAL: DISP_N '${DISP_N}' doesn't match DISPLAY '${DISPLAY}'" 1>&2
126+
exit 122
127+
fi

0 commit comments

Comments
 (0)