/******************************************************************************* * Copyright (c) 2016 Frank Becker and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Frank Becker - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.commons.sdk.util; import java.text.MessageFormat; import java.util.Iterator; import java.util.List; import java.util.Timer; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; @RunListener.ThreadSafe public class JUnitExecutionListener extends RunListener { private static JUnitExecutionListener INSTANCE; public static JUnitExecutionListener getDefault() { return INSTANCE; } public static JUnitExecutionListener createDefault() { if (INSTANCE == null) { INSTANCE = new JUnitExecutionListener(); return INSTANCE; } return null; } private final CopyOnWriteArrayList<String> ingored = new CopyOnWriteArrayList<String>(); /** * Tests may execute in parallel and hence multiple dump threads maybe scheduled concurrently. */ private final ConcurrentHashMap<Description, DumpThreadTask> taskByTest = new ConcurrentHashMap<Description, DumpThreadTask>(); public final static long DELAY = 10 * 60 * 1000; private final Timer timer = new Timer(true); @Override public void testRunFinished(Result result) throws Exception { dumpResults(result); } @Override public void testStarted(Description description) throws Exception { System.err.println("Running " + description.toString()); DumpThreadTask task = new DumpThreadTask(description.toString()); taskByTest.put(description, task); timer.schedule(task, DELAY); } @Override public void testFinished(Description description) throws Exception { DumpThreadTask task = taskByTest.remove(description); if (task != null) { task.cancel(); } // clear flag in case timeout occurred Thread.interrupted(); } @Override public void testFailure(Failure failure) throws Exception { if (failure.getException() instanceof AssertionError) { System.err.println("[FAILURE]"); } else { System.err.println("[ERROR]"); } } @Override public void testIgnored(Description description) throws Exception { System.err.println("Ignored " + description.getMethodName()); ingored.add(description.getMethodName()); } private void dumpErrorList(List<Failure> failures) { System.err.println("Error: "); Iterator<Failure> it = failures.iterator(); while (it.hasNext()) { Failure failure = it.next(); if (failure.getException() instanceof AssertionError) { continue; } System.err.print(" "); System.err.println(failure.toString()); } } private void dumpFailureList(List<Failure> failures) { System.err.println("Failures: "); Iterator<Failure> it = failures.iterator(); while (it.hasNext()) { Failure failure = it.next(); if (!(failure.getException() instanceof AssertionError)) { continue; } System.err.print(" "); System.err.println(failure.toString()); } } private void dumpIgnored() { System.err.println("Ignored: "); Iterator<String> it = ingored.iterator(); while (it.hasNext()) { System.err.print(" "); System.err.println(it.next()); } } private void dumpResults(Result result) { if (result.getFailureCount() > 0) { System.err.println(); dumpFailureList(result.getFailures()); dumpErrorList(result.getFailures()); } if (result.getIgnoreCount() > 0) { System.err.println(); dumpIgnored(); } int failedCount = result.getFailureCount(); System.err.println(); System.err.println(MessageFormat.format("{0} out of {1} tests failed ({2} tests skipped)", result.getFailureCount(), result.getRunCount() + result.getIgnoreCount(), result.getIgnoreCount())); } }