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