From 4156f43b51c6f2d42df6e45535e1967aa46514d3 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 14 Dec 2016 12:50:47 +0000 Subject: Remove support for stuck threads The experimental support for stuck threads requires access to the java.lang.management package which is not supported on Android. Bug: 33613916 Test: make checkbuild Change-Id: I0146a9881f34f6da8f8f24c1ab14131e32733465 --- .../internal/runners/statements/FailOnTimeout.java | 154 +-------------------- 1 file changed, 2 insertions(+), 152 deletions(-) (limited to 'src/main/java/org/junit/internal') diff --git a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java index 7f4f0d5..9fad35b 100644 --- a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java +++ b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java @@ -1,8 +1,5 @@ package org.junit.internal.runners.statements; -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; -import java.util.Arrays; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -10,7 +7,6 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; import org.junit.runners.model.TestTimedOutException; @@ -18,8 +14,6 @@ public class FailOnTimeout extends Statement { private final Statement originalStatement; private final TimeUnit timeUnit; private final long timeout; - private final boolean lookForStuckThread; - private volatile ThreadGroup threadGroup = null; /** * Returns a new builder for building an instance. @@ -46,7 +40,6 @@ public class FailOnTimeout extends Statement { originalStatement = statement; timeout = builder.timeout; timeUnit = builder.unit; - lookForStuckThread = builder.lookForStuckThread; } /** @@ -55,7 +48,6 @@ public class FailOnTimeout extends Statement { * @since 4.12 */ public static class Builder { - private boolean lookForStuckThread = false; private long timeout = 0; private TimeUnit unit = TimeUnit.SECONDS; @@ -87,20 +79,6 @@ public class FailOnTimeout extends Statement { return this; } - /** - * Specifies whether to look for a stuck thread. If a timeout occurs and this - * feature is enabled, the test will look for a thread that appears to be stuck - * and dump its backtrace. This feature is experimental. Behavior may change - * after the 4.12 release in response to feedback. - * - * @param enable {@code true} to enable the feature - * @return {@code this} for method chaining. - */ - public Builder withLookingForStuckThread(boolean enable) { - this.lookForStuckThread = enable; - return this; - } - /** * Builds a {@link FailOnTimeout} instance using the values in this builder, * wrapping the given statement. @@ -119,8 +97,7 @@ public class FailOnTimeout extends Statement { public void evaluate() throws Throwable { CallableStatement callable = new CallableStatement(); FutureTask task = new FutureTask(callable); - threadGroup = new ThreadGroup("FailOnTimeoutGroup"); - Thread thread = new Thread(threadGroup, task, "Time-limited test"); + Thread thread = new Thread(task, "Time-limited test"); thread.setDaemon(true); thread.start(); callable.awaitStarted(); @@ -154,139 +131,12 @@ public class FailOnTimeout extends Statement { private Exception createTimeoutException(Thread thread) { StackTraceElement[] stackTrace = thread.getStackTrace(); - final Thread stuckThread = lookForStuckThread ? getStuckThread(thread) : null; Exception currThreadException = new TestTimedOutException(timeout, timeUnit); if (stackTrace != null) { currThreadException.setStackTrace(stackTrace); thread.interrupt(); } - if (stuckThread != null) { - Exception stuckThreadException = - new Exception ("Appears to be stuck in thread " + - stuckThread.getName()); - stuckThreadException.setStackTrace(getStackTrace(stuckThread)); - return new MultipleFailureException( - Arrays.asList(currThreadException, stuckThreadException)); - } else { - return currThreadException; - } - } - - /** - * Retrieves the stack trace for a given thread. - * @param thread The thread whose stack is to be retrieved. - * @return The stack trace; returns a zero-length array if the thread has - * terminated or the stack cannot be retrieved for some other reason. - */ - private StackTraceElement[] getStackTrace(Thread thread) { - try { - return thread.getStackTrace(); - } catch (SecurityException e) { - return new StackTraceElement[0]; - } - } - - /** - * Determines whether the test appears to be stuck in some thread other than - * the "main thread" (the one created to run the test). This feature is experimental. - * Behavior may change after the 4.12 release in response to feedback. - * @param mainThread The main thread created by {@code evaluate()} - * @return The thread which appears to be causing the problem, if different from - * {@code mainThread}, or {@code null} if the main thread appears to be the - * problem or if the thread cannot be determined. The return value is never equal - * to {@code mainThread}. - */ - private Thread getStuckThread(Thread mainThread) { - if (threadGroup == null) { - return null; - } - Thread[] threadsInGroup = getThreadArray(threadGroup); - if (threadsInGroup == null) { - return null; - } - - // Now that we have all the threads in the test's thread group: Assume that - // any thread we're "stuck" in is RUNNABLE. Look for all RUNNABLE threads. - // If just one, we return that (unless it equals threadMain). If there's more - // than one, pick the one that's using the most CPU time, if this feature is - // supported. - Thread stuckThread = null; - long maxCpuTime = 0; - for (Thread thread : threadsInGroup) { - if (thread.getState() == Thread.State.RUNNABLE) { - long threadCpuTime = cpuTime(thread); - if (stuckThread == null || threadCpuTime > maxCpuTime) { - stuckThread = thread; - maxCpuTime = threadCpuTime; - } - } - } - return (stuckThread == mainThread) ? null : stuckThread; - } - - /** - * Returns all active threads belonging to a thread group. - * @param group The thread group. - * @return The active threads in the thread group. The result should be a - * complete list of the active threads at some point in time. Returns {@code null} - * if this cannot be determined, e.g. because new threads are being created at an - * extremely fast rate. - */ - private Thread[] getThreadArray(ThreadGroup group) { - final int count = group.activeCount(); // this is just an estimate - int enumSize = Math.max(count * 2, 100); - int enumCount; - Thread[] threads; - int loopCount = 0; - while (true) { - threads = new Thread[enumSize]; - enumCount = group.enumerate(threads); - if (enumCount < enumSize) { - break; - } - // if there are too many threads to fit into the array, enumerate's result - // is >= the array's length; therefore we can't trust that it returned all - // the threads. Try again. - enumSize += 100; - if (++loopCount >= 5) { - return null; - } - // threads are proliferating too fast for us. Bail before we get into - // trouble. - } - return copyThreads(threads, enumCount); - } - - /** - * Returns an array of the first {@code count} Threads in {@code threads}. - * (Use instead of Arrays.copyOf to maintain compatibility with Java 1.5.) - * @param threads The source array. - * @param count The maximum length of the result array. - * @return The first {@count} (at most) elements of {@code threads}. - */ - private Thread[] copyThreads(Thread[] threads, int count) { - int length = Math.min(count, threads.length); - Thread[] result = new Thread[length]; - for (int i = 0; i < length; i++) { - result[i] = threads[i]; - } - return result; - } - - /** - * Returns the CPU time used by a thread, if possible. - * @param thr The thread to query. - * @return The CPU time used by {@code thr}, or 0 if it cannot be determined. - */ - private long cpuTime (Thread thr) { - ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); - if (mxBean.isThreadCpuTimeSupported()) { - try { - return mxBean.getThreadCpuTime(thr.getId()); - } catch (UnsupportedOperationException e) { - } - } - return 0; + return currThreadException; } private class CallableStatement implements Callable { -- cgit v1.2.3