package Sequenic.T2ext.Selection; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import Sequenic.T2.Pool; import Sequenic.T2.TrFile; import Sequenic.T2.Coverage.BasicPath; import Sequenic.T2.Coverage.TrieSensor; import Sequenic.T2.Engines.Util; import Sequenic.T2.Seq.ReportersPool; import Sequenic.T2.Seq.Trace; import Sequenic.T2.Seq.TraceExecInfo; import Sequenic.T2.Seq.TraceStep; public class SelectiveRunner { Iterable traces; Class C ; Pool pool ; List classinvs ; final boolean updateCoverage; public SelectiveRunner(TrFile trFile) { this(trFile,true); } public SelectiveRunner(TrFile trFile, boolean updateCoverage) { this.updateCoverage = updateCoverage; traces = trFile.traces; try { C = Class.forName(trFile.CUTname) ; } catch (ClassNotFoundException e) { throw new Error("## Fail to obtain the target class " + trFile.CUTname + ".",e) ; } pool = (Pool) Util.mkAnInstance(trFile.poolClassName) ; if (pool==null) throw new Error("## Fail to instantiate the pool " + trFile.poolClassName + ".") ; // Recovering the class invs: classinvs = new LinkedList(); try { for (String cowner : trFile.classinvariantOwners) { classinvs.add(Util.getClassINV(Class.forName(cowner))); } } catch (Exception e) { throw new Error("## Fail to load the class invariant(s).", e); } } public int runAll() { // T2TraceFileCoverageResult result = new T2TraceFileCoverageResult() ; // result.trfile = trFile; // This should be turned off if we plan to do concurrent monitoring: // Sensor.resetSensor() ; TrieSensor.clear(); int numOfTraces = 0; for (Trace tr : traces) { execTrace2(tr); numOfTraces++; } return numOfTraces; // Calculate total coverage: // result.observedpaths = Sensor.getObservedPaths() ; // result.totCoverage = COVanalyzer.calculateCoverage() ; // // if (debug) result.simplePrint() ; // // return result ; } public void runAll(Iterator iter) { TrieSensor.clear(); while(iter.hasNext()) execTrace2(iter.next()); } public int runSelected(ISelector sel) { return runSelected(sel,traces.iterator()); } public int runSelected(ISelector sel, Iterator iter) { int numOfTraces = 0; if(updateCoverage) { TrieSensor.clear(); while(iter.hasNext()) { Trace tr = iter.next(); if(synthesizeAll(sel, tr.coverage())<0) { execTrace2(tr); numOfTraces++; } } } else { while(iter.hasNext()) { Trace tr = iter.next(); for(BasicPath bp : tr.coverage()) if(sel.isModificationTraversing(bp)) { tr.exec(C, pool, classinvs, tr.diverging, false, ReportersPool.NULLreporter); numOfTraces++; break; } } } return numOfTraces; } public void execTrace(Trace trace) { // initialize various infos: pool.reset(); TraceExecInfo info = new TraceExecInfo(trace) ; Object targetObj = null; int stepNr = 0 ; boolean ok = true ; // Do this to keep track which runids belong to which trace //runIdTableLevel1.add(new Pair(Sensor.currentRunId(),trace)) ; // Creation step: // Do this to keep track which runids belong to which step //runIdTableLevel2.add(new Pair(Sensor.currentRunId(),stepNr)) ; ok = info.update_with_step(trace.creation.MkTargetObject(C,pool,classinvs),stepNr) ; stepNr++ ; // Creation step-done if (ok) { // Creation successful, continue with the steps: targetObj = pool.get(trace.indexOfTargetObj) ; for (TraceStep step : trace.trace) { if (trace.diverging && step == trace.trace.getLast()) break ; // Do this to keep track which runids belong to which step //if (step instanceof CALL_METHOD) { //runIdTableLevel2.add(new Pair(Sensor.currentRunId(),stepNr)) ; //} ok = info.update_with_step(step.exec(C,pool,targetObj,stepNr,classinvs),stepNr) ; stepNr++ ; if (!ok) break; } } // DONE } //Execute trace and record coverage data the easy way. private void execTrace2(Trace trace) { /* old Sensor: Sensor.resetSensor(); trace.exec(C, pool, classinvs, trace.diverging, false, ReportersPool.NULLreporter); Set coverage = new HashSet(); ObservedPath.CachingPickleFactory cache = new ObservedPath.CachingPickleFactory(); for(ObservedPath op : Sensor.getObservedPaths().values()) coverage.add(cache.pickle(op)); trace.setCoverage(coverage); */ trace.exec(C, pool, classinvs, trace.diverging, false, ReportersPool.NULLreporter); trace.setCoverage(TrieSensor.reset()); } public static boolean isAnyModificationTraversing(ISelector sel, Iterable coverage) { for(BasicPath bp : coverage) if(sel.isModificationTraversing(bp)) return true; return false; } /** * Returns -1 if coverage could not be synthesized, note that some elements might have already been removed. * Returns 0 if no BasicPaths needed to be updated. * Otherwise returns the number BasicPaths which were updated. * * @param sel * @param coverage * @return */ public static int synthesizeAll(ISelector sel, Set coverage) { Collection addThese = new ArrayList(); for (Iterator iterator = coverage.iterator(); iterator.hasNext();) { BasicPath basicPath = iterator.next(); BasicPath newPath = sel.synthesizeCoverage(basicPath); if(newPath==null) return -1; else if(newPath!=basicPath) { addThese.add(newPath); iterator.remove(); } } coverage.addAll(addThese); return addThese.size(); } }