2009-06-11 6 views
3

최종적으로 StackOverflow를 일으키는 끝없는 반복에서 멈추는 코드 조각을 방지하기 위해 junit 테스트를 작성하려고합니다.Java에서 런타임시 max stacksize를 줄입니다.

그래서 나는 런타임에 스택 크기를 줄이는 방법을 찾고 있으므로 Junittest는 더 빨리 실패 할 것입니다.

테스트가 훨씬 더 큰 테스트 스위트의 일부이기 때문에 최대 스택을 jvm 인수로 설정할 수 없습니다.

답변

5

당신은 자신에게 주어진 시간 수를 실행하는 재귀 적 방법을 실행할 수 있습니다 주어진 액션을 실행한다. 소리 꽤 색다른하지만 ​​:(

뭔가 같은 :

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이 여기에 꼬리 호출을 최적화 할 가능성이 있습니다, 그래서 우리가 후 "뭔가"를해야 할 거라고 할 수있다 재귀 호출은

출몰하고 'N 물건 :(

+0

와우. 이 얼마나 끔찍한 생각. 그러나 실제로는 스택 깊이를 JVM의 최대 값으로 설정합니다. 런타임시 깊이 인수이므로 +1합니다. –

2

는 런타임 스택의 크기를 설정하는 것은 불가능하지만, 아마도 당신이 할 수 있습니다

다른 스레드 내부 코드의 조각을 호출
  • - 그것은에 대한 참조를 유지;
  • 주기적으로 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()); 
1

당신은 시작시이 같은 경우에만 설정 매개 변수, 그러나 당신은 자바에서 다른 프로세스를 시작할 수 있습니다 ... 일어나는 것을 중지합니다. 당신이 당신의 단위 테스트를 할 수 있도록 p보다 작은 스택 크기로 두 번째 프로세스 시작 시험을 지우십시오.

+0

"프로세스"에서 첫 번째 "진행"을해야합니까? –

+0

@MattFenwick 예, 감사합니다. –

0

이것은 조금 ... 잘, 흥미있다. .. 그러나 그것의 가치가 있을지도 모른다.

  1. .class 파일을 가지고 jasper으로 디 컴파일하십시오.
  2. 결과 JVM 어셈블리 esque 코드를 편집하고이 방식으로 테스트하려는 루틴의 ".limit stack x"인수를 추가하거나 변경하십시오.
  3. Jasmin으로 다시 컴파일하십시오.
  4. 실행하여 테스트하십시오.
+0

나는 이것이 테스트 케이스에 사용하는 많은 실패 지점을 소개한다고 생각하지만 감사합니다. – pvgoddijn

관련 문제