/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.backend.java.absunit;
import java.util.List;
import abs.backend.java.lib.runtime.ABSException;
import abs.backend.java.lib.types.ABSValue;
import abs.backend.java.observing.TaskStackFrameView;
/**
* An instance of this class is created when a test method is invoked. The
* created instance is used to track the progress and status of the test.
* Eentually, it can be queried if the test passed or failed. There are
* different failure reasons like FAILED (assertion violated), deadlocked or an
* (internal) error.
*
* The status instance also tracks the currently executed line of code which can
* be used to identify the point of failure.
*
*
* @author Richard Bubel
*
*/
public class TestStatus {
/* enumeration of possible test statuses */
enum Status {
/** test method running or at least task created */
ACTIVE,
/* test passed */
OK,
/* test assertion failed */
FAILED,
/* test deadlocked */
DEADLOCKED,
/* test error */
ERROR
}
/* the status of the test */
private Status status;
/* the id of the task executing the tracked test */
private final int taskID;
/* the name of the test method and its class */
private final String testMethod;
private final String className;
/** The value of the parameters of the test method at invocation time */
private final List<ABSValue> args;
/*
* the last executed line of code and the name of the file containing the
* test method
*/
private int line = -1;
private String fileName = "";
/* not iff a test assertion failed or an internal error occurred */
private ABSException exception;
/*
* depth of stack frame of the test's task when the test method has been
* invoked
*/
private final int framesDepth;
public TestStatus(int id, String method, String className, List<ABSValue> args,
List<? extends TaskStackFrameView> frames, Status status) {
taskID = id;
testMethod = method;
this.className = className;
this.args = args;
this.framesDepth = frames == null ? 0 : frames.size();
this.status = status;
}
/* the tasks' stack frame depth when starting the thread */
public int depth() {
return framesDepth;
}
/* formatted text which can be displayed */
public String displayString() {
String result = "<html><body>";
result += "<strong>Class:</strong> " + className + "<br>";
result += "<strong>Method:</strong> " + testMethod + "<br>";
result += "<strong>Arguments:</strong> " + args + "<br>";
result += "<strong>Status:</strong> " + status + "<br>";
if (getException() != null) {
if (exception.isAssertion()) {
result += "<strong>Reason:</strong> Assertion failed.";
if (line > 0) {
result += " at line " + line + " in file " + fileName + "\n";
}
} else if (!exception.isDeadlock()) {
result += "<strong>Reason:</strong> Internal Error,\n";
}
}
return result + "</body></html>";
}
/**
* ABS exception instance of Java backend used to indicate a failure
* situation
*/
public ABSException getException() {
return exception;
}
/* the name of the testmethod */
public String getMethodName() {
return testMethod;
}
/* returns the test status */
public Status getStatus() {
return status;
}
/* returns the id of the task running the test method */
public int getTaskID() {
return taskID;
}
/*
* set the ABSException used by the Java backend to represent a failure
* situation
*/
public void setException(ABSException exception) {
this.exception = exception;
}
/* sets the test status */
public void setStatus(Status status) {
this.status = status;
}
/* toString */
public String toString() {
String result = "";
result += testMethod;
if (getException() != null && getException().isAssertion()) {
result += " at: " + getException().getMessage().substring(0, getException().getMessage().lastIndexOf(':'));
}
return result;
}
/**
* called to update the current execution position of the test method the
* information is used to identify the source code position of the failed
* assertion
*/
public void updatePos(String fileName, int line) {
this.fileName = fileName;
this.line = line;
}
}