RunUtils.java
/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* Xerox/PARC initial implementation
* ******************************************************************/
package org.aspectj.testing.util;
import java.io.PrintStream;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.bridge.IMessageHolder;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.bridge.MessageUtil.IMessageRenderer;
import org.aspectj.testing.harness.bridge.AbstractRunSpec;
import org.aspectj.testing.harness.bridge.IRunSpec;
import org.aspectj.testing.run.IRunStatus;
import org.aspectj.testing.run.RunValidator;
import org.aspectj.util.LangUtil;
/**
*
*/
public class RunUtils {
/** enable verbose for this an any related AbstractRunSpec children */
public static void enableVerbose(AbstractRunSpec spec) { // instanceof hack
LangUtil.throwIaxIfNull(spec, "spec");
spec.runtime.setVerbose(true);
for (Object element : spec.getChildren()) {
IRunSpec child = (IRunSpec) element;
if (child instanceof AbstractRunSpec) {
enableVerbose((AbstractRunSpec) child);
}
}
}
/**
* Calculate failures for this status.
* If the input status has no children and failed, the result is 1.
* If it has children and recurse is false, then
* the result is the number of children whose status has failed
* (so a failed status with some passing and no failing children
* will return 0).
* If it has children and recurse is true,
* then return the number of leaf failures in the tree,
* ignoring (roll-up) node failures.
* @return number of failures in children of this status
*/
public static int numFailures(IRunStatus status, boolean recurse) {
int numFails = 0;
IRunStatus[] children = status.getChildren();
int numChildren = (null == children? 0 : children.length);
if (0 == numChildren) {
if (!RunValidator.NORMAL.runPassed(status)) {
return 1;
}
} else {
// int i = 0;
for (IRunStatus element : children) {
if (recurse) {
numFails += numFailures(element, recurse);
} else {
if (!RunValidator.NORMAL.runPassed(element)) {
numFails++;
}
}
}
}
return numFails;
}
// ------------------------ printing status
public static void printShort(PrintStream out, IRunStatus status) {
if ((null == out) || (null == status)) {
return;
}
printShort(out, "", status);
}
public static void printShort(PrintStream out, String prefix, IRunStatus status) {
int numFails = numFailures(status, true);
String fails = (0 == numFails ? "" : " - " + numFails + " failures");
out.println(prefix + toShortString(status) + fails);
IRunStatus[] children = status.getChildren();
int numChildren = (null == children? 0 : children.length);
if (0 < numChildren) {
int i = 0;
for (IRunStatus element : children) {
printShort(out, prefix + "[" + LangUtil.toSizedString(i++, 3) + "]: ", element);
if (!RunValidator.NORMAL.runPassed(element)) {
numFails++;
}
}
}
}
public static void print(PrintStream out, IRunStatus status) {
if ((null == out) || (null == status)) {
return;
}
print(out, "", status);
}
public static void print(PrintStream out, String prefix, IRunStatus status) {
print(out, prefix, status, MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL);
}
public static void print(PrintStream out, String prefix, IRunStatus status,
IMessageRenderer renderer, IMessageHandler selector) {
String label = status.getIdentifier()
+ (status.runResult() ? "PASS" : "FAIL");
out.println(prefix + label);
out.println(prefix + debugString(status));
IMessageHolder messageHolder = status;
if ((null != messageHolder) && (0 < messageHolder.numMessages(null, true))) {
MessageUtil.print(out, messageHolder, prefix, renderer, selector);
}
Throwable thrown = status.getThrown();
if (null != thrown) {
out.println(prefix + "--- printing stack trace for thrown");
thrown.printStackTrace(out);
}
IRunStatus[] children = status.getChildren();
int numChildren = (null == children? 0 : children.length);
int numFails = 0;
if (0 < numChildren) {
out.println(prefix + "--- printing children [" + numChildren + "]");
int i = 0;
for (IRunStatus element : children) {
print(out, prefix + "[" + LangUtil.toSizedString(i++, 3) + "]: ", element);
if (!RunValidator.NORMAL.runPassed(element)) {
numFails++;
}
}
}
if (0 < numFails) {
label = numFails + " fails " + label;
}
out.println("");
}
public static String debugString(IRunStatus status) {
if (null == status) {
return "null";
}
final String[] LABELS =
new String[] {
"runResult",
"id",
"result",
"numChildren",
"completed",
//"parent",
"abort",
"started",
"thrown",
"messages" };
String runResult = status.runResult() ? "PASS" : "FAIL";
Throwable thrown = status.getThrown();
String thrownString = LangUtil.unqualifiedClassName(thrown);
IRunStatus[] children = status.getChildren();
String numChildren = (null == children? "0" : ""+children.length);
String numMessages = ""+status.numMessages(null, IMessageHolder.EQUAL);
Object[] values =
new Object[] {
runResult,
status.getIdentifier(),
status.getResult(),
numChildren,
status.isCompleted(),
//status.getParent(), // costly if parent printing us
status.getAbortRequest(),
status.started(),
thrownString,
numMessages };
return org.aspectj.testing.util.LangUtil.debugStr(status.getClass(), LABELS, values);
}
public static String toShortString(IRunStatus status) {
if (null == status) {
return "null";
}
String runResult = status.runResult() ? " PASS: " : " FAIL: ";
return (runResult + status.getIdentifier());
}
/** renderer for IRunStatus */
public interface IRunStatusPrinter {
void printRunStatus(PrintStream out, IRunStatus status);
}
public static final IRunStatusPrinter VERBOSE_PRINTER = new IRunStatusPrinter() {
@Override
public String toString() { return "VERBOSE_PRINTER"; }
/** Render IRunStatus produced by running an AjcTest */
@Override
public void printRunStatus(PrintStream out, IRunStatus status) {
printRunStatus(out, status, "");
}
private void printRunStatus(PrintStream out, IRunStatus status, String prefix) {
LangUtil.throwIaxIfNull(out, "out");
LangUtil.throwIaxIfNull(status, "status");
String label = (status.runResult() ? " PASS: " : " FAIL: ")
+ status.getIdentifier();
out.println(prefix + "------------ " + label);
out.println(prefix + "--- result: " + status.getResult());
if (0 < status.numMessages(null, true)) {
out.println(prefix + "--- messages ");
MessageUtil.print(out, status, prefix, MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL);
}
Throwable thrown = status.getThrown();
if (null != thrown) {
out.println(prefix + "--- thrown");
thrown.printStackTrace(out);
}
IRunStatus[] children = status.getChildren();
for (int i = 0; i < children.length; i++) {
String number = "[" + LangUtil.toSizedString(i,3) + "] ";
printRunStatus(out, children[i], prefix + number);
}
}
};
/** print only status and fail/abort messages */
public static final IRunStatusPrinter TERSE_PRINTER = new IRunStatusPrinter() {
@Override
public String toString() { return "TERSE_PRINTER"; }
/** print only status and fail messages */
@Override
public void printRunStatus(PrintStream out, IRunStatus status) {
printRunStatus(out, status, "");
}
private void printRunStatus(PrintStream out, IRunStatus status, String prefix) {
LangUtil.throwIaxIfNull(out, "out");
LangUtil.throwIaxIfNull(status, "status");
String label = (status.runResult() ? "PASS: " : "FAIL: ")
+ status.getIdentifier();
out.println(prefix + label);
Object result = status.getResult();
if ((null != result) && (IRunStatus.PASS != result) && (IRunStatus.FAIL != result)) {
out.println(prefix + "--- result: " + status.getResult());
}
if (0 < status.numMessages(IMessage.FAIL, true)) {
MessageUtil.print(out, status, prefix, MessageUtil.MESSAGE_ALL, MessageUtil.PICK_FAIL_PLUS);
}
Throwable thrown = status.getThrown();
if (null != thrown) {
out.println(prefix + "--- thrown: " + LangUtil.renderException(thrown, true));
}
IRunStatus[] children = status.getChildren();
for (int i = 0; i < children.length; i++) {
if (!children[i].runResult()) {
String number = "[" + LangUtil.toSizedString(i,3) + "] ";
printRunStatus(out, children[i], prefix + number);
}
}
out.println("");
}
};
/** Render IRunStatus produced by running an AjcTest.Suite. */
public static final IRunStatusPrinter AJCSUITE_PRINTER = new IRunStatusPrinter() {
@Override
public String toString() { return "AJCSUITE_PRINTER"; }
/**
* Render IRunStatus produced by running an AjcTest.Suite.
* This renders only test failures and
* a summary at the end.
*/
@Override
public void printRunStatus(PrintStream out, IRunStatus status) {
LangUtil.throwIaxIfNull(out, "out");
LangUtil.throwIaxIfNull(status, "status");
final String prefix = "";
final boolean failed = status.runResult();
String label = (status.runResult() ? "PASS: " : "FAIL: ")
+ status.getIdentifier();
out.println(prefix + label);
// print all messages - these are validator comments
if (0 < status.numMessages(null, true)) {
MessageUtil.print(out, status, "init", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL);
}
// XXX ignore thrown if failed - will be printed as message anyway?
Throwable thrown = status.getThrown();
if ((null != thrown) && !failed) {
out.println(prefix + "--- printing stack trace for thrown");
thrown.printStackTrace(out);
}
IRunStatus[] children = status.getChildren();
int numChildren = (null == children? 0 : children.length);
int numFails = 0;
if (0 < numChildren) {
for (IRunStatus element : children) {
if (!RunValidator.NORMAL.runPassed(element)) {
numFails++;
}
}
}
if (0 < numFails) {
out.println(prefix + "--- " + numFails + " failures when running " + children.length + " tests");
for (int j = 0; j < children.length; j++) {
if (!RunValidator.NORMAL.runPassed(children[j])) {
print(out, prefix + "[" + LangUtil.toSizedString(j, 3) + "]: ", children[j]);
out.println("");
}
}
}
label = "ran " + children.length + " tests"
+ (numFails == 0 ? "" : "(" + numFails + " fails)");
out.println("");
}
};
/** Render IRunStatus produced by running an AjcTest (verbose) */
public static final IRunStatusPrinter AJCTEST_PRINTER = VERBOSE_PRINTER;
/** print this with messages, then children using AJCRUN_PRINTER */
public static final IRunStatusPrinter AJC_PRINTER = new IRunStatusPrinter() {
@Override
public String toString() { return "AJC_PRINTER"; }
/** Render IRunStatus produced by running an AjcTest */
@Override
public void printRunStatus(PrintStream out, IRunStatus status) {
LangUtil.throwIaxIfNull(out, "out");
LangUtil.throwIaxIfNull(status, "status");
String label = (status.runResult() ? " PASS: " : " FAIL: ")
+ status.getIdentifier();
out.println("------------ " + label);
MessageUtil.print(out, status, "", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL);
IRunStatus[] children = status.getChildren();
for (IRunStatus element : children) {
AJCRUN_PRINTER.printRunStatus(out, element);
}
//out.println("------------ END " + label);
out.println("");
}
};
/** print only fail messages */
public static final IRunStatusPrinter AJCRUN_PRINTER = new IRunStatusPrinter() {
@Override
public String toString() { return "AJCRUN_PRINTER"; }
/** Render IRunStatus produced by running an AjcTest child */
@Override
public void printRunStatus(PrintStream out, IRunStatus status) {
LangUtil.throwIaxIfNull(out, "out");
LangUtil.throwIaxIfNull(status, "status");
final boolean orGreater = false;
int numFails = status.numMessages(IMessage.FAIL, orGreater);
if (0 < numFails) {
out.println("--- " + status.getIdentifier());
IMessage[] fails = status.getMessages(IMessage.FAIL, orGreater);
for (int i = 0; i < fails.length; i++) {
out.println("[fail " + LangUtil.toSizedString(i, 3) + "]: "
+ MessageUtil.MESSAGE_ALL.renderToString(fails[i]));
}
}
}
};
private RunUtils() {
}
}