Para realizar algunas pruebas unitarias de JavaScript conkarmadentro de un contenedor acoplable (basado en ubuntu 14.04) estoy iniciando Firefox en el contenedor usando unlanzador-de-script-karmacon xvfb-run
. El script de inicio se ve así:
#!/bin/bash
set -o errexit
# nasty workaround as xvfb-run doesn't cleanup properly...
trap "pkill -f /usr/lib/firefox/firefox" EXIT
xvfb-run --auto-servernum --server-args='-screen 0, 1024x768x16' firefox $1
Iniciar el navegador y ejecutar las pruebas unitarias funciona muy bien. Después de ejecutar las pruebas, karma finaliza la instancia del navegador generada; en mi caso, el script que inició Firefox a través de xvfb-run.
En el script anterior puede ver que registré un comando trap
para eliminar el Firefox iniciado al salir de mi script. Esto funciona, pero el guión no es muy agradable cuando termina.todoinstancias de Firefox que se están ejecutando actualmente en lugar de simplemente terminar la instancia que inició el script. Primero intenté finalizar el xfvb-run
proceso, pero finalizar este proceso no tiene ningún efecto en el subproceso iniciado por el xvfb-run
script...
Si inicio Firefox xvfb-run
manualmente, se generan un montón de procesos:
root@1d7a5988e521:/data# xvfb-run --auto-servernum --server-args='-screen 0, 1024x768x16' firefox &
[1] 348
root@1d7a5988e521:/data# ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 bash
348 ? S 0:00 /bin/sh /usr/bin/xvfb-run --auto-servernum --server-args=-screen 0, 1024x768x16 firefox
360 ? S 0:00 Xvfb :99 -screen 0, 1024x768x16 -nolisten tcp -auth /tmp/xvfb-run.bgMEuq/Xauthority
361 ? Sl 0:00 /usr/lib/firefox/firefox
378 ? S 0:00 dbus-launch --autolaunch bcf665e095759bae9fc1929b57455cad --binary-syntax --close-stderr
379 ? Ss 0:00 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
388 ? S 0:00 /usr/lib/x86_64-linux-gnu/gconf/gconfd-2
414 ? R+ 0:00 ps ax
root@1d7a5988e521:/data#
Si ahora finalizo el xvfb-run
proceso (PID 348), solo este proceso finalizará, dejando los demás procesos en ejecución. Si en su lugar elimino el proceso de Firefox (PID 361), el xvfb-run
script finaliza correctamente y también elimina los otros procesos. Pero por mi script sólo conozco el PID del xvfb-run
proceso...
Durante mi investigación me topé coneste informe de error bastante antiguolo xvfb-run
cual todavía parece ser válido a pesar de que el estado del error se solucionó en 2012.
¿Existe alguna forma educada de finalizar el xvfb-run
proceso para que los demás procesos se limpien correctamente?
Ya pregunté esto en Stack Overflow, pero no obtuve respuesta hasta ahora. ¿Quizás sea algo OT para Stack Overflow pero esté mejor ubicado aquí?
Respuesta1
Parece que solo lo estás utilizando xvfb-run
por su --auto-servernum
funcionalidad.
Como señaló @meuh: esa lógica esen realidad bastante simple:
# Copyright (C) 2005 The T2 SDE Project
# Copyright (C) XXXX - 2005 Debian
# GNU GPLv2
find_free_servernum() {
# Sadly, the "local" keyword is not POSIX. Leave the next line commented in
# the hope Debian Policy eventually changes to allow it in /bin/sh scripts
# anyway.
#local i
i=$SERVERNUM
while [ -f /tmp/.X$i-lock ]; do
i=$(($i + 1))
done
echo $i
}
Con esa función definida: podrías probar una invocación como estaEn lugar de usarxvfb-run
:
Xvfb :$(find_free_servernum) -screen 0, 1024x768x16 firefox $1 &
THE_PID=$!
# kill Xvfb whenever you feel like it
kill -15 $THE_PID
Con xvfb-run
eliminado: ya no tenemos que preocuparnos por cómo matar xvfb-run
.
Respuesta2
Me he topado con este mismo problema hoy.
Todoservidor xApoyamos el -terminate
argumento.
−terminar
hace que el servidor finalice al reiniciarse, en lugar de continuar ejecutándose. Esto anula una opción de línea de comando anterior −noreset.
Así que terminé especificando esto usando xvfb-run
's -s
:
xvfb-run -d -s '-terminate' firefox --no-remote --profile $PROFILE_DIR $URL
Entonces, en nuestro caso de un ejecutor de pruebas de Karma, una vez que Karma cierra la instancia de Firefox, el servidor Xvfb finaliza cuando finaliza su último xclient (firefox). xvfb-run completó la ejecución después de que Firefox también sale.
Editar
Terminé armando mi propia versión "más simple" del script xvfb-run:
PROFILE=$(mktemp -d)
trap "rm -rf $PROFILE" EXIT
# Start Xvfb and let it find a display number itself.
# Some versions of Xvfb (apparently 1.17.x) refuse to write to stdout
Xvfb -displayfd 4 -terminate -nolisten tcp 4>$PROFILE/.Xdisplay &
# Wait a few seconds for Xvfb to start
sleep ${START_WAIT-2}
${FIREFOX_HOME}/firefox --profile $PROFILE --no-remote --display :$(<$PROFILE/.Xdisplay) "${@?}" &
# Karma appears to send a SIGTERM to the browser when it's done, forward that signal to the Firefox process.
trap "kill -SIGTERM $!" SIGTERM
# Wait for all children to terminate
wait
Respuesta3
Mi solución fue iniciar xvfb en el script de punto de entrada de Docker:
Xvfb :0 -screen 0 1024x768x24 &
Puede poner esta misma línea también en algún tipo de script de inicio del sistema operativo (por ejemplo .bashrc
), si no está utilizando Docker.
Luego, en otro script, exporté la pantalla y llamé a la función real que quería usar.
export DISPLAY=:0
firefox $1