package org.nuprocess.unix;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Assert;
import org.junit.Test;
import org.nuprocess.NuAbstractProcessHandler;
import org.nuprocess.NuProcess;
import org.nuprocess.NuProcessBuilder;
import org.nuprocess.NuProcessHandler;
import org.nuprocess.internal.BasePosixProcess;
import org.nuprocess.internal.LibC;

public class InterruptTest
{

    @Test
    public void testInterrupt1() throws InterruptedException
    {
        final Semaphore semaphore = new Semaphore(0);
        final AtomicInteger exitCode = new AtomicInteger();
        final AtomicInteger count = new AtomicInteger();

        NuProcessHandler processListener = new NuAbstractProcessHandler()
        {

            @Override
            public void onStart(NuProcess nuProcess)
            {
                nuProcess.wantWrite();
            }

            @Override
            public void onExit(int statusCode)
            {
                exitCode.set(statusCode);
                semaphore.release();
            }

            @Override
            public void onStdout(ByteBuffer buffer)
            {
                if (buffer == null)
                {
                    return;
                }

                count.addAndGet(buffer.remaining());
            }

            @Override
            public boolean onStdinReady(ByteBuffer buffer)
            {
                buffer.put("This is a test".getBytes());
                return true;
            }

        };

        NuProcessBuilder pb = new NuProcessBuilder(Arrays.asList("/bin/cat"), processListener);
        NuProcess process = pb.start();
        while (true)
        {
            if (count.get() > 10000)
            {
                process.destroy();
                break;
            }
            Thread.sleep(20);
        }

        semaphore.acquireUninterruptibly();
        Assert.assertEquals("Output did not matched expected result", 0, exitCode.get());
    }

    @Test
    public void chaosMonkey() throws InterruptedException
    {
        NuProcessHandler processListener = new NuAbstractProcessHandler()
        {

            @Override
            public void onStart(NuProcess nuProcess)
            {
                nuProcess.wantWrite();
            }

            @Override
            public void onStdout(ByteBuffer buffer)
            {
                if (buffer == null)
                {
                    return;
                }
            }

            @Override
            public boolean onStdinReady(ByteBuffer buffer)
            {
                buffer.put("This is a test".getBytes());
                return true;
            }

        };

        NuProcessBuilder pb = new NuProcessBuilder(Arrays.asList("/bin/cat"), processListener);
        List<NuProcess> processes = new LinkedList<>();
        for (int times = 0; times < 25; times++)
        {
            for (int i = 0; i < 50; i++)
            {
                processes.add(pb.start());
            }
    
            while (true)
            {
                Thread.sleep(20);
                int dead = (int) (Math.random() * processes.size());
                BasePosixProcess bpp = (BasePosixProcess) processes.remove(dead);
                LibC.kill(bpp.getPid(), LibC.SIGTERM);
    
                if (processes.isEmpty())
                {
                    break;
                }
            }
        }
    }
}

@@ -46,24 +46,52 @@
 ByteBuffer;%0A
+import java.util.ArrayList;%0A
 import java.
@@ -2063,94 +2063,134 @@
 ();%0A
-        Assert.assertEquals(%22Output did not matched expected result%22, 0, exitCode.get(
+%09%09int exit = process.waitFor();%0A%09%09Assert.assertTrue(%22Process exit code did not match%22, (exit == 0 %7C%7C exit == Integer.MAX_VALUE
 ));%0A
@@ -3233,24 +3233,83 @@
      %7D%0A    %0A
+            List%3CNuProcess%3E deadProcs = new ArrayList%3C%3E();%0A
             
@@ -3313,32 +3313,32 @@
    while (true)%0A
-
             %7B%0A  
@@ -3520,16 +3520,52 @@
 (dead);%0A
+                deadProcs.add(bpp);%0A
         
@@ -3657,16 +3657,16 @@
 mpty())%0A
-
         
@@ -3667,32 +3667,287 @@
               %7B%0A
+                %09for (int i = 0; i %3C 50; i++)%0A                %09%7B%0A                %09%09int exit = deadProcs.get(i).waitFor();%0A                %09%09Assert.assertTrue(%22Process exit code did not match%22, (exit == 0 %7C%7C exit == Integer.MAX_VALUE));%0A                %09%7D%0A
                 

Check different exit code from linux.