Commit f5cbef34 authored by ISWB Prasetya's avatar ISWB Prasetya
Browse files

Removing multicore for G2. Improving prefix gen for G2.

parent 559566da
...@@ -106,6 +106,7 @@ public class G2 { ...@@ -106,6 +106,7 @@ public class G2 {
g2sg = new G2SuiteGen(CUTname,config.CUTrootDir, config.useCoverageGuidance,config.useStaticInfo,config.dirOfStaticInfo) ; g2sg = new G2SuiteGen(CUTname,config.CUTrootDir, config.useCoverageGuidance,config.useStaticInfo,config.dirOfStaticInfo) ;
g2sg.regressionMode = config.regressionMode ; g2sg.regressionMode = config.regressionMode ;
g2sg.injectOracles = config.injectOracles ; g2sg.injectOracles = config.injectOracles ;
g2sg.maxSuffixLength = config.maxSuffixLength ;
// configuring testing scope: // configuring testing scope:
g2sg.scope.testingFromTheSamePackagePespective = config.assumeClientInTheSamePackage ; g2sg.scope.testingFromTheSamePackagePespective = config.assumeClientInTheSamePackage ;
g2sg.scope.includePrivateAndDefaultMembers = config.includePrivateAndDefaultMembers ; g2sg.scope.includePrivateAndDefaultMembers = config.includePrivateAndDefaultMembers ;
...@@ -169,12 +170,12 @@ public class G2 { ...@@ -169,12 +170,12 @@ public class G2 {
} }
if (g2sg.getPrefixes() == null) { if (g2sg.getPrefixes() == null) {
//System.out.println(">>> here, K="+K); //System.out.println(">>> here, K="+K);
g2sg.incrementallyGeneratePrefixes(K,10,50,4,5) ; g2sg.incrementallyGeneratePrefixes(K,10,50,config.maxPrefixLength,config.maxObjectDepth) ;
} }
else { else {
int currentSize = g2sg.getPrefixes().suite.size() ; int currentSize = g2sg.getPrefixes().suite.size() ;
int nextSize = Math.min(600,currentSize+50) ; int nextSize = Math.min(600,currentSize+50) ;
g2sg.incrementallyRefinePrefixes(10,nextSize,4); g2sg.incrementallyRefinePrefixes(10,nextSize,config.maxPrefixLength);
} }
prefixRefinementCount++ ; prefixRefinementCount++ ;
t3log.info("=== Generating/refining prefixes of " t3log.info("=== Generating/refining prefixes of "
...@@ -200,8 +201,18 @@ public class G2 { ...@@ -200,8 +201,18 @@ public class G2 {
double budget = Math.max(1,timebudgetTracker.getBudget()) ; double budget = Math.max(1,timebudgetTracker.getBudget()) ;
double remaining = timebudgetTracker.check() ; double remaining = timebudgetTracker.check() ;
t3log.info("Start generating suites for: " + g2sg.scope.CUT.getName()); t3log.info("Start generating suites for: " + g2sg.scope.CUT.getName());
// Initial idea is to generate the suites for multiple targets in parallel.
// Unfortunately this won't work, because this would mean that generators
// have to concurrently update and read from coverage information and the
// special pool used by G2SuiteGen. This would require quite intricate
// programming.
// DROPPED!!!
// int numberOfCPUcores = config.numberOfCPUcores ;
int numberOfCPUcores = 1 ;
while (!worklist.isEmpty()) { while (!worklist.isEmpty()) {
if (worklist.targets.size() < config.numberOfCPUcores) { if (worklist.targets.size() < numberOfCPUcores) {
// the first time, this will generate the prefixes, upon the next iterations, // the first time, this will generate the prefixes, upon the next iterations,
// this will refine the prefixes each time the targetlist is emptied (more precisely, has less targets than // this will refine the prefixes each time the targetlist is emptied (more precisely, has less targets than
// the number of cores). // the number of cores).
...@@ -211,7 +222,7 @@ public class G2 { ...@@ -211,7 +222,7 @@ public class G2 {
// take few targets, and refine them in parallel, if we have multiple CPU cores: // take few targets, and refine them in parallel, if we have multiple CPU cores:
List<SingleTarget> work = new LinkedList<SingleTarget>() ; List<SingleTarget> work = new LinkedList<SingleTarget>() ;
for(int k=0; k<config.numberOfCPUcores ; k++) { for(int k=0; k<numberOfCPUcores ; k++) {
SingleTarget target = worklist.getNext(remaining/budget) ; SingleTarget target = worklist.getNext(remaining/budget) ;
if (target == null) break ; if (target == null) break ;
work.add(target) ; work.add(target) ;
...@@ -309,6 +320,7 @@ public class G2 { ...@@ -309,6 +320,7 @@ public class G2 {
// we additionally constructs instances of G2 for every static inner // we additionally constructs instances of G2 for every static inner
// class of the CUT // class of the CUT
if (config.targetStaticInnerClassesToo) {
// in some rare case CUT.getDeclaredClasses() may throw java.lang.IllegalAccessError, cannot access superclass... // in some rare case CUT.getDeclaredClasses() may throw java.lang.IllegalAccessError, cannot access superclass...
// can't figure out why; probably classloader issue // can't figure out why; probably classloader issue
for (Class innerC : CUT.getDeclaredClasses()) { for (Class innerC : CUT.getDeclaredClasses()) {
...@@ -320,6 +332,7 @@ public class G2 { ...@@ -320,6 +332,7 @@ public class G2 {
g2s.addAll(mkG2worker(innerC.getName(),config,imap,loader)) ; g2s.addAll(mkG2worker(innerC.getName(),config,imap,loader)) ;
} }
} }
}
catch (Throwable t) { catch (Throwable t) {
t3log.warning("G2.mkG2worker throws an exception: " + t.getStackTrace()) ; t3log.warning("G2.mkG2worker throws an exception: " + t.getStackTrace()) ;
//System.out.println("### G2.mkG2worker throws:") ; //System.out.println("### G2.mkG2worker throws:") ;
...@@ -331,8 +344,8 @@ public class G2 { ...@@ -331,8 +344,8 @@ public class G2 {
/** /**
* This will generate test suites for the given CUT. If CUT is abstract or * This will generate test suites for the given CUT. If CUT is abstract or
* an interface, we will target a randomly chosen implementation instead. * an interface, we will target a randomly chosen implementation instead.
* If CUT has static inner classes, these will be recursively targeted as * If CUT has static inner classes, and if G2 is configured to go after them,
* well. * these will be recursively targeted as well.
*/ */
static public void generateSuites(String CUTname, G2Config config, long timebudget) throws TimeBudgetException, InterruptedException static public void generateSuites(String CUTname, G2Config config, long timebudget) throws TimeBudgetException, InterruptedException
{ {
......
...@@ -9,6 +9,8 @@ public class G2Config { ...@@ -9,6 +9,8 @@ public class G2Config {
public boolean assumeClientInTheSamePackage = true ; public boolean assumeClientInTheSamePackage = true ;
public boolean includePrivateAndDefaultMembers = false ; public boolean includePrivateAndDefaultMembers = false ;
public boolean targetStaticInnerClassesToo = false ;
public String worklistType = "standard" ; public String worklistType = "standard" ;
public boolean regressionMode = false; public boolean regressionMode = false;
...@@ -32,6 +34,11 @@ public class G2Config { ...@@ -32,6 +34,11 @@ public class G2Config {
* ADT testing. If it is left null, it will be calculated. The default is null. * ADT testing. If it is left null, it will be calculated. The default is null.
*/ */
public Integer numberOfPrefixes = null ; public Integer numberOfPrefixes = null ;
public int maxPrefixLength = 4 ;
public int maxObjectDepth = 5 ;
public int maxSuffixLength = 5 ;
/** /**
* If not null will determine the number of test sequences generated when * If not null will determine the number of test sequences generated when
* targeting a single method (e.g. a constructor or a static method) that * targeting a single method (e.g. a constructor or a static method) that
...@@ -47,7 +54,14 @@ public class G2Config { ...@@ -47,7 +54,14 @@ public class G2Config {
public int maxNumberOfRefinements_ofEachTarget = 8 ; public int maxNumberOfRefinements_ofEachTarget = 8 ;
public double minimumCovTobeHappy_ofEachTarget = 0.95 ; public double minimumCovTobeHappy_ofEachTarget = 0.95 ;
public int numberOfCPUcores = 1 ; /**
* Multi-core is disabled. It's not going to work because generating
* suites for multiple targets (of the same CUT) in parallel implies the
* generators need to concurrentlly update and access common shared coverage
* information. This will require quite intricate concurrent programming.
* Dropped.
*/
// public int numberOfCPUcores = 1 ;
// controlling how violating sequences are shown: // controlling how violating sequences are shown:
public boolean showExcExecution = true ; public boolean showExcExecution = true ;
......
...@@ -80,6 +80,9 @@ public class G2SuiteGen { ...@@ -80,6 +80,9 @@ public class G2SuiteGen {
public float fieldUpdateProbability = 0.3f ; public float fieldUpdateProbability = 0.3f ;
private G2SuiteGen() {}
public G2SuiteGen(String CUTname, public G2SuiteGen(String CUTname,
String CUTrootDir) String CUTrootDir)
throws Exception throws Exception
...@@ -192,7 +195,6 @@ public class G2SuiteGen { ...@@ -192,7 +195,6 @@ public class G2SuiteGen {
valueMG = gen2vmg.valueMG() ; valueMG = gen2vmg.valueMG() ;
} }
private String[] seededSPrimitives; private String[] seededSPrimitives;
/** /**
......
...@@ -58,7 +58,7 @@ public class G2_forSBST2016 { ...@@ -58,7 +58,7 @@ public class G2_forSBST2016 {
config.worklistType = worklisttype ; config.worklistType = worklisttype ;
config.refinementHeuristic = refinementHeuristic ; config.refinementHeuristic = refinementHeuristic ;
config.maxNumberOfRefinements_ofEachTarget = maxNumberOfTargetRefinements ; config.maxNumberOfRefinements_ofEachTarget = maxNumberOfTargetRefinements ;
config.numberOfCPUcores = numberOfcores ; //config.numberOfCPUcores = numberOfcores ;
config.useCoverageGuidance = turnOnCoverageGuidance ; config.useCoverageGuidance = turnOnCoverageGuidance ;
config.useStaticInfo = turnOnUseOfStaticInfo ; config.useStaticInfo = turnOnUseOfStaticInfo ;
config.includePrivateAndDefaultMembers = true ; // force private members to be tested as well... config.includePrivateAndDefaultMembers = true ; // force private members to be tested as well...
......
...@@ -43,9 +43,9 @@ public class Test_G2_forTriangle { ...@@ -43,9 +43,9 @@ public class Test_G2_forTriangle {
} }
static public void main(String[] args) throws Throwable { static public void main(String[] args) throws Throwable {
//test_one_bareG2() ; test_one_bareG2() ;
//test_two_bareG2() ; //test_two_bareG2() ;
//genWithG2() ; //genWithG2() ;
replayG2() ; //replayG2() ;
} }
} }
package Sequenic.T3.DerivativeSuiteGens.Gen2;
// Tetsing that G2 generate prefixes where each prefix tries not to call
// the same method more than twice.
public class Test_G2_generating_prefix_with_minimal_duplicate {
static G2Config config() {
G2Config config = new G2Config() ;
config.regressionMode = true ;
config.CUTrootDir = "/Users/iswbprasetya/eclipseWorkspace/t3Workspace/t3/bin" ;
config.dirToSaveSuites = "/Users/iswbprasetya/tmp/t3" ;
config.dirOfStaticInfo = "/Users/iswbprasetya/tmp/t3" ;
config.generateJunitForEachSuite = false ;
config.refinementHeuristic="evo" ;
config.maxPrefixLength = 7 ;
config.maxSuffixLength = 0 ;
config.numberOfPrefixes = 10 ;
return config ;
}
static void genWithG2() throws Exception {
G2.generateSuites("Sequenic.T3.Examples.Item",config(),5000) ;
}
static public void main(String[] args) throws Throwable {
genWithG2() ;
}
}
...@@ -7,18 +7,36 @@ public class Item implements Serializable { ...@@ -7,18 +7,36 @@ public class Item implements Serializable {
int price ; int price ;
private String code ; private String code ;
public Item() {} public Item() {
System.out.println(">>> Item ") ;
}
public Item(String name) { public Item(String name) {
this.name = name ; this.name = name ;
this.price = 100 ; this.price = 100 ;
code = null ; code = null ;
System.out.println(">>> Item " + name) ;
} }
public void incPrice(int x) { price += x ; } public void incPrice(int x) {
public String setCode(String code) { this.code = code; return this.code ; } System.out.println(">>> incPrice " + x) ;
public String getCode() { return code ; } price += x ;
public int getPrice() { return price ; } }
public String resetCode() { code = null ; return code ; } public String setCode(String code) {
System.out.println(">>> setCode " + code) ;
this.code = code; return this.code ;
}
public String getCode() {
System.out.println(">>> getCode ") ;
return code ;
}
public int getPrice() {
System.out.println(">>> getPrice ") ;
return price ;
}
public String resetCode() {
System.out.println(">>> resetCode ") ;
code = null ; return code ;
}
} }
...@@ -70,6 +70,56 @@ public class SegmentG extends AbstractSeqGenerator { ...@@ -70,6 +70,56 @@ public class SegmentG extends AbstractSeqGenerator {
} ; } ;
} }
/**
* Generate a segment where the same methods are invoked at most twice.
*/
private Generator<SEQ_RT_info,SEQ_RT_info> segmentWithMinimizedDuplicates(
List<Method> methods,
Predicate<STEP_RT_info> requirement,
double fieldUpdateProbability,
int maxLength
)
{
Generator<SEQ_RT_info,STEP> fieldMG = new UPDATE_FIELDMG(this.scope,this.valueGenerator).random() ;
// make a custom methodMG that will not invoke the same method more than twice
METHODMG methodMGbase = new METHODMG(this.pool,this.scope,this.valueGenerator) ;
List<Method> methods_ = new LinkedList<Method>() ;
methods_.addAll(methods) ;
Map<Method,Integer> counts = new HashMap<Method,Integer>() ;
Generator<SEQ_RT_info,STEP> methodMGxx = info -> {
int N = methods_.size() ;
if (N==0) return null ;
if (N==1) {
Method M = methods_.get(0) ;
Integer M_cnt = counts.get(M) ;
if (M_cnt == null) M_cnt = 1 ; else M_cnt ++ ;
if (M_cnt >= 2) methods_.remove(M) ;
return methodMGbase.select(M).generate(info) ;
}
// randomly select a method :
Method M = methods_.get(methodMGbase.rnd.nextInt(N)) ;
Integer M_cnt = counts.get(M) ;
if (M_cnt == null) M_cnt = 1 ; else M_cnt ++ ;
if (M_cnt >= 2) methods_.remove(M) ;
counts.put(M, M_cnt) ;
return methodMGbase.select(M).generate(info) ;
} ;
Generator<SEQ_RT_info,STEP> stepMG = FirstOf(fieldMG.WithChance(fieldUpdateProbability),methodMGxx) ;
Generator<SEQ_RT_info,SEQ_RT_info> stepGenerator = STEPexec.until(requirement, maxNumberOfStepRetry,stepMG,this.scope.CUT,pool) ;
return info -> {
int N = info.executionCounter + maxLength ;
//System.out.println("**>> current legth = " + info.executionCounter) ;
return IterateWhile(info_ -> info_.executionCounter < N && !info_.isFail(),
stepGenerator
)
.generate(info) ;
} ;
}
/** /**
* Extend the current sequence with a segment, up to the specified length. * Extend the current sequence with a segment, up to the specified length.
*/ */
...@@ -94,7 +144,8 @@ public class SegmentG extends AbstractSeqGenerator { ...@@ -94,7 +144,8 @@ public class SegmentG extends AbstractSeqGenerator {
} }
public Generator<SEQ_RT_info,SEQ_RT_info> no_exc_mutators(double fieldUpdateProbability, int maxLength) { public Generator<SEQ_RT_info,SEQ_RT_info> no_exc_mutators(double fieldUpdateProbability, int maxLength) {
return segment(scope.mutators,r -> r.exc == null, fieldUpdateProbability, maxLength) ; //return segment(scope.mutators,r -> r.exc == null, fieldUpdateProbability, maxLength) ;
return segmentWithMinimizedDuplicates(scope.mutators,r -> r.exc == null, fieldUpdateProbability, maxLength) ;
} }
public Generator<SEQ_RT_info,SEQ_RT_info> grey_nonmutators(int maxLength) { public Generator<SEQ_RT_info,SEQ_RT_info> grey_nonmutators(int maxLength) {
......
...@@ -193,9 +193,15 @@ public class T3SuiteG { ...@@ -193,9 +193,15 @@ public class T3SuiteG {
SUITE zero = new SUITE(scope.CUT.getName()) ; SUITE zero = new SUITE(scope.CUT.getName()) ;
Stream<List<Goal>> stream ; Stream<List<Goal>> stream ;
if (goals.size() == 1) stream = goals.stream() ; if (goals.size() == 1) stream = goals.stream() ;
else stream = goals.parallelStream() ; else {
//System.out.println("### number of worklist " + goals.size()) ;
//System.out.println("### using parallel stream to generate suites...") ;
stream = goals.parallelStream() ;
}
SUITE S = stream SUITE S = stream
. map(subgoals -> generateSubSuite(subgoals)) . map(subgoals -> {
//System.out.println("### generating suite") ;
return generateSubSuite(subgoals) ; })
. reduce(zero, union) ; . reduce(zero, union) ;
Logger.getLogger(CONSTANTS.T3loggerName).info("Suite for " Logger.getLogger(CONSTANTS.T3loggerName).info("Suite for "
......
...@@ -90,16 +90,16 @@ public class TestingScope { ...@@ -90,16 +90,16 @@ public class TestingScope {
} }
private static boolean isMutator(Method M) { private static boolean isMutator(Method M) {
String name = M.getName() ; String name = M.getName().toLowerCase() ;
if (name == "size" if (name == "size"
|| name == "length" || name == "length"
|| name == "toString" || name == "tostring"
|| name == "toArray" || name == "toarray"
|| name == "toInt" || name == "toint"
|| name == "equals" || name == "equals"
|| name == "clone" || name == "clone"
|| name == "hashCode" || name == "hashcode"
|| name == "indexOf" || name == "indexof"
) return false ; ) return false ;
return !(name.startsWith("get") || name.startsWith("is") || name.startsWith("contains")) ; return !(name.startsWith("get") || name.startsWith("is") || name.startsWith("contains")) ;
......
import Sequenic.T3.T3Cmd;
public class Test_T3_multicore {
static public void main(String[] args) throws Exception {
T3Cmd.main("-core 2 -ms 1 -pl 2 -sl 0 -sex -d . -sd ./bin Sequenic.T3.Examples.Item");
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment