0

スリープするモックストリームを使用せずに(割り込みに反応するため)、IOパフォーマンスが非常に悪い場合に、アプリケーションコードの動作をテストするにはどうすればよいですか?

たとえば、ConcurrentWrapperファイルIO用のスレッドのプールがあるユーティリティをテストしたいと思います。各操作をタイムアウト付きのwithExecutorServiceに送信します。タイムアウトの前に終了する呼び出しだけでなく、 (リークを回避するために)内部のスレッドが何らかの形で終了したこともinvokeAll()確認したいと思います。ConcurrentWrapperExecutorService

どういうわけか、内側のスレッドで遅いIOをシミュレートする必要がありますが、(実際のIOのように)割り込みを無視する方法で。

少し明確にするInterruptedException:「眠って飲み込む」や「眠って、捕まえInterruptedExceptionて眠りに戻る」のような答えは受け入れられません。コードが割り込みをどのように処理するかをテストしたいのですが、そのようなインストルメンテーションは、割り込み自体を処理することで目的を達成できません。

4

3 に答える 3

1

割り込みによるスリープを主張する方法でスリープできます。

long start = System.currentTimeMillis();
long end = start + sleepTime;
for (long now = start; now < end; now = System.currentTimeMillis()) {
    try {
        Thread.sleep(end - now);
    } catch (InterruptedException ignored) {
    }
}
于 2012-06-04T15:34:18.277 に答える
0

タイムアウトを使用したテストでは、実際にテストを実行する最大時間を設定できます。JUnit では注釈のタイムアウトを含めることができます。

@Test(timeout=100)
public void method_withTimeout() {
       while(true);
}

メソッドが終了することをテストする部分については、結果を取得するためのタイムアウトを提供するFutureインターフェイスを使用できます。

于 2012-06-04T15:38:17.343 に答える
0

あなたの質問を正しく理解できれば、 ReentrantLock が役立つかもしれません。

final ReentrantLock lock = new ReentrantLock();

Callable<Void> c = new Callable<Void>() {
  public void call() {
    lock.lock();

    try {

       if (Thread.currentThread().isInterrupted()) {
         ...
       }
    }
    finally {
      lock.unlock();
    }
  }
}

// Submit to the pool
Future<Void> future = executorService.submit(c);

// you might want to sleep a bit to give the pool a chance
// to pull off the queue.

// Issue a cancel
future.cancel();

// Now release the lock, which should let your
// callable continue onto to the interrupted check.
lock.unlock();

「lock」メソッドは InterruptedException をスローしないことに注意してください (ただし、「lockInterruptively」と呼ばれるメソッドがあります)。そのクラスのコードを見ると、キャッチして飲み込んでいないことに注意してください (あなたが述べたように、あなたが望むものになる)。

于 2012-06-04T19:26:01.353 に答える