package com.twitter.service;

import junit.framework.TestCase;

/**
 * @author Attila Szegedi
 */
public class TestVirtualMachineErrorTerminator extends TestCase
{
    private static boolean exitInvoked;
    private static final Object lock = new Object();

    static {
        VirtualMachineErrorTerminator.setExitInvoker(new Runnable() {
            public void run() {
                synchronized(lock) {
                    exitInvoked = true;
                    lock.notify();
                }
            }
        });
    }

    public void testNotTerminatingWhenNew() {
        assertNotTerminating();
    }

    private static void assertNotTerminating() {
        try {
            VirtualMachineErrorTerminator.checkTerminating();
        }
        catch(Throwable t) {
            fail();
        }
    }

    public void testNotTerminatingOnNull() {
        VirtualMachineErrorTerminator.terminateVMIfMust(null);
        assertNotTerminating();
    }

    public void testNotTerminatingOnOtherException() {
        VirtualMachineErrorTerminator.terminateVMIfMust(new Exception());
        assertNotTerminating();
    }

    public void testTerminatingOnNestedVirtualMachineError() throws Exception {
        Exception e = new Exception();
        OutOfMemoryError oome = new OutOfMemoryError();
        e.initCause(oome);
        VirtualMachineErrorTerminator.terminateVMIfMust(e);
        assertTerminated();
    }

    public void testTerminatingOnVirtualMachineError() throws Exception {
        VirtualMachineErrorTerminator.terminateVMIfMust(new OutOfMemoryError());
        assertTerminated();
    }

    public void testTerminateDoesntAcceptNull() throws Exception {
        try {
            VirtualMachineErrorTerminator.terminateVM(null);
            fail();
        }
        catch(IllegalArgumentException e) {
        }
    }

    public void testSecondTerminateIneffective() throws Exception {
        OutOfMemoryError oome1 = new OutOfMemoryError();
        OutOfMemoryError oome2 = new OutOfMemoryError();
        VirtualMachineErrorTerminator.terminateVM(oome1);
        VirtualMachineErrorTerminator.terminateVM(oome2);
        try {
            VirtualMachineErrorTerminator.checkTerminating();
            fail();
        }
        catch(OutOfMemoryError oome) {
            assertSame(oome, oome1);
        }
    }

    private static void assertTerminated() throws InterruptedException {
        try {
            VirtualMachineErrorTerminator.checkTerminating();
            fail();
        }
        catch(VirtualMachineError e) {
            try {
                synchronized(lock) {
                    long timeout = System.currentTimeMillis() + 1000;
                    for(;;) {
                        if(exitInvoked) {
                            exitInvoked = false;
                            break;
                        }
                        long now = System.currentTimeMillis();
                        if(now >= timeout) {
                            fail();
                        }
                        lock.wait(timeout - now);
                    }
                }
            }
            finally {
                VirtualMachineErrorTerminator.reset();
            }
        }
    }
}
@@ -521,32 +521,116 @@
      %7D);%0A    %7D%0A%0A
+    protected void tearDown() %7B%0A      VirtualMachineErrorTerminator.reset();%0A    %7D%0A%0A
     public void 
@@ -2653,30 +2653,8 @@
 ) %7B%0A
-            try %7B%0A    
     
@@ -2694,28 +2694,24 @@
             
- 
-   
 long timeout
@@ -2764,20 +2764,16 @@
         
-    
 for(;;) 
@@ -2770,28 +2770,24 @@
   for(;;) %7B%0A
-    
             
@@ -2828,36 +2828,32 @@
                 
-    
 exitInvoked = fa
@@ -2881,20 +2881,16 @@
         
-    
 break;%0A 
@@ -2904,34 +2904,26 @@
             
-   
- 
 %7D%0A
-    
             
@@ -2989,20 +2989,16 @@
         
-    
 if(now %3E
@@ -3026,36 +3026,32 @@
                 
-   
- 
 fail();%0A        
@@ -3058,34 +3058,26 @@
             
-    %7D%0A    
+%7D%0A
             
@@ -3130,122 +3130,9 @@
     
-  
-  %7D%0A                %7D%0A            %7D%0A            finally %7B%0A                VirtualMachineErrorTerminator.reset();
+%7D
 %0A   
@@ -3159,8 +3159,9 @@
 %0A    %7D%0A%7D
+%0A

fix VM test error by ensuring reset