Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VDMUnit for VDM-SL #671

Open
wants to merge 13 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ node {
throw any //rethrow exception to prevent the build from proceeding
} finally {

stage ('Clean up workspace'){
step([$class: 'WsCleanup'])
}

stage('Reporting'){
// Notify on build failure using the Email-ext plugin
emailext(body: '${DEFAULT_CONTENT}', mimeType: 'text/html',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public InternalException(int number, String message)
this.number = number;
}

public InternalException(int number, String message, Throwable cause)
{
super(message,cause);
this.number = number;
}

@Override
public String toString()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
import org.overture.codegen.assistant.NodeAssistantIR;
import org.overture.codegen.ir.IRConstants;
import org.overture.codegen.ir.IRGeneratedTag;
import org.overture.codegen.ir.STypeIR;
import org.overture.codegen.ir.analysis.AnalysisException;
import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor;
import org.overture.codegen.ir.declarations.ADefaultClassDeclIR;
import org.overture.codegen.ir.declarations.AMethodDeclIR;
import org.overture.codegen.ir.declarations.SClassDeclIR;
import org.overture.codegen.ir.statements.APlainCallStmIR;
import org.overture.codegen.ir.types.AClassTypeIR;
import org.overture.codegen.trans.assistants.TransAssistantIR;
import org.overture.config.Settings;

Expand All @@ -30,6 +33,12 @@ public class JUnit4Trans extends DepthFirstAnalysisAdaptor
public static final String TEST_SETUP_ANNOTATION = "@Before";
public static final String TEST_TEARDOWN_ANNOTATION = "@After";
public static final String JUNI4_IMPORT = "org.junit.*";
public static final String ASSERT_MODULE = "Assert";
public static final String ASSERT_TRUE_MSG_METHOD = "assertTrueMsg";
public static final String ASSERT_FALSE_MSG_METHOD = "assertFalseMsg";
public static final String JUNIT4_ASSERT_TRUE_METHOD = "assertTrue";
public static final String JUNIT4_ASSERT_FALSE_METHOD = "assertFalse";


public TransAssistantIR assist;
private JavaCodeGen javaCg;
Expand Down Expand Up @@ -123,6 +132,39 @@ private void adjustTestClass(ADefaultClassDeclIR copy) {
for(AMethodDeclIR m : copy.getMethods())
{
m.setStatic(false);

try
{
m.apply(new DepthFirstAnalysisAdaptor()
{
@Override
public void caseAPlainCallStmIR(APlainCallStmIR node)
throws AnalysisException
{
STypeIR type = node.getClassType();

if (type instanceof AClassTypeIR)
{
AClassTypeIR classType = (AClassTypeIR) type;

if (classType.getName().equals(ASSERT_MODULE))
{
if (node.getName().equals(ASSERT_FALSE_MSG_METHOD))
{
node.setName(JUNIT4_ASSERT_FALSE_METHOD);
} else if (node.getName().equals(ASSERT_TRUE_MSG_METHOD))
{
node.setName(JUNIT4_ASSERT_TRUE_METHOD);
}
}
}
}
});
} catch (AnalysisException e)
{
log.error("Got unexpected analysis error: " + e.getMessage());
e.printStackTrace();
}
}

for(int i = 0; i < copy.getMethods().size(); i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class IRConstants

public static final String TEST_MODULE_NAME_POSTFIX = "Test";

public static final String[] CLASS_NAMES_USED_IN_SL = {"CSV", "IO", "MATH", "VDMUtil"};
public static final String[] CLASS_NAMES_USED_IN_SL = {"CSV", "IO", "MATH", "VDMUtil", "Assert", "TestRunner"};

public static final String[] CLASS_NAMES_USED_IN_VDM_PP_RT = (String[]) ArrayUtils.addAll(CLASS_NAMES_USED_IN_SL,
new String[]{"VDMUnit", "Throwable", "Error", "AssertionFailedError",
Expand Down
90 changes: 75 additions & 15 deletions core/interpreter/src/main/java/TestCase.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import org.overture.ast.definitions.AExplicitOperationDefinition;
import org.overture.ast.messages.InternalException;
import org.overture.ast.modules.AModuleModules;
import org.overture.interpreter.runtime.*;
import org.overture.interpreter.values.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

Expand All @@ -14,6 +16,7 @@
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;


public class TestCase {
Expand Down Expand Up @@ -44,19 +47,17 @@ public static Value reflectionRunTest(Value obj, Value name)
success = true;
} catch (Exception e) {
if (e instanceof ExitException) {
if(((ExitException)e).value.objectValue(null).type.getName().equals("AssertionFailedError"))
{
if (((ExitException) e).value.objectValue(null).type.getName().equals("AssertionFailedError")) {
success = false;
}
throw e;
}

try {
return ClassInterpreter.getInstance().evaluate("Error`throw(\""
return ClassInterpreter.getInstance().evaluate("Error`throw(\""
+ e.getMessage().replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"").replaceAll("\'", "\\\'")
+ "\")", mainContext);
}catch(ExitException e2)
{
} catch (ExitException e2) {
error = e2;
throw e2;
}
Expand All @@ -81,7 +82,58 @@ public static Value reflectionRunTest(Value obj, Value name)

}

private static void recordTestResults(String containerName, String methodName, boolean success, ExitException error, long totalExecTime) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException, TransformerException {
public static boolean reflectionRunTest(AModuleModules module, AExplicitOperationDefinition opDef) throws Exception {
String moduleName = module.getName().getName();
String testName = opDef.getName().getName();

long timerStart = System.nanoTime();
boolean success = false;
Exception error = null;
try {
ModuleInterpreter.getInstance().evaluate(moduleName + "`" + testName + "()"
, ModuleInterpreter.getInstance().initialContext);
success = !TestRunner.isFailed();
} catch(TestRunner.TestAsserException e)
{
success =false;
}catch(InternalException e)
{
if(e.getCause() instanceof InvocationTargetException && ((InvocationTargetException)e.getCause()).getTargetException() instanceof TestRunner.TestAsserException)
{
success =false;
}else
{
throw e;
}
}
catch (Exception e) {
success = false;
error = e;
throw e;
} finally {
long totalExecTime = System.nanoTime() - timerStart;

if (System.getProperty(vdmUnitReportEnable) != null) {
recordTestResults(moduleName, testName, success, error, totalExecTime);
}
}
return success;
}


public static void reflectionRun(AModuleModules module, AExplicitOperationDefinition opDef) {
String moduleName = module.getName().getName();
String testName = opDef.getName().getName();

try {
ModuleInterpreter.getInstance().evaluate(moduleName + "`" + testName + "()"
, ModuleInterpreter.getInstance().initialContext);
} catch (Exception e) {
// Fine
}
}

private static void recordTestResults(String containerName, String methodName, boolean success, Exception error, long totalExecTime) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException, TransformerException {

File report = new File("TEST-" + containerName + ".xml");

Expand Down Expand Up @@ -115,8 +167,7 @@ private static void recordTestResults(String containerName, String methodName, b
n = doc.createElement("testcase");
}

while(n.getFirstChild()!=null)
{
while (n.getFirstChild() != null) {
n.removeChild(n.getFirstChild());
}

Expand All @@ -127,21 +178,30 @@ private static void recordTestResults(String containerName, String methodName, b

testSuiteNode.setAttribute("tests", String.valueOf(Integer.parseInt(testSuiteNode.getAttribute("tests")) + 1));

if (error!=null) {
if (error != null) {
testSuiteNode.setAttribute("error", String.valueOf(Integer.parseInt(testSuiteNode.getAttribute("errors")) + 1));
Element errorElement = doc.createElement("error");
errorElement.setAttribute("message",error.number+"");
errorElement.setAttribute("type","ERROR");
errorElement.setAttribute("message", error.getMessage() + "");
errorElement.setAttribute("type", "ERROR");
StringWriter strOut = new StringWriter();
error.ctxt.printStackTrace(new PrintWriter(strOut),true);
if(error instanceof ExitException) {
((ExitException)error).ctxt.printStackTrace(new PrintWriter(strOut), true);
}else
{
error.printStackTrace(new PrintWriter(strOut));
}
errorElement.setTextContent(strOut.toString());
n.appendChild(errorElement);
} else if (!success) {
testSuiteNode.setAttribute("failures", String.valueOf(Integer.parseInt(testSuiteNode.getAttribute("failures")) + 1));
Element failureElement = doc.createElement("failure");
failureElement.setAttribute("message",methodName);
failureElement.setAttribute("type","WARNING");
failureElement.setAttribute("message", methodName);
failureElement.setAttribute("type", "WARNING");
failureElement.setAttribute("time", totalExecTime * 1E-9 + "");
if(TestRunner.getMsg()!=null)
{
failureElement.setTextContent(TestRunner.getMsg());
}
n.appendChild(failureElement);
}

Expand Down
Loading