Skip to content
Snippets Groups Projects
Commit b59aa741 authored by Simon Barner's avatar Simon Barner
Browse files

Remove dependencies to refinement, testing, and verification

* Affected plugins (non-UI plugins are referenced indirectly)
  * org.fortiss.af3.ocra
  * org.fortiss.af3.refinement
  * org.fortiss.af3.refinement.ui
  * org.fortiss.af3.specification
  * org.fortiss.af3.specification.ui
  * org.fortiss.af3.testing
  * org.fortiss.af3.testing.ui
  * org.fortiss.af3.tools
  * org.fortiss.pragmatictransformation
* Move semantic alignment test to org.fortiss.af3.testing

Issue-Ref: 3861
Issue-Url: https://af3-developer.fortiss.org/issues/3861



Signed-off-by: default avatarSimon Barner <barner@fortiss.org>
parent 141068c1
No related branches found
No related tags found
1 merge request!173861: Remove deprecated plugins
Showing
with 13 additions and 744 deletions
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test-src"/>
<classpathentry kind="output" path="build"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="build"/>
</classpath>
......@@ -17,8 +17,7 @@ Export-Package: org.fortiss.af3.rcp.application;
org.eclipse.ui.plugin,
org.eclipse.equinox.app,
org.osgi.framework",
org.fortiss.af3.rcp.application.example,
test.org.fortiss.af3.rcp.application
org.fortiss.af3.rcp.application.example
Require-Bundle: org.fortiss.af3.rcp.help;bundle-version="2.16.0",
eu.fbk.af3.tools.diagram.ui;bundle-version="2.16.0",
org.fortiss.af3.cosimulation.ui;bundle-version="2.16.0",
......@@ -33,15 +32,11 @@ Require-Bundle: org.fortiss.af3.rcp.help;bundle-version="2.16.0",
org.fortiss.af3.platform.ui;bundle-version="2.16.0",
org.fortiss.af3.project;bundle-version="2.16.0",
org.fortiss.af3.project.ui;bundle-version="2.16.0",
org.fortiss.af3.refinement.ui;bundle-version="2.16.0",
org.fortiss.af3.safety.ui;bundle-version="2.16.0",
org.fortiss.af3.safetycases.ui;bundle-version="2.16.0",
org.fortiss.af3.task.ui;bundle-version="2.16.0",
org.fortiss.af3.schedule.ui;bundle-version="2.16.0",
org.fortiss.af3.specification.ui;bundle-version="2.16.0",
org.fortiss.af3.state.ui;bundle-version="2.16.0",
org.fortiss.af3.testing.ui;bundle-version="2.16.0",
org.fortiss.af3.testing;bundle-version="2.16.0",
org.fortiss.af3.timing.ui;bundle-version="2.16.0",
org.fortiss.tooling.kernel.ui;bundle-version="2.16.0",
javax.servlet,
......
# (c) 2011 fortiss GmbH
source.. = src/,\
test-src/
source.. = src/
output.. = build/
bin.includes = plugin.xml,\
META-INF/,\
......
/*-------------------------------------------------------------------------+
| Copyright 2011 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package test.org.fortiss.af3.rcp.application;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import test.org.fortiss.af3.rcp.application.semantic.alignment.c.CCodeEquivalenceTest;
import test.org.fortiss.af3.rcp.application.semantic.alignment.java.JavaEquivalenceTest_SimpleTrafficLights;
/**
* Index to all tests.
*
* @author ratiu
*/
// @CodeFormatterOff
@RunWith(Suite.class)
@SuiteClasses({
CCodeEquivalenceTest.class,
JavaEquivalenceTest_SimpleTrafficLights.class
})
// @CodeFormatterOn
public class AllTests {
// empty class
}
<!-- (c) 2017 fortiss GmbH -->
<body>
Base package for tests of the AF3 testing plugins.
</body>
/*-------------------------------------------------------------------------+
| Copyright 2011 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package test.org.fortiss.af3.rcp.application.semantic.alignment.c;
import static org.fortiss.af3.project.utils.ProjectUtils.loadProjectFromPlugin;
import static org.fortiss.af3.testing.method.random.util.RandomSpecificationModelElementFactory.createPortBinding;
import static org.fortiss.af3.testing.method.random.util.RandomSpecificationModelElementFactory.createRandomSpecificationPart;
import static org.fortiss.af3.testing.utils.TestingModelElementFactory.createTestSuiteSpecification;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.findContentElementByNameAndClass;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.conqat.lib.commons.collections.Pair;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.model.InputPort;
import org.fortiss.af3.expression.model.terms.DoubleConst;
import org.fortiss.af3.project.model.FileProject;
import org.fortiss.af3.rcp.application.AF3ApplicationActivator;
import org.fortiss.af3.testing.extension.data.TestSuiteGenerationException;
import org.fortiss.af3.testing.method.random.generator.RandomTestSuiteGenerator;
import org.fortiss.af3.testing.method.random.model.RandomSpecificationPart;
import org.fortiss.af3.testing.model.TestCase;
import org.fortiss.af3.testing.model.TestInput;
import org.fortiss.af3.testing.model.TestOutput;
import org.fortiss.af3.testing.model.TestStep;
import org.fortiss.af3.testing.model.TestSuite;
import org.fortiss.af3.testing.model.TestSuiteSpecification;
import org.fortiss.tooling.kernel.service.ICommandStackService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests for the C code equivalence.
*
* @author mou
*/
@RunWith(Parameterized.class)
public class CCodeEquivalenceTest {
/** The test-data area. */
private static final int TEST_CASES_NUM = 10;
/** The test-case to be used. */
private TestCase testCase;
/** The tested project. */
private FileProject project;
/** Constructor. */
public CCodeEquivalenceTest(Pair<FileProject, TestCase> pair) {
this.project = pair.getFirst();
this.testCase = pair.getSecond();
}
/**
* Test data.
*
* @throws InterruptedException
*/
@Parameters
public static Collection<Pair<FileProject, TestCase>[]> testDataCollection()
throws TestSuiteGenerationException, InterruptedException {
// @CodeFormatterOff
String[][] fileNamesAndComponents = {
new String[] {"platform:/plugin/org.fortiss.af3.rcp.application/test-data/SimpleTrafficLightsExample.af3_23", "Controller"}
};
// @CodeFormatterOn
List<Pair<FileProject, TestCase>[]> testData =
new ArrayList<Pair<FileProject, TestCase>[]>();
// summarize all the FileProject TestCase pairs for all files and them components
for(String[] fileNameAndComponent : fileNamesAndComponents) {
// pack FileProjet TestCase pair in a one element array and then add it to the testData
// list
for(Pair<FileProject, TestCase> projectTestCasePair : collectTestCasesForProject(
fileNameAndComponent[0], fileNameAndComponent[1])) {
@SuppressWarnings("unchecked") Pair<FileProject, TestCase>[] projectTestCasePairArray =
new Pair[1];
projectTestCasePairArray[0] = projectTestCasePair;
testData.add(projectTestCasePairArray);
}
}
return testData;
}
/** */
static TestSuiteSpecification spec;
/** */
static RandomSpecificationPart rsp;
/** */
static TestSuite newSuite = null;
/**
* Generates the tests for a project.
*
* @param fileName
* @param componentName
* @return collection of project test case pair
* @throws TestSuiteGenerationException
* @throws InterruptedException
*/
private static Collection<Pair<FileProject, TestCase>>
collectTestCasesForProject(String fileName, String componentName)
throws TestSuiteGenerationException, InterruptedException {
FileProject project =
loadProjectFromPlugin(AF3ApplicationActivator.PLUGIN_ID, fileName, true);
Component testedComponent =
findContentElementByNameAndClass(project, componentName, Component.class);
ICommandStackService.getInstance().runAsCommand(project, () -> {
spec = createTestSuiteSpecification();
testedComponent.getSpecifications().add(spec);
RandomSpecificationPart rsp = createRandomSpecificationPart();
spec.getSpecifications().add(rsp);
rsp.setNumberOfTestCases(TEST_CASES_NUM);
for(InputPort port : testedComponent.getInputPorts()) {
rsp.getPortBinding().add(createPortBinding(port));
}
RandomTestSuiteGenerator rtsg = new RandomTestSuiteGenerator();
try {
newSuite = rtsg.generate(spec, new NullProgressMonitor());
} catch(Exception e) {
e.printStackTrace();
}
});
List<Pair<FileProject, TestCase>> projectsAndTestCases =
new ArrayList<Pair<FileProject, TestCase>>();
for(TestCase tc : newSuite.getTestCases()) {
projectsAndTestCases.add(new Pair<FileProject, TestCase>(project, tc));
}
return projectsAndTestCases;
}
/** Simple test if code generation succeeded. */
@Test
public void codeGenerationTest() {
int caseNum = 0;
StringBuffer debugInfo = new StringBuffer();
// test the equivalence of expected value and simulated value of all TestSteps
for(int stepNum = 0; stepNum < testCase.getTestSteps().size(); stepNum++) {
TestStep step = testCase.getTestSteps().get(stepNum);
int inputPortPos = 0;
debugInfo.append("Step " + stepNum + " (");
// configure debug info StringBuffer with name and value of Inputports
for(TestInput ti : step.getInputs()) {
InputPort ip = testCase.getTestSuite().getInputPorts().get(inputPortPos);
debugInfo.append(ip.getName() + ":" + ti.getValue() + ", ");
inputPortPos++;
}
debugInfo.append(") -- ");
for(TestOutput to : step.getOutputs()) {
if(to.getExpectedValue() instanceof DoubleConst) {
// reduced equality assertion: expected and simulated are equal if first three
// characters are equal
String expected = to.getExpectedValue().toString().substring(0, 3);
String simulated = to.getSimulatedValue().toString().substring(0, 3);
if(!expected.equals(simulated)) {
assertEquals("Project: " + project.getName() +
" Output mismatch in test case " + caseNum + " (test step " +
stepNum + ") -- inputs are: " + debugInfo, expected, simulated);
}
} else {
if(!to.getExpectedValue().equals(to.getSimulatedValue())) {
// FIXME AssertionFailedError Bug #1164 {@link
// https://af3.fortiss.org/issues/1164}
assertEquals("Project: " + project.getName() +
" Output mismatch in test case " + caseNum + " (test step " +
stepNum + ") -- inputs are: " + debugInfo, to.getExpectedValue(),
to.getSimulatedValue());
}
}
}
}
caseNum++;
}
}
<!-- (c) 2017 fortiss GmbH -->
<body>
This package contains tests for assuring the alignment of the simulator and C code generator.
</body>
/*-------------------------------------------------------------------------+
| Copyright 2012 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package test.org.fortiss.af3.rcp.application.semantic.alignment.java;
import static java.io.File.separator;
import static org.conqat.lib.commons.filesystem.FileSystemUtils.deleteRecursively;
import static org.conqat.lib.commons.filesystem.FileSystemUtils.ensureDirectoryExists;
import static org.fortiss.af3.generator.common.utils.JavaLanguageModelElementFactory.SRC_GEN_SOURCE_PACKAGE;
import static org.fortiss.tooling.base.utils.SystemUtils.getTempDirPath;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import org.fortiss.af3.component.generator.java.ComponentArchitectureToJavaSourcePackageTransformation;
import org.fortiss.af3.component.generator.java.ComponentProgramToJavaSourcePackageTransformation;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.model.ComponentArchitecture;
import org.fortiss.af3.expression.generator.java.DataDictionaryToJavaSourcePackageTransformation;
import org.fortiss.af3.expression.language.evaluation.NoVal;
import org.fortiss.af3.expression.model.DataDictionary;
import org.fortiss.af3.expression.utils.ExpressionModelElementFactory;
import org.fortiss.af3.generator.common.model.java.JavaSourcePackage;
import org.fortiss.af3.project.model.FileProject;
import org.fortiss.af3.project.model.typesystem.ITerm;
import org.fortiss.af3.project.utils.ProjectUtils;
import org.fortiss.af3.rcp.application.AF3ApplicationActivator;
import org.fortiss.af3.testing.model.TestCase;
import org.fortiss.af3.testing.model.TestInput;
import org.fortiss.af3.testing.model.TestOutput;
import org.fortiss.af3.testing.model.TestStep;
import org.fortiss.af3.testing.model.TestSuite;
import org.fortiss.af3.testing.model.TestingModelFactory;
import org.fortiss.af3.testing.simulator.TestCaseSimulator;
import org.fortiss.af3.testing.simulator.TestCaseSimulatorException;
import org.fortiss.af3.testing.ui.Af3TestingUIActivator;
import org.fortiss.af3.testing.utils.TestingModelElementFactory;
import org.fortiss.tooling.kernel.extension.exception.TransformationFailedException;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
import org.fortiss.tooling.kernel.utils.IdentifierUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Java code generator test. Checks using the Simple Traffic Lights model that the
* generated Java code behaves equivalently to the model simulator.
*
* @author trachtenherz
*/
public class JavaEquivalenceTest_SimpleTrafficLights {
/** Plug-in id */
public static final String PLUGIN_ID = AF3ApplicationActivator.PLUGIN_ID;
/** Project */
public FileProject project;
/** Component architecture of the model. */
ComponentArchitecture compArch;
/** Root component of the model. */
Component rootComp;
/** Data dictionary. */
DataDictionary dataDict;
/** Class representing the root component in the generated Java code */
protected Class<?> gen_rootComp;
/** Class representing the data dictionary in the generated Java code */
protected Class<?> gen_dataDict;
/** Method for clearing root component's input ports in the generated Java code */
Method genMethod_clear_inputs;
/** Method for clearing root component's output ports in the generated Java code */
Method genMethod_clear_outputs;
/** Method for initializing the root component in the generated Java code */
Method genMethod_init;
/** Method for performing a step of the root component in the generated Java code */
Method genMethod_perform_step;
/** Input port tlarchInButtonA in the generated Java code. */
Field genField_InButtonA;
/** Input port tlarchOutTrafficSignal in the generated Java code. */
Field genField_OutTrafficSignal;
/** Input port tlarchOutPedestrianSignal in the generated Java code. */
Field genField_OutPedestrianSignal;
/** Input port tlarchOutIndicatorSignalA in the generated Java code. */
Field genField_OutIndicatorSignalA;
/** Input port tlarchOutIndicatorSignalB in the generated Java code. */
Field genField_OutIndicatorSignalB;
/** Map of constant names to methods representing the constants in the generated Java code */
Map<String, Method> gen_dataDictMap = new HashMap<String, Method>();
/** Test data. */
enum InputSignal {
/** Test data value */
Present;
}
/** String value of the {@code Present} signal for the InButtonA input port. */
public static final String INPUT_SIGNAL_VALUE_STRING = "Present";
/** File representing the target forlder for Java code generation. */
File targetLocation;
/** Path to the root folder of the generated Java code. */
public File javaSourcePath;
/** Name of Java class representing the root component of the model. */
public String rootCompClassName;
/**
* Set up.
*
* @throws MalformedURLException
* if the temporary user directory for code generation cannot be found.
*/
@Before
public void setup() throws MalformedURLException {
setupProject();
setupJavaPaths();
generateJavaCode();
setupGeneratedJavaCode(javaSourcePath, rootCompClassName);
}
/** Loads the Traffic Lights model project for test. */
public void setupProject() {
project = ProjectUtils.loadProjectFromPlugin(Af3TestingUIActivator.PLUGIN_ID,
"/test-data/SimpleTrafficLightsExample.af3_23", true);
for(IProjectRootElement element : project.getRootElements()) {
if(element instanceof ComponentArchitecture) {
compArch = (ComponentArchitecture)element;
rootComp = compArch.getTopComponent();
} else if(element instanceof DataDictionary) {
dataDict = (DataDictionary)element;
}
}
}
/**
* Sets up the paths to generated Java code.
*
* @throws MalformedURLException
* if the temporary user directory for code generation cannot be found.
*
* @see #javaSourcePath
* @see #rootCompClassName
*/
protected void setupJavaPaths() throws MalformedURLException {
rootCompClassName = IdentifierUtils.getUniqueIdentifier(rootComp);
targetLocation = new File(getTempDirPath(false, getClass().getName()));
javaSourcePath = new File(targetLocation, SRC_GEN_SOURCE_PACKAGE);
}
/**
* Generates the Java code for the loaded model {@link #setupProject()} to a temporary folder.
*/
protected void generateJavaCode() {
try {
JavaSourcePackage javaSourcePackage =
(JavaSourcePackage)(new ComponentArchitectureToJavaSourcePackageTransformation())
.transform(compArch, null);
javaSourcePackage.setBaseLocation("");
if(targetLocation.exists()) {
deleteRecursively(targetLocation);
}
ensureDirectoryExists(targetLocation);
javaSourcePackage.writeToLocation(targetLocation.getAbsolutePath());
} catch(TransformationFailedException e) {
e.printStackTrace();
throw new AssertionError(e);
} catch(IOException e) {
e.printStackTrace();
throw new AssertionError(e);
}
}
/** Sets up the generated Java code. */
protected void setupGeneratedJavaCode(File sourcePath, String rootCompClassName) {
// Compile the generated Java code
String mainJavaFilePath = sourcePath + separator + "af3" + separator + "javagen" +
separator + "component" + separator + rootCompClassName + ".java";
String[] args = new String[] {"-sourcepath", sourcePath.toString(), mainJavaFilePath};
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, args);
ClassLoader classLoader = null;
try {
// Due to a bug in the URLClassPath (see
// https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/999dbd4192d0f819cb5224f26e9e7fa75ca6f289/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java#L471)
// generated classes are not found on Windows. Hence, we must "unify" the source path.
URL sourcePathURL = new URL(sourcePath.toURI().toString().replace("\\", "/"));
classLoader = URLClassLoader.newInstance(new URL[] {sourcePathURL});
// Load the classes for root component and data dictionary
gen_rootComp = Class.forName(
ComponentProgramToJavaSourcePackageTransformation.COMPONENT_JAVA_PACKAGE + "." +
rootCompClassName,
true, classLoader);
gen_dataDict = Class.forName(
DataDictionaryToJavaSourcePackageTransformation.DD_JAVA_PACKAGE + "." +
DataDictionaryToJavaSourcePackageTransformation.DD_JAVA_CLASS,
true, classLoader);
} catch(Exception e) {
e.printStackTrace();
throw new AssertionError(e);
}
// Store references to certain methods and fields in the generated Java code
readGenMethods();
readGenFields();
readGenDataDict();
}
/** Stored method references from the generated Java code required to perform the test. */
protected void readGenMethods() {
Method[] methods = gen_rootComp.getDeclaredMethods();
for(Method m : methods) {
final String methodName = m.getName();
if(methodName.contains("clear_inputs")) {
genMethod_clear_inputs = m;
} else if(methodName.contains("clear_outputs")) {
genMethod_clear_outputs = m;
} else if(methodName.contains("init")) {
genMethod_init = m;
} else if(methodName.contains("perform_step")) {
genMethod_perform_step = m;
} else {
// Nothing
}
}
}
/** Stored field references from the generated Java code required to perform the test. */
protected void readGenFields() {
Field[] fields = gen_rootComp.getDeclaredFields();
for(Field f : fields) {
final String fieldName = f.getName();
if(fieldName.contains("InButtonA")) {
genField_InButtonA = f;
} else if(fieldName.contains("OutTrafficSignal")) {
genField_OutTrafficSignal = f;
} else if(fieldName.contains("OutPedestrianSignal")) {
genField_OutPedestrianSignal = f;
} else if(fieldName.contains("OutIndicatorSignalA")) {
genField_OutIndicatorSignalA = f;
} else if(fieldName.contains("OutIndicatorSignalB")) {
genField_OutIndicatorSignalB = f;
} else {
// Nothing
}
}
}
/** Stores the data dictionary from the generated Java code. */
protected void readGenDataDict() {
Method[] methods = gen_dataDict.getDeclaredMethods();
for(Method m : methods) {
gen_dataDictMap.put(m.getName(), m);
}
}
/** Performs one step for the generated Java code. */
protected void genPerformStep()
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
genMethod_clear_outputs.invoke(null);
genMethod_perform_step.invoke(null);
genMethod_clear_inputs.invoke(null);
}
/**
* @param inputSignals
* Input values for the tlarchInButtonA input port of the Traffic Lights Example.
* {@link InputSignal#Present} correspond to {@code Present} message inputs while
* {@code null} values correspond to {@code NoVal} inputs.
* @param testSuite
* {@link TestSuite} to which the test case will be added. If {@code null} a new
* {@link TestSuite} instance is created.
* @return
* A {@link TestCase} with inputs corresponding to {@code inputSignals}.
*/
protected TestCase generateTestCase(InputSignal[] inputSignals, TestSuite testSuite) {
TestCase testCase = TestingModelFactory.eINSTANCE.createTestCase();
if(testSuite == null) {
testSuite = TestingModelElementFactory.createTestSuite("Java Generator Test Suite",
rootComp);
}
testSuite.getTestCases().add(testCase);
List<TestStep> stepList = testCase.getTestSteps();
for(InputSignal in : inputSignals) {
TestStep testStep = TestingModelFactory.eINSTANCE.createTestStep();
TestInput testInput = TestingModelFactory.eINSTANCE.createTestInput();
ITerm value = in == InputSignal.Present
? ExpressionModelElementFactory.funcCall("Present") : NoVal.NOVAL.toITerm();
testInput.setValue(value);
testStep.getInputs().add(testInput);
stepList.add(testStep);
}
return testCase;
}
/**
* Returns the current output port values for the generated java code.
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
protected Object[] genOutputResult() throws IllegalArgumentException, IllegalAccessException {
return new Object[] {genField_OutTrafficSignal.get(null),
genField_OutPedestrianSignal.get(null), genField_OutIndicatorSignalA.get(null),
genField_OutIndicatorSignalB.get(null)};
}
/**
* Simulates the model and the generated Java code with the specified input data. After each
* simulation step the equivalence of the results from the model and generated code is asserted
* ({@link Assert#assertTrue(String, boolean)})
*
* @see #simOutputsEquiv(TestStep, Object[])
*
* @param inputSignals
* Input values. The i-th value is {@link InputSignal#Present} if the input in the
* i-th step should be the {@code Present} signal and {@code null} if the input
* should be {@code NoVal}.
*/
protected void assertSimulationEquiv(InputSignal[] inputSignals)
throws IllegalArgumentException, IllegalAccessException {
TestCase testCase = generateTestCase(inputSignals, null);
TestCaseSimulator sim = new TestCaseSimulator(testCase, rootComp);
try {
sim.simulate(true);
} catch(TestCaseSimulatorException e) {
e.printStackTrace();
throw new AssertionError(e);
}
List<TestStep> testSteps = testCase.getTestSteps();
try {
genMethod_init.invoke(null);
for(int i = 0; i < inputSignals.length; i++) {
if(inputSignals[i] == InputSignal.Present) {
genField_InButtonA.set(null,
gen_dataDictMap.get(INPUT_SIGNAL_VALUE_STRING).invoke(null));
}
// Perform one step in the generated Java code
genPerformStep();
// Compare the results from the model simulation and the generated Java code
// execution
assertTrue("Simulation step " + i,
simOutputsEquiv(testSteps.get(i), genOutputResult()));
}
} catch(InvocationTargetException e) {
e.getCause().printStackTrace();
}
}
/**
* Checks that the simulation results of the model (stored in {@code testStep}) and of the
* generated Java code stored in {@code genCodeOutput} are equivalent.
*/
protected boolean simOutputsEquiv(TestStep testStep, Object[] genCodeOutput) {
List<TestOutput> testOutputs = testStep.getOutputs();
for(int i = 0; i < testOutputs.size(); i++) {
ITerm simOutValue = testOutputs.get(i).getSimulatedValue();
Object genCodeValue = genCodeOutput[i];
String simOutStr = simOutValue.toString();
// Remove parentheses from string representation
int parPos = simOutStr.indexOf('(');
if(parPos >= 0) {
simOutStr = simOutStr.substring(0, parPos).trim();
}
// Result string for generated Java code
String genCodeStr = genCodeValue == null ? NoVal.NOVAL_STRING : genCodeValue.toString();
/*
* We consider outputs equivalent if the result string from Java code execution starts
* with the string representing the simulated model output (possible parentheses and
* spaces have been removed before comparison). The result string in the Java code may
* contain additional information like a unique id so that we check not for equality but
* for prefix relation.
*/
if(!genCodeStr.startsWith(simOutStr)) {
// Outputs are not equivalent
return false;
}
}
return true;
}
/**
* Tests behavior equivalence for an input sequence containing one {@code Present} signal,
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@Test
public void test1() throws IllegalArgumentException, IllegalAccessException {
final int testDataSize = 20;
InputSignal[] testData1 = new InputSignal[testDataSize];
testData1[2] = InputSignal.Present;
assertSimulationEquiv(testData1);
}
/**
* Tests behavior equivalence for an input sequence containing several {@code Present} signals
* with distance less than time needed to completely process one {@code Present} input signal.
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@Test
public void test2() throws IllegalArgumentException, IllegalAccessException {
final int testDataSize = 40;
InputSignal[] testData1 = new InputSignal[testDataSize];
testData1[10] = testData1[20] = testData1[30] = InputSignal.Present;
assertSimulationEquiv(testData1);
}
/**
* Tests behavior equivalence for a long input sequence containing periodic {@code Present}
* signals.
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@Test
public void test3() throws IllegalArgumentException, IllegalAccessException {
final int testDataSize = 1000;
final int inputPeriod = 10;
InputSignal[] testData1 = new InputSignal[testDataSize];
for(int i = 0; i < testDataSize / inputPeriod; ++i) {
testData1[i * inputPeriod] = InputSignal.Present;
}
assertSimulationEquiv(testData1);
}
}
<!-- (c) 2017 fortiss GmbH -->
<body>
This package contains tests for assuring the alignment of the simulator and Java code generator.
</body>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment