mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-0 Added ability to ignore specific pcode test failures. Corrected
BigInteger to BigFloat conversion used by INT2FLOAT emulation op.
This commit is contained in:
parent
a3ca5a67e1
commit
f56e922d43
9 changed files with 284 additions and 105 deletions
|
@ -18,6 +18,7 @@ package ghidra.test.processors.support;
|
|||
import java.awt.Color;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
|
@ -44,6 +45,8 @@ public class PCodeTestCombinedTestResults {
|
|||
private File xmlFile;
|
||||
private File htmlFile;
|
||||
|
||||
private Map<String, Set<String>> ignoredJunitTestNames = new HashMap<>();
|
||||
|
||||
private Map<String, PCodeTestResults> combinedResults = new HashMap<>();
|
||||
|
||||
PCodeTestCombinedTestResults(File reportsDir, boolean readExisting) throws IOException {
|
||||
|
@ -57,12 +60,31 @@ public class PCodeTestCombinedTestResults {
|
|||
public PCodeTestResults getTestResults(String jUnitName, boolean create) {
|
||||
PCodeTestResults testResults = combinedResults.get(jUnitName);
|
||||
if (testResults == null && create) {
|
||||
testResults = new PCodeTestResults(jUnitName);
|
||||
testResults = new PCodeTestResults(jUnitName, new IgnoreTestPredicate(jUnitName));
|
||||
combinedResults.put(jUnitName, testResults);
|
||||
}
|
||||
return testResults;
|
||||
}
|
||||
|
||||
private class IgnoreTestPredicate implements Predicate<String> {
|
||||
|
||||
private String jUnitName;
|
||||
|
||||
IgnoreTestPredicate(String jUnitName) {
|
||||
this.jUnitName = jUnitName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(String testName) {
|
||||
Set<String> ignoredTestNames = ignoredJunitTestNames.get(jUnitName);
|
||||
if (ignoredTestNames != null) {
|
||||
return ignoredTestNames.contains(testName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void restoreFromXml() throws IOException {
|
||||
|
||||
FileInputStream istream = new FileInputStream(xmlFile);
|
||||
|
@ -80,8 +102,10 @@ public class PCodeTestCombinedTestResults {
|
|||
@SuppressWarnings("unchecked")
|
||||
List<Element> elementList = root.getChildren(PCodeTestResults.TAG_NAME);
|
||||
for (Element element : elementList) {
|
||||
PCodeTestResults testResults = new PCodeTestResults(element);
|
||||
combinedResults.put(testResults.getJUnitName(), testResults);
|
||||
String jUnitName = PCodeTestResults.getJunitName(element);
|
||||
PCodeTestResults testResults =
|
||||
new PCodeTestResults(element, new IgnoreTestPredicate(jUnitName));
|
||||
combinedResults.put(jUnitName, testResults);
|
||||
}
|
||||
}
|
||||
catch (org.jdom.JDOMException je) {
|
||||
|
@ -93,6 +117,14 @@ public class PCodeTestCombinedTestResults {
|
|||
|
||||
}
|
||||
|
||||
public void addIgnoredTests(String junitName, String... testNames) {
|
||||
Set<String> ignoredTestSet =
|
||||
ignoredJunitTestNames.computeIfAbsent(junitName, n -> new HashSet<>());
|
||||
for (String testName : testNames) {
|
||||
ignoredTestSet.add(testName);
|
||||
}
|
||||
}
|
||||
|
||||
void saveToXml() throws IOException {
|
||||
|
||||
File dir = xmlFile.getParentFile();
|
||||
|
@ -226,7 +258,9 @@ public class PCodeTestCombinedTestResults {
|
|||
return;
|
||||
}
|
||||
int count =
|
||||
computeCharCount(testResults.passCount) + computeCharCount(testResults.failCount) +
|
||||
computeCharCount(testResults.passCount) +
|
||||
computeCharCount(testResults.ignoredCount) +
|
||||
computeCharCount(testResults.failCount) +
|
||||
computeCharCount(testResults.callOtherCount) + 2;
|
||||
charCount = Math.max(count, charCount);
|
||||
}
|
||||
|
@ -433,6 +467,8 @@ public class PCodeTestCombinedTestResults {
|
|||
getSummaryHighlightColorClass(testResults) + "\">");
|
||||
writeResultCount(w, testResults.summaryPassCount, Palette.GREEN);
|
||||
w.print("/");
|
||||
writeResultCount(w, testResults.summaryIgnoreCount, Palette.GRAY);
|
||||
w.print("/");
|
||||
writeResultCount(w, testResults.summaryFailCount, Palette.RED);
|
||||
w.print("/");
|
||||
writeResultCount(w, testResults.summaryCallOtherCount, Palette.ORANGE);
|
||||
|
@ -485,9 +521,10 @@ public class PCodeTestCombinedTestResults {
|
|||
for (NamedTestColumn namedTestColumn : namedTestColumns) {
|
||||
String testName = namedTestColumn.getTestName();
|
||||
int pass = testResults.getPassResult(groupName, testName);
|
||||
int ignored = testResults.getIgnoredResult(groupName, testName);
|
||||
int fail = testResults.getFailResult(groupName, testName);
|
||||
int callother = testResults.getCallOtherResult(groupName, testName);
|
||||
int total = pass + fail + callother;
|
||||
int total = pass + ignored + fail + callother;
|
||||
int totalAsserts = testResults.getTotalAsserts(groupName, testName);
|
||||
|
||||
boolean severeFailure = testResults.hadSevereFailure(groupName, testName);
|
||||
|
@ -515,6 +552,8 @@ public class PCodeTestCombinedTestResults {
|
|||
else {
|
||||
writeResultCount(w, pass, Palette.GREEN);
|
||||
w.print("/");
|
||||
writeResultCount(w, ignored, Palette.GRAY);
|
||||
w.print("/");
|
||||
writeResultCount(w, fail, Palette.RED);
|
||||
w.print("/");
|
||||
writeResultCount(w, callother, Palette.ORANGE);
|
||||
|
|
|
@ -48,6 +48,10 @@ public class PCodeTestControlBlock extends PCodeTestAbstractControlBlock {
|
|||
|
||||
private List<PCodeTestGroup> testGroups; // test group data
|
||||
|
||||
// accumulators for tests pass/fail results which have been designated as ignored
|
||||
private int ignoredPassed = 0;
|
||||
private int ignoredFailed = 0;
|
||||
|
||||
// TestInfo data read from program memory
|
||||
private Address onPassFunctionAddress;
|
||||
private Address onErrorFunctionAddress;
|
||||
|
@ -319,6 +323,40 @@ public class PCodeTestControlBlock extends PCodeTestAbstractControlBlock {
|
|||
emuWrite(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4, value);
|
||||
}
|
||||
|
||||
void resultIgnored(String testGroupName, String testName, boolean passed) {
|
||||
if (passed) {
|
||||
++ignoredPassed;
|
||||
}
|
||||
else {
|
||||
++ignoredFailed;
|
||||
}
|
||||
testResults.addIgnoredResult(testGroupName, testName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of passed tests which should be ignored
|
||||
* @return number of passed tests which should be ignored
|
||||
*/
|
||||
int getNumberPassedIgnored() {
|
||||
return ignoredPassed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of failed tests which should be ignored
|
||||
* @return number of failed tests which should be ignored
|
||||
*/
|
||||
int getNumberFailedIgnored() {
|
||||
return ignoredFailed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear ignored test result accumulators
|
||||
*/
|
||||
void clearNumberIgnored() {
|
||||
ignoredFailed = 0;
|
||||
ignoredPassed = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 'numfail' field value from emulation memory state
|
||||
* @param emuTestRunner emulator test runner
|
||||
|
|
|
@ -35,6 +35,10 @@ public class PCodeTestGroup implements Comparable<PCodeTestGroup> {
|
|||
*/
|
||||
public static final String FUNCTION_NAME_PREFIX = "main_";
|
||||
|
||||
public static final String IGNORED_TAG = "IGNORED";
|
||||
private static final String IGNORED_FAILED_TAG = "(" + IGNORED_TAG + ")";
|
||||
private static final String IGNORED_PASSED_TAG = "(Passed and " + IGNORED_TAG + ")";
|
||||
|
||||
public final String testGroupName;
|
||||
public final Address functionEntryPtr;
|
||||
// public final int testCount; // TODO: not yet fully implemented - do not use!
|
||||
|
@ -57,31 +61,41 @@ public class PCodeTestGroup implements Comparable<PCodeTestGroup> {
|
|||
return testGroupName + "@" + functionEntryPtr;
|
||||
}
|
||||
|
||||
boolean isIgnoredTest(String testName) {
|
||||
return mainTestControlBlock.getTestResults().isIgnoredTest(testName);
|
||||
}
|
||||
|
||||
void testPassed(String testName, String errFileName, int errLineNum, Program program,
|
||||
TestLogger logger) {
|
||||
if (isIgnoredTest(testName)) {
|
||||
mainTestControlBlock.resultIgnored(testGroupName, testName, true);
|
||||
String testDetail =
|
||||
getTestDetail(testName, errFileName, errLineNum, program, IGNORED_PASSED_TAG);
|
||||
testFailures.add(testDetail);
|
||||
logger.log(this, "WARNING! Ignored Test Passed: " + testDetail);
|
||||
return;
|
||||
}
|
||||
mainTestControlBlock.getTestResults().addPassResult(testGroupName, testName);
|
||||
}
|
||||
|
||||
void testFailed(String testName, String errFileName, int errLineNum, boolean callOtherFailure,
|
||||
Program program, TestLogger logger) {
|
||||
if (callOtherFailure) {
|
||||
String ignoreTag = "";
|
||||
if (isIgnoredTest(testName)) {
|
||||
mainTestControlBlock.resultIgnored(testGroupName, testName, false);
|
||||
ignoreTag = IGNORED_FAILED_TAG;
|
||||
}
|
||||
else if (callOtherFailure) {
|
||||
mainTestControlBlock.getTestResults().addCallOtherResult(testGroupName, testName);
|
||||
}
|
||||
else {
|
||||
mainTestControlBlock.getTestResults().addFailResult(testGroupName, testName);
|
||||
}
|
||||
String failure = testName;
|
||||
if (testName != null) {
|
||||
Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(program, testName,
|
||||
err -> Msg.error(this, err));
|
||||
if (symbol != null) {
|
||||
failure += " @ " + symbol.getAddress().toString(true);
|
||||
}
|
||||
failure += " (" + errFileName + ":" + errLineNum + ")";
|
||||
}
|
||||
testFailures.add(failure);
|
||||
String testDetail = getTestDetail(testName, errFileName, errLineNum, program, ignoreTag);
|
||||
testFailures.add(testDetail);
|
||||
logger.log(this,
|
||||
"Test Failed: " + failure + (callOtherFailure ? " (callother error)" : ""));
|
||||
"Test Failed: " + testDetail +
|
||||
(callOtherFailure ? " (callother error)" : ""));
|
||||
}
|
||||
|
||||
void severeTestFailure(String testName, String errFileName, int errLineNum, Program program,
|
||||
|
@ -94,6 +108,20 @@ public class PCodeTestGroup implements Comparable<PCodeTestGroup> {
|
|||
testFailures.clear();
|
||||
}
|
||||
|
||||
private String getTestDetail(String testName, String errFileName, int errLineNum,
|
||||
Program program, String ignoreTag) {
|
||||
String testDetail = testName;
|
||||
if (testName != null) {
|
||||
Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(program, testName,
|
||||
err -> Msg.error(this, err));
|
||||
if (symbol != null) {
|
||||
testDetail += " @ " + symbol.getAddress().toString(true);
|
||||
}
|
||||
testDetail += " (" + errFileName + ":" + errLineNum + ") " + ignoreTag;
|
||||
}
|
||||
return testDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of recorded emulation test failures
|
||||
*/
|
||||
|
|
|
@ -18,13 +18,15 @@ package ghidra.test.processors.support;
|
|||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.Element;
|
||||
|
||||
public class PCodeTestResults {
|
||||
|
||||
private String jUnitName;
|
||||
private final String jUnitName;
|
||||
private final Predicate<String> ignoreTestPredicate;
|
||||
|
||||
boolean summaryHasIngestErrors;
|
||||
boolean summaryHasRelocationErrors;
|
||||
|
@ -32,6 +34,7 @@ public class PCodeTestResults {
|
|||
|
||||
int summaryTotalAsserts;
|
||||
int summaryPassCount;
|
||||
int summaryIgnoreCount;
|
||||
int summaryFailCount;
|
||||
int summaryCallOtherCount;
|
||||
int summarySevereFailures;
|
||||
|
@ -41,17 +44,91 @@ public class PCodeTestResults {
|
|||
// map keys formed with "<groupName>.<testName>" string
|
||||
private Map<String, TestResults> results = new HashMap<>();
|
||||
|
||||
PCodeTestResults(String jUnitName) {
|
||||
private static String XML_VERSION = "1";
|
||||
|
||||
public static String TAG_NAME = "PCodeTestResults";
|
||||
|
||||
PCodeTestResults(String jUnitName, Predicate<String> ignoreTestPredicate) {
|
||||
this.jUnitName = jUnitName;
|
||||
this.ignoreTestPredicate = ignoreTestPredicate;
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public PCodeTestResults(Element root, Predicate<String> ignoreTestPredicate) {
|
||||
|
||||
if (!TAG_NAME.equals(root.getName())) {
|
||||
throw new IllegalArgumentException("Unsupported root element: " + root.getName());
|
||||
}
|
||||
String ver = root.getAttributeValue("VERSION");
|
||||
if (!XML_VERSION.equals(ver)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported XML format version " + ver + ", required format is " + XML_VERSION);
|
||||
}
|
||||
|
||||
jUnitName = getJunitName(root);
|
||||
this.ignoreTestPredicate = ignoreTestPredicate;
|
||||
|
||||
time = 0;
|
||||
String timeStr = root.getAttributeValue("TIME");
|
||||
if (timeStr != null) {
|
||||
try {
|
||||
time = Long.parseLong(timeStr);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
summaryHasIngestErrors = getAttributeValue(root, "INGEST_ERR", false);
|
||||
summaryHasRelocationErrors = getAttributeValue(root, "RELOC_ERR", false);
|
||||
summaryHasDisassemblyErrors = getAttributeValue(root, "DIS_ERR", false);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Element> elementList = root.getChildren("TestResults");
|
||||
for (Element element : elementList) {
|
||||
|
||||
String testName = element.getAttributeValue("NAME");
|
||||
if (testName == null) {
|
||||
throw new IllegalArgumentException("Invalid TestResults element in XML");
|
||||
}
|
||||
TestResults testResults = new TestResults();
|
||||
testResults.totalAsserts = getAttributeValue(element, "TOTAL_ASSERTS", 0);
|
||||
testResults.passCount = getAttributeValue(element, "PASS", 0);
|
||||
testResults.ignoredCount = getAttributeValue(element, "IGNORE", 0);
|
||||
testResults.failCount = getAttributeValue(element, "FAIL", 0);
|
||||
testResults.callOtherCount = getAttributeValue(element, "CALLOTHER", 0);
|
||||
testResults.severeFailure = getAttributeValue(element, "SEVERE_FAILURE", false);
|
||||
|
||||
summaryTotalAsserts += testResults.totalAsserts;
|
||||
summaryPassCount += testResults.passCount;
|
||||
summaryIgnoreCount += testResults.ignoredCount;
|
||||
summaryFailCount += testResults.failCount;
|
||||
summaryCallOtherCount += testResults.callOtherCount;
|
||||
if (testResults.severeFailure) {
|
||||
++summarySevereFailures;
|
||||
}
|
||||
|
||||
results.put(testName, testResults);
|
||||
}
|
||||
}
|
||||
|
||||
static String getJunitName(Element root) {
|
||||
return root.getAttributeValue("JUNIT");
|
||||
}
|
||||
|
||||
public String getJUnitName() {
|
||||
return jUnitName;
|
||||
}
|
||||
|
||||
private static DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm");
|
||||
|
||||
public boolean isIgnoredTest(String testName) {
|
||||
if (ignoreTestPredicate != null) {
|
||||
return ignoreTestPredicate.test(testName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
if (time == 0) {
|
||||
return null;
|
||||
|
@ -131,6 +208,21 @@ public class PCodeTestResults {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void addIgnoredResult(String groupName, String testName) {
|
||||
String groupTestName = getGroupTestName(groupName, testName);
|
||||
getTestResults(groupTestName, true).ignoredCount++;
|
||||
summaryIgnoreCount++;
|
||||
}
|
||||
|
||||
public int getIgnoredResult(String groupName, String testName) {
|
||||
String groupTestName = getGroupTestName(groupName, testName);
|
||||
TestResults testResults = getTestResults(groupTestName, false);
|
||||
if (testResults != null) {
|
||||
return testResults.ignoredCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void addFailResult(String groupName, String testName) {
|
||||
String groupTestName = getGroupTestName(groupName, testName);
|
||||
getTestResults(groupTestName, true).failCount++;
|
||||
|
@ -183,71 +275,13 @@ public class PCodeTestResults {
|
|||
summaryHasDisassemblyErrors = false;
|
||||
summaryTotalAsserts = 0;
|
||||
summaryPassCount = 0;
|
||||
summaryIgnoreCount = 0;
|
||||
summaryFailCount = 0;
|
||||
summaryCallOtherCount = 0;
|
||||
summarySevereFailures = 0;
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private static String XML_VERSION = "1";
|
||||
|
||||
public static String TAG_NAME = "PCodeTestResults";
|
||||
|
||||
public PCodeTestResults(Element root) {
|
||||
|
||||
if (!TAG_NAME.equals(root.getName())) {
|
||||
throw new IllegalArgumentException("Unsupported root element: " + root.getName());
|
||||
}
|
||||
String ver = root.getAttributeValue("VERSION");
|
||||
if (!XML_VERSION.equals(ver)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported XML format version " + ver + ", required format is " + XML_VERSION);
|
||||
}
|
||||
|
||||
jUnitName = root.getAttributeValue("JUNIT");
|
||||
|
||||
time = 0;
|
||||
String timeStr = root.getAttributeValue("TIME");
|
||||
if (timeStr != null) {
|
||||
try {
|
||||
time = Long.parseLong(timeStr);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
summaryHasIngestErrors = getAttributeValue(root, "INGEST_ERR", false);
|
||||
summaryHasRelocationErrors = getAttributeValue(root, "RELOC_ERR", false);
|
||||
summaryHasDisassemblyErrors = getAttributeValue(root, "DIS_ERR", false);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Element> elementList = root.getChildren("TestResults");
|
||||
for (Element element : elementList) {
|
||||
|
||||
String testName = element.getAttributeValue("NAME");
|
||||
if (testName == null) {
|
||||
throw new IllegalArgumentException("Invalid TestResults element in XML");
|
||||
}
|
||||
TestResults testResults = new TestResults();
|
||||
testResults.totalAsserts = getAttributeValue(element, "TOTAL_ASSERTS", 0);
|
||||
testResults.passCount = getAttributeValue(element, "PASS", 0);
|
||||
testResults.failCount = getAttributeValue(element, "FAIL", 0);
|
||||
testResults.callOtherCount = getAttributeValue(element, "CALLOTHER", 0);
|
||||
testResults.severeFailure = getAttributeValue(element, "SEVERE_FAILURE", false);
|
||||
|
||||
summaryTotalAsserts += testResults.totalAsserts;
|
||||
summaryPassCount += testResults.passCount;
|
||||
summaryFailCount += testResults.failCount;
|
||||
summaryCallOtherCount += testResults.callOtherCount;
|
||||
if (testResults.severeFailure) {
|
||||
++summarySevereFailures;
|
||||
}
|
||||
|
||||
results.put(testName, testResults);
|
||||
}
|
||||
}
|
||||
|
||||
int getAttributeValue(Element element, String attrName, int defaultValue) {
|
||||
String val = element.getAttributeValue(attrName);
|
||||
if (val == null) {
|
||||
|
@ -305,6 +339,8 @@ public class PCodeTestResults {
|
|||
element.setAttribute(
|
||||
new Attribute("TOTAL_ASSERTS", Integer.toString(testResults.totalAsserts)));
|
||||
element.setAttribute(new Attribute("PASS", Integer.toString(testResults.passCount)));
|
||||
element.setAttribute(
|
||||
new Attribute("IGNORE", Integer.toString(testResults.ignoredCount)));
|
||||
element.setAttribute(new Attribute("FAIL", Integer.toString(testResults.failCount)));
|
||||
element.setAttribute(
|
||||
new Attribute("CALLOTHER", Integer.toString(testResults.callOtherCount)));
|
||||
|
@ -319,6 +355,7 @@ public class PCodeTestResults {
|
|||
static class TestResults {
|
||||
int totalAsserts;
|
||||
int passCount;
|
||||
int ignoredCount;
|
||||
int failCount;
|
||||
int callOtherCount;
|
||||
|
||||
|
@ -326,9 +363,10 @@ public class PCodeTestResults {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO Auto-generated method stub
|
||||
return "{" + passCount + "/" + failCount + "/" + callOtherCount + "(" + totalAsserts +
|
||||
return "{" + passCount + "/" + ignoredCount + "/" + failCount + "/" + callOtherCount +
|
||||
"(" + totalAsserts +
|
||||
")}";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ package ghidra.test.processors.support;
|
|||
import java.io.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -1180,6 +1181,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||
// Initialize pass/fail counts at runtime to detect severe failure
|
||||
testGroup.mainTestControlBlock.setNumberPassed(testRunner, Integer.MIN_VALUE);
|
||||
testGroup.mainTestControlBlock.setNumberFailed(testRunner, Integer.MIN_VALUE);
|
||||
testGroup.mainTestControlBlock.clearNumberIgnored();
|
||||
|
||||
boolean done;
|
||||
if (traceDisabled) {
|
||||
|
@ -1190,6 +1192,8 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||
}
|
||||
|
||||
int pass = testGroup.mainTestControlBlock.getNumberPassed(testRunner);
|
||||
int ignoredPassed = testGroup.mainTestControlBlock.getNumberPassedIgnored();
|
||||
int ignoredFailed = testGroup.mainTestControlBlock.getNumberFailedIgnored();
|
||||
int callOtherErrors = testRunner.getCallOtherErrors();
|
||||
int fail = testGroup.mainTestControlBlock.getNumberFailed(testRunner);
|
||||
|
||||
|
@ -1199,21 +1203,31 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||
pass + " fail " + fail);
|
||||
}
|
||||
|
||||
pass -= ignoredPassed;
|
||||
pass -= callOtherErrors;
|
||||
fail -= ignoredFailed;
|
||||
|
||||
String passFailText = "Passed: " + pass + " Failed: " + fail;
|
||||
String passFailText = "Passed: " + pass + " Ignored: " +
|
||||
(ignoredFailed + ignoredPassed) + " Failed: " + fail;
|
||||
if (callOtherErrors != 0) {
|
||||
passFailText += " Passed(w/CALLOTHER): " + callOtherErrors;
|
||||
}
|
||||
passFailText += " Expected Assertions: " + totalExpectedAsserts;
|
||||
log(testGroup, passFailText);
|
||||
|
||||
boolean hasFailures = false;
|
||||
List<String> testFailures = testGroup.getTestFailures();
|
||||
if (!testFailures.isEmpty()) {
|
||||
log(testGroup, "TEST FAILURES:");
|
||||
if (!traceDisabled) {
|
||||
log(testGroup, "TEST FAILURE SUMMARY:");
|
||||
}
|
||||
for (String testFailure : testFailures) {
|
||||
if (!traceDisabled) {
|
||||
log(testGroup, " >>> " + testFailure);
|
||||
}
|
||||
// failure is any entry not marked as ignored
|
||||
hasFailures |= (testFailure.indexOf(PCodeTestGroup.IGNORED_TAG) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
|
@ -1235,12 +1249,12 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||
}
|
||||
failTest(testRunner, msg.toString());
|
||||
}
|
||||
int ranCnt = pass + fail + callOtherErrors;
|
||||
int ranCnt = pass + fail + callOtherErrors + ignoredFailed + ignoredPassed;
|
||||
if ((totalExpectedAsserts != 0) && (totalExpectedAsserts != ranCnt)) {
|
||||
failTest(testRunner,
|
||||
"ERROR Unexpected number of assertions ( " + passFailText + " )");
|
||||
}
|
||||
if (fail != 0 || callOtherErrors != 0 || testFailures.size() != 0) {
|
||||
if (fail != 0 || callOtherErrors != 0 || hasFailures) {
|
||||
failTest(testRunner,
|
||||
"ERROR One or more group tests failed ( " + passFailText + " )");
|
||||
}
|
||||
|
@ -1424,6 +1438,17 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E
|
|||
return maxAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add specified test names to the set of tests which should be ignored due to know issues
|
||||
* or limitations. The tests will still be executed, if present, however they will
|
||||
* not be included in pass/fail counts. They will appear in log as "(IGNORED)" test
|
||||
* result.
|
||||
* @param testNames one or more test names to be ignored
|
||||
*/
|
||||
protected void addIgnoredTests(String... testNames) {
|
||||
combinedResults.addIgnoredTests(getClass().getSimpleName(), testNames);
|
||||
}
|
||||
|
||||
//
|
||||
// Protected helper methods which may be overriden
|
||||
//
|
||||
|
|
|
@ -136,7 +136,8 @@
|
|||
<DIV ID="topLeftTable" STYLE="position: absolute; top: 0; left: 0;">
|
||||
<TABLE ID="headerTable1" BORDER=1 CELLSPACING=0 CELLPADDING=0 style="height: 100; cursor: pointer;" onclick="toggleHeaderHeight()" onmouseover="mouseOverHeader()" onmouseout="mouseOutHeader()">
|
||||
<TR>
|
||||
<TD CLASS="TestNameHead"><DIV STYLE="position:absolute; left: 8px; top: 5px; ">P-Code Test Results</DIV><DIV STYLE="position:absolute; left: 140px; bottom: 5px; "><font color="green" size="2">Pass</font>/<font color="red" size="2">Fail</font>/<font color="orange" size="2">CallOther</font></DIV></TD>
|
||||
<TD CLASS="TestNameHead"><DIV STYLE="position:absolute; left: 8px; top: 5px; ">P-Code Test Results</DIV><DIV STYLE="position:absolute; left: 140px; bottom: 5px; ">
|
||||
<font color="green" size="2">Pass</font>/<font color="gray" size="2">Ignore</font>/<font color="red" size="2">Fail</font>/<font color="orange" size="2">CallOther</font></DIV></TD>
|
||||
<TD CLASS="DateTimeHead" ALIGN="center" VALIGN="bottom"><DIV CLASS="r90">DATE/TIME</DIV></TD>
|
||||
<TD CLASS="ResultSummaryHead" ALIGN="center" VALIGN="bottom"><DIV CLASS="r90">SUMMARY</DIV></TD>
|
||||
</TR>
|
||||
|
|
|
@ -518,6 +518,9 @@ public class EmulatorHelper implements MemoryFaultHandler, EmulatorConfiguration
|
|||
if (t instanceof CancelledException) {
|
||||
throw (CancelledException) t;
|
||||
}
|
||||
Msg.error(this,
|
||||
"Emulation failure at " + emulator.getExecuteAddress() + ": " + program.getName(),
|
||||
t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,8 +60,7 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||
* @param scale value's scale (signed value with the biased range of expbits)
|
||||
* @throws IllegalArgumentException if invalid unscaled and scale values are specified based upon the fracbits and expbits values.
|
||||
*/
|
||||
BigFloat(int fracbits, int expbits, FloatKind kind, int sign, BigInteger unscaled,
|
||||
int scale) {
|
||||
BigFloat(int fracbits, int expbits, FloatKind kind, int sign, BigInteger unscaled, int scale) {
|
||||
this.fracbits = fracbits;
|
||||
this.expbits = expbits;
|
||||
this.kind = kind;
|
||||
|
@ -151,21 +150,6 @@ public strictfp class BigFloat implements Comparable<BigFloat> {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BigFloat with the given number of bits representing the given BigInteger.
|
||||
*
|
||||
* @param fracbits number of fractional bits
|
||||
* @param expbits number of bits in the exponent
|
||||
* @param i an integer
|
||||
* @return a BigFloat representing i
|
||||
*/
|
||||
public static BigFloat valueOf(int fracbits, int expbits, BigInteger i) {
|
||||
BigFloat f = new BigFloat(fracbits, expbits, FloatKind.FINITE, i.signum() >= 0 ? +1 : -1,
|
||||
i.abs(), fracbits);
|
||||
f.scaleUpTo(fracbits + 1);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BigFloat with the given number of bits representing zero.
|
||||
*
|
||||
|
|
|
@ -897,7 +897,7 @@ public strictfp class FloatFormat {
|
|||
else {
|
||||
a = Utils.convertToUnsignedValue(a, sizein);
|
||||
}
|
||||
return getEncoding(BigFloat.valueOf(frac_size, exp_size, a));
|
||||
return getEncoding(valueOf(a));
|
||||
}
|
||||
|
||||
public long opFloat2Float(long a, FloatFormat outformat) { // convert between floating
|
||||
|
@ -968,4 +968,27 @@ public strictfp class FloatFormat {
|
|||
return getEncoding(fa);
|
||||
}
|
||||
|
||||
public BigFloat valueOf(BigInteger value) {
|
||||
|
||||
BigInteger unscaled = value;
|
||||
int sign = 1;
|
||||
if (unscaled.signum() < 0) {
|
||||
sign = -1;
|
||||
unscaled = unscaled.negate();
|
||||
}
|
||||
|
||||
int ulen = unscaled.bitLength();
|
||||
int shift = frac_size + 1 - ulen;
|
||||
|
||||
unscaled = unscaled.shiftLeft(shift);
|
||||
|
||||
int scale = frac_size - shift;
|
||||
|
||||
if (scale > bias) {
|
||||
return BigFloat.infinity(frac_size, exp_size, sign);
|
||||
}
|
||||
|
||||
return new BigFloat(frac_size, exp_size, FloatKind.FINITE, sign, unscaled, scale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue