Commit 9e6f3739 authored by Sascha Niklas Schneiders's avatar Sascha Niklas Schneiders
Browse files

automatic stream test generation works now for test components

parent b537ec95
package de.monticore.lang.monticar.generator.cpp;
import de.ma2cfg.helper.Names;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc.ComponentScanner;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.math._symboltable.MathStatementsSymbol;
import de.monticore.lang.monticar.generator.BluePrint;
......@@ -23,10 +25,7 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* @author Sascha Schneiders
......@@ -61,8 +60,17 @@ public class GeneratorCPP implements Generator {
MathConverter.curBackend = new ArmadilloBackend();
}
public void useStreamTestTestGeneration() {
protected String testNamePostFix = "";
protected int amountTickValues = 100;
public void useStreamTestTestGeneration(String testNamePostFix, int amountTickValues) {
streamTestGenerationMode = true;
this.testNamePostFix = testNamePostFix;
this.amountTickValues = amountTickValues;
}
public void useStreamTestTestGeneration(String testNamePostFix) {
useStreamTestTestGeneration(testNamePostFix, 100);
}
public void useOctaveBackend() {
......@@ -97,7 +105,7 @@ public class GeneratorCPP implements Generator {
if (!streamTestGenerationMode)
languageUnitCPP.generateBluePrints();
else
streamTestGenerator.createStreamTest(componentSymbol);
streamTestGenerator.createStreamTest(componentSymbol, amountTickValues, testNamePostFix);
BluePrintCPP bluePrintCPP = null;
for (BluePrint bluePrint : languageUnitCPP.getBluePrints()) {
if (bluePrint.getOriginalSymbol().equals(componentSymbol)) {
......@@ -127,41 +135,60 @@ public class GeneratorCPP implements Generator {
//setGenerateMainClass(true);
}
currentFileContentList = fileContents;
fileContents.add(new FileContent(generateString(taggingResolver, componentInstanceSymbol, symtab), componentInstanceSymbol));
if (!streamTestGenerationMode)
fileContents.add(new FileContent(generateString(taggingResolver, componentInstanceSymbol, symtab), componentInstanceSymbol));
else
fileContents.add(new FileContent(generateString(taggingResolver, componentInstanceSymbol, symtab),
componentInstanceSymbol.getPackageName().replaceAll("\\.", "\\/") + "/" + Names.FirstUpperCase(componentInstanceSymbol.getName()) + "Test" + testNamePostFix + ".stream"));
String lastNameWithoutArrayPart = "";
for (ExpandedComponentInstanceSymbol instanceSymbol : componentInstanceSymbol.getSubComponents()) {
//fileContents.add(new FileContent(generateString(instanceSymbol, symtab), instanceSymbol));
int arrayBracketIndex = instanceSymbol.getName().indexOf("[");
boolean generateComponentInstance = true;
if (arrayBracketIndex != -1) {
generateComponentInstance = !instanceSymbol.getName().substring(0, arrayBracketIndex).equals(lastNameWithoutArrayPart);
lastNameWithoutArrayPart = instanceSymbol.getName().substring(0, arrayBracketIndex);
Log.info(lastNameWithoutArrayPart, "Without:");
Log.info(generateComponentInstance + "", "Bool:");
if (!streamTestGenerationMode) {
for (ExpandedComponentInstanceSymbol instanceSymbol : componentInstanceSymbol.getSubComponents()) {
//fileContents.add(new FileContent(generateString(instanceSymbol, symtab), instanceSymbol));
int arrayBracketIndex = instanceSymbol.getName().indexOf("[");
boolean generateComponentInstance = true;
if (arrayBracketIndex != -1) {
generateComponentInstance = !instanceSymbol.getName().substring(0, arrayBracketIndex).equals(lastNameWithoutArrayPart);
lastNameWithoutArrayPart = instanceSymbol.getName().substring(0, arrayBracketIndex);
Log.info(lastNameWithoutArrayPart, "Without:");
Log.info(generateComponentInstance + "", "Bool:");
}
if (generateComponentInstance) {
fileContents.addAll(generateStrings(taggingResolver, instanceSymbol, symtab));
}
}
if (generateComponentInstance) {
fileContents.addAll(generateStrings(taggingResolver, instanceSymbol, symtab));
if (MathConverter.curBackend.getBackendName().equals("OctaveBackend"))
fileContents.add(OctaveHelper.getOctaveHelperFileContent());
if (MathConverter.curBackend.getBackendName().equals("ArmadilloBackend"))
fileContents.add(ArmadilloHelper.getArmadilloHelperFileContent());
if (shouldGenerateMainClass()) {
//fileContents.add(getMainClassFileContent(componentInstanceSymbol, fileContents.get(0)));
} else if (shouldGenerateSimulatorInterface()) {
fileContents.addAll(SimulatorIntegrationHelper.getSimulatorIntegrationHelperFileContent());
}
}
if (MathConverter.curBackend.getBackendName().equals("OctaveBackend"))
fileContents.add(OctaveHelper.getOctaveHelperFileContent());
if (MathConverter.curBackend.getBackendName().equals("ArmadilloBackend"))
fileContents.add(ArmadilloHelper.getArmadilloHelperFileContent());
if (shouldGenerateMainClass()) {
//fileContents.add(getMainClassFileContent(componentInstanceSymbol, fileContents.get(0)));
} else if (shouldGenerateSimulatorInterface()) {
fileContents.addAll(SimulatorIntegrationHelper.getSimulatorIntegrationHelperFileContent());
}
return fileContents;
}
//TODO add incremental generation based on described concept
public List<File> generateFiles(TaggingResolver taggingResolver, ExpandedComponentInstanceSymbol componentSymbol,
Scope symtab) throws IOException {
List<FileContent> fileContents = generateStrings(taggingResolver, componentSymbol, symtab);
List<FileContent> fileContents = new ArrayList<>();
if (componentSymbol == null) {
ComponentScanner componentScanner = new ComponentScanner(getModelsDirPath(), symtab, "emam");
Set<String> availableComponents = componentScanner.scan();
for (String componentFullName : availableComponents) {
componentFullName = Names.getExpandedComponentInstanceSymbolName(componentFullName);
if (symtab.resolve(componentFullName,
ExpandedComponentInstanceSymbol.KIND).isPresent()) {
ExpandedComponentInstanceSymbol componentInstanceSymbol = (ExpandedComponentInstanceSymbol) symtab.resolve(componentFullName,
ExpandedComponentInstanceSymbol.KIND).get();
fileContents.addAll(generateStrings(taggingResolver, componentInstanceSymbol, symtab));
}
}
} else
fileContents = generateStrings(taggingResolver, componentSymbol, symtab);
fileContents.addAll(generateTypes(TypeConverter.getTypeSymbols()));
fileContents.addAll(handleTestAndCheckDir(symtab));
if (isGenerateAutopilotAdapter()) {
......
......@@ -33,7 +33,7 @@ public final class AllTemplates {
conf.setLogTemplateExceptions(false);
conf.setClassForTemplateLoading(AllTemplates.class, "/template");
try {
COMPONENT_STREAM_TEST = conf.getTemplate("/test/ComponentStreamTest.ftl");
COMPONENT_STREAM_TEST = conf.getTemplate("/test/ComponentStreamTest2.ftl");
TESTS_MAIN_ENTRY = conf.getTemplate("/test/TestsMainEntry.ftl");
TESTS_MAIN_ENTRY_ARMADILLO = conf.getTemplate("/test/TestsMainEntryArmadillo.ftl");
STRUCT = conf.getTemplate("/type/Struct.ftl");
......
package de.monticore.lang.monticar.generator.testing;
/**
* @author Sascha Schneiders
*/
public class MatrixStreamTestValue<T> implements StreamTestValue {
protected T[][] matrixValues;
public MatrixStreamTestValue(T[][] matrixValues) {
this.matrixValues = matrixValues;
}
public T[][] getMatrixValues() {
return matrixValues;
}
public void setMatrixValues(T[][] matrixValues) {
this.matrixValues = matrixValues;
}
@Override
public String getStringRepresentation() {
//TODO
StringBuilder result = new StringBuilder();
result.append("[");
for (int i = 0; i < matrixValues.length; ++i) {
for (int j = 0; j < matrixValues[0].length; ++j) {
result.append(matrixValues[i][j]);
if (j + 1 < matrixValues[0].length)
result.append(", ");
}
if (i + 1 < matrixValues.length)
result.append("; ");
}
result.append("]");
return result.toString();
}
}
......@@ -27,6 +27,30 @@ public class StreamTest {
this.ports.add(port);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getComponentName() {
return componentName;
}
public void setComponentName(String componentName) {
this.componentName = componentName;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
......
package de.monticore.lang.monticar.generator.testing;
import alice.tuprolog.Int;
import de.ma2cfg.helper.Names;
import de.monticore.ast.ASTNode;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._ast.ASTPort;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.monticar.ts.MontiCarTypeSymbol;
import de.monticore.lang.monticar.ts.references.CommonMCTypeReference;
import de.monticore.lang.monticar.ts.references.MCASTTypeSymbolReference;
import de.monticore.lang.math._ast.ASTNumberExpression;
import de.monticore.lang.monticar.common2._ast.ASTCommonMatrixType;
import de.monticore.lang.monticar.types2._ast.ASTElementType;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
......@@ -14,42 +19,146 @@ import java.util.Collection;
public class StreamTestGenerator {
protected StreamTest currentGeneratedStreamTest;
public void createStreamTest(ExpandedComponentInstanceSymbol expandedComponentInstanceSymbol) {
//TODO write stream test creation based on input ports with random values in input range
int currentPrecisionValueType = 0;// 0: double, 1:int, 2:Boolean
double doubleMin, doubleMax;
int intMin, intMax;
public void createStreamTest(ExpandedComponentInstanceSymbol expandedComponentInstanceSymbol, int amountOfValues, String testNamePostFix) {
//TODO remove System.out.printlns
currentGeneratedStreamTest = new StreamTest();
Collection<PortSymbol> inPorts = expandedComponentInstanceSymbol.getIncomingPorts();
currentGeneratedStreamTest.setComponentName(Names.FirstUpperCase(expandedComponentInstanceSymbol.getName()));
currentGeneratedStreamTest.setPackageName(expandedComponentInstanceSymbol.getPackageName());
currentGeneratedStreamTest.setName(currentGeneratedStreamTest.getComponentName() + "Test" + testNamePostFix);
System.out.println("Generating StreamTest for component " + currentGeneratedStreamTest.getComponentName());
for (PortSymbol p : inPorts) {
System.out.println(p.getTypeReference().getClass().getName());
if (p.getTypeReference().getName().equals("CommonMatrixType")) {
//TODO handle commonMatrixType
MCASTTypeSymbolReference typeReference = (MCASTTypeSymbolReference) p.getTypeReference();
System.out.println(typeReference.getActualTypeArguments().size());
if (typeReference.getAstNode().isPresent())
System.out.println(p.getTypeReference().getAstNode().get().getClass().getName());
} else if (p.getTypeReference().getName().equals("Q")) {
CommonMCTypeReference typeReference = (CommonMCTypeReference) p.getTypeReference();
System.out.println(typeReference.getReferencedSymbol().getName());
MontiCarTypeSymbol typeSymbol = (MontiCarTypeSymbol) typeReference.getReferencedSymbol();
System.out.println(typeSymbol.getFormalTypeParameters().size());
System.out.println(typeSymbol.getInterfaces().size());
if (typeReference.getAstNode().isPresent())
System.out.println(p.getTypeReference().getAstNode().get().getClass().getName());
} else if (p.getTypeReference().getName().equals("Z")) {
CommonMCTypeReference typeReference = (CommonMCTypeReference) p.getTypeReference();
if (typeReference.getAstNode().isPresent())
System.out.println(p.getTypeReference().getAstNode().get().getClass().getName());
} else if (p.getTypeReference().getName().equals("N")) {
CommonMCTypeReference typeReference = (CommonMCTypeReference) p.getTypeReference();
if (typeReference.getAstNode().isPresent())
System.out.println(p.getTypeReference().getAstNode().get().getClass().getName());
if (p.getAstNode().isPresent()) {
System.out.println(p.getAstNode().get().getClass().getName());
ASTPort astPort = (ASTPort) p.getAstNode().get();
System.out.println(astPort.getName());
StreamTestPort streamTestPort = new StreamTestPort();
streamTestPort.setName(p.getName());
doubleMin = -10000000;//Maybe these values should be configurable as parameters later?
doubleMax = 10000000;
intMin = -10000000;
intMax = 10000000;
int sizeX = 1;
int sizeY = 1;
int type = 0;// 0: singular value, 1: matrix, 2:Boolean
if (astPort.getType() instanceof ASTElementType) {
ASTElementType astElementType = (ASTElementType) astPort.getType();
handleASTElementType(astElementType);
} else if (astPort.getType() instanceof ASTCommonMatrixType) {
type = 1;
ASTCommonMatrixType astCommonMatrixType = (ASTCommonMatrixType) astPort.getType();
System.out.println(astCommonMatrixType.getDimension().getDimensionList().get(0).getClass().getName());
System.out.println(astCommonMatrixType.getDimension().getDimensionList().get(1).getClass().getName());
//System.out.println(astCommonMatrixType.getDimension().getDimensionList().get(0).toString());
//System.out.println(astCommonMatrixType.getDimension().getDimensionList().get(1).toString());
ASTNode node1 = astCommonMatrixType.getDimension().getDimensionList().get(0);
ASTNode node2 = astCommonMatrixType.getDimension().getDimensionList().get(1);
if (node1 instanceof ASTNumberExpression) {
sizeX = ((ASTNumberExpression) node1).getNumberWithUnit().getNumber().get().intValue();
}
if (node2 instanceof ASTNumberExpression) {
sizeY = ((ASTNumberExpression) node2).getNumberWithUnit().getNumber().get().intValue();
}
handleASTElementType(astCommonMatrixType.getElementType());
//sizeX = astCommonMatrixType.getDimension().getDimensionList().get(0).getClass().getName().toString();
//sizeY = astCommonMatrixType.getDimension().getDimensionList().get(1).toString();
}
for (int i = 0; i < amountOfValues; ++i) {
StreamTestValue streamTestValue;
if (type == 0) {//singular value
if (currentPrecisionValueType == 0) {
streamTestValue = new BasicStreamTestValue<Double>(getRandomDoubleBetween(doubleMin, doubleMax));
} else if (currentPrecisionValueType == 1) {
streamTestValue = new BasicStreamTestValue<Integer>(getRandomIntegerBetween(intMin, intMax));
} else /*(currentPrecisionValueType == 2)*/ {
streamTestValue = new BasicStreamTestValue<Boolean>(Math.random() > 0.5 ? true : false);
}
} else if (type == 1) {//matrix value
if (currentPrecisionValueType == 0)
streamTestValue = new MatrixStreamTestValue<Double>(getRandomDoubleMatrix(sizeX, sizeY));
else if (currentPrecisionValueType == 1)
streamTestValue = new MatrixStreamTestValue<Integer>(getRandomIntegerMatrix(sizeX, sizeY));
else
streamTestValue = null;//TODO handle Boolean Matrix
} else if (type == 2) {//singular boolean value
streamTestValue = new BasicStreamTestValue<Boolean>(Math.random() > 0.5 ? true : false);
} else {
streamTestValue = null;
Log.debug("PortType Not Handled!", "StreamTestTestGeneration:");
}
streamTestPort.addValue(streamTestValue);
}
currentGeneratedStreamTest.addPort(streamTestPort);
} else {
//ConstantPorts do not have an ASTNode
//Log.debug(p.getName(), "PortSymbol has no ASTNode:");
}
System.out.println();
}
}
private void handleASTElementType(ASTElementType astElementType) {
if (astElementType.getName().equals("Q")) {
currentPrecisionValueType = 0;
} else if (astElementType.getName().equals("Z")) {
currentPrecisionValueType = 1;
} else if (astElementType.getName().equals("B")) {
currentPrecisionValueType = 2;
}
if (astElementType.isPresentRange()) {
if (astElementType.getRange().getMin().getNumber().isPresent()) {
doubleMin = astElementType.getRange().getStartValue().doubleValue();
intMin = astElementType.getRange().getStartValue().intValue();
}
System.out.println("Min: " + doubleMin);
if (astElementType.getRange().getMax().getNumber().isPresent()) {
doubleMax = astElementType.getRange().getEndValue().doubleValue();
intMax = astElementType.getRange().getEndValue().intValue();
System.out.println("Max: " + doubleMax);
}
}
}
public StreamTest getCurrentGeneratedStreamTest() {
return currentGeneratedStreamTest;
}
public int getRandomIntegerBetween(int min, int max) {
return (int) getRandomDoubleBetween(min, max);
}
public Integer[][] getRandomIntegerMatrix(int sizeX, int sizeY) {
return getRandomIntegerMatrix(sizeX, sizeY, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public Integer[][] getRandomIntegerMatrix(int sizeX, int sizeY, int min, int max) {
Integer[][] matrix = new Integer[sizeX][sizeY];
for (int i = 0; i < sizeX; ++i)
for (int j = 0; j < sizeY; ++j)
matrix[i][j] = getRandomIntegerBetween(min, max);
return matrix;
}
public double getRandomDoubleBetween(double min, double max) {
return Math.random() + min + Math.random() * (max - min);
}
public Double[][] getRandomDoubleMatrix(int sizeX, int sizeY, double min, double max) {
Double[][] matrix = new Double[sizeX][sizeY];
for (int i = 0; i < sizeX; ++i)
for (int j = 0; j < sizeY; ++j)
matrix[i][j] = getRandomDoubleBetween(min, max);
return matrix;
}
public Double[][] getRandomDoubleMatrix(int sizeX, int sizeY) {
return getRandomDoubleMatrix(sizeX, sizeY, Double.MIN_VALUE, Double.MAX_VALUE);
}
}
......@@ -28,4 +28,8 @@ public class StreamTestPort {
public void setValues(List<StreamTestValue> values) {
this.values = values;
}
public void addValue(StreamTestValue value) {
this.values.add(value);
}
}
......@@ -35,7 +35,6 @@ TEST_CASE("${stream.name}", "[${viewModel.componentName}]") {
<#elseif helper.isRangeOutputPortCheck(check)>
REQUIRE( ${portValue} >= ${check.lowerBound} );
REQUIRE( ${portValue} <= ${check.upperBound} );
</#if>
<#else>
std::cout << (${portValue}) << "\n";
</#if>
......
......@@ -5,10 +5,12 @@ import de.monticore.lang.monticar.generator.AbstractSymtabTest;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.se_rwth.commons.logging.Log;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import static org.junit.Assert.assertNotNull;
......@@ -31,11 +33,58 @@ public class StreamTestGenerationTest extends AbstractSymtabTest {
ExpandedComponentInstanceSymbol componentSymbol = symtab.<ExpandedComponentInstanceSymbol>resolve("de.rwth.armin.modeling.autopilot.autopilot", ExpandedComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(componentSymbol);
GeneratorCPP generatorCPP = new GeneratorCPP();
generatorCPP.useStreamTestTestGeneration();
generatorCPP.useStreamTestTestGeneration("1");
generatorCPP.setGenerationTargetPath("./target/generated-sources-cpp/streamtest/autopilot/");
generatorCPP.useArmadilloBackend();
List<File> files = generatorCPP.generateFiles(symtab, componentSymbol, symtab);
String restPath = "streamtest/autopilot";
testFilesAreEqual(files, restPath);
//testFilesAreEqual(files, restPath); generated values are random
}
@Test
public void testStreamTestAutopilotAllComponentsTestGen() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources/emastudio/autopilot");
GeneratorCPP generatorCPP = new GeneratorCPP();
generatorCPP.useStreamTestTestGeneration("1");
generatorCPP.setGenerationTargetPath("./target/generated-sources-cpp/streamtest/autopilot/");
generatorCPP.useArmadilloBackend();
generatorCPP.setModelsDirPath(Paths.get("src/test/resources"));
List<File> files = generatorCPP.generateFiles(symtab, null, symtab);
String restPath = "streamtest/autopilot";
//testFilesAreEqual(files, restPath); generated values are random
}
@Test
public void testStreamTestPacmanControllerSimpleTestGen() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources/emastudio/pacman");
ExpandedComponentInstanceSymbol componentSymbol = symtab.<ExpandedComponentInstanceSymbol>resolve("de.rwth.pacman.pacManControllerSimple", ExpandedComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(componentSymbol);
GeneratorCPP generatorCPP = new GeneratorCPP();
generatorCPP.useStreamTestTestGeneration("1",2);
generatorCPP.setGenerationTargetPath("./target/generated-sources-cpp/streamtest/pacman/");
generatorCPP.useArmadilloBackend();
generatorCPP.setModelsDirPath(Paths.get("src/test/resources"));
List<File> files = generatorCPP.generateFiles(symtab, componentSymbol, symtab);
String restPath = "streamtest/pacman";
//testFilesAreEqual(files, restPath); generated values are random
}
//Create image test manually, as generation for these large matrices takes a lot of time
@Ignore
@Test
public void testStreamTestClustererAllComponentsTestGen() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources/emastudio/clustering");
GeneratorCPP generatorCPP = new GeneratorCPP();
generatorCPP.useStreamTestTestGeneration("1");
generatorCPP.setGenerationTargetPath("./target/generated-sources-cpp/streamtest/cluster/");
generatorCPP.useArmadilloBackend();
generatorCPP.setModelsDirPath(Paths.get("src/test/resources"));
List<File> files = generatorCPP.generateFiles(symtab, null, symtab);
String restPath = "streamtest/cluster";
//testFilesAreEqual(files, restPath); generated values are random
}
}
......@@ -2,7 +2,7 @@ package detection;
component NormalizedLaplacian<N1 n = 1>{
ports in diag Q(-oo:oo)^{n,n} degree,
ports in /*diag*/ Q(-oo:oo)^{n,n} degree,//TODO report issue
in Q(-oo:oo)^{n,n} W,
out Q(-oo:oo)^{n,n} nLaplacian;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment