HBASE-19986 If HBaseTestClassRule timesout a test, thread dump

Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/c2ee82c9
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/c2ee82c9
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/c2ee82c9

Branch: refs/heads/HBASE-19064
Commit: c2ee82c9091a721e22a0eb69be17cd0217739099
Parents: 00f8877
Author: Michael Stack <st...@apache.org>
Authored: Mon Feb 12 14:00:35 2018 -0800
Committer: Michael Stack <st...@apache.org>
Committed: Mon Feb 12 15:28:40 2018 -0800

----------------------------------------------------------------------
 .../apache/hadoop/hbase/HBaseClassTestRule.java |   3 +-
 .../org/apache/hadoop/hbase/TestTimeout.java    |  15 +-
 .../hadoop/hbase/TimedOutTestsListener.java     | 177 +++++++++++++++++++
 .../hadoop/hbase/TimedOutTestsListener.java     | 176 ------------------
 pom.xml                                         |   2 +-
 5 files changed, 194 insertions(+), 179 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/c2ee82c9/hbase-common/src/test/java/org/apache/hadoop/hbase/HBaseClassTestRule.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/test/java/org/apache/hadoop/hbase/HBaseClassTestRule.java 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/HBaseClassTestRule.java
index bcde826..b964872 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/HBaseClassTestRule.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/HBaseClassTestRule.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hbase;
 
 import java.util.concurrent.TimeUnit;
+
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;

