ろじかるんるんものがたり

病人が特に何も書かない。無駄だからだ。

Windows 環境での Scala 処理系(scaladoc 等含む)のテストについて

作業しながら、まとまりもなく、適当に書きます。

何故か新年早々 Scala 処理系のテストをしている。

scala/scala · GitHub

パターン周りの型チェックにバグを見つけたので直すかと思ったのだけれど、Windows 環境では HEAD でいくつかのテストがこける。のでテスト周りの事情を調べるというはめになっている。

 

一つ目の問題は、環境による改行コードの差異によるもの。これは git の設定弄って core.autocrlf を false か input にしてね、とのことらしい。clone した後なのでどうしようもない。clone しなおすのもだるい。とりあえずコメントアウトで対処。

 

テストは ant test で走らせるか、test/partest スクリプトで走らせることができる。昔は test/partest.bat もあったようだけれど誰も保守しないものだから消されていた。Typesafe のコミッタ達、誰も windows 環境で開発してないんじゃないかな。一応 bash スクリプトcygwin 用の記述とかあるし、windows 環境では無視するテストのためのディレクトリとかもあるけど…保守されてるかどうかは怪しい。

 

ant test すると当然テスト全部走ってすごい時間がかかる。そのうえ test.interactive ターゲットのテストは、性質上メモリを馬鹿食いするので、うちの貧弱な環境だと ant test 中に確実にメモリが枯渇して死ぬ。ので、test ターゲットが依存しているターゲットを調べて少しずつテストを実行…結局 ant test.interactive は数回に一回しか全部通らない。まあ通ることが分かったのでよし。

そもそも ant test は scala/scalac だけでなく scaladoc とかのテストも入っちゃうので基本的には test.suite ターゲットを指定すると良い。しかし test.suite ターゲットは pos, neg, run, jvm, res, scalap, scalacheck, specialized, instrumented と色々な種類のテストを実行してくれる。もっと細かい粒度でテストしたい。なんなら失敗してるテストだけテストしたい。

 

そこで test/partest スクリプトを使う。これならもっと細かい粒度でテストすることができる。

 

少し脱線。テストに関しては公式のドキュメントにも書いてある。

Running the Test Suite | The Scala Programming Language

…のだが、このページは保守されておらず、完全に古い。--show-log オプションとか、もうないし。他にも contribute 以下のページは色々あるんだけれど、この辺のドキュメントはまともに保守されていないらしい。例えば以下のページも完全に古い。

Scala hacker guide | The Scala Programming Language

で、ページに問題があったら Contribution してくれといっている。

Documentation Contributions | The Scala Programming Language

型チェッカのバグ直したいだけなのに、そこまで一々やってられない。とりあえずドキュメント担当を替えて欲しい。話にならない。

https://github.com/scala/scala#get-in-touch

こんな状態だから、ただでさえ開発リソース不足気味なのに contribution 少ないんじゃないんですかね。愚痴終わり。まあドキュメントへの contribution は…ちょっと勉強会とかで呼びかけてみるかな…

 

test/partest の使い方については、これを開発しているリポジトリがあるので、そこの README を読むのが一番いい(これも README がこのコミットについていけてなかったり普通に死んでるリンクあるの確認してるけど)。それで分からなかったら、まあソースコードを読めばいいでしょう。

scala/scala-partest · GitHub

というわけでいざ、と思って実行したら、エラーメッセージがロケールの関係で日本語で出力されてしまい、正しいエラーメッセージが出力されているかどうか確認する negative テストが失敗する。ant で実行したときには、何故か例外が投げられて失敗していたテストだ。仕方ないなあと思いつつ LANG=C 指定しても化ける。調べたところ JDK の野郎は、この辺の環境変数を無視するらしい。何を考えているんだ。-Duser.language=en とか指定すればいいらしいぞと知り、試したけれど効果なし。

ここで不図、-Dfile.encoding=UTF8 が partest では設定されているが、ant ではどうだろう…と思って partest をちょっと弄ってファイルエンコーディングの設定を削除する。ビンゴ。ant で実行したときのように、テストランナーが例外を投げた。ant 側でも正しくオプションを指定する必要があることが分かった。

 

このあと、コード読んだり色々試したりするのだけれど、partest に verbose オプションがあったのでとりあえずつけて結果を眺めていたら、致命的な勘違いをしていることに気がついた。自分は java コマンドの実行結果とばかり思っていたが、問題のテストはコンパイルが通るかというテストなので javac コマンドの実行結果が重要なのだ。あまりに致命的だけれど、こういうのはよくある…そして毎回時間を吸われる…吸われた…

 

改めてコードを追っかけたところ、java コマンドにはオプションを指定する方法がある(し、そもそも初めから -Duser.language=en は指定されていた)が、javac コマンドにはオプションを指定する方法がないことに気がついた。仕方がないので partest スクリプトで指定される javac コマンドのパスを "@XXX\javac.exe -J-Duser.language=en -J-Duser.country=us %*" みたいなお手製の bat ファイルへのパスに置き換えて無事 PASSED…

さて ant ではどうかな、と思ったら、何故か java から scala のクラスを import するテストが軒並みこける。はて、と思って調べたところ、partest スクリプトjava/javac を見つけるのに JAVA_HOME 環境変数をみるが、ant によるテストは JAVA_HOME 環境変数をみないため、「JAVA_HOME は 1.8 だけど PATH 通ってるのは 1.6 のまま」とかいううちのひどい環境が悪さをしていた。1.8 いれたのは単に scala のビルドが 1.8 必須になっていたからなので(公式の contribute ドキュメントには 1.6 推奨とまだ書いてるけど)PATH まで通していなかったのだ。なんとなくバージョンあげたくなかった。冷静に考えるとそれで動いてる時点で違和感に気づくべきだけど…PATH 通したら当然直った。こうしてモダンな環境がうちにもやってきた。わーいラムダがうちの Java にもやってきたー…

 

partest では解決できた javac のコンパイルエラー問題と ant で対決。色々調べた結果、ant でテストを実行する PartestTask クラスの実装では、javac にオプションを渡せないので無理と判断。諦める。というかもう ant でテスト全部通すの諦めよう…partest スクリプトで通ればいい…scala-internal 見てても、なんかコアな開発者は皆 partest スクリプトをもう長いこと使っているみたいだし…どうでもいい…

 

ということで明日こそは本来の目的だった型推論周りの修正できるんじゃないかな。どうかな。もっと三が日はだらだらと過ごすはずが半日くらい Scala といちゃついてしまった。まあ ant は実行するテストの細かい指定ができないので、テスト結果出るまで待つ時間がかなりの部分を占めていた気がするけど…自分でターゲット足してディレクトリまで絞り込めるようにしても、一つのディレクトリに 1000 以上のテストがあるんだもんなあ。

 

まったくまとまりもなかったが、まとめる気もない備忘録なので唐突に終わる。