39
39
*/
40
40
class AssertTimeout {
41
41
42
- private static final PreemptiveTimeoutAssertionExecutor <AssertionFailedError > ASSERTION_ERROR_TIMEOUT_EXECUTOR = new PreemptiveTimeoutAssertionExecutor <>(
43
- new AssertionTimeoutFailureFactory ());
44
-
45
42
private AssertTimeout () {
46
43
/* no-op */
47
44
}
@@ -117,82 +114,79 @@ static void assertTimeoutPreemptively(Duration timeout, Executable executable, S
117
114
}
118
115
119
116
static <T > T assertTimeoutPreemptively (Duration timeout , ThrowingSupplier <T > supplier ) {
120
- return ASSERTION_ERROR_TIMEOUT_EXECUTOR . executeThrowing (timeout , supplier , null );
117
+ return assertTimeoutPreemptively (timeout , supplier , null , AssertTimeout :: createAssertionFailure );
121
118
}
122
119
123
120
static <T > T assertTimeoutPreemptively (Duration timeout , ThrowingSupplier <T > supplier , String message ) {
124
- return ASSERTION_ERROR_TIMEOUT_EXECUTOR . executeThrowing (timeout , supplier ,
125
- message == null ? null : () -> message );
121
+ return assertTimeoutPreemptively (timeout , supplier , message == null ? null : () -> message ,
122
+ AssertTimeout :: createAssertionFailure );
126
123
}
127
124
128
125
static <T > T assertTimeoutPreemptively (Duration timeout , ThrowingSupplier <T > supplier ,
129
126
Supplier <String > messageSupplier ) {
130
- return ASSERTION_ERROR_TIMEOUT_EXECUTOR . executeThrowing (timeout , supplier , messageSupplier );
127
+ return assertTimeoutPreemptively (timeout , supplier , messageSupplier , AssertTimeout :: createAssertionFailure );
131
128
}
132
129
133
130
static <T , E extends Throwable > T assertTimeoutPreemptively (Duration timeout , ThrowingSupplier <T > supplier ,
134
131
Supplier <String > messageSupplier , TimeoutFailureFactory <E > failureFactory ) throws E {
135
- return new PreemptiveTimeoutAssertionExecutor <>(failureFactory ).executeThrowing (timeout , supplier ,
136
- messageSupplier );
137
- }
138
-
139
- static class PreemptiveTimeoutAssertionExecutor <T extends Throwable > {
140
- private final TimeoutFailureFactory <T > failureFactory ;
132
+ AtomicReference <Thread > threadReference = new AtomicReference <>();
133
+ ExecutorService executorService = Executors .newSingleThreadExecutor (new TimeoutThreadFactory ());
141
134
142
- PreemptiveTimeoutAssertionExecutor (TimeoutFailureFactory <T > failureFactory ) {
143
- this .failureFactory = failureFactory ;
135
+ try {
136
+ Future <T > future = submitTask (supplier , threadReference , executorService );
137
+ return resolveFutureAndHandleException (future , timeout , messageSupplier , threadReference ::get ,
138
+ failureFactory );
144
139
}
140
+ finally {
141
+ executorService .shutdownNow ();
142
+ }
143
+ }
145
144
146
- <V > V executeThrowing (Duration timeout , ThrowingSupplier <V > supplier , Supplier <String > messageSupplier )
147
- throws T {
148
- AtomicReference <Thread > threadReference = new AtomicReference <>();
149
- ExecutorService executorService = Executors .newSingleThreadExecutor (new TimeoutThreadFactory ());
150
-
145
+ private static <T > Future <T > submitTask (ThrowingSupplier <T > supplier , AtomicReference <Thread > threadReference ,
146
+ ExecutorService executorService ) {
147
+ return executorService .submit (() -> {
151
148
try {
152
- Future < V > future = submitTask ( supplier , threadReference , executorService );
153
- return resolveFutureAndHandleException ( future , timeout , messageSupplier , threadReference :: get );
149
+ threadReference . set ( Thread . currentThread () );
150
+ return supplier . get ( );
154
151
}
155
- finally {
156
- executorService . shutdownNow ( );
152
+ catch ( Throwable throwable ) {
153
+ throw throwAsUncheckedException ( throwable );
157
154
}
158
- }
155
+ });
156
+ }
159
157
160
- private <V > Future <V > submitTask (ThrowingSupplier <V > supplier , AtomicReference <Thread > threadReference ,
161
- ExecutorService executorService ) {
162
- return executorService .submit (() -> {
163
- try {
164
- threadReference .set (Thread .currentThread ());
165
- return supplier .get ();
166
- }
167
- catch (Throwable throwable ) {
168
- throw throwAsUncheckedException (throwable );
169
- }
170
- });
158
+ private static <T , E extends Throwable > T resolveFutureAndHandleException (Future <T > future , Duration timeout ,
159
+ Supplier <String > messageSupplier , Supplier <Thread > threadSupplier , TimeoutFailureFactory <E > failureFactory )
160
+ throws E {
161
+ try {
162
+ return future .get (timeout .toMillis (), TimeUnit .MILLISECONDS );
171
163
}
172
-
173
- private <V > V resolveFutureAndHandleException (Future <V > future , Duration timeout ,
174
- Supplier <String > messageSupplier , Supplier <Thread > threadSupplier ) throws T {
175
- try {
176
- return future .get (timeout .toMillis (), TimeUnit .MILLISECONDS );
177
- }
178
- catch (TimeoutException ex ) {
179
- Thread thread = threadSupplier .get ();
180
- ExecutionTimeoutException cause = null ;
181
- if (thread != null ) {
182
- cause = new ExecutionTimeoutException ("Execution timed out in thread " + thread .getName ());
183
- cause .setStackTrace (thread .getStackTrace ());
184
- }
185
- throw failureFactory .createTimeoutFailure (timeout , messageSupplier , cause );
186
- }
187
- catch (ExecutionException ex ) {
188
- throw throwAsUncheckedException (ex .getCause ());
189
- }
190
- catch (Throwable ex ) {
191
- throw throwAsUncheckedException (ex );
164
+ catch (TimeoutException ex ) {
165
+ Thread thread = threadSupplier .get ();
166
+ ExecutionTimeoutException cause = null ;
167
+ if (thread != null ) {
168
+ cause = new ExecutionTimeoutException ("Execution timed out in thread " + thread .getName ());
169
+ cause .setStackTrace (thread .getStackTrace ());
192
170
}
171
+ throw failureFactory .createTimeoutFailure (timeout , messageSupplier , cause );
172
+ }
173
+ catch (ExecutionException ex ) {
174
+ throw throwAsUncheckedException (ex .getCause ());
175
+ }
176
+ catch (Throwable ex ) {
177
+ throw throwAsUncheckedException (ex );
193
178
}
194
179
}
195
180
181
+ private static AssertionFailedError createAssertionFailure (Duration timeout , Supplier <String > messageSupplier ,
182
+ Throwable cause ) {
183
+ return assertionFailure () //
184
+ .message (messageSupplier ) //
185
+ .reason ("execution timed out after " + timeout .toMillis () + " ms" ) //
186
+ .cause (cause ) //
187
+ .build ();
188
+ }
189
+
196
190
private static class ExecutionTimeoutException extends JUnitException {
197
191
198
192
private static final long serialVersionUID = 1L ;
@@ -214,17 +208,4 @@ public Thread newThread(Runnable r) {
214
208
return new Thread (r , "junit-timeout-thread-" + threadNumber .getAndIncrement ());
215
209
}
216
210
}
217
-
218
- private static class AssertionTimeoutFailureFactory implements TimeoutFailureFactory <AssertionFailedError > {
219
-
220
- @ Override
221
- public AssertionFailedError createTimeoutFailure (Duration timeout , Supplier <String > messageSupplier ,
222
- Throwable cause ) {
223
- return assertionFailure () //
224
- .message (messageSupplier ) //
225
- .reason ("execution timed out after " + timeout .toMillis () + " ms" ) //
226
- .cause (cause ) //
227
- .build ();
228
- }
229
- }
230
211
}
0 commit comments