001package org.junit.rules;
002
003import org.junit.internal.runners.statements.FailOnTimeout;
004import org.junit.runner.Description;
005import org.junit.runners.model.Statement;
006
007import java.util.concurrent.TimeUnit;
008
009/**
010 * The Timeout Rule applies the same timeout to all test methods in a class:
011 *
012 * <pre>
013 * public static class HasGlobalLongTimeout {
014 *
015 *  &#064;Rule
016 *  public Timeout globalTimeout= new Timeout(20);
017 *
018 *  &#064;Test
019 *  public void run1() throws InterruptedException {
020 *      Thread.sleep(100);
021 *  }
022 *
023 *  &#064;Test
024 *  public void infiniteLoop() {
025 *      while (true) {}
026 *  }
027 * }
028 * </pre>
029 *
030 * Each test is run in a new thread. If the specified timeout elapses before
031 * the test completes, its execution is interrupted via {@link Thread#interrupt()}.
032 * This happens in interruptable I/O and locks, and methods in {@link Object}
033 * and {@link Thread} throwing {@link InterruptedException}.
034 *
035 * @since 4.7
036 */
037public class Timeout implements TestRule {
038    private final long fTimeout;
039    private final TimeUnit fTimeUnit;
040
041    /**
042     * Create a {@code Timeout} instance with the timeout specified
043     * in milliseconds.
044     * <p> This constructor is deprecated.
045     * <p> Instead use {@link #Timeout(long, java.util.concurrent.TimeUnit)},
046     * {@link Timeout#millis(long)}, or {@link Timeout#seconds(long)}.
047     *
048     * @param millis the maximum time in milliseconds to allow the
049     * test to run before it should timeout
050     */
051    @Deprecated
052    public Timeout(int millis) {
053        this(millis, TimeUnit.MILLISECONDS);
054    }
055
056    /**
057     * Create a {@code Timeout} instance with the timeout specified
058     * at the unit of granularity of the provided {@code TimeUnit}.
059     *
060     * @param timeout the maximum time to allow the test to run
061     * before it should timeout
062     * @param unit the time unit for the {@code timeout}
063     * @since 4.12
064     */
065    public Timeout(long timeout, TimeUnit unit) {
066        fTimeout = timeout;
067        fTimeUnit = unit;
068    }
069
070    /**
071     * @param millis the timeout in milliseconds
072     * @since 4.12
073     */
074    public static Timeout millis(long millis) {
075        return new Timeout(millis, TimeUnit.MILLISECONDS);
076    }
077
078    /**
079     * @param seconds the timeout in seconds
080     * @since 4.12
081     */
082    public static Timeout seconds(long seconds) {
083        return new Timeout(seconds, TimeUnit.SECONDS);
084    }
085
086
087    public Statement apply(Statement base, Description description) {
088        return new FailOnTimeout(base, fTimeout, fTimeUnit);
089    }
090}