You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ma...@apache.org on 2021/04/08 07:52:14 UTC

[cassandra] branch trunk updated: Add JStackJUnitTask to avoid downloading the jar

This is an automated email from the ASF dual-hosted git repository.

marcuse pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 6a45728  Add JStackJUnitTask to avoid downloading the jar
6a45728 is described below

commit 6a45728b089f431338d907d135df909aac9aacae
Author: Marcus Eriksson <ma...@apache.org>
AuthorDate: Wed Apr 7 10:23:18 2021 +0200

    Add JStackJUnitTask to avoid downloading the jar
    
    Patch by marcuse; reviewed by Brandon Williams, David Capwell, Michael Semb Wever for CASSANDRA-16570
---
 .build/build-resolver.xml                          |  16 +--
 build.xml                                          |   7 +-
 .../unit/org/apache/cassandra/JStackJUnitTask.java | 122 +++++++++++++++++++++
 3 files changed, 128 insertions(+), 17 deletions(-)

diff --git a/.build/build-resolver.xml b/.build/build-resolver.xml
index e71fd54..dbce99d 100644
--- a/.build/build-resolver.xml
+++ b/.build/build-resolver.xml
@@ -38,12 +38,6 @@
     <property name="lib.download.base.url" value="https://raw.githubusercontent.com/apache/cassandra/${lib.download.sha}" />
     <property name="lib.download.url.postfix" value="" />
 
-    <!-- jstackunit is not in maven central -->
-    <property name="jstackunit.local" value="${user.home}/.m2/repository/org/krummas/junit/jstackjunit/0.0.1/jstackjunit-0.0.1.jar"/>
-    <condition property="jstackunit.jar.exists">
-        <available file="${jstackunit.local}" />
-    </condition>
-
     <path id="resolver-ant-tasks.classpath" path="${resolver-ant-tasks.local}" />
 
     <!--
@@ -58,12 +52,6 @@
              dest="${resolver-ant-tasks.local}" usetimestamp="true" quiet="true"/>
     </target>
 
-    <target name="_jstackunit_download" unless="jstackunit.jar.exists" description="Fetch jstackunit">
-        <echo>Downloading jstackunit...</echo>
-        <mkdir dir="${user.home}/.m2/repository/org/krummas/junit/jstackjunit/0.0.1" />
-        <get src="${artifact.github.release}/krummas/jstackjunit/releases/download/v0.0.1/jstackjunit-0.0.1.jar" dest="${jstackunit.local}" usetimestamp="true" quiet="true"/>
-    </target>
-
     <target name="resolver-init" depends="init,_resolver_download" unless="resolver-ant-tasks.initialized" description="Initialize Resolver ANT Tasks">
 
         <typedef uri="antlib:org.apache.maven.resolver.ant" resource="org/apache/maven/resolver/ant/antlib.xml" classpathref="resolver-ant-tasks.classpath" />
@@ -177,7 +165,7 @@
         <property name="resolver-ant-tasks.initialized" value="true"/>
     </target>
 
-    <target name="resolver-retrieve-build" depends="resolver-init,_jstackunit_download,write-poms">
+    <target name="resolver-retrieve-build" depends="resolver-init,write-poms">
         <resolvepom file="${build.dir}/${final.name}.pom" id="all-pom" />
         <resolvepom file="${build.dir}/tmp-${final.name}-deps.pom" id="pom-deps" />
 
@@ -190,7 +178,6 @@
             <files dir="${test.lib}/jars" layout="{artifactId}-{version}-{classifier}.{extension}" scopes="test,!provide,!system"/>
         </resolve>
 
-        <copy todir="${test.lib}/jars/" file="${jstackunit.local}" quiet="true"/>
 
         <!-- jacoco agent jar comes wrapped in a jar -->
         <unzip src="${user.home}/.m2/repository/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}.jar" dest="${build.dir.lib}/jars">
@@ -252,7 +239,6 @@
             <file file="${user.home}/.m2/repository/org/apache/cassandra/deps/futures-2.1.6-py2.py3-none-any.zip"/>
             <file file="${user.home}/.m2/repository/org/apache/cassandra/deps/cassandra-driver-internal-only-3.25.0.zip"/>
             <file file="${user.home}/.m2/repository/org/apache/cassandra/deps/six-1.12.0-py2.py3-none-any.zip"/>