http://git-wip-us.apache.org/repos/asf/hbase/blob/c2ee82c9/hbase-common/src/test/java/org/apache/hadoop/hbase/TestTimeout.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestTimeout.java 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestTimeout.java
index 343108e..495667c 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestTimeout.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestTimeout.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hbase;
 
 import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.apache.hadoop.hbase.util.Threads;
 import org.junit.ClassRule;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -41,6 +42,18 @@ public class TestTimeout {
      */
     @Ignore @Test
     public void infiniteLoop() {
-        while (true) {}
+      // Launch a background non-daemon thread.
+      Thread t = new Thread("HangingThread") {
+        public void run() {
+          synchronized(this) {
+            while(true) {
+            }
+          }
+        }
+      };
+      t.start();
+      while (true) {
+        // Just hang out too.
+      }
    }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/c2ee82c9/hbase-common/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java
new file mode 100644
index 0000000..d5c87f3
--- /dev/null
+++ 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java
@@ -0,0 +1,177 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.management.LockInfo;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MonitorInfo;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+/**
+ * JUnit run listener which prints full thread dump into System.err
+ * in case a test is failed due to timeout.
+ */
+public class TimedOutTestsListener extends RunListener {
+
+  static final String TEST_TIMED_OUT_PREFIX = "test timed out after";
+  
+  private static String INDENT = "    ";
+
+  private final PrintWriter output;
+  
+  public TimedOutTestsListener() {
+    this.output = new PrintWriter(System.err);
+  }
+  
+  public TimedOutTestsListener(PrintWriter output) {
+    this.output = output;
+  }
+
+  @Override
+  public void testFailure(Failure failure) throws Exception {
+    if (failure != null && failure.getMessage() != null
+        && failure.getMessage().startsWith(TEST_TIMED_OUT_PREFIX)) {
+      output.println("====> TEST TIMED OUT. PRINTING THREAD DUMP. <====");
+      output.println();
+      output.print(buildThreadDiagnosticString());
+    }
+    output.flush();
+  }
+  
+  public static String buildThreadDiagnosticString() {
+    StringWriter sw = new StringWriter();
+    PrintWriter output = new PrintWriter(sw);
+    
+    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss,SSS");
+    output.println(String.format("Timestamp: %s", dateFormat.format(new 
Date())));
+    output.println();
+    output.println(buildThreadDump());
+    
+    String deadlocksInfo = buildDeadlockInfo();
+    if (deadlocksInfo != null) {
+      output.println("====> DEADLOCKS DETECTED <====");
+      output.println();
+      output.println(deadlocksInfo);
+    }
+
+    return sw.toString();
+  }
+
+  static String buildThreadDump() {
+    StringBuilder dump = new StringBuilder();
+    Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
+    for (Map.Entry<Thread, StackTraceElement[]> e : stackTraces.entrySet()) {
+      Thread thread = e.getKey();
+      dump.append(String.format(
+          "\"%s\" %s prio=%d tid=%d %s\njava.lang.Thread.State: %s",
+          thread.getName(),
+          (thread.isDaemon() ? "daemon" : ""),
+          thread.getPriority(),
+          thread.getId(),
+          Thread.State.WAITING.equals(thread.getState()) ? 
+              "in Object.wait()" : 
thread.getState().name().toLowerCase(Locale.ROOT),
+          Thread.State.WAITING.equals(thread.getState()) ? 
+              "WAITING (on object monitor)" : thread.getState()));
+      for (StackTraceElement stackTraceElement : e.getValue()) {
+        dump.append("\n        at ");
+        dump.append(stackTraceElement);
+      }
+      dump.append("\n");
+    }
+    return dump.toString();
+  }
+  
+  static String buildDeadlockInfo() {
+    ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
+    long[] threadIds = threadBean.findMonitorDeadlockedThreads();
+    if (threadIds != null && threadIds.length > 0) {
+      StringWriter stringWriter = new StringWriter();
+      PrintWriter out = new PrintWriter(stringWriter);
+      
+      ThreadInfo[] infos = threadBean.getThreadInfo(threadIds, true, true);
+      for (ThreadInfo ti : infos) {
+        printThreadInfo(ti, out);
+        printLockInfo(ti.getLockedSynchronizers(), out);
+        out.println();
+      }
+      
+      out.close();
+      return stringWriter.toString();
+    } else {
+      return null;
+    }
+  }
+  
+  private static void printThreadInfo(ThreadInfo ti, PrintWriter out) {
+    // print thread information
+    printThread(ti, out);
+
+    // print stack trace with locks
+    StackTraceElement[] stacktrace = ti.getStackTrace();
+    MonitorInfo[] monitors = ti.getLockedMonitors();
+    for (int i = 0; i < stacktrace.length; i++) {
+      StackTraceElement ste = stacktrace[i];
+      out.println(INDENT + "at " + ste.toString());
+      for (MonitorInfo mi : monitors) {
+        if (mi.getLockedStackDepth() == i) {
+          out.println(INDENT + "  - locked " + mi);
+        }
+      }
+    }
+    out.println();
+  }
+
+  private static void printThread(ThreadInfo ti, PrintWriter out) {
+    out.print("\"" + ti.getThreadName() + "\"" + " Id="
+        + ti.getThreadId() + " in " + ti.getThreadState());
+    if (ti.getLockName() != null) {
+      out.print(" on lock=" + ti.getLockName());
+    }
+    if (ti.isSuspended()) {
+      out.print(" (suspended)");
+    }
+    if (ti.isInNative()) {
+      out.print(" (running in native)");
+    }
+    out.println();
+    if (ti.getLockOwnerName() != null) {
+      out.println(INDENT + " owned by " + ti.getLockOwnerName() + " Id="
+          + ti.getLockOwnerId());
+    }
+  }
+
+  private static void printLockInfo(LockInfo[] locks, PrintWriter out) {
+    out.println(INDENT + "Locked synchronizers: count = " + locks.length);
+    for (LockInfo li : locks) {
+      out.println(INDENT + "  - " + li);
+    }
+    out.println();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/c2ee82c9/hbase-server/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java
deleted file mode 100644
index 5beeace..0000000
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/TimedOutTestsListener.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.hbase;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.management.LockInfo;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MonitorInfo;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Map;
-
-import org.junit.runner.notification.Failure;
-import org.junit.runner.notification.RunListener;
-
-/**
- * JUnit run listener which prints full thread dump into System.err
- * in case a test is failed due to timeout.
- */
-public class TimedOutTestsListener extends RunListener {
-
-  static final String TEST_TIMED_OUT_PREFIX = "test timed out after";
-  
-  private static String INDENT = "    ";
-
-  private final PrintWriter output;
-  
-  public TimedOutTestsListener() {
-    this.output = new PrintWriter(System.err);
-  }
-  
-  public TimedOutTestsListener(PrintWriter output) {
-    this.output = output;
-  }
-
-  @Override
-  public void testFailure(Failure failure) throws Exception {
-    if (failure != null && failure.getMessage() != null 
-        && failure.getMessage().startsWith(TEST_TIMED_OUT_PREFIX)) {
-      output.println("====> TEST TIMED OUT. PRINTING THREAD DUMP. <====");
-      output.println();
-      output.print(buildThreadDiagnosticString());
-    }
-  }
-  
-  public static String buildThreadDiagnosticString() {
-    StringWriter sw = new StringWriter();
-    PrintWriter output = new PrintWriter(sw);
-    
-    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss,SSS");
-    output.println(String.format("Timestamp: %s", dateFormat.format(new 
Date())));
-    output.println();
-    output.println(buildThreadDump());
-    
-    String deadlocksInfo = buildDeadlockInfo();
-    if (deadlocksInfo != null) {
-      output.println("====> DEADLOCKS DETECTED <====");
-      output.println();
-      output.println(deadlocksInfo);
-    }
-
-    return sw.toString();
-  }
-
-  static String buildThreadDump() {
-    StringBuilder dump = new StringBuilder();
-    Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
-    for (Map.Entry<Thread, StackTraceElement[]> e : stackTraces.entrySet()) {
-      Thread thread = e.getKey();
-      dump.append(String.format(
-          "\"%s\" %s prio=%d tid=%d %s\njava.lang.Thread.State: %s",
-          thread.getName(),
-          (thread.isDaemon() ? "daemon" : ""),
-          thread.getPriority(),
-          thread.getId(),
-          Thread.State.WAITING.equals(thread.getState()) ? 
-              "in Object.wait()" : 
thread.getState().name().toLowerCase(Locale.ROOT),
-          Thread.State.WAITING.equals(thread.getState()) ? 
-              "WAITING (on object monitor)" : thread.getState()));
-      for (StackTraceElement stackTraceElement : e.getValue()) {
-        dump.append("\n        at ");
-        dump.append(stackTraceElement);
-      }
-      dump.append("\n");
-    }
-    return dump.toString();
-  }
-  
-  static String buildDeadlockInfo() {
-    ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
-    long[] threadIds = threadBean.findMonitorDeadlockedThreads();
-    if (threadIds != null && threadIds.length > 0) {
-      StringWriter stringWriter = new StringWriter();
-      PrintWriter out = new PrintWriter(stringWriter);
-      
-      ThreadInfo[] infos = threadBean.getThreadInfo(threadIds, true, true);
-      for (ThreadInfo ti : infos) {
-        printThreadInfo(ti, out);
-        printLockInfo(ti.getLockedSynchronizers(), out);
-        out.println();
-      }
-      
-      out.close();
-      return stringWriter.toString();
-    } else {
-      return null;
-    }
-  }
-  
-  private static void printThreadInfo(ThreadInfo ti, PrintWriter out) {
-    // print thread information
-    printThread(ti, out);
-
-    // print stack trace with locks
-    StackTraceElement[] stacktrace = ti.getStackTrace();
-    MonitorInfo[] monitors = ti.getLockedMonitors();
-    for (int i = 0; i < stacktrace.length; i++) {
-      StackTraceElement ste = stacktrace[i];
-      out.println(INDENT + "at " + ste.toString());
-      for (MonitorInfo mi : monitors) {
-        if (mi.getLockedStackDepth() == i) {
-          out.println(INDENT + "  - locked " + mi);
-        }
-      }
-    }
-    out.println();
-  }
-
-  private static void printThread(ThreadInfo ti, PrintWriter out) {
-    out.print("\"" + ti.getThreadName() + "\"" + " Id="
-        + ti.getThreadId() + " in " + ti.getThreadState());
-    if (ti.getLockName() != null) {
-      out.print(" on lock=" + ti.getLockName());
-    }
-    if (ti.isSuspended()) {
-      out.print(" (suspended)");
-    }
-    if (ti.isInNative()) {
-      out.print(" (running in native)");
-    }
-    out.println();
-    if (ti.getLockOwnerName() != null) {
-      out.println(INDENT + " owned by " + ti.getLockOwnerName() + " Id="
-          + ti.getLockOwnerId());
-    }
-  }
-
-  private static void printLockInfo(LockInfo[] locks, PrintWriter out) {
-    out.println(INDENT + "Locked synchronizers: count = " + locks.length);
-    for (LockInfo li : locks) {
-      out.println(INDENT + "  - " + li);
-    }
-    out.println();
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/hbase/blob/c2ee82c9/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b23a966..1cb5082 100755
--- a/pom.xml
+++ b/pom.xml
@@ -677,7 +677,7 @@
             <properties>
               <property>
                 <name>listener</name>
-                
<value>org.apache.hadoop.hbase.HBaseClassTestRuleChecker,org.apache.hadoop.hbase.ResourceCheckerJUnitListener</value>
+                
<value>org.apache.hadoop.hbase.TimedOutTestsListener,org.apache.hadoop.hbase.HBaseClassTestRuleChecker,org.apache.hadoop.hbase.ResourceCheckerJUnitListener</value>
               </property>
             </properties>
           </configuration>

Reply via email to