環境が絡む不具合はいつも難しい原因があると思ってしまう

復帰後初めての不具合の原因調査は、JUnitを用いたテストについて。あるプロジェクトで、あるテストクラスが、ある環境で、うまく実行できないとのことだった。状況は、次の通り。

  • PC上のEclipseからテストを起動すると、テストが実行され、テストの結果が見られる(テストがうまくいっているように見える)
  • JenkinsからAntを呼び出してテストをすると、テストが実行されないように見える。コンソールの情報を見ても、テストターゲットが開始した情報までしか出力されていない

Eclipse上では動くのだから、このテストクラスと環境の相性が悪い?と、そんな雰囲気。でも、相性って何よ?
この時点では、「何かとてつもない、難解な原因が潜んでいるのでは?Jenkinsの不具合か?OSの不具合か?」と思ってしまう。悪い癖だ。結果、単純な設定ミスだったことが何回あったことか。


ま、まずは簡単なところから、手を動かして、調査対象をしぼっていこうかと。

  • 他のテストクラス(数クラス)を指定して、JenkinsからAntを呼び出してテストをすると、どれもうまくいく

えっ?そうなの?「その(一番実行したい)テストクラス自体に問題がある可能性が高いなぁ」と思いながら。もう少し追い詰めていこうと、色々やってみる。

  • Jenkinsが起動しているサーバで、直接antコマンドを実行すると、Jenkinsのコンソールと同じ情報が得られる

なので、Jenkinsは関係なさそう。やっぱり、テストクラス自体があやしい。

  • antコマンドに、"-vorbose"や"-debug"オプションをつけて実行するも、Javaのクラスをたくさんロードしている以外の情報が得られず
  • AntのJUnitタスクのfork属性をonにして実行すると、テストが途中でクラッシュした旨が得られる(コンソールに、クラッシュ時の情報が表示される)
  • いずれも、戻り値は"0"(おそらく正常を意味している)

エラーになっているっぽいのに、正常終了?
しかし、何の情報も吐いてくれないと、取りつく島もない。ソースコードを見る前に、もう少し手を動かして、範囲を絞っていこう。

  • Jenkinsが起動しているサーバで、直接javaコマンドを実行してJUnitを起動すると、途中までコンソールの情報が表示され、突然終了する
  • クラスパスから、いくつかライブラリを抜いて実行すると、ClassNotFoundExceptionをスローし、きれいに落ちる

ってことは、やっぱりテストクラスの一部のロジックに問題がありそう。ちなみに、javaコマンドを直接たたいてJUnitを実行したのって、もしかしたら初めてかも。って感動している場合ではない。
ここで、「まさか。まさかこれ、このテストクラスで、強引にプログラムを終了させているのでは?」という不安がよぎった(以前にも似たようなことがあった)。ので、何をやっているか全く知らないテストクラスのソースコード(そこそこのボリューム)を、しぶしぶ読み進めていくと、、あった。

    try {
        // 色々な処理
    } catch (Exceprion e) {
        System.exit(0);
    }

エラー情報を握り潰し、正常な振りをして、Javaのプロセスそのものを落とす。凶悪だ。こんなコードは「ダメよ〜、ダメダメ」っていうか、もはや「ラッスン・ゴレライ」。
てか、最初からこのクラスが怪しかったんだから、嫌がらずに、ソースコードを見ておくべきだったでしょう。この調査能力の低さ、これも「ラッスン・ゴレライ」。


結局、この調査に何時間も費やしたが、何のことはない。
PCのEclipse上では、必要なリソースと環境が整っていたからテストが正常に進み、System#exitが実行されなかったから、不具合に気がつかなかったいうわけ。Jenkinsのサーバ上でテストをするには、環境が不十分で(おそらくDBまわりの設定)、エラーロジックに入り、System#exitが実行されていたというわけ。そもそも最初から、PC上とサーバ上では、全く違う動きをしていたのね。何が環境との相性だ。。


AntからJUnitを実行した場合は、これらが同じプロセス上で実行されるっぽいので、System#exitで、Antごと終了していたのだろう。
JUnitタスクのfork属性をonにしたときは、JUnitが、Antとは別プロセスで実行される。ただ、JUnitで用意されている終了の仕方ではなかったので、クラッシュした旨が表示されたのだろう。で、クラッシュ時にパイプをリフレッシュし、それまで保持していた情報を出力してくれたのだろう(情報は、ほとんどなかったけど)。


何にせよ、原因がわかってよかった。ほっとした。