Gradle 1.10

Gradle 1.10がリリースされた. GCCVisual Studioに対するサポートが強化されている感じ. 気になるところでは、テスト実行について、コマンドラインで指定したテストだけを実行するオプション (test タスクの --tests) がついた. 今までは -Dtest.singleton.option というものがあったらしい. テストメソッド、クラス、パッケージを指定したり、ワイルドカードで指定できたり、列挙することもできるらしい. 具体的には以下のような記述ができる

gradle test --tests org.gradle.SomeTest.someSpecificFeature
gradle test --tests SomeTest.someSpecificFeature
gradle test --tests SomeSpecificTest
gradle test --tests all.in.specific.package*
gradle test --tests *IntegTest
gradle test --tests *IntegTest*ui*
gradle someTestTask --tests *UiTest someOtherTestTask --tests *WebTest*ui

また、testタスクに同様の記法でフィルタ指定できる. http://www.gradle.org/docs/current/userguide/java_plugin.html#sec:java_test に記述されている.

あとは gradle help --task タスク名 でタスクのオプションなど表示できるようになって便利.

正規表現にマッチする文字列のカウント

find()の連続呼び出しでマッチする部分文字列を巡回することができる.

実行結果

find 0 : 0, 2
find 1 : 3, 5
find 2 : 6, 8

Object#wait()に関連するテスト

タイムアウト可能な同期をとって処理を行うメソッドを定義するとき、うっかり時間単位間違えて使ってエンバグすることがある.

private final Object mutex_ = new Object(); // モニタ
private String value_; // ガードする変数

public void method0(long timeout, TimeUnit unit) {
    long deadline = System.nanoTime() + unit.toNanos(timeout); // 単位はナノ秒固定
    synchronized (mutex_) {
        while (value_ == null) {
            long rest = deadline - System.nanoTime();
            if (rest <= 0) {
                break;
            }
            unit.timedWait(rest); // TimeUnit.NANOTIMES.timedWait(rest); が正解
        }
    }
}

待ちに関する処理を独立したメソッドにしておくとうっかり Object#wait() を使ってしまう. Object#wait()を使ってしまうと単位がミリ秒になるので、テストではTimeUnit.MILLISECONDS以外を使っておくとバグがあぶり出せて良い. 変数名に単位がナノ秒であることが分かるような名前を採用するのも良いかもしれない.

CIFSマウント先がいなくなる?と親ディレクトリまで操作不能になる

CIFSでマウントしていたWindows7にWindowsUpdateをあてて再起動したら、マウントしているディレクトリを持つ親ディレクトリ毎 ls すら不能になる. 何もできなかったので再起動して回復. つまり、Windows側を落とすときは明示的にアンマウントしておかないと更に面倒.

NotificationBroadcasterSupportにExecutor

JMXの通知で使えるサポートクラス javax.management.NotificationBroadcasterSupport に、リスナ呼び出しをExecutorで行う機能がついていた. 適当な Executor を渡すと、リスナ毎に Executor の呼び出しを行うようになっていた. 未指定時はそのまま Runnable を呼び出す Executor. リモートへの通知だとつまりやすそうなので、そこへの配慮かしら.

mockito で可変長引数に Matcher を使うときに注意すること

mockito で使って可変長引数を持つメソッドをモックしたとき、明示的に配列を使うとMatcherを使う/使わないで挙動が違う. 例えば、

public class Hoge {
    public int varArgsMethod(String...args) {
        return args.length;
    }
}

という定義がある時、

        Hoge hoge = mock(Hoge.class);

        hoge.varArgsMethod("a", "b");

        verify(hoge).varArgsMethod("a", "b");                   // OK
        verify(hoge).varArgsMethod(new String[]{"a", "b"});     // OK
        verify(hoge).varArgsMethod(eq("a"), eq("b"));           // OK
        verify(hoge).varArgsMethod(eq(new String[]{"a", "b"})); // NG

となる. 2番目は通って4番目はとおらない. when()でMatcherを使うときにも同様なことが起きる.

coveralls-gradle-plugin 0.2.1

coveralls-gradle-plugin が 0.2.1 になって coveralls-gradle-plugin に JaCoCo でカバレッジをとれる機能を追加したmavenに登場した. ためしてるけどビルド自体がうまくいってない模様で確認しきれてない.