-            <file file="${user.home}/.m2/repository/org/krummas/junit/jstackjunit/0.0.1/jstackjunit-0.0.1.jar"/>
             <file file="${user.home}/.m2/repository/org/apache/cassandra/deps/geomet-0.1.0.zip"/>
         </copy>
         <copy todir="${build.lib}/sigar-bin/" quiet="true">
diff --git a/build.xml b/build.xml
index 15f3219..93fb254 100644
--- a/build.xml
+++ b/build.xml
@@ -1333,8 +1333,11 @@
                  else="">
         <istrue value="${usejacoco}"/>
       </condition>
-      <!-- use https://github.com/krummas/jstackjunit to get thread dumps when unit tests time out -->
-      <taskdef name="junit-timeout" classname="org.krummas.junit.JStackJUnitTask" classpath="${test.lib}/jars/jstackjunit-0.0.1.jar"/>
+      <taskdef name="junit-timeout" classname="org.apache.cassandra.JStackJUnitTask">
+        <classpath>
+          <pathelement location="${test.classes}"/>
+        </classpath>
+      </taskdef>
       <mkdir dir="${build.test.dir}/cassandra"/>
       <mkdir dir="${build.test.dir}/output"/>
       <mkdir dir="${build.test.dir}/output/@{testtag}"/>
diff --git a/test/unit/org/apache/cassandra/JStackJUnitTask.java b/test/unit/org/apache/cassandra/JStackJUnitTask.java
new file mode 100644
index 0000000..69480a6
--- /dev/null
+++ b/test/unit/org/apache/cassandra/JStackJUnitTask.java
@@ -0,0 +1,122 @@
+/*
+ * 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.cassandra;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.ExecuteWatchdog;
+import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask;
+import org.apache.tools.ant.util.Watchdog;
+
+public class JStackJUnitTask extends JUnitTask
+{
+    private Integer timeout;
+
+    public JStackJUnitTask() throws Exception
+    {
+    }
+
+    @Override
+    public void setTimeout(Integer timeout)
+    {
+        this.timeout = timeout;
+        super.setTimeout(timeout);
+    }
+
+    @Override
+    public ExecuteWatchdog createWatchdog() throws BuildException
+    {
+        return new JStackWatchDog(timeout);
+    }
+
+    private static class JStackWatchDog extends ExecuteWatchdog
+    {
+        private long pid;
+
+        public JStackWatchDog(long timeout)
+        {
+            super(timeout);
+        }
+
+        public JStackWatchDog(int timeout)
+        {
+            super(timeout);
+        }
+
+        @Override
+        public synchronized void start(Process process)
+        {
+            this.pid = getPid(process);
+            super.start(process);
+        }
+
+        @Override
+        public synchronized void timeoutOccured(Watchdog w)
+        {
+            if (pid > 0)
+            {
+                ProcessBuilder pb = new ProcessBuilder("jstack","-l", String.valueOf(pid));
+                try
+                {
+                    Process p = pb.start();
+                    try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())))
+                    {
+                        StringBuilder sb = new StringBuilder();
+                        String line;
+                        while((line = br.readLine()) != null)
+                        {
+                            sb.append(line).append("\n");
+                        }
+                        System.out.println(sb.toString());
+                    }
+                }
+                catch (IOException e)
+                {
+                    System.err.println("Could not get stack for "+pid);
+                    e.printStackTrace();
+                }
+            }
+            super.timeoutOccured(w);
+        }
+
+        private long getPid(Process process)
+        {
+            if (process.getClass().getName().equals("java.lang.UNIXProcess"))
+            {
+                try
+                {
+                    Field f = process.getClass().getDeclaredField("pid");
+                    f.setAccessible(true);
+                    long pid = f.getLong(process);
+                    f.setAccessible(false);
+                    return pid;
+                }
+                catch (IllegalAccessException | NoSuchFieldException e)
+                {
+                    System.err.println("Could not get PID");
+                }
+            }
+            return -1;
+        }
+    }
+
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org