Skip to content

Commit 64cac6f

Browse files
committed
Avoid extra instance creation
1 parent 7cce38f commit 64cac6f

File tree

1 file changed

+50
-69
lines changed

1 file changed

+50
-69
lines changed

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertTimeout.java

+50-69
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@
3939
*/
4040
class AssertTimeout {
4141

42-
private static final PreemptiveTimeoutAssertionExecutor<AssertionFailedError> ASSERTION_ERROR_TIMEOUT_EXECUTOR = new PreemptiveTimeoutAssertionExecutor<>(
43-
new AssertionTimeoutFailureFactory());
44-
4542
private AssertTimeout() {
4643
/* no-op */
4744
}
@@ -117,82 +114,79 @@ static void assertTimeoutPreemptively(Duration timeout, Executable executable, S
117114
}
118115

119116
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);
121118
}
122119

123120
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);
126123
}
127124

128125
static <T> T assertTimeoutPreemptively(Duration timeout, ThrowingSupplier<T> supplier,
129126
Supplier<String> messageSupplier) {
130-
return ASSERTION_ERROR_TIMEOUT_EXECUTOR.executeThrowing(timeout, supplier, messageSupplier);
127+
return assertTimeoutPreemptively(timeout, supplier, messageSupplier, AssertTimeout::createAssertionFailure);
131128
}
132129

133130
static <T, E extends Throwable> T assertTimeoutPreemptively(Duration timeout, ThrowingSupplier<T> supplier,
134131
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());
141134

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);
144139
}
140+
finally {
141+
executorService.shutdownNow();
142+
}
143+
}
145144

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(() -> {
151148
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();
154151
}
155-
finally {
156-
executorService.shutdownNow();
152+
catch (Throwable throwable) {
153+
throw throwAsUncheckedException(throwable);
157154
}
158-
}
155+
});
156+
}
159157

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);
171163
}
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());
192170
}
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);
193178
}
194179
}
195180

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+
196190
private static class ExecutionTimeoutException extends JUnitException {
197191

198192
private static final long serialVersionUID = 1L;
@@ -214,17 +208,4 @@ public Thread newThread(Runnable r) {
214208
return new Thread(r, "junit-timeout-thread-" + threadNumber.getAndIncrement());
215209
}
216210
}
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-
}
230211
}

0 commit comments

Comments
 (0)