package SBST2015; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.util.LinkedList; import java.util.List; import Sequenic.T3.* ; import Sequenic.T3.Sequence.Datatype.*; import Sequenic.T3.Oracle.* ; //import Sequenic.T3.Generator.Generator ; //import static Sequenic.T3.Generator.GenCombinators.FirstOf ; //import static Sequenic.T3.Generator.Value.ValueMGCombinators.* ; import Sequenic.T3.T3groovyAPI ; /** * Containing the configurations, pre-processing for generating test suites with T3, and * related utilities. */ public class Common { public static Class CUT ; public static String[] CUTclassDir = // { "d:/workshop/EclipseT3workspace/SBST2015_competition/bin" } ; { "d:/workshop/t2framework/repos/benchmark/SBST2015competition/build/CUTs" } ; public static String dirToSaveTraces = "d:/workshop/t2framework/repos/benchmark/SBST2015competition/data/traces" ; public static int splitSuite = 10 ; public static void setCUT(Class C) { CUT = C ; } public static void setClassDir(String... dir) { CUTclassDir = dir ; } public static void setTraceDir(String d) { dirToSaveTraces = d ; } public static void printImplementationMap() { ImplementationMap imap = new ImplementationMap(CUTclassDir, CUT) ; imap.print() ; System.out.println("*** CUT's known implementations: " + imap.getImps(CUT)) ; System.out.println("*** CUT is publicly instantiable: " + imap.isPubliclyInstantiable(CUT)) ; } // ---------------------------------------------------------------------------------------------- // T3 configurations public static Config stdConfig() { Config C = new Config() ; C.CUT = CUT ; C.dirsToClasses = CUTclassDir ; C.regressionMode = true ; C.injectOracles = true ; C.maxPrefixLength = 5 ; C.maxSuffixLength = 2 ; C.maximizePrefix = false ; //C.includeInheritedMembers = false ; C.reportOut = System.err ; C.sequencePrintOut = System.err ; C.fieldUpdateProbability = 0.0 ; C.suiteSizeMultiplierPerGoal=8 ; C.maxNumberOfPairs = 350 ; return C ; } public static Config replayConfig(){ Config C = new Config() ; C.CUT = CUT ; C.regressionMode = true ; C.replayRunAll = false ; C.reportOut = System.err ; C.sequencePrintOut = System.err ; return C ; } // ---------------------------------------------------------------------------------------------- private static List split(SUITE S) { if (S==null) return new LinkedList() ; if (S.suite.isEmpty()) return new LinkedList() ; List suites = S.split(splitSuite,20) ; System.err.println("***** Generated suites are merged:\n" + S.showSuiteStatistics()) ; System.err.println("***** Split merged suite to: " + suites.size() + " subsuites.") ; return suites ; } public static String mkSaveFileName(String cname) { return cname.replace('.','_') ; } private static void saveSuite(String prefix, SUITE S, int k) throws Exception { S.save(dirToSaveTraces, "" + prefix + mkSaveFileName(S.CUTname) + "_" + k, false) ; } private static void saveSuites(String prefix, List suites) throws Exception { int k = 0; for (SUITE Z : suites) { saveSuite(prefix,Z,k) ; k++ ; } } private static List reduceOracles(List suites) { for (SUITE S : suites) for (SEQ sigma : S.suite) // sigma.clearOracle(); reduceOracles(S) ; return suites ; } // drop all oracles, except those specifying thrown exceptions private static SUITE reduceOracles(SUITE S) { for (SEQ sigma : S.suite) for (STEP step : sigma.steps) { Oracle o = null ; if (step instanceof METHOD) { o = ((METHOD) step).oracle ; } else if (step instanceof CONSTRUCTOR) { o = ((CONSTRUCTOR) step).oracle ; } else if (step instanceof UPDATE_FIELD) { o = ((UPDATE_FIELD) step).oracle ; } if (o != null && o instanceof StrDumpEqOracle) { StrDumpEqOracle o_ = (StrDumpEqOracle) o ; if (o_.expectedReceiverObj != null && !o_.expectedReceiverObj.val.equals("null")) o_.expectedReceiverObj = null ; if (o_.expectedReturnedObj != null && !o_.expectedReturnedObj.val.equals("null")) o_.expectedReturnedObj = null ; } } return S ; } // remove all oracles... doesn't work, because thrown exception will then ALWAYS be // mistaken for violations. private static List removeOracles(List suites) { for (SUITE S : suites) for (SEQ sigma : S.suite) sigma.clearOracle() ; return suites ; } // for generating T3 suites that we will use private static SUITE stdMainSuite(Class C, Class[] knownclasses){ Config config = stdConfig() ; config.CUT = C ; T3groovyAPI t3 = new T3groovyAPI(null,config, knownclasses) ; boolean adt = Inspection.has_NonPrivateDeclared_IMethod_OrConstructor(C) ; boolean nonAdt = Inspection.has_NonPrivateDeclared_SMethod(C) ; if (adt) { TestingScope scope = t3.getT3API().scope ; scope.configureForADTtesting(); // handle a number of special cases : // Case-1: C is a an abstract class, but has no creator method --> T3 can't instantiate C // this is handled stdSuite(); here --> just supress calling T3: if (Modifier.isAbstract(C.getModifiers())) { if (scope.creatorMethods.isEmpty()) adt = false ; } else { // Case-2, C is not abtract but has no accessible constructors nor creator methods // --> forcefully add all, incl private, constructors in the scope : if (scope.constructors.isEmpty() && scope.creatorMethods.isEmpty()) { Constructor[] cos = C.getDeclaredConstructors() ; for(Constructor co : cos) scope.forceConstructors.add(co) ; } //System.out.println("===================================================================") ; //System.out.println("** " + C + ", #forced constructors: " + scope.forceConstructors.size()) ; } } // generate the suite: SUITE S ; if (adt && nonAdt) { S = t3.ADT().plus(t3.nonADT()) ; } else if (adt) { S = t3.ADT() ; } else if (nonAdt) { S = t3.nonADT() ; } else { System.err.println("** T3 does not know how to test " + C.getName() + " !") ; return null ; } if (S.suite.isEmpty()) { System.err.println("** T3 tried by failed to generate any sequence for " + C.getName() + " !") ; return null ; } return S ; } // generate a suite with the above standard configuration, split it, then save // then strip all oracles, split again, and save public static void stdSuite() throws Exception { // scanning concrete classes under CUT's patent package: Class[] knownConcreteClasses = Inspection.getAllConcreteClassesUnderParentPackage(CUT) ; //Class[] knownConcreteClasses = new Class[0] ; // suites for CUT itself : List suites = split(stdMainSuite(CUT,knownConcreteClasses)) ; saveSuites("suite_",suites) ; suites = reduceOracles(suites) ; //suites = removeOracles(suites) ; --> don't use. Doesn't work! saveSuites("minOrcSuite_",suites) ; // handle the special case when CUT is an abstract class, with no creator method if (Modifier.isAbstract(CUT.getModifiers())) { Config config = stdConfig() ; config.CUT = CUT ; T3groovyAPI t3 = new T3groovyAPI(config) ; boolean adt = Inspection.has_NonPrivateDeclared_IMethod_OrConstructor(CUT) ; if (adt) { TestingScope scope = t3.getT3API().scope ; scope.configureForADTtesting(); if (scope.creatorMethods.isEmpty()) { System.err.println("** " + CUT.getName() + " is an abstract class with instance menthods, but no creator method!" ) ; ImplementationMap imap = t3.getT3API().impMap ; Class replacement = imap.getImp1(CUT) ; if (replacement == null) { // try a stand-in String standinName = mkSaveFileName(CUT.getName()) + "_StandIn" ; try { replacement = Class.forName(standinName) ; } catch(Exception e) { replacement = null ; } } if (replacement != null) { System.err.println("** Testing through " + replacement.getName() + " instead...") ; suites = split(stdMainSuite(replacement,knownConcreteClasses)) ; saveSuites("suite_" + mkSaveFileName(CUT.getName()) + "_subclass_",suites) ; suites = reduceOracles(suites) ; saveSuites("minOrcSuite_" + mkSaveFileName(CUT.getName()) + "_subclass_",suites) ; } else { System.err.println("** Unfortunately no testable replacement can be found...") ; } } } } // for CUT's inner classes: List innerclasses = Inspection.getStaticInnerClasses(CUT) ; for (Class ic : innerclasses) { suites = split(stdMainSuite(ic,knownConcreteClasses)) ; saveSuites("inner_suite_",suites) ; suites = reduceOracles(suites) ; saveSuites("inner_minOrcSuite_",suites) ; } System.err.println("** DONE") ; } public static void stdAdt() throws Exception { T3groovyAPI t3 = new T3groovyAPI(stdConfig()) ; saveSuites("suite_",split(t3.ADT())) ; } public static SUITE smallTestAdt() { Config config = stdConfig() ; config.suiteSizeMultiplierPerGoal = 1.0 ; T3groovyAPI t3 = new T3groovyAPI(config) ; return t3.ADT() ; } public static List load(String prefix) throws Exception { //List suites = SUITE.loadMany("" + mkSaveFileName(CUT.getName()), dirToSaveTraces) ; String pattern = "" + prefix + mkSaveFileName(CUT.getName()) + ".*" ; System.err.println("** Pattern = " + pattern) ; List suites = SUITE.loadMany(pattern, dirToSaveTraces) ; System.err.println("** Loading " + suites.size() + " suites") ; return suites ; } }