コードの一部が無限の反復でスタックし、最終的にStackOverflowが発生するのを防ぐために、junitテストを作成しようとしています。
そのため、実行時にスタックサイズを減らして、Junittestがより速く失敗するようにする方法を探しています。
テストははるかに大きなテストスイートの一部であるため、最大スタックをjvm引数として設定することはできません。
コードの一部が無限の反復でスタックし、最終的にStackOverflowが発生するのを防ぐために、junitテストを作成しようとしています。
そのため、実行時にスタックサイズを減らして、Junittestがより速く失敗するようにする方法を探しています。
テストははるかに大きなテストスイートの一部であるため、最大スタックをjvm引数として設定することはできません。
再帰的なメソッドを実行して、それ自体を指定された回数実行してから、指定されたアクションを実行することができます。かなり不安定に聞こえますが:(
何かのようなもの:
public void eatStackThenExecute(int depth, Runnable action)
{
// Maybe put some locals here (and use them) to eat more stack per iteration?
if (depth == 0)
{
action();
}
else
{
eatStackThenExecute(depth - 1, action);
}
}
編集:スマートJVMがここで末尾呼び出しを最適化する可能性があるため、再帰呼び出しの後に「何か」を実行して、それが起こらないようにする必要があるかもしれません...
Ick'n stuff :(
実行時にスタック サイズを設定することはできませんが、おそらく次のことができます。
thread.getStackTrace()
し、サイズが x より大きい場合は失敗します。コンパイルされていない概念実証コード (すべてのエッジ条件を適切にチェックするわけではありません):
AtomicBoolean success = new AtomicBoolean(false);
Thread t= new Thread(new Runnable() {
public void run() {
codeToTest();
success.set(true);
}
});
t.start();
while ( t.isAlive() ) {
if ( t.getStackTrace().length > 50 )
fail("Stack trace too large");
Thread.sleep(50);
}
assertTrue(sucess.get());
このようなパラメーターは起動時にしか設定できませんが、Java から別のプロセスを開始することはできます。そのため、単体テストでスタック サイズが小さい 2 番目のプロセスを開始して、テストを実行することができます。