Commit c5f57c8d authored by Sascha Niklas Schneiders's avatar Sascha Niklas Schneiders
Browse files

fixed some streamtest generation issues

parent 2c3f30c0
Pipeline #68606 passed with stage
in 8 minutes and 55 seconds
......@@ -24,4 +24,5 @@ cd /D N:
cd native
call variables.bat
cd %PROJECT_ROOT%%1
xcopy /s /y "N:\native\lib\win" "%PROJECT_ROOT%%1"
call TestsForCurrentModel.exe
\ No newline at end of file
......@@ -272,12 +272,23 @@ public final class TestsGeneratorCPP {
} else {
processOutgoingPort(vm, sv, portName);
}
} else if (nextInstruction.getStreamArrayValuesOpt().isPresent()) {
ASTStreamArrayValues sv = nextInstruction.getStreamArrayValues();
String portName = port.getName();
if (port.isIncoming()) {
processIncomingPortArray(vm, sv, portName);
} else {
processOutgoingPortArray(vm, sv, portName);
}
} else if (nextInstruction.getStreamCompareOpt().isPresent()) {
Log.error("Not handled!");
}
}
private static void processIncomingPort(ComponentCheckViewModel vm, ASTStreamValue sv, String portName) {
ASTStreamValue2InputPortValue converter = new ASTStreamValue2InputPortValue();
sv.accept(converter);
System.out.println("Processing: " + portName);
if (converter.getResult() != null) {
vm.getInputPortName2Value().put(portName, converter.getResult());
}
......@@ -291,6 +302,23 @@ public final class TestsGeneratorCPP {
}
}
private static void processIncomingPortArray(ComponentCheckViewModel vm, ASTStreamArrayValues sv, String portName) {
ASTStreamValue2InputPortValue converter = new ASTStreamValue2InputPortValue();
sv.accept(converter);
System.out.println("Processing: " + portName);
if (converter.getResult() != null) {
vm.getInputPortName2Value().put(portName, converter.getResult());
}
}
private static void processOutgoingPortArray(ComponentCheckViewModel vm, ASTStreamArrayValues sv, String portName) {
ASTStreamValue2OutputPortCheck converter = new ASTStreamValue2OutputPortCheck(portName);
sv.accept(converter);
if (converter.getResult() != null) {
vm.getOutputPortName2Check().put(portName, converter.getResult());
}
}
private static FileContent getCatchLib() {
return FileUtil.getResourceAsFile(
"/vendor/catch.hpp",
......@@ -304,46 +332,174 @@ public final class TestsGeneratorCPP {
private static final class ASTStreamValue2OutputPortCheck implements StreamUnitsVisitor {
private IOutputPortCheck result = null;
public IOutputPortCheck getResult() {
return result;
}
boolean handled = false;
String portName = "";
boolean isMatrix = false;
public boolean getIsMatrix() {
return isMatrix;
}
public ASTStreamValue2OutputPortCheck(String portName) {
this.portName = portName;
}
public ASTStreamValue2OutputPortCheck() {
}
@Override
public void visit(ASTBooleanLiteral node) {
if (node.getValue()) {
result = BooleanOutputPortCheck.TRUE_EXPECTED;
} else {
result = BooleanOutputPortCheck.FALSE_EXPECTED;
if (!handled) {
if (node.getValue()) {
result = BooleanOutputPortCheck.TRUE_EXPECTED;
} else {
result = BooleanOutputPortCheck.FALSE_EXPECTED;
}
}
handled = true;
}
@Override
public void visit(ASTPrecisionNumber node) {
ASTNumberWithUnit unitNumber = node.getNumberWithUnit();
if (!unitNumber.getNumber().isPresent()) {
return;
if (!handled) {
ASTNumberWithUnit unitNumber = node.getNumberWithUnit();
if (!unitNumber.getNumber().isPresent()) {
return;
}
double baseValue = unitNumber.getNumber().get().doubleValue();
if (node.getPrecisionOpt().isPresent()
&& node.getPrecisionOpt().get().getNumberWithUnit().getNumber().isPresent()) {
double delta = node.getPrecisionOpt().get().getNumberWithUnit().getNumber().get().doubleValue();
result = RangeOutputPortCheck.from(baseValue - delta, baseValue + delta);
} else {
result = RangeOutputPortCheck.from(baseValue, baseValue);
}
}
double baseValue = unitNumber.getNumber().get().doubleValue();
if (node.getPrecisionOpt().isPresent()
&& node.getPrecisionOpt().get().getNumberWithUnit().getNumber().isPresent()) {
double delta = node.getPrecisionOpt().get().getNumberWithUnit().getNumber().get().doubleValue();
result = RangeOutputPortCheck.from(baseValue - delta, baseValue + delta);
} else {
result = RangeOutputPortCheck.from(baseValue, baseValue);
handled = true;
}
@Override
public void visit(ASTStreamArrayValues node) {
if (!handled) {
isMatrix = true;
StringBuilder builder = new StringBuilder();
StreamValueConverter converter = new StreamValueConverter();
if (node.getMatrixPairOpt().isPresent()) {
builder.append(" <<");
for (int j = 0; j < node.getMatrixPair().getValuePairList().size(); ++j) {
ASTValuePair valuePair = node.getMatrixPair().getValuePair(j);
for (int i = 0; i < valuePair.getStreamValueList().size(); ++i) {
ASTStreamValue value = valuePair.getStreamValueList().get(i);
//TODO Name, PrecisionNumber, SignedLiteral, valueAtTick
if (value.getNameOpt().isPresent()) {
builder.append(value.getName());
} else {
builder.append(converter.convert(value));
}
if (i + 1 < valuePair.getStreamValueList().size()) {
builder.append(" << ");
}
}
builder.append("<< arma::endr ");
if (j + 1 < node.getMatrixPair().getValuePairList().size()) {
builder.append(" << ");
}
}
} else if (node.getValuePairOpt().isPresent()) {
//TODO valuepair conversion
builder.append("NOT HANDLED VALUEPAIROPT!!!");
}
System.out.println("Result: " + builder.toString());
result = RangeOutputPortCheck.from(builder.toString(), builder.toString(),true);
}
handled = true;
}
}
private static final class ASTStreamValue2InputPortValue implements StreamUnitsVisitor {
private String result = null;
boolean handled = false;
public String getResult() {
return result;
}
@Override
public void visit(ASTBooleanLiteral node) {
if (!handled) result = "=" + (node.getValue() ? "true" : "false");
handled = true;
}
@Override
public void visit(ASTPrecisionNumber node) {
if (!handled) {
ASTNumberWithUnit unitNumber = node.getNumberWithUnit();
if (!unitNumber.getNumber().isPresent()) {
return;
}
result = "= " + Double.toString(unitNumber.getNumber().get().doubleValue());
}
handled = true;
}
@Override
public void visit(ASTStreamArrayValues node) {
if (!handled) {
StringBuilder builder = new StringBuilder();
StreamValueConverter converter = new StreamValueConverter();
if (node.getMatrixPairOpt().isPresent()) {
result = " <<";
for (int j = 0; j < node.getMatrixPair().getValuePairList().size(); ++j) {
ASTValuePair valuePair = node.getMatrixPair().getValuePair(j);
for (int i = 0; i < valuePair.getStreamValueList().size(); ++i) {
ASTStreamValue value = valuePair.getStreamValueList().get(i);
//TODO Name, PrecisionNumber, SignedLiteral, valueAtTick
if (value.getNameOpt().isPresent()) {
builder.append(value.getName());
} else {
builder.append(converter.convert(value));
}
if (i + 1 < valuePair.getStreamValueList().size()) {
builder.append(" << ");
}
}
builder.append("<< arma::endr ");
if (j + 1 < node.getMatrixPair().getValuePairList().size()) {
builder.append(" << ");
}
}
} else if (node.getValuePairOpt().isPresent()) {
//TODO valuepair conversion
result += "NOT HANDLED VALUEPAIROPT!!!";
}
System.out.println("Result: " + builder.toString());
result += builder.toString();
}
handled = true;
}
}
private static class StreamValueConverter implements StreamUnitsVisitor {
String result = "";
public String convert(ASTStreamValue node) {
result = "";
handle(node);
return result;
}
@Override
public void visit(ASTBooleanLiteral node) {
result = node.getValue() ? "true" : "false";
......@@ -357,5 +513,6 @@ public final class TestsGeneratorCPP {
}
result = Double.toString(unitNumber.getNumber().get().doubleValue());
}
}
}
......@@ -43,6 +43,13 @@ public final class TemplateHelper {
return check instanceof RangeOutputPortCheck;
}
public boolean isRangeOutputPortCheckMatrix(Object check) {
if (isRangeOutputPortCheck(check)) {
return ((RangeOutputPortCheck) check).isMatrix();
}
return false;
}
public boolean isTrueExpectedCheck(Object check) {
return BooleanOutputPortCheck.TRUE_EXPECTED.equals(check);
}
......
......@@ -29,6 +29,15 @@ public final class RangeOutputPortCheck extends ViewModelBase implements IOutput
private String lowerBound;
private String upperBound;
boolean isMatrix = false;
public boolean isMatrix() {
return isMatrix;
}
public void setMatrix(boolean matrix) {
isMatrix = matrix;
}
public String getLowerBound() {
return lowerBound;
......@@ -94,4 +103,14 @@ public final class RangeOutputPortCheck extends ViewModelBase implements IOutput
result.setUpperBound(upperBound);
return result;
}
public static RangeOutputPortCheck from(String lowerBound, String upperBound, boolean isMatrix) {
Log.errorIfNull(lowerBound);
Log.errorIfNull(upperBound);
RangeOutputPortCheck result = new RangeOutputPortCheck();
result.isMatrix = isMatrix;
result.setLowerBound(lowerBound);
result.setUpperBound(upperBound);
return result;
}
}
/**
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
* <p>
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* <p>
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.generator.testing;
......
......@@ -6,8 +6,62 @@
#include "../${viewModel.componentName}.h"
#include <iostream>
#include <fstream>
#include <string>
void toFileString(std::ofstream& myfile, mat A){
myfile << "[";
for (int i = 0; i < A.n_rows; i++){
for (int j = 0; j < A.n_cols; j++){
myfile << A(i,j);
if(j + 1 < A.n_cols){
myfile << ", ";
}
}
if(i + 1 < A.n_rows){
myfile << ";";
}
}
myfile << "]";
}
void toFileString(std::ofstream& myfile, double A){
myfile << A;
}
void toFileString(std::ofstream& myfile, float A){
myfile << A;
}
void toFileString(std::ofstream& myfile, int A){
myfile << A;
}
void toFileString(std::ofstream& myfile, bool A){
myfile << A;
}
bool Is_close(mat& X, mat& Y, double tol)
{
// abs returns a mat type then max checks columns and returns a row_vec
// max used again will return the biggest element in the row_vec
bool close(false);
if(arma::max(arma::max(arma::abs(X-Y))) < tol)
{
close = true;
}
return close;
}
void rangeValueCheck(double A, double lower, double upper){
REQUIRE( A >= lower );
REQUIRE( A <= upper );
}
void rangeValueCheck(int A, double lower, double upper){
REQUIRE( A >= lower );
REQUIRE( A <= upper );
}
void rangeValueCheck(mat& A, mat& lower , mat& upper){
REQUIRE(Is_close(A, lower, 0.0001));
REQUIRE(Is_close(A, upper, 0.0001));
}
<#list viewModel.streams as stream>
TEST_CASE("${stream.name}", "[${viewModel.componentName}]") {
mat tmpA;
mat tmpB;
${viewModel.componentName} component;
std::ofstream myfile;
myfile.open ("${stream.name}");
......@@ -15,15 +69,16 @@ TEST_CASE("${stream.name}", "[${viewModel.componentName}]") {
component.init();
<#list stream.checks as check>
<#list check.inputPortName2Value?keys as portName>
component.${portName} = ${check.inputPortName2Value[portName]};
component.${portName} ${check.inputPortName2Value[portName]};
</#list>
component.execute();
<#list check.outputPortName2Check?keys as outputPortName>
<@renderPortCheck outputPortName=outputPortName check=check.outputPortName2Check[outputPortName] />
</#list>
<#list stream.outputPortNames as outputPortName>
std::cout << (component.${outputPortName}) << "\n";
myfile << "${outputPortName}: " << component.${outputPortName} << "\n";
myfile << "${outputPortName}: ";
toFileString(myfile, component.${outputPortName});
myfile << "\n";
</#list>
</#list>
myfile.close();
......@@ -31,6 +86,7 @@ TEST_CASE("${stream.name}", "[${viewModel.componentName}]") {
}
</#list>
#endif
<#macro renderPortCheck outputPortName check>
......@@ -42,9 +98,21 @@ TEST_CASE("${stream.name}", "[${viewModel.componentName}]") {
REQUIRE_FALSE( ${portValue} );
</#if>
<#elseif helper.isRangeOutputPortCheck(check)>
REQUIRE( ${portValue} >= ${check.lowerBound} );
REQUIRE( ${portValue} <= ${check.upperBound} );
<#if check.isMatrix??>
<#if check.isMatrix()>
tmpA = mat();
tmpA ${check.lowerBound};
tmpB = mat();
tmpB ${check.upperBound};
rangeValueCheck(${portValue}, tmpA , tmpB);
<#else>
rangeValueCheck(${portValue}, ${check.lowerBound} , ${check.upperBound});
</#if>
<#else>
rangeValueCheck(${portValue}, ${check.lowerBound} , ${check.upperBound});
</#if>
<#else>
std::cout << (${portValue}) << "\n";
</#if>
</#macro>
<#include "/Common.ftl">
#ifndef ${viewModel.fileNameWithoutExtension?upper_case}
#define ${viewModel.fileNameWithoutExtension?upper_case}
#include "catch.hpp"
#include "../${viewModel.componentName}.h"
#include <iostream>
#include <fstream>
#include <string>
void toFileString(std::ofstream& myfile, mat A){
myfile << "[";
for (int i = 0; i < A.n_rows; i++){
for (int j = 0; j < A.n_cols; j++){
myfile << A(i,j);
if(j + 1 < A.n_cols){
myfile << ", ";
}
}
if(i + 1 < A.n_rows){
myfile << ";";
}
}
myfile << "]";
}
void toFileString(std::ofstream& myfile, double A){
myfile << A;
}
void toFileString(std::ofstream& myfile, float A){
myfile << A;
}
void toFileString(std::ofstream& myfile, int A){
myfile << A;
}
void toFileString(std::ofstream& myfile, bool A){
myfile << A;
}
bool Is_close(mat& X, mat& Y, double tol)
{
// abs returns a mat type then max checks columns and returns a row_vec
// max used again will return the biggest element in the row_vec
bool close(false);
if(arma::max(arma::max(arma::abs(X-Y))) < tol)
{
close = true;
}
return close;
}
void rangeValueCheck(double A, double lower, double upper){
REQUIRE( A >= lower );
REQUIRE( A <= upper );
}
void rangeValueCheck(int A, double lower, double upper){
REQUIRE( A >= lower );
REQUIRE( A <= upper );
}
void rangeValueCheck(mat& A, mat& lower , mat& upper){
REQUIRE(Is_close(A, lower, 0.0001));
REQUIRE(Is_close(A, upper, 0.0001));
}
<#list viewModel.streams as stream>
TEST_CASE("${stream.name}", "[${viewModel.componentName}]") {
mat tmpA;
mat tmpB;
${viewModel.componentName} component;
std::ofstream myfile;
myfile.open ("${stream.name}");
myfile.precision(64);
component.init();
<#list stream.checks as check>
<#list check.inputPortName2Value?keys as portName>
component.${portName} ${check.inputPortName2Value[portName]};
</#list>
std::cout << "Execution Starting!";
component.execute();
std::cout << "Execution Done!";
<#list check.outputPortName2Check?keys as outputPortName>
<@renderPortCheck outputPortName=outputPortName check=check.outputPortName2Check[outputPortName] />
</#list>
<#list stream.outputPortNames as outputPortName>
std::cout << (component.${outputPortName}) << "\n";
myfile << "${outputPortName}: ";
toFileString(myfile, component.${outputPortName});
myfile << "\n";
</#list>
</#list>
myfile.close();
std::cout << "${stream.name}: success\n";
}
</#list>
#endif
<#macro renderPortCheck outputPortName check>
<#assign portValue="component.${outputPortName}">
<#if helper.isBooleanOutputPortCheck(check)>
<#if helper.isTrueExpectedCheck(check)>
REQUIRE( ${portValue} );
<#else>
REQUIRE_FALSE( ${portValue} );
</#if>
<#elseif helper.isRangeOutputPortCheck(check)>
<#if check.isMatrix??>
<#if check.isMatrix()>
tmpA = mat();
tmpA ${check.lowerBound};
tmpB = mat();
tmpB ${check.upperBound};
rangeValueCheck(${portValue}, tmpA , tmpB);
<#else>
rangeValueCheck(${portValue}, ${check.lowerBound} , ${check.upperBound});
</#if>
<#else>
rangeValueCheck(${portValue}, ${check.lowerBound} , ${check.upperBound});
</#if>
<#else>
std::cout << (${portValue}) << "\n";
</#if>
</#macro>
......@@ -27,10 +27,6 @@ import de.monticore.lang.monticar.generator.testing.StreamTestExecution;
import de.monticore.lang.monticar.generator.testing.StreamTestModifier;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.se_rwth.commons.logging.Log;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.SystemUtils;
import org.junit.BeforeClass;
......@@ -40,7 +36,6 @@ import org.junit.Test;
import java.io.File;