package org.threadly.test.concurrent;

import org.threadly.util.Clock;

/**
 * <p>Generic tools to be used in unit testing.</p>
 * 
 * @author jent - Mike Jensen
 * @since 1.0.0
 */
public class TestUtils {
  private TestUtils() {
    // don't construct
  }
  
  /**
   * Since sleeps are sometimes necessary, this makes an easy way to ignore InterruptedException's.
   * 
   * @param time time in milliseconds to make the thread to sleep
   */
  public static void sleep(long time) {
    try {
      Thread.sleep(time);
    } catch (InterruptedException e) {
      // reset interrupted status
      Thread.currentThread().interrupt();
    }
  }
  
  /**
   * Blocks until the System clock advances at least 1 millisecond.  This will also ensure that 
   * the {@link Clock} class's representation of time has advanced.
   */
  public static void blockTillClockAdvances() {
    new TestCondition() {
      private static final int TIMEOUT_IN_MS = 1000;
      private static final int POLL_INTERVAL_IN_MS = 1;
      
      private final long startTime = Clock.accurateTimeMillis();
      
      @Override
      public boolean get() {
        return Clock.accurateTimeMillis() != startTime;
      }
      
      @Override
      public void blockTillTrue() {
        blockTillTrue(TIMEOUT_IN_MS, POLL_INTERVAL_IN_MS);
      }
    }.blockTillTrue();
  }
}

package org.threadly.test.concurrent;

import org.threadly.util.Clock;

/**
 * <p>Generic tools to be used in unit testing.</p>
 * 
 * @author jent - Mike Jensen
 * @since 1.0.0
 */
public class TestUtils {
  private TestUtils() {
    // don't construct
  }
  
  /**
   * Since sleeps are sometimes necessary, this makes an easy way to ignore InterruptedException's.
   * 
   * @param time time in milliseconds to make the thread to sleep
   */
  public static void sleep(long time) {
    try {
      Thread.sleep(time);
    } catch (InterruptedException e) {
      // reset interrupted status
      Thread.currentThread().interrupt();
    }
  }
  
  /**
   * Blocks until the System clock advances at least 1 millisecond.  This will also ensure that 
   * the {@link Clock} class's representation of time has advanced.
   */
  public static void blockTillClockAdvances() {
    new TestCondition() {
      private static final int TIMEOUT_IN_MS = 1000;
      private static final int POLL_INTERVAL_IN_MS = 1;
      
      private final long startTime = Clock.accurateTimeMillis();
      private final long alwaysProgressingStartTime = Clock.alwaysProgressingAccurateTimeMillis();
      
      @Override
      public boolean get() {
        return Clock.accurateTimeMillis() > startTime && 
                 Clock.alwaysProgressingAccurateTimeMillis() > alwaysProgressingStartTime;
      }
      
      @Override
      public void blockTillTrue() {
        blockTillTrue(TIMEOUT_IN_MS, POLL_INTERVAL_IN_MS);
      }
    }.blockTillTrue();
  }
}

Fix for unit test regressions Because the alwaysProgressing time is based off nanoseconds, it may not have progressed forward even though the accurateTimeMillis has progressed forwrad.
Fix for unit test regressions
Because the alwaysProgressing time is based off nanoseconds, it may not have progressed forward even though the accurateTimeMillis has progressed forwrad.
