/******************************************************************************* * * Copyright (C) 2008, 2009 Fujitsu Services Ltd. * * Author: Nick Battle * * This file is part of VDMJ. * * VDMJ is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VDMJ 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VDMJ. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ package org.overture.codegen.runtime.traces; import java.util.LinkedList; import java.util.List; import org.overture.codegen.runtime.Utils; public abstract class TraceNode { private static final int ENCLOSING_MODULE_ID = -1; private static final Object NOT_AVAILABLE = new Object(); private CallSequence traceVars; public TraceNode() { this.traceVars = new CallSequence(); } public void addVarFirst(TraceVariable var) { this.traceVars.add(0, var); } public CallSequence getVars() { CallSequence c = new CallSequence(); c.addAll(traceVars); return c; } @Override abstract public String toString(); abstract public TestSequence getTests(); // SL public static void executeTests(TraceNode trace, TestAccumulator acc, Store store) { executeTests(trace, null, acc, store); } // PP public static void executeTests(TraceNode trace, Class<?> instanceType, TestAccumulator acc, Store store) { try { if (instanceType != null) { store.register(ENCLOSING_MODULE_ID, instanceType.newInstance()); } int testNo = 1; TestSequence tests = trace.getTests(); tests.size(); for (CallSequence test : tests) { /** * We should reset the state before running the test in case the trace variable statements have modified * it, e.g. let a = opWithSideEffects() in .... */ store.reset(); List<String> callStms = new LinkedList<String>(); List<Object> callStmResults = new LinkedList<Object>(); /* * TODO: Type check missing here If the type check fails we would also have to do filtering */ if (test.getFilter() > 0) { acc.registerTest(new TraceTest(testNo, test.toString(), "", Verdict.SKIPPED)); } else { int callStmIdx = 0; for (; callStmIdx < test.size(); callStmIdx++) { Statement stm = test.get(callStmIdx); if (!(stm instanceof CallStatement)) { continue; } CallStatement callStm = (CallStatement) stm; try { callStms.add(callStm.toString()); if (callStm instanceof CallStatementPp) { ((CallStatementPp) callStm).setInstance(store.getValue(ENCLOSING_MODULE_ID)); } // TODO: To be done. Consider where the right place is to check for this. if (!callStm.isTypeCorrect() || !callStm.meetsPreCond()) { // Inconclusive callStmResults.add(NOT_AVAILABLE); callStmResults.add(Verdict.INCONCLUSIVE); tests.filter(callStmResults, test, testNo); acc.registerTest(new TraceTest(testNo, test.toString(), "", Verdict.INCONCLUSIVE)); break; } Object result = callStm.execute(); callStmResults.add(result); if (callStmIdx == test.size() - 1) { callStmResults.add(Verdict.PASSED); acc.registerTest(new TraceTest(testNo, getResultStr(callStms, "; "), getResultStr(callStmResults.subList(0, callStmResults.size() - 1), " ; "), Verdict.PASSED)); } } catch (RuntimeException | AssertionError e) { for (int p = callStmIdx + 1; p < test.size(); p++) { callStms.add(callStms.toString()); } for (; callStmIdx < test.size(); callStmIdx++) { if (e.getMessage() != null) { callStmResults.add(e.getClass().getSimpleName() + ": " + e.getMessage()); } else { // Happens for null pointer exceptions callStmResults.add(e.getClass().getSimpleName()); } } Verdict verdict = Verdict.FAILED; callStmResults.add(verdict); tests.filter(callStmResults, test, testNo); acc.registerTest(new TraceTest(testNo, getResultStr(callStms, "; "), getResultStr(callStmResults.subList(0, callStmResults.size() - 1), " ; "), verdict)); } } } callStms.clear(); callStmResults.clear(); testNo++; } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } private static String getResultStr(List<? extends Object> results, String sep) { StringBuilder sb = new StringBuilder(); if (!results.isEmpty()) { sb.append(toStr(results.get(0))); } for (int i = 1; i < results.size(); i++) { sb.append(sep + toStr(results.get(i))); } return sb.toString(); } public static void showResults(List<TraceTest> results) { for (TraceTest testResult : results) { System.out.println(testResult.toString()); } } private static String toStr(Object obj) { if (obj instanceof String) { return obj.toString(); } else { return Utils.toString(obj); } } }