aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2016-12-14 12:50:47 +0000
committerPaul Duffin <paulduffin@google.com>2016-12-20 15:52:52 +0000
commit4156f43b51c6f2d42df6e45535e1967aa46514d3 (patch)
treeca9d24808c88cad0dc96ea4eb186972b8073781f /src
parentc8055484aac0d002d00140b789711414f4130428 (diff)
downloadjunit-4156f43b51c6f2d42df6e45535e1967aa46514d3.tar.gz
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
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java154
-rw-r--r--src/main/java/org/junit/rules/Timeout.java33
2 files changed, 2 insertions, 185 deletions
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;
@@ -88,20 +80,6 @@ public class FailOnTimeout extends Statement {
}
/**
- * 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<Throwable> task = new FutureTask<Throwable>(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.<Throwable>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<Throwable> {
diff --git a/src/main/java/org/junit/rules/Timeout.java b/src/main/java/org/junit/rules/Timeout.java
index 45a5bc5..8d382df 100644
--- a/src/main/java/org/junit/rules/Timeout.java
+++ b/src/main/java/org/junit/rules/Timeout.java
@@ -40,7 +40,6 @@ import java.util.concurrent.TimeUnit;
public class Timeout implements TestRule {
private final long timeout;
private final TimeUnit timeUnit;
- private final boolean lookForStuckThread;
/**
* Returns a new builder for building an instance.
@@ -80,7 +79,6 @@ public class Timeout implements TestRule {
public Timeout(long timeout, TimeUnit timeUnit) {
this.timeout = timeout;
this.timeUnit = timeUnit;
- lookForStuckThread = false;
}
/**
@@ -92,7 +90,6 @@ public class Timeout implements TestRule {
protected Timeout(Builder builder) {
timeout = builder.getTimeout();
timeUnit = builder.getTimeUnit();
- lookForStuckThread = builder.getLookingForStuckThread();
}
/**
@@ -125,16 +122,6 @@ public class Timeout implements TestRule {
}
/**
- * Gets whether this {@code Timeout} will look for a stuck thread
- * when the test times out.
- *
- * @since 4.12
- */
- protected final boolean getLookingForStuckThread() {
- return lookForStuckThread;
- }
-
- /**
* Creates a {@link Statement} that will run the given
* {@code statement}, and timeout the operation based
* on the values configured in this rule. Subclasses
@@ -146,7 +133,6 @@ public class Timeout implements TestRule {
Statement statement) throws Exception {
return FailOnTimeout.builder()
.withTimeout(timeout, timeUnit)
- .withLookingForStuckThread(lookForStuckThread)
.build(statement);
}
@@ -205,25 +191,6 @@ public class Timeout implements TestRule {
}
/**
- * Specifies whether to look for a stuck thread. If a timeout occurs and this
- * feature is enabled, the rule 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;
- }
-
- protected boolean getLookingForStuckThread() {
- return lookForStuckThread;
- }
-
-
- /**
* Builds a {@link Timeout} instance using the values in this builder.,
*/
public Timeout build() {