refactoring of test case extraction

This commit is contained in:
hneemann 2020-11-07 10:51:44 +01:00
parent 3534d92961
commit 72558db65f
9 changed files with 103 additions and 118 deletions

View File

@ -47,8 +47,19 @@ C 0
</dataString>
</testData>
</entry>
<entry>
<string>generic</string>
<string>?&gt;C G
0 0
loop (n,(1&lt;&lt; &lt;?=args.bits?&gt; )-1)
C ((n+1) ^ ((n+1)&gt;&gt;1))
end loop
C 0&lt;?
this.Testdata=output();</string>
</entry>
</elementAttributes>
<pos x="620" y="40"/>
<pos x="680" y="40"/>
</visualElement>
<visualElement>
<elementName>Text</elementName>
@ -153,7 +164,7 @@ if (args.bits&gt;3) {
<string>bits := 3;</string>
</entry>
</elementAttributes>
<pos x="200" y="160"/>
<pos x="680" y="100"/>
</visualElement>
</visualElements>
<wires>

View File

@ -10,17 +10,14 @@ import de.neemann.digital.cli.cli.BasicCommand;
import de.neemann.digital.cli.cli.CLIException;
import de.neemann.digital.core.ErrorDetector;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.TestCaseDescription;
import de.neemann.digital.testing.TestExecutor;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
/**
* Tester used from the command line
@ -28,7 +25,7 @@ import java.util.ArrayList;
public class CommandLineTester {
private final CircuitLoader circuitLoader;
private ArrayList<TestCase> testCases;
private List<Circuit.TestCase> testCases;
private int testsPassed;
private boolean allowMissingInputs;
@ -51,19 +48,10 @@ public class CommandLineTester {
*/
public CommandLineTester useTestCasesFrom(File file) throws IOException {
Circuit c = Circuit.loadCircuit(file, circuitLoader.getShapeFactory());
testCases = getTestCasesFrom(c);
testCases = c.getTestCases();
return this;
}
private ArrayList<TestCase> getTestCasesFrom(Circuit circuit) {
ArrayList<TestCase> tsl = new ArrayList<>();
for (VisualElement el : circuit.getTestCases())
tsl.add(new TestCase(
el.getElementAttributes().get(Keys.TESTDATA),
el.getElementAttributes().getLabel()));
return tsl;
}
/**
* Executes test test
*
@ -72,7 +60,7 @@ public class CommandLineTester {
*/
public int execute(PrintStream out) {
if (testCases == null)
testCases = getTestCasesFrom(circuitLoader.getCircuit());
testCases = circuitLoader.getCircuit().getTestCases();
int errorCount = 0;
@ -80,7 +68,7 @@ public class CommandLineTester {
out.println("no test cases given");
errorCount++;
} else {
for (TestCase t : testCases) {
for (Circuit.TestCase t : testCases) {
String label = t.getLabel();
if (label.isEmpty())
label = "unnamed";
@ -123,24 +111,6 @@ public class CommandLineTester {
return testsPassed;
}
private static final class TestCase {
private final TestCaseDescription testCaseDescription;
private final String label;
private TestCase(TestCaseDescription testCaseDescription, String label) {
this.testCaseDescription = testCaseDescription;
this.label = label;
}
private TestCaseDescription getTestCaseDescription() {
return testCaseDescription;
}
private String getLabel() {
return label;
}
}
private CommandLineTester setAllowMissingInputs(boolean allowMissingInputs) {
this.allowMissingInputs = allowMissingInputs;
return this;

View File

@ -348,8 +348,41 @@ public class Circuit implements Copyable<Circuit> {
*
* @return the test case elements
*/
public List<VisualElement> getTestCases() {
return getElements(v -> v.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION) && v.getElementAttributes().get(Keys.ENABLED));
public List<TestCase> getTestCases() {
ArrayList<TestCase> tc = new ArrayList<>();
for (VisualElement ve : getElements(v -> v.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION) && v.getElementAttributes().get(Keys.ENABLED))) {
tc.add(new TestCase(
ve.getElementAttributes().getLabel(),
new TestCaseDescription(ve.getElementAttributes().get(Keys.TESTDATA))));
}
return tc;
}
/**
* A simple java bean to encapsulate a test case description
*/
public static final class TestCase {
private final String label;
private final TestCaseDescription testCaseDescription;
private TestCase(String label, TestCaseDescription testCaseDescription) {
this.label = label;
this.testCaseDescription = testCaseDescription;
}
/**
* @return the label of the test case
*/
public String getLabel() {
return label;
}
/**
* @return the test case description
*/
public TestCaseDescription getTestCaseDescription() {
return testCaseDescription;
}
}
/**

View File

@ -1128,10 +1128,8 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
public void startTests() {
try {
ArrayList<ValueTableDialog.TestSet> tsl = new ArrayList<>();
for (VisualElement el : circuitComponent.getCircuit().getTestCases())
tsl.add(new ValueTableDialog.TestSet(
el.getElementAttributes().get(Keys.TESTDATA),
el.getElementAttributes().getLabel()));
for (Circuit.TestCase tc : circuitComponent.getCircuit().getTestCases())
tsl.add(new ValueTableDialog.TestSet(tc.getTestCaseDescription(), tc.getLabel()));
if (tsl.isEmpty())
throw new TestingDataException(Lang.get("err_noTestData"));

View File

@ -5,17 +5,15 @@
*/
package de.neemann.digital.hdl.verilog2;
import de.neemann.digital.hdl.vhdl2.*;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.data.Value;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.hdl.model2.HDLCircuit;
import de.neemann.digital.hdl.model2.HDLException;
import de.neemann.digital.hdl.model2.HDLModel;
import de.neemann.digital.hdl.model2.HDLPort;
import de.neemann.digital.hdl.printer.CodePrinter;
import de.neemann.digital.hdl.printer.CodePrinterStr;
import de.neemann.digital.hdl.vhdl2.Separator;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.TestCaseDescription;
import de.neemann.digital.testing.TestingDataException;
@ -27,9 +25,7 @@ import de.neemann.digital.testing.parser.TestRow;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import static de.neemann.digital.core.element.Keys.TESTDATA;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -38,7 +34,7 @@ import java.util.logging.Logger;
* The needed test date is taken from the test cases in the circuit
*/
public class VerilogTestBenchCreator {
private final ArrayList<ElementAttributes> testCases;
private final List<Circuit.TestCase> testCases;
private final HDLCircuit main;
private final String topModuleName;
private final HDLModel.Renaming renaming;
@ -54,9 +50,7 @@ public class VerilogTestBenchCreator {
public VerilogTestBenchCreator(Circuit circuit, HDLModel model, String topModuleName) {
this.main = model.getMain();
this.topModuleName = topModuleName;
testCases = new ArrayList<>();
for (VisualElement ve : circuit.getTestCases())
testCases.add(ve.getElementAttributes());
testCases = circuit.getTestCases();
testFileWritten = new ArrayList<>();
renaming = model.getRenaming();
}
@ -75,7 +69,7 @@ public class VerilogTestBenchCreator {
if (p > 0)
filename = filename.substring(0, p);
for (ElementAttributes tc : testCases) {
for (Circuit.TestCase tc : testCases) {
String testName = tc.getLabel();
if (testName.length() > 0)
testName = filename + "_" + testName + "_tb";
@ -107,7 +101,7 @@ public class VerilogTestBenchCreator {
return testFileWritten;
}
private void writeTestBench(CodePrinter out, String moduleName, String testName, ElementAttributes tc) throws IOException, HDLException, TestingDataException, ParserException {
private void writeTestBench(CodePrinter out, String moduleName, String testName, Circuit.TestCase tc) throws IOException, HDLException, TestingDataException, ParserException {
out.print("// A testbench for ").println(testName);
out.println("`timescale 1us/1ns").println();
out.print("module ").print(testName).println(";");
@ -131,7 +125,7 @@ public class VerilogTestBenchCreator {
}
out.dec().println().print(");").println().println();
TestCaseDescription testdata = tc.get(TESTDATA);
TestCaseDescription testdata = tc.getTestCaseDescription();
ArrayList<HDLPort> dataOrder = new ArrayList<>();
ArrayList<HDLPort> inputsInOrder = new ArrayList<>();

View File

@ -5,10 +5,8 @@
*/
package de.neemann.digital.hdl.vhdl2;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.data.Value;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.hdl.model2.HDLCircuit;
import de.neemann.digital.hdl.model2.HDLException;
import de.neemann.digital.hdl.model2.HDLModel;
@ -25,15 +23,14 @@ import de.neemann.digital.testing.parser.TestRow;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import static de.neemann.digital.core.element.Keys.TESTDATA;
import java.util.List;
/**
* Creates a test bench for a model.
* The needed test data is taken from the test cases in the circuit
*/
public class VHDLTestBenchCreator {
private final ArrayList<ElementAttributes> testCases;
private final List<Circuit.TestCase> testCases;
private final HDLCircuit main;
private final HDLModel.Renaming renaming;
private ArrayList<File> testFileWritten;
@ -47,9 +44,7 @@ public class VHDLTestBenchCreator {
VHDLTestBenchCreator(Circuit circuit, HDLModel model) {
this.main = model.getMain();
this.renaming = model.getRenaming();
testCases = new ArrayList<>();
for (VisualElement ve : circuit.getTestCases())
testCases.add(ve.getElementAttributes());
testCases = circuit.getTestCases();
testFileWritten = new ArrayList<>();
}
@ -68,7 +63,7 @@ public class VHDLTestBenchCreator {
filename = filename.substring(0, p);
VHDLRenaming renaming = new VHDLRenaming();
for (ElementAttributes tc : testCases) {
for (Circuit.TestCase tc : testCases) {
String testName = tc.getLabel();
if (testName.length() > 0) {
testName = filename + "_" + renaming.checkName(testName) + "_tb";
@ -95,7 +90,7 @@ public class VHDLTestBenchCreator {
return testFileWritten;
}
private void writeTestBench(CodePrinter out, String testName, ElementAttributes tc) throws IOException, TestingDataException, ParserException {
private void writeTestBench(CodePrinter out, String testName, Circuit.TestCase tc) throws IOException, TestingDataException, ParserException {
out.print("-- A testbench for ").println(testName);
out.println("LIBRARY ieee;");
out.println("USE ieee.std_logic_1164.all;");
@ -140,7 +135,7 @@ public class VHDLTestBenchCreator {
out.println("process").inc();
TestCaseDescription testdata = tc.get(TESTDATA);
TestCaseDescription testdata = tc.getTestCaseDescription();
ArrayList<HDLPort> dataOrder = new ArrayList<>();
out.println("type pattern_type is record").inc();

View File

@ -7,10 +7,8 @@ package de.neemann.digital.testing;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.draw.model.ModelCreator;
@ -23,6 +21,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
* Runs all tests in al circuits in a folder
@ -186,12 +185,7 @@ public class FolderTestRunner {
FileToTest f = files.get(i);
try {
Circuit circuit = Circuit.loadCircuit(f.file, shapeFactory);
ArrayList<TestCase> testCases = new ArrayList<>();
for (VisualElement el : circuit.getTestCases()) {
String label = el.getElementAttributes().getLabel();
TestCaseDescription testData = el.getElementAttributes().get(Keys.TESTDATA);
testCases.add(new TestCase(label, testData));
}
List<Circuit.TestCase> testCases = circuit.getTestCases();
if (testCases.isEmpty()) {
// if no test data is available, at least check if the model is error free
try {
@ -204,21 +198,21 @@ public class FolderTestRunner {
} else {
StringBuilder sb = new StringBuilder();
int rowCount = 0;
for (TestCase tc : testCases) {
for (Circuit.TestCase tc : testCases) {
Model model = new ModelCreator(circuit, library).createModel(false);
try {
TestExecutor te = new TestExecutor(tc.testData).create(model);
TestExecutor te = new TestExecutor(tc.getTestCaseDescription()).create(model);
if (te.allPassed()) {
rowCount += te.getResult().getRows();
} else {
if (sb.length() > 0)
sb.append("; ");
sb.append(Lang.get("msg_test_N_Failed", tc.label));
sb.append(Lang.get("msg_test_N_Failed", tc.getLabel()));
}
} catch (TestingDataException | NodeException e) {
if (sb.length() > 0)
sb.append("; ");
sb.append(tc.label).append(": ").append(e.getMessage());
sb.append(tc.getLabel()).append(": ").append(e.getMessage());
}
}
if (sb.length() == 0) {
@ -240,16 +234,6 @@ public class FolderTestRunner {
}
}
private static final class TestCase {
private final String label;
private final TestCaseDescription testData;
private TestCase(String label, TestCaseDescription testData) {
this.label = label;
this.testData = testData;
}
}
/**
* Interface to notify a listener for changes
*/

View File

@ -6,6 +6,7 @@
package de.neemann.digital.draw.library;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.integration.Resources;
import de.neemann.digital.integration.ToBreakRunner;
@ -36,13 +37,7 @@ public class JarComponentManagerTest extends TestCase {
}
};
for (VisualElement ve : br.getCircuit().getElements()) {
if (ve.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION)) {
TestCaseDescription td = ve.getElementAttributes().get(Keys.TESTDATA);
TestExecutor tr = new TestExecutor(td).create(br.getModel());
assertTrue(tr.allPassed());
}
}
for (Circuit.TestCase tc : br.getCircuit().getTestCases())
assertTrue(new TestExecutor(tc.getTestCaseDescription()).create(br.getModel()).allPassed());
}
}

View File

@ -18,7 +18,6 @@ import de.neemann.digital.draw.library.GenericInitCode;
import de.neemann.digital.draw.library.ResolveGenerics;
import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.testing.TestCaseDescription;
import de.neemann.digital.testing.TestCaseElement;
import de.neemann.digital.testing.TestExecutor;
import junit.framework.TestCase;
@ -79,29 +78,28 @@ public class TestExamples extends TestCase {
assertEquals("wrong locked mode", isLib, (boolean) br.getCircuit().getAttributes().get(Keys.LOCKED_MODE));
try {
for (VisualElement el : br.getCircuit().getElements())
if (el.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION)) {
testCasesInFiles++;
for (Circuit.TestCase tc : br.getCircuit().getTestCases()) {
testCasesInFiles++;
String label = el.getElementAttributes().getLabel();
TestCaseDescription td = el.getElementAttributes().get(Keys.TESTDATA);
String label = tc.getLabel();
TestCaseDescription td = tc.getTestCaseDescription();
Model model = new ModelCreator(br.getCircuit(), br.getLibrary()).createModel(false);
ErrorDetector ed = new ErrorDetector();
model.addObserver(ed);
try {
TestExecutor tr = new TestExecutor(td).create(model);
Model model = new ModelCreator(br.getCircuit(), br.getLibrary()).createModel(false);
ErrorDetector ed = new ErrorDetector();
model.addObserver(ed);
try {
TestExecutor tr = new TestExecutor(td).create(model);
if (label.contains("Failing"))
assertFalse(dig.getName() + ":" + label, tr.allPassed());
else
assertTrue(dig.getName() + ":" + label, tr.allPassed());
if (label.contains("Failing"))
assertFalse(dig.getName() + ":" + label, tr.allPassed());
else
assertTrue(dig.getName() + ":" + label, tr.allPassed());
} finally {
model.close();
}
ed.check();
} finally {
model.close();
}
ed.check();
}
} catch (Exception e) {
if (shouldFail) {
return;
@ -114,8 +112,15 @@ public class TestExamples extends TestCase {
br.close();
}
if (br.getCircuit().getAttributes().get(Keys.IS_GENERIC))
checkGeneric(br.getCircuit(), br.getLibrary());
if (br.getCircuit().
getAttributes().
get(Keys.IS_GENERIC))
checkGeneric(br.getCircuit(), br.
getLibrary());
}
private void checkGeneric(Circuit circuit, ElementLibrary library) throws NodeException, ElementNotFoundException, PinException {