/**
* 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.openejb.tool.junit;
import org.apache.openejb.util.Pipe;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class OpenEJBJUnitDebugListener extends RunListener {
private static final String OS = System.getProperty("os.name", "unknown");
private static final boolean UNIX = !OS.toLowerCase(Locale.ENGLISH).startsWith("windows");
private static final boolean MONITOR = Boolean.getBoolean("openejb.junit.monitor");
static {
//System.out.println(">>OpenEJBJUnitDebugListener> will debug - unix? " + UNIX + " (" + OS + ")");
}
private MonitoringThread thread;
@Override
public void testRunStarted(final Description description) throws Exception {
if (!UNIX) {
return;
}
if (description != null) {
System.out.println(">>OpenEJBJUnitDebugListener> will monitor " + description.getDisplayName());
}
if (MONITOR) {
thread = new MonitoringThread();
thread.setName(MonitoringThread.class.getSimpleName() + "-" + thread.hashCode());
thread.start();
}
}
@Override
public void testRunFinished(final Result result) throws Exception {
doStop();
}
@Override
public void testStarted(final Description description) throws Exception {
if (description != null) {
System.out.println(">>OpenEJBJUnitDebugListener> started " + description.getDisplayName());
}
}
@Override
public void testFinished(final Description description) throws Exception {
if (description != null) {
System.out.println(">>OpenEJBJUnitDebugListener> finished " + description.getDisplayName());
}
}
@Override
public void testFailure(final Failure failure) throws Exception {
if (failure != null) {
System.out.println(">>OpenEJBJUnitDebugListener> FAILURE on " + failure.getTestHeader());
System.out.println(">>OpenEJBJUnitDebugListener> : " + failure.getDescription());
System.out.println(">>OpenEJBJUnitDebugListener> : " + failure.getException());
System.out.println(">>OpenEJBJUnitDebugListener> : " + failure.getTrace());
}
doStop();
}
@Override
public void testAssumptionFailure(final Failure failure) {
try {
doStop();
} catch (final InterruptedException e) {
Thread.interrupted();
}
}
private void doStop() throws InterruptedException {
if (!UNIX) {
return;
}
if (thread != null) {
thread.done = true;
thread.join();
thread = null;
}
}
public static class MonitoringThread extends Thread {
private volatile boolean done = false;
@Override
public void run() {
long lastCheckpoint = System.currentTimeMillis();
while (!done) {
try {
sleep(50);
} catch (final InterruptedException e) {
Thread.interrupted();
break;
}
final long now = System.currentTimeMillis();
if (now - lastCheckpoint > TimeUnit.MINUTES.toMillis(1)) {
makeSpace();
kill3UNIX();
makeSpace();
lastCheckpoint = now;
}
}
}
private static void makeSpace() {
System.out.println();
System.out.println();
System.out.println();
System.out.flush();
}
public static void kill3UNIX() {
try {
final int pid = getPid();
final Runtime runtime = Runtime.getRuntime();
final Process exec = runtime.exec("kill -3 " + pid);
Pipe.pipe(exec);
exec.waitFor();
} catch (final Exception e1) {
e1.printStackTrace();
}
}
public static int getPid() throws Exception {
final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
final Object mgmt = jvm.get(runtime);
final Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
return Number.class.cast(pid_method.invoke(mgmt)).intValue();
}
}
}