/* * Copyright 2008 Wishnu Prasetya. * * This file is part of T2. * T2 is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License (GPL) as published by the * Free Software Foundation; either version 3 of the License, or any * later version. * * T2 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. * * A copy of the GNU General Public License can be found in T2 distribution. * If it is missing, see http://www.gnu.org/licenses. */ package t2ext.trace; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import t2ext.trace.utils.TraceAnalysis; import t2ext.util.InfoFile; import t2ext.util.Util; import t2ext.xml.XMLBuilder; import Sequenic.T2.BaseDomain0; import Sequenic.T2.BaseDomainSmall; import Sequenic.T2.TrFile; import Sequenic.T2.DataGen.RandomBoolUniform; import Sequenic.T2.Engines.BaseEngine; import Sequenic.T2.Msg.T2Exception; import Sequenic.T2.Seq.Trace; /** * @author Maaike Gerritsen */ public class PathFinder { private String _className; private XMLBuilder _xmlBuilder; private BaseEngine _baseEngine; private InfoFile _infoFile; private final int _attempts = 5; private int _foundPathsAmount; private LinkedList _allFaultyTraces; public PathFinder(String className, InfoFile infoFile) { _foundPathsAmount = 0; _className = className; _xmlBuilder = new XMLBuilder(); _infoFile = infoFile; _allFaultyTraces = new LinkedList(); // _baseEngine = new BaseEngine(); try { _baseEngine = new BaseEngine(Class.forName(_className)); if (_infoFile.nullProbability != 0.1) { _baseEngine.generateNullProb = new RandomBoolUniform( _infoFile.nullProbability); } if (_infoFile.pickPoolProbability != 0.7) { _baseEngine.pickTargetObjFromPoolProb = new RandomBoolUniform( _infoFile.pickPoolProbability); } if (_infoFile.objectDepth != 4) { _baseEngine.maxMkValSeqDepth = _infoFile.objectDepth; } // set access options _baseEngine.accessOption.setExcludePrivate(!_infoFile.inclPrivate); _baseEngine.accessOption.setExcludeDefault(_infoFile.exclDefault); _baseEngine.accessOption .setExcludeProtected(_infoFile.exclProtected); _baseEngine.accessOption.setExcludeStatic(_infoFile.exclStatic); //_baseEngine.setFieldIps(); System.out.println("base engine created"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } @SuppressWarnings("unchecked") private boolean coveredAllPaths() { Document doc = _xmlBuilder.readXMLFile("paths.xml"); NodeList foundPaths = _xmlBuilder.getNodesFromXML(doc, "//path[@found='false']"); if (foundPaths.getLength() > 0) return false; return true; } public void updateFoundPaths() { try { String file = _className + ".tr"; if (!_infoFile.saveFile.equals("")) file = _infoFile.saveFile; String cleanMethodsDir = new File(file).getAbsolutePath() .toString(); File existsFile = new File(cleanMethodsDir); if (existsFile.exists()) { TrFile trFile = TrFile.load(file); int i = 0; TraceAnalyser analyser = new TraceAnalyser(trFile, _baseEngine); System.out.println("START ANALYSIS"); analyser.analyseTraces(); while (i < _infoFile.maximumAttempts && !coveredAllPaths()) { System.out.println("START SEARCH"); noChangeFound(); findPathsPerMethod(analyser); boolean domainChanged = false; if (noChangeFound()) { System.out.println("base engine small initiated"); _baseEngine.baseDomain = new BaseDomainSmall(100); findPathsPerMethod(analyser); domainChanged = true; } if (domainChanged && noChangeFound()) { System.out.println("base engine 0 initiated"); _baseEngine.baseDomain = new BaseDomain0(); findPathsPerMethod(analyser); } i++; } if (!_allFaultyTraces.isEmpty()) { trFile.traces.addAll(_allFaultyTraces); trFile.save(); _infoFile.saveTraces = true; _infoFile.save(); } System.out.println("done"); } else System.out.println("File " + file + "does not exist!"); } catch (T2Exception e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } @SuppressWarnings("unchecked") private boolean noChangeFound() { Document doc = _xmlBuilder.readXMLFile("paths.xml"); NodeList foundPaths = _xmlBuilder.getNodesFromXML(doc, "//path[@found='false']"); int pathsFoundThisTime = foundPaths.getLength(); if (pathsFoundThisTime == _foundPathsAmount) return true; _foundPathsAmount = pathsFoundThisTime; return false; } @SuppressWarnings("unchecked") private void findPathsPerMethod(TraceAnalyser analyser) { PathComparison pComp = new PathComparison(); Document doc = _xmlBuilder.readXMLFile("paths.xml"); NodeList nodeList = doc.getChildNodes(); Element root = (Element) nodeList.item(0); NodeList methods = root.getChildNodes(); for(int i=0;i 1) { Hashtable list = pComp.findBestPath(method); if (list.size() > 0) changeBestPath(method, analyser, list); } } } private void changeBestPath(Element method, TraceAnalyser analyser, Hashtable bestPaths) { boolean checkSpec = false; List specNames = analyser.getSpecNames(); String name = method.getAttribute("official").toString(); String originalName = new String(name); if (specNames.contains(name)) { checkSpec = true; name = name.replace("(", "_spec("); } List analyserList = analyser.getAnalysisForMethod(name); Enumeration unfoundPaths = bestPaths.keys(); TraceModifier tme = new TraceModifier(_baseEngine); while (unfoundPaths.hasMoreElements() && analyserList.size() > 0) { Integer id = unfoundPaths.nextElement(); if (_infoFile.endMethods) setPathToFind(id, originalName); Integer bestId = bestPaths.get(id); if (!Util.foundPath(id, originalName)) { boolean foundMatchingTrace = execBestPathForMethod(checkSpec, name, analyserList, tme, bestId, id); if (!foundMatchingTrace) execAllPathsForMethod(name, analyserList, tme); if (!Util.foundPath(id, originalName)) execCompleteTraceForMethod(analyserList, tme); if (!Util.foundPath(id, originalName)) execTraceWithFieldUpdates(analyserList, tme, name); } } if (!tme.getFaultyTraces().isEmpty()) { _allFaultyTraces.addAll(tme.getFaultyTraces()); } } @SuppressWarnings("unchecked") private void setPathToFind(Integer id, String name) { Document doc = _xmlBuilder.readXMLFile("paths.xml"); String condition = "//method[@official='"+name+"']/path[@id='"+id+"]/nodes"; NodeList paths = _xmlBuilder.getNodesFromXML(doc, condition); Element nodes = (Element) paths.item(0); String pathToFind = nodes.getAttribute("value"); NodeList methods = _xmlBuilder.getNodesFromXML(doc, "//method[@official='"+name+"']"); Element method = (Element) methods.item(0); method.setAttribute("pathtofind", pathToFind); _xmlBuilder.writeToFile(doc, "paths.xml"); } private void execTraceWithFieldUpdates(List analyserList, TraceModifier tme, String name) { for (Iterator iterator = analyserList.iterator(); iterator .hasNext();) { TraceAnalysis traceAnalysis = iterator.next(); if (!traceAnalysis.foundAllFields()) tme.modifyTraceWithFieldUpdates(traceAnalysis, name); } } private void execCompleteTraceForMethod(List analyserList, TraceModifier tme) { for (Iterator iterator = analyserList.iterator(); iterator .hasNext();) { TraceAnalysis traceAnalysis = iterator.next(); tme.modifyAndExecCompleteTrace(traceAnalysis); } } private void execAllPathsForMethod(String name, List analyserList, TraceModifier tme) { for (Iterator iterator = analyserList.iterator(); iterator .hasNext();) { TraceAnalysis traceAnalysis = iterator.next(); for (int i = 0; i < _attempts; i++) tme.modifyAndExecuteTraceChangingCurrentMethodParams( traceAnalysis, name); } } private boolean execBestPathForMethod(boolean checkSpec, String name, List analyserList, TraceModifier tme, Integer bestId, Integer pathToFind) { boolean foundMatchingTrace = false; for (Iterator iterator = analyserList.iterator(); iterator .hasNext();) { TraceAnalysis traceAnalysis = iterator.next(); boolean found = false; if (checkSpec) found = traceAnalysis.getSpecPathsForMethod(name).contains( bestId); else found = traceAnalysis.getPathsForMethod(name).contains(bestId); if (found) { foundMatchingTrace = true; for (int i = 0; i < _attempts; i++) { tme .modifyAndExecuteTraceChangingCurrentMethodParamsForBestID( traceAnalysis, bestId, name, checkSpec, pathToFind); } } } return foundMatchingTrace; } }