1b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpackage org.junit.rules;
2b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
3b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.internal.runners.statements.FailOnTimeout;
4b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.Description;
5b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.Statement;
6b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
7aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffinimport java.util.concurrent.TimeUnit;
8aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
9b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot/**
10b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * The Timeout Rule applies the same timeout to all test methods in a class:
11b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <pre>
12aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * public static class HasGlobalLongTimeout {
13aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *
14aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  &#064;Rule
15aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  public Timeout globalTimeout= new Timeout(20);
16aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *
17aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  &#064;Test
18aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  public void run1() throws InterruptedException {
19aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *      Thread.sleep(100);
20aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  }
21aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *
22aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  &#064;Test
23aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  public void infiniteLoop() {
24aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *      while (true) {}
25aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *  }
26b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * }
27b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * </pre>
28aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * <p>
29aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * Each test is run in a new thread. If the specified timeout elapses before
30aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * the test completes, its execution is interrupted via {@link Thread#interrupt()}.
31aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * This happens in interruptable I/O and locks, and methods in {@link Object}
32aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * and {@link Thread} throwing {@link InterruptedException}.
33aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * <p>
34aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * A specified timeout of 0 will be interpreted as not set, however tests will
35aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * still launch from separate threads. This can be useful for disabling timeouts
36aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * in environments where they are dynamically set based on some property.
37aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin *
38aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin * @since 4.7
39b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */
40b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpublic class Timeout implements TestRule {
41aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    private final long timeout;
42aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    private final TimeUnit timeUnit;
43aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
44aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
45aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Returns a new builder for building an instance.
46aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
47aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
48aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
49aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    public static Builder builder() {
50aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        return new Builder();
51aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
52aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
53aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
54aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Create a {@code Timeout} instance with the timeout specified
55aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * in milliseconds.
56aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * <p>
57aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * This constructor is deprecated.
58aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * <p>
59aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Instead use {@link #Timeout(long, java.util.concurrent.TimeUnit)},
60aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * {@link Timeout#millis(long)}, or {@link Timeout#seconds(long)}.
61aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
62aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @param millis the maximum time in milliseconds to allow the
63aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * test to run before it should timeout
64aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
65aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    @Deprecated
66aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    public Timeout(int millis) {
67aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        this(millis, TimeUnit.MILLISECONDS);
68aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
69aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
70aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
71aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Create a {@code Timeout} instance with the timeout specified
72aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * at the timeUnit of granularity of the provided {@code TimeUnit}.
73aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
74aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @param timeout the maximum time to allow the test to run
75aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * before it should timeout
76aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @param timeUnit the time unit for the {@code timeout}
77aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
78aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
79aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    public Timeout(long timeout, TimeUnit timeUnit) {
80aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        this.timeout = timeout;
81aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        this.timeUnit = timeUnit;
82aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
83aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
84aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
85aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Create a {@code Timeout} instance initialized with values form
86aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * a builder.
87aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
88aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
89aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
90aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    protected Timeout(Builder builder) {
91aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        timeout = builder.getTimeout();
92aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        timeUnit = builder.getTimeUnit();
93aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
94aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
95aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
96aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Creates a {@link Timeout} that will timeout a test after the
97aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * given duration, in milliseconds.
98aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
99aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
100aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
101aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    public static Timeout millis(long millis) {
102aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        return new Timeout(millis, TimeUnit.MILLISECONDS);
103aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
104aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
105aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
106aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Creates a {@link Timeout} that will timeout a test after the
107aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * given duration, in seconds.
108aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
109aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
110aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
111aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    public static Timeout seconds(long seconds) {
112aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        return new Timeout(seconds, TimeUnit.SECONDS);
113aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
114aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
115aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
116aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Gets the timeout configured for this rule, in the given units.
117aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
118aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
119aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
120aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    protected final long getTimeout(TimeUnit unit) {
121aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        return unit.convert(timeout, timeUnit);
122aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
123aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
124aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
125aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Creates a {@link Statement} that will run the given
126aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * {@code statement}, and timeout the operation based
127aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * on the values configured in this rule. Subclasses
128aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * can override this method for different behavior.
129aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
130aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
131aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
132aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    protected Statement createFailOnTimeoutStatement(
133aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            Statement statement) throws Exception {
134aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        return FailOnTimeout.builder()
135aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            .withTimeout(timeout, timeUnit)
136aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            .build(statement);
137aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
138aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
139aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    public Statement apply(Statement base, Description description) {
140aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        try {
141aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            return createFailOnTimeoutStatement(base);
142aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        } catch (final Exception e) {
143aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            return new Statement() {
144aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin                @Override public void evaluate() throws Throwable {
145aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin                    throw new RuntimeException("Invalid parameters for Timeout", e);
146aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin                }
147aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            };
148aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        }
149aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
150aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
151aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    /**
152aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * Builder for {@link Timeout}.
153aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     *
154aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     * @since 4.12
155aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin     */
156aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    public static class Builder {
157aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        private boolean lookForStuckThread = false;
158aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        private long timeout = 0;
159aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        private TimeUnit timeUnit = TimeUnit.SECONDS;
160aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
161aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        protected Builder() {
162aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        }
163aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
164aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        /**
165aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * Specifies the time to wait before timing out the test.
166aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         *
167aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * <p>If this is not called, or is called with a
168aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * {@code timeout} of {@code 0}, the returned {@code Timeout}
169aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * rule instance will cause the tests to wait forever to
170aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * complete, however the tests will still launch from a
171aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * separate thread. This can be useful for disabling timeouts
172aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * in environments where they are dynamically set based on
173aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * some property.
174aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         *
175aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * @param timeout the maximum time to wait
176aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * @param unit the time unit of the {@code timeout} argument
177aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * @return {@code this} for method chaining.
178aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         */
179aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        public Builder withTimeout(long timeout, TimeUnit unit) {
180aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            this.timeout = timeout;
181aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            this.timeUnit = unit;
182aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            return this;
183aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        }
184aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
185aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        protected long getTimeout() {
186aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            return timeout;
187aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        }
188aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
189aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        protected TimeUnit getTimeUnit()  {
190aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            return timeUnit;
191aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        }
192aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin
193aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        /**
194aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         * Builds a {@link Timeout} instance using the values in this builder.,
195aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin         */
196aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        public Timeout build() {
197aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin            return new Timeout(this);
198aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin        }
199aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin    }
200aeb93fc33cae3aadbb9b46083350ad2dc9aea645Paul Duffin}
201