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 {
g2sg = new G2SuiteGen(CUTname,config.CUTrootDir, config.useCoverageGuidance,config.useStaticInfo,config.dirOfStaticInfo) ;
g2sg.regressionMode = config.regressionMode ;
g2sg.injectOracles = config.injectOracles ;
g2sg.maxSuffixLength = config.maxSuffixLength ;
// configuring testing scope:
g2sg.scope.testingFromTheSamePackagePespective = config.assumeClientInTheSamePackage ;
g2sg.scope.includePrivateAndDefaultMembers = config.includePrivateAndDefaultMembers ;
......@@ -169,12 +170,12 @@ public class G2 {
}
if (g2sg.getPrefixes() == null) {
//System.out.println(">>> here, K="+K);
g2sg.incrementallyGeneratePrefixes(K,10,50,4,5) ;
g2sg.incrementallyGeneratePrefixes(K,10,50,config.maxPrefixLength,config.maxObjectDepth) ;
}
else {
int currentSize = g2sg.getPrefixes().suite.size() ;
int nextSize = Math.min(600,currentSize+50) ;
g2sg.incrementallyRefinePrefixes(10,nextSize,4);
g2sg.incrementallyRefinePrefixes(10,nextSize,config.maxPrefixLength);
}
prefixRefinementCount++ ;
t3log.info("=== Generating/refining prefixes of "
......@@ -200,8 +201,18 @@ public class G2 {
double budget = Math.max(1,timebudgetTracker.getBudget()) ;
double remaining = timebudgetTracker.check() ;
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()) {
if (worklist.targets.size() < config.numberOfCPUcores) {
if (worklist.targets.size() < numberOfCPUcores) {
// 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
// the number of cores).
......@@ -211,7 +222,7 @@ public class G2 {
// take few targets, and refine them in parallel, if we have multiple CPU cores:
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) ;
if (target == null) break ;
work.add(target) ;
......@@ -308,17 +319,19 @@ public class G2 {
// we additionally constructs instances of G2 for every static inner
// class of the CUT
// in some rare case CUT.getDeclaredClasses() may throw java.lang.IllegalAccessError, cannot access superclass...
// can't figure out why; probably classloader issue
for (Class innerC : CUT.getDeclaredClasses()) {
// non static inner classes and inherited inner classes are NOT targeted:
// NOTE: well, include them nonetheless...
// if (! Modifier.isStatic(innerC.getModifiers())) continue ;
// if (innerC.getDeclaringClass() != CUT) continue ;
// t3log.info("Found an inner static class " + innerC.getName());
g2s.addAll(mkG2worker(innerC.getName(),config,imap,loader)) ;
}
if (config.targetStaticInnerClassesToo) {
// in some rare case CUT.getDeclaredClasses() may throw java.lang.IllegalAccessError, cannot access superclass...
// can't figure out why; probably classloader issue
for (Class innerC : CUT.getDeclaredClasses()) {
// non static inner classes and inherited inner classes are NOT targeted:
// NOTE: well, include them nonetheless...
// if (! Modifier.isStatic(innerC.getModifiers())) continue ;
// if (innerC.getDeclaringClass() != CUT) continue ;
// t3log.info("Found an inner static class " + innerC.getName());
g2s.addAll(mkG2worker(innerC.getName(),config,imap,loader)) ;
}
}
}
catch (Throwable t) {
t3log.warning("G2.mkG2worker throws an exception: " + t.getStackTrace()) ;
......@@ -331,8 +344,8 @@ public class G2 {
/**
* This will generate test suites for the given CUT. If CUT is abstract or
* an interface, we will target a randomly chosen implementation instead.
* If CUT has static inner classes, these will be recursively targeted as
* well.
* If CUT has static inner classes, and if G2 is configured to go after them,
* these will be recursively targeted as well.
*/
static public void generateSuites(String CUTname, G2Config config, long timebudget) throws TimeBudgetException, InterruptedException
{
......
......@@ -8,6 +8,8 @@ public class G2Config {
// some variables to define scope (which members of the CUT are to be tested)
public boolean assumeClientInTheSamePackage = true ;
public boolean includePrivateAndDefaultMembers = false ;
public boolean targetStaticInnerClassesToo = false ;
public String worklistType = "standard" ;
......@@ -32,6 +34,11 @@ public class G2Config {
* ADT testing. If it is left null, it will be calculated. The default is 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
* targeting a single method (e.g. a constructor or a static method) that
......@@ -47,7 +54,14 @@ public class G2Config {
public int maxNumberOfRefinements_ofEachTarget = 8 ;
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:
public boolean showExcExecution = true ;
......
......@@ -80,6 +80,9 @@ public class G2SuiteGen {
public float fieldUpdateProbability = 0.3f ;
private G2SuiteGen() {}
public G2SuiteGen(String CUTname,
String CUTrootDir)
throws Exception
......@@ -191,8 +194,7 @@ public class G2SuiteGen {
pool = gen2vmg.pool ;
valueMG = gen2vmg.valueMG() ;
}
private String[] seededSPrimitives;
/**
......
......@@ -58,7 +58,7 @@ public class G2_forSBST2016 {
config.worklistType = worklisttype ;
config.refinementHeuristic = refinementHeuristic ;
config.maxNumberOfRefinements_ofEachTarget = maxNumberOfTargetRefinements ;
config.numberOfCPUcores = numberOfcores ;
//config.numberOfCPUcores = numberOfcores ;
config.useCoverageGuidance = turnOnCoverageGuidance ;
config.useStaticInfo = turnOnUseOfStaticInfo ;
config.includePrivateAndDefaultMembers = true ; // force private members to be tested as well...
......
......@@ -43,9 +43,9 @@ public class Test_G2_forTriangle {
}
static public void main(String[] args) throws Throwable {
//test_one_bareG2() ;
test_one_bareG2() ;
//test_two_bareG2() ;
//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 {
int price ;
private String code ;
public Item() {}
public Item() {
System.out.println(">>> Item ") ;
}
public Item(String name) {
this.name = name ;
this.price = 100 ;
code = null ;
System.out.println(">>> Item " + name) ;
}
public void incPrice(int x) { price += x ; }
public String setCode(String code) { this.code = code; return this.code ; }
public String getCode() { return code ; }
public int getPrice() { return price ; }
public String resetCode() { code = null ; return code ; }
public void incPrice(int x) {
System.out.println(">>> incPrice " + x) ;
price += x ;
}
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 {
} ;
}
/**
* 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.
*/
......@@ -94,7 +144,8 @@ public class SegmentG extends AbstractSeqGenerator {
}
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) {
......
......@@ -193,9 +193,15 @@ public class T3SuiteG {
SUITE zero = new SUITE(scope.CUT.getName()) ;
Stream<List<Goal>> 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
. map(subgoals -> generateSubSuite(subgoals))
. map(subgoals -> {
//System.out.println("### generating suite") ;
return generateSubSuite(subgoals) ; })
. reduce(zero, union) ;
Logger.getLogger(CONSTANTS.T3loggerName).info("Suite for "
......
......@@ -90,16 +90,16 @@ public class TestingScope {
}
private static boolean isMutator(Method M) {
String name = M.getName() ;
String name = M.getName().toLowerCase() ;
if (name == "size"
|| name == "length"
|| name == "toString"
|| name == "toArray"
|| name == "toInt"
|| name == "tostring"
|| name == "toarray"
|| name == "toint"
|| name == "equals"
|| name == "clone"
|| name == "hashCode"
|| name == "indexOf"
|| name == "hashcode"
|| name == "indexof"
) return false ;
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");
}
}
Markdown is supported
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