@Test(
      enabled = true && !DEBUG,
      dataProvider = "NanoSchedulerBasicTest",
      dependsOnMethods = "testMultiThreadedNanoScheduler",
      timeOut = NANO_SCHEDULE_MAX_RUNTIME)
  public void testNanoSchedulerInLoop(final NanoSchedulerBasicTest test)
      throws InterruptedException {
    if (test.bufferSize > 1) {
      logger.warn("Running " + test);

      final NanoScheduler<Integer, Integer, Integer> nanoScheduler = test.makeScheduler();

      // test reusing the scheduler
      for (int i = 0; i < 10; i++) {
        final Integer sum =
            nanoScheduler.execute(
                test.makeReader(), test.makeMap(), test.initReduce(), test.makeReduce());
        Assert.assertNotNull(sum);
        Assert.assertEquals(
            (int) sum,
            test.expectedResult,
            "NanoScheduler sum not the same as calculated directly");
      }

      nanoScheduler.shutdown();
    }
  }
 @Test(
     enabled = true && !DEBUG,
     expectedExceptions = IllegalStateException.class,
     timeOut = NANO_SCHEDULE_MAX_RUNTIME)
 public void testShutdownExecuteFailure() throws InterruptedException {
   final NanoScheduler<Integer, Integer, Integer> nanoScheduler =
       new NanoScheduler<Integer, Integer, Integer>(1, 2);
   nanoScheduler.shutdown();
   nanoScheduler.execute(
       exampleTest.makeReader(),
       exampleTest.makeMap(),
       exampleTest.initReduce(),
       exampleTest.makeReduce());
 }
  @DataProvider(name = "NanoSchedulerBasicTest")
  public Object[][] createNanoSchedulerBasicTest() {
    //        for ( final int bufferSize : Arrays.asList(1, 10) ) {
    //            for ( final int nt : Arrays.asList(1, 2, 4) ) {
    //                for ( final int start : Arrays.asList(0) ) {
    //                    for ( final int end : Arrays.asList(0, 1, 2) ) {
    //                        exampleTest = new NanoSchedulerBasicTest(bufferSize, nt, start, end,
    // false);
    //                    }
    //                }
    //            }
    //        }

    for (final int bufferSize : Arrays.asList(-1, 1, 10, 100)) {
      for (final int nt : Arrays.asList(1, 2, 4)) {
        for (final int start : Arrays.asList(0)) {
          for (final int end : Arrays.asList(0, 1, 2, 11, 100, 10000, 100000)) {
            for (final boolean addDelays : Arrays.asList(true, false)) {
              if (end < 1000) new NanoSchedulerBasicTest(bufferSize, nt, start, end, addDelays);
            }
          }
        }
      }
    }

    return NanoSchedulerBasicTest.getTests(NanoSchedulerBasicTest.class);
  }
  private void testNanoScheduler(final NanoSchedulerBasicTest test) throws InterruptedException {
    final SimpleTimer timer = new SimpleTimer().start();
    final NanoScheduler<Integer, Integer, Integer> nanoScheduler = test.makeScheduler();

    final ProgressCallback callback = new ProgressCallback();
    nanoScheduler.setProgressFunction(callback);

    if (test.bufferSize > -1)
      Assert.assertEquals(nanoScheduler.getBufferSize(), test.bufferSize, "bufferSize argument");
    Assert.assertEquals(nanoScheduler.getnThreads(), test.nThreads, "nThreads argument");

    final Integer sum =
        nanoScheduler.execute(
            test.makeReader(), test.makeMap(), test.initReduce(), test.makeReduce());
    Assert.assertNotNull(sum);
    Assert.assertEquals(
        (int) sum, test.expectedResult, "NanoScheduler sum not the same as calculated directly");

    Assert.assertTrue(
        callback.callBacks >= test.nExpectedCallbacks(),
        "Not enough callbacks detected.  Expected at least "
            + test.nExpectedCallbacks()
            + " but saw only "
            + callback.callBacks);
    nanoScheduler.shutdown();
  }
  public static void main(String[] args) {
    org.apache.log4j.Logger logger = org.apache.log4j.Logger.getRootLogger();
    BasicConfigurator.configure();
    logger.setLevel(org.apache.log4j.Level.DEBUG);

    final NanoSchedulerBasicTest test =
        new NanoSchedulerBasicTest(
            1000, Integer.valueOf(args[0]), 0, Integer.valueOf(args[1]), false);
    final NanoScheduler<Integer, Integer, Integer> nanoScheduler =
        new NanoScheduler<Integer, Integer, Integer>(test.bufferSize, test.nThreads);
    nanoScheduler.setDebug(true);

    final Integer sum =
        nanoScheduler.execute(
            test.makeReader(), test.makeMap(), test.initReduce(), test.makeReduce());
    System.out.printf("Sum = %d, expected =%d%n", sum, test.expectedResult);
    nanoScheduler.shutdown();
  }
 private void executeTestErrorThrowingInput(
     final int nElementsBeforeError,
     final Throwable ex,
     final NanoSchedulerBasicTest test,
     final boolean addDelays) {
   logger.warn(
       "executeTestErrorThrowingInput "
           + nElementsBeforeError
           + " ex="
           + ex
           + " test="
           + test
           + " addInputDelays="
           + addDelays);
   final NanoScheduler<Integer, Integer, Integer> nanoScheduler = test.makeScheduler();
   nanoScheduler.execute(
       new ErrorThrowingIterator(nElementsBeforeError, ex, addDelays),
       test.makeMap(),
       test.initReduce(),
       test.makeReduce());
 }