// Path: src/main/java/javafixes/collection/CollectionUtil.java
// @SafeVarargs
// public static <T> ArrayList<T> newList(T... values) {
//     ArrayList<T> list = new ArrayList<T>(values.length);
//     Collections.addAll(list, values);
//     return list;
// }
// 
// Path: src/test/java/javafixes/test/Random.java
//     @SafeVarargs
//     public static long randomLong(long from, long to, Function<Long, Boolean>... validityConditions) {
//         return generateValidValue(
// //                () -> new RandomDataGenerator().nextLong(from, to),
//                 () -> ThreadLocalRandom.current().nextLong(from, to) + (long) randomInt(0, 1),
//                 validityConditions
//         );
//     }


import org.junit.Test;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import static javafixes.collection.CollectionUtil.newList;
import static javafixes.test.Random.randomLong;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
package javafixes.concurrency;




public class RunnerTest extends BaseExecutorTest {

    protected Runner executor;

    @Override
    protected void initializeExecutor() {
        // create executor with 10 threads
        executor = Runner.runner(10);
    }

    @Override
    protected void shutdownExecutor() throws InterruptedException {
        executor.shutdownAndAwaitTermination();
    }

    @Override
    protected MonitoringTaskSubmitter executor() {
        return executor;
    }

    @Test
    public void shouldNotDeadlockOnShutdownNow() {
        // fill the queue
        for (int i = 0; i < 10_000; i++) {
            executor.run(this::doSomethingThatTakesTime);
        }

        // When
        executor.shutdownNow();

        // Then
        boolean done = executor.waitTillDone(3, TimeUnit.SECONDS);
        assertThat(done, is(true));

        assertThat(executor.toBeCompletedCount(), is(0));
        assertThat(executor.failedToStartCount(), greaterThan(0));
    }

    @Test
    public void shouldInformShutdownAwareTasksThatShutdownHasBeenTriggered() throws InterruptedException {
// Path: src/main/java/javafixes/collection/CollectionUtil.java
// @SafeVarargs
// public static <T> ArrayList<T> newList(T... values) {
//     ArrayList<T> list = new ArrayList<T>(values.length);
//     Collections.addAll(list, values);
//     return list;
// }
// 
// Path: src/test/java/javafixes/test/Random.java
//     @SafeVarargs
//     public static long randomLong(long from, long to, Function<Long, Boolean>... validityConditions) {
//         return generateValidValue(
// //                () -> new RandomDataGenerator().nextLong(from, to),
//                 () -> ThreadLocalRandom.current().nextLong(from, to) + (long) randomInt(0, 1),
//                 validityConditions
//         );
//     }


// Path: src/test/java/javafixes/concurrency/RunnerTest.java
import org.junit.Test;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import static javafixes.collection.CollectionUtil.newList;
import static javafixes.test.Random.randomLong;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

package javafixes.concurrency;




public class RunnerTest extends BaseExecutorTest {

    protected Runner executor;

    @Override
    protected void initializeExecutor() {
        // create executor with 10 threads
        executor = Runner.runner(10);
    }

    @Override
    protected void shutdownExecutor() throws InterruptedException {
        executor.shutdownAndAwaitTermination();
    }

    @Override
    protected MonitoringTaskSubmitter executor() {
        return executor;
    }

    @Test
    public void shouldNotDeadlockOnShutdownNow() {
        // fill the queue
        for (int i = 0; i < 10_000; i++) {
            executor.run(this::doSomethingThatTakesTime);
        }

        // When
        executor.shutdownNow();

        // Then
        boolean done = executor.waitTillDone(3, TimeUnit.SECONDS);
        assertThat(done, is(true));

        assertThat(executor.toBeCompletedCount(), is(0));
        assertThat(executor.failedToStartCount(), greaterThan(0));
    }

    @Test
    public void shouldInformShutdownAwareTasksThatShutdownHasBeenTriggered() throws InterruptedException {
        List<Consumer<Runner>> shutdownMethods = newList(