/** Test of sharedInstance method, of class Scheduler. */
  @Test
  public void sharedInstance() {
    System.out.println("sharedInstance");

    Scheduler result1 = Scheduler.sharedInstance();
    Scheduler result2 = Scheduler.sharedInstance();
    assertTrue(result1 == result2); // shared instance MUST remain the same across all calls
  }
  @Test
  public void suspendSuspend() {
    System.out.println("suspend-suspend");
    final CountDownLatch barrier1 = new CountDownLatch(1);
    final CountDownLatch barrier2 = new CountDownLatch(2);

    SchedulerTask task =
        new SchedulerTask() {

          public void onSchedule(long timeStamp) {
            barrier1.countDown();
            barrier2.countDown();
          }
        };

    final ScheduledTask scheduled =
        Scheduler.sharedInstance().schedule(task, Quantum.seconds(2), false);
    stasks.add(scheduled);
    try {
      if (!barrier1.await(3, TimeUnit.SECONDS)) {
        fail();
      }
      scheduled.suspend();
      if (barrier2.await(3, TimeUnit.SECONDS)) {
        fail();
      }
      scheduled.suspend();
      if (barrier2.await(3, TimeUnit.SECONDS)) {
        fail();
      }
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
  }
  @Test
  public void dynamicRescheduleSuspended() {
    System.out.println("dynamicReschedule suspended");
    final CountDownLatch barrier1 = new CountDownLatch(1);
    final CountDownLatch barrier2 = new CountDownLatch(5);

    SchedulerTask task =
        new SchedulerTask() {

          public void onSchedule(long timeStamp) {
            System.out.println("dynamicReschedule; executing periodic task");
            barrier1.countDown();
            barrier2.countDown();
          }
        };

    final ScheduledTask scheduled =
        Scheduler.sharedInstance().schedule(task, Quantum.SUSPENDED, false);
    stasks.add(scheduled);
    try {
      if (barrier1.await(5, TimeUnit.SECONDS)) {
        fail();
      }
      scheduled.resume();
      if (barrier2.await(2, TimeUnit.SECONDS)) {
        fail();
      }
      scheduled.setInterval(Quantum.seconds(1));
      if (!barrier2.await(8, TimeUnit.SECONDS)) {
        fail();
      }
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
  }
  /**
   * Test of schedule method, immediate execution, blocking in the scheduled task, of class
   * Scheduler.
   */
  @Test
  public void scheduleImmediateBlocking() {
    System.out.println("schedule, immediate, blocking");
    final CountDownLatch barrier = new CountDownLatch(1);
    SchedulerTask task =
        new SchedulerTask() {

          public void onSchedule(long timeStamp) {
            try {
              barrier.countDown();
              Thread.sleep(10000000);
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
            }
          }
        };
    Quantum interval = Quantum.seconds(2000);
    Scheduler instance = Scheduler.sharedInstance();
    ScheduledTask scheduled = instance.schedule(task, interval, true);
    stasks.add(scheduled);
    try {
      boolean executed = barrier.await(1000, TimeUnit.SECONDS);
      assertTrue(executed);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
  }
  /** Test of unschedule method, of class Scheduler. */
  @Test
  public void unschedule() {
    System.out.println("unschedule");
    final AtomicBoolean executed = new AtomicBoolean(false);
    SchedulerTask task =
        new SchedulerTask() {

          public void onSchedule(long timeStamp) {
            executed.set(true);
          }
        };
    Scheduler instance = Scheduler.sharedInstance();
    ScheduledTask scheduled = instance.schedule(task, Quantum.seconds(3), false);
    instance.unschedule(scheduled);

    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
    assertFalse(executed.get());
  }
  /** Test of schedule method of class Scheduler. */
  @Test
  public void schedule() {
    System.out.println("schedule");
    final CountDownLatch barrier = new CountDownLatch(1);
    SchedulerTask task =
        new SchedulerTask() {

          public void onSchedule(long timeStamp) {
            barrier.countDown();
          }
        };
    Quantum interval = Quantum.seconds(5);
    Scheduler instance = Scheduler.sharedInstance();
    ScheduledTask scheduled = instance.schedule(task, interval, false);
    stasks.add(scheduled);
    try {
      boolean executed = barrier.await(8, TimeUnit.SECONDS);
      assertTrue(executed);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    }
  }
 @After
 public void tearDown() {
   for (ScheduledTask stask : stasks) {
     Scheduler.sharedInstance().unschedule(stask);
   }
 }