--- jsr166/src/test/tck/JSR166TestCase.java 2015/10/05 22:34:45 1.167 +++ jsr166/src/test/tck/JSR166TestCase.java 2015/10/09 16:24:12 1.173 @@ -20,6 +20,8 @@ import java.lang.management.ThreadMXBean import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Paths; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; @@ -52,6 +54,7 @@ import java.util.concurrent.ThreadFactor import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.framework.AssertionFailedError; @@ -188,7 +191,9 @@ public class JSR166TestCase extends Test return (regex == null) ? null : Pattern.compile(regex); } + // Instrumentation to debug very rare, but very annoying hung test runs. static volatile TestCase currentTestCase; + // static volatile int currentRun = 0; static { Runnable checkForWedgedTest = new Runnable() { public void run() { // avoid spurious reports with enormous runsPerTest @@ -197,9 +202,15 @@ public class JSR166TestCase extends Test try { MINUTES.sleep(timeoutMinutes); } catch (InterruptedException unexpected) { break; } if (lastTestCase == currentTestCase) { - System.err.println - ("Looks like we're stuck running test: " - + lastTestCase); + System.err.printf( + "Looks like we're stuck running test: %s%n", + lastTestCase); +// System.err.printf( +// "Looks like we're stuck running test: %s (%d/%d)%n", +// lastTestCase, currentRun, runsPerTest); + System.err.println("availableProcessors=" + + Runtime.getRuntime().availableProcessors()); + System.err.printf("cpu model = %s%n", cpuModel()); dumpTestThreads(); // one stack dump is probably enough; more would be spam break; @@ -211,6 +222,16 @@ public class JSR166TestCase extends Test thread.start(); } + public static String cpuModel() { + try { + Matcher matcher = Pattern.compile("model name\\s*: (.*)") + .matcher(new String( + Files.readAllBytes(Paths.get("/proc/cpuinfo")), "UTF-8")); + matcher.find(); + return matcher.group(1); + } catch (Exception ex) { return null; } + } + public void runBare() throws Throwable { currentTestCase = this; if (methodFilter == null @@ -220,6 +241,7 @@ public class JSR166TestCase extends Test protected void runTest() throws Throwable { for (int i = 0; i < runsPerTest; i++) { + // currentRun = i; if (profileTests) runTestProfiled(); else @@ -1203,7 +1225,7 @@ public class JSR166TestCase extends Test } finally { if (t.getState() != Thread.State.TERMINATED) { t.interrupt(); - fail("Test timed out"); + threadFail("Test timed out"); } } }