読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

Volley のテスト (com.android.volley.toolbox.HttpHeaderParserTest) に失敗する問題と対策

Android アプリ

Android アプリ用のネットワークライブラリ Volley のテストを実行すると、一部環境でテストに失敗することがある問題についてです。

対象とする Volley のバージョン

現時点の master ブランチの最新コミット (コミット faa2a13dce6) を対象としています。

Volley のテストを実行

Volley 公開当初は build.gradle が Volley のプロジェクトには含まれていませんでしたが、最近は build.gradle が Volley のプロジェクトに含まれていて、Gradle によるビルドができるようになっています。 当然、テストの実行も Gradle のタスクとして実行できます。 例えば、Volley をサブプロジェクト :modules:volley としてプロジェクト内に組み込んでいるならば、以下のような感じで Volley のテストを実行できます。 *1

./gradlew --daemon :modules:volley:connectedInstrumentTest

で、実行すると失敗する場合がある

上記のようにテストの実行はできるのですが、環境によっては以下のような感じで com.android.volley.toolbox.HttpHeaderParserTest のテストに失敗する場合があります。 具体的には、端末の言語設定を日本語にしている場合などに失敗するはずです。

com.android.volley.toolbox.HttpHeaderParserTest > testParseCacheHeaders_expiresInPast[small_xxhdpi(AVD) - 4.3] FAILED
        junit.framework.AssertionFailedError
        at com.android.volley.toolbox.HttpHeaderParserTest.assertEqualsWithin(HttpHeaderParserTest.java:161)

com.android.volley.toolbox.HttpHeaderParserTest > testParseCacheHeaders_normalExpire[small_xxhdpi(AVD) - 4.3] FAILED
        junit.framework.AssertionFailedError
        at com.android.volley.toolbox.HttpHeaderParserTest.assertEqualsWithin(HttpHeaderParserTest.java:161)

com.android.volley.toolbox.HttpHeaderParserTest > testParseCacheHeaders_serverRelative[small_xxhdpi(AVD) - 4.3] FAILED
        junit.framework.AssertionFailedError
        at com.android.volley.toolbox.HttpHeaderParserTest.assertEqualsWithin(HttpHeaderParserTest.java:161)

:modules:volley:connectedInstrumentTest  FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':modules:volley:connectedInstrumentTest'.
> There were failing tests. See the report at: file:///.../modules/volley/build/reports/instrumentTests/connected/index.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

原因と対策

テスト用の com.android.volley.toolbox.HttpHeaderParserTest クラスの中に次のようなメソッドがあって、テスト用に RFC 1123 形式の日付文字列を生成するのに使われています。

    private static String rfc1123Date(long millis) {
        DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
        return df.format(new Date(millis));
    }

で、これは en-US なロケールだと期待どおり動くのですが、ja-JP ロケールだと “EEE” の部分が漢字の曜日になってしまって、RFC 1123 形式でなくなってしまい、その結果テストが落ちる、ということのようでした。

     private static String rfc1123Date(long millis) {
-        DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
+        DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
         return df.format(new Date(millis));
     }

なので、上記のような変更を加えることで端末の言語設定によらず US ロケールが使用されるようになって、言語設定が日本語の端末上でも Volley のテストが通るようになります。 Volley のテストが落ちて困ってる方の参考になれば。

ところで

この変更を AOSP に投げたけど全然見られてる気配ないしなんかコミュニケーションする必要あるんでしょうか。 AOSP のドキュメントを見た感じだとパッチ投げたら自動的に処理が進んでレビュアの人が見てくれるっぽい感じだったのですが。

AOSP よくわかりません><

*1:現在の Volley プロジェクト内の build.gradle にはビルド時の依存関係の記述がないので、親プロジェクトの方で記述してやる必要があります。