JavaScriptユニットテストを実行するにはカルマdockerコンテナ内(ubuntu 14.04ベース)で、コンテナ内でFirefoxを起動しています。カルマ スクリプト ランチャーとしますxvfb-run
。開始スクリプトは次のようになります。
#!/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
ブラウザを起動してユニット テストを実行すると、うまく動作します。テストを実行した後、Karma は生成されたブラウザ インスタンス (私の場合は xvfb-run 経由で Firefox を起動したスクリプト) を終了します。
上記のスクリプトでは、スクリプトの終了時に起動したFirefoxを終了するように登録していることがわかりますtrap
。これは機能しますが、スクリプトは終了するのであまり良い市民ではありません。全てスクリプトによって起動された 1 つのインスタンスを終了するのではなく、現在実行中の Firefox のインスタンスをすべて終了します。最初にプロセスを強制終了しようとしましたxfvb-run
が、このプロセスを強制終了しても、スクリプトによって起動されたサブプロセスには影響しませんxvfb-run
...
Firefox を手動で再起動すると、xvfb-run
多数のプロセスが生成されます:
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#
ここでxvfb-run
プロセス (PID 348) を強制終了すると、このプロセスのみが終了し、他のプロセスは実行されたままになります。代わりに firefox プロセス (PID 361) を強制終了すると、スクリプトはxvfb-run
正常に終了し、他のプロセスも強制終了します。ただし、私のスクリプトからはプロセスの PID しかわかりませんxvfb-run
...
調査中に偶然見つけたこのかなり古いバグレポートxvfb-run
このバグの状態は 2012 年に修正されたにもかかわらず、まだ有効であるようです。
xvfb-run
他のプロセスが正しくクリーンアップされるように、プロセスを終了する丁寧な方法はありますか?
すでに Stack Overflow でこの質問をしましたが、今のところ回答がありません。Stack Overflow では少し OT かもしれませんが、こちらの方が適切でしょうか?
答え1
xvfb-run
機能面のみで使用しているようです--auto-servernum
。
@meuhが指摘したように、その論理は実はかなりシンプル:
# 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
}
この関数を定義すると、次のような呼び出しを試すことができます。代わりにxvfb-run
:
Xvfb :$(find_free_servernum) -screen 0, 1024x768x16 firefox $1 &
THE_PID=$!
# kill Xvfb whenever you feel like it
kill -15 $THE_PID
を削除するとxvfb-run
、 を kill する方法について心配する必要がなくなりますxvfb-run
。
答え2
今日、まさにこの問題に遭遇しました。
全てXサーバーsはその-terminate
議論を支持します。
−終了する
サーバーのリセット時にサーバーが実行を継続せずに終了します。これは、以前の −noreset コマンドライン オプションを上書きします。
xvfb-run
そこで、 's を使用してこれを指定しました-s
。
xvfb-run -d -s '-terminate' firefox --no-remote --profile $PROFILE_DIR $URL
したがって、Karma テスト ランナーの場合、Firefox インスタンスが Karma によって閉じられると、最後の xclient (Firefox) が終了したため、Xvfb サーバーも終了します。Firefox が終了した後も、xvfb-run の実行が完了します。
編集
最終的に、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
答え3
私の解決策は、Docker エントリポイント スクリプトで xvfb を起動することでした。
Xvfb :0 -screen 0 1024x768x24 &
.bashrc
Docker を使用していない場合は、この同じ行を何らかの OS 起動スクリプト (例 ) スクリプトにも配置できます。
次に別のスクリプトで表示をエクスポートし、実際に使用したい関数を呼び出しました
export DISPLAY=:0
firefox $1