This is an automated email from the ASF dual-hosted git repository. brandonwilliams pushed a commit to branch cassandra-3.11 in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit c44dfab9b5b62820d70aba062ba3c9b9117912db Author: Marcus Eriksson <[email protected]> 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 | 17 +-- build.xml | 7 +- .../unit/org/apache/cassandra/JStackJUnitTask.java | 122 +++++++++++++++++++++ 3 files changed, 129 insertions(+), 17 deletions(-) diff --git a/.build/build-resolver.xml b/.build/build-resolver.xml index 20f4244..5b1e9cd 100644 --- a/.build/build-resolver.xml +++ b/.build/build-resolver.xml @@ -34,12 +34,6 @@ <!-- version of lib/ downloads --> <property name="lib.download.sha" value="1371883db3d8bf7d7c54e0baaca89c6c2d2a5abe"/> - <!-- 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}" /> <!-- @@ -54,12 +48,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="https://github.com/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" /> @@ -145,11 +133,11 @@ <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"> <resolver:pom file="${build.dir}/${final.name}.pom" id="all-pom"/> <resolver:pom file="${build.dir}/${ant.project.name}-thrift-${version}.pom" id="thrift-pom"/> <resolver:pom file="${build.dir}/tmp-${final.name}-deps.pom" id="pom-deps"/> - + <resolver:resolve> <remoterepos refid="all"/> <dependencies pomRef="thrift-pom"/> @@ -166,7 +154,6 @@ <files dir="${test.lib}/jars" layout="{artifactId}-{version}-{classifier}.{extension}" scopes="test,!provide,!system"/> </resolver: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"> diff --git a/build.xml b/build.xml index 3b43cdc..9b379e8 100644 --- a/build.xml +++ b/build.xml @@ -1151,8 +1151,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: [email protected] For additional commands, e-mail: [email protected]
