Skip to content

Commit

Permalink
Merge master into release branch
Browse files Browse the repository at this point in the history
  • Loading branch information
gofraser committed Jan 3, 2017
2 parents e34f26c + ba19123 commit aff3611
Show file tree
Hide file tree
Showing 400 changed files with 11,664 additions and 6,183 deletions.
31 changes: 18 additions & 13 deletions IMPORTANT_README_FOR_DEVELOPERS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,30 +150,35 @@ HOW TO MAKE A RELEASE

To use the Maven plugin, and to link the "runtime" jar (plus dependencies)
to a project, EvoSuite needs to be released and deployed on an accessible
repository. Currently, EvoSuite is hosted at:
repository.

www.evosuite.org/m2

Unfortunately, we cannot use the "release" plugin to make a release, as that
server is not accessible through ssh from outside. The release steps
need then to be made manually.
Assume current EvoSuite version is x.y.z-SNAPSHOT. You need choose
a new version number (x for major, y for minor, and z for patch).

Once chosen a new version a.b.c (with *no* SNAPSHOT, and it is fine to
have a.b.c == x.y.z), from command line execute:
have a.b.c == x.y.z), create a new Git branch with name equal to this
new version number.
Then, from command line execute:

mvn versions:set -DnewVersion=a.b.c
mvn versions:set -DnewVersion=a.b.c

This command will go through all the pom files in the project, and replace
the version numbers there with the new one.
Commit and push the changed pom files.
Then, login to the Jenkins server, and manually start the "Deploy" job.
(Note, trying a "mvn deploy" from your local machine will likely fail
unless you are on the same network of the Jenkins server).

To deploy to Maven Central, execute:

mvn clean source:jar javadoc:jar verify -PsignJars -DskipTests deploy

Note: this requires that you have configured GPG on your machine with the right
valid keys.

If the "Deploy" job ends correctly, then the new release has been deployed.
Now, need to change back the version to a SNAPSHOT one:
It might take up to 2 hours before it will be visible on Maven Central.

Now, on the Git master branch, need to set a new SNAPSHOT version:

mvn versions:set -DnewVersion=a.b.(c+1)-SNAPSHOT
mvn versions:set -DnewVersion=a.b.(c+1)-SNAPSHOT

(eg, here we just incremented the patch number by one).
Commit and push the modified pom files.
Expand Down
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ dependencies:

test:
override:
- mvn --fail-never dependency:resolve install
- mvn --fail-never dependency:resolve -DskipITs install
post:
- mkdir -p $CIRCLE_TEST_REPORTS/junit/
- find . -type f -regex ".*/generated/target/surefire-reports/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
Expand Down
2 changes: 1 addition & 1 deletion client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<version>3.0.2</version>
<executions>
<execution>
<goals>
Expand Down
73 changes: 55 additions & 18 deletions client/src/main/java/org/evosuite/Properties.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.evosuite.classpath.ClassPathHandler;
import org.evosuite.lm.MutationType;
import org.evosuite.regression.RegressionMeasure;
import org.evosuite.runtime.LoopCounter;
import org.evosuite.runtime.Runtime;
import org.evosuite.runtime.RuntimeSettings;
Expand Down Expand Up @@ -304,15 +305,15 @@ public class Properties {

@Parameter(key = "p_reflection_on_private", group = "Test Creation", description = "Probability [0,1] of using reflection to set private fields or call private methods")
@DoubleValue(min = 0.0, max = 1.0)
public static double P_REFLECTION_ON_PRIVATE = 0.5;
public static double P_REFLECTION_ON_PRIVATE = 0.0; // Optimal value: 0.5

@Parameter(key = "reflection_start_percent", group = "Test Creation", description = "Percentage [0,1] of search budget after which reflection fields/methods handling is activated")
@DoubleValue(min = 0.0, max = 1.0)
public static double REFLECTION_START_PERCENT = 0.8;

@Parameter(key = "p_functional_mocking", group = "Test Creation", description = "Probability [0,1] of using functional mocking (eg Mockito) when creating object instances")
@DoubleValue(min = 0.0, max = 1.0)
public static double P_FUNCTIONAL_MOCKING = 0.8;
public static double P_FUNCTIONAL_MOCKING = 0.0; // Optimal value: 0.8

@Parameter(key = "functional_mocking_percent", group = "Test Creation", description = "Percentage [0,1] of search budget after which functional mocking can be activated. Mocking of missing concrete classes will be activated immediately regardless of this parameter")
@DoubleValue(min = 0.0, max = 1.0)
Expand All @@ -326,9 +327,19 @@ public class Properties {
// ---------------------------------------------------------------
// Search algorithm
public enum Algorithm {
STANDARDGA, MONOTONICGA, ONEPLUSONEEA, STEADYSTATEGA, RANDOM, NSGAII, MOSA
STANDARDGA, MONOTONICGA, ONEPLUSONEEA, STEADYSTATEGA, RANDOM, NSGAII, MOSA, SPEA2
}

// MOSA PROPERTIES
public enum RankingType {
// Preference sorting is the ranking strategy proposed in
PREFERENCE_SORTING,
FAST_NON_DOMINATED_SORTING
}

@Parameter(key = "ranking_type", group = "Runtime", description = "type of ranking to use in MOSA")
public static RankingType RANKING_TYPE = RankingType.PREFERENCE_SORTING;

/** Constant <code>ALGORITHM</code> */
@Parameter(key = "algorithm", group = "Search Algorithm", description = "Search algorithm")
public static Algorithm ALGORITHM = Algorithm.MONOTONICGA;
Expand Down Expand Up @@ -390,7 +401,7 @@ public enum Algorithm {
public static int DSE_VARIABLE_RESETS = 2;

public enum DSEType {
/** apply DSE per primitive */
/** apply DSE per statement */
STATEMENT,
/** apply DSE with all primitives in a test */
TEST,
Expand Down Expand Up @@ -432,6 +443,7 @@ public enum SolverType {
@DoubleValue(min = 0.0, max = 1.0)
public static double LOCAL_SEARCH_PROBABILITY = 1.0;

@Deprecated
@Parameter(key = "local_search_selective", group = "Local Search", description = "Apply local search only to individuals that changed fitness")
public static boolean LOCAL_SEARCH_SELECTIVE = false;

Expand All @@ -448,7 +460,7 @@ public enum SolverType {
public static boolean LOCAL_SEARCH_RESTORE_COVERAGE = false; // Not needed with archive

@Parameter(key = "local_search_adaptation_rate", group = "Local Search", description = "Parameter used to adapt at runtime the probability of applying local search")
public static double LOCAL_SEARCH_ADAPTATION_RATE = 0.33;
public static double LOCAL_SEARCH_ADAPTATION_RATE = 2.0;

@Parameter(key = "local_search_budget", group = "Local Search", description = "Maximum budget usable for improving individuals per local search")
public static long LOCAL_SEARCH_BUDGET = 5;
Expand Down Expand Up @@ -565,6 +577,11 @@ public enum PopulationLimit {
@Parameter(key = "population_limit", group = "Search Algorithm", description = "What to use as limit for the population size")
public static PopulationLimit POPULATION_LIMIT = PopulationLimit.INDIVIDUALS;

/** Constant <code>WRITE_INDIVIDUALS=false</code> */
@Parameter(key = "write_individuals", group = "Search Algorithm",
description = "Write to a file all fitness values of each individual on each iteration of a GA")
public static boolean WRITE_INDIVIDUALS = false;

/** Constant <code>SEARCH_BUDGET=60</code> */
@Parameter(key = "search_budget", group = "Search Algorithm", description = "Maximum search duration")
@LongValue(min = 1)
Expand Down Expand Up @@ -1081,6 +1098,9 @@ public enum AssertionStrategy {

@Parameter(key = "new_statistics", group = "Output", description = "Use the new statistics backend on the master")
public static boolean NEW_STATISTICS = true;

@Parameter(key = "ignore_missing_statistics", group = "Output", description = "Return an empty string for missing output variables")
public static boolean IGNORE_MISSING_STATISTICS = false;

@Parameter(key = "float_precision", group = "Output", description = "Precision to use in float comparisons and assertions")
public static float FLOAT_PRECISION = 0.01F;
Expand Down Expand Up @@ -1153,7 +1173,7 @@ public enum TestNamingStrategy {
public static boolean VIRTUAL_NET = true;

@Parameter(key = "use_separate_classloader", group = "Sandbox", description = "Usa a separate classloader in the final test cases")
public static boolean USE_SEPARATE_CLASSLOADER = false;
public static boolean USE_SEPARATE_CLASSLOADER = true;


// ---------------------------------------------------------------
Expand Down Expand Up @@ -1519,9 +1539,7 @@ public enum Criterion {
public static boolean EXCLUDE_IBRANCHES_CUT = false;


public enum Strategy {
ONEBRANCH, EVOSUITE, RANDOM, RANDOM_FIXED, ENTBUG, REGRESSION, REGRESSIONTESTS, MOSUITE, DSE
}
/*** Evosuite regression testing properties ***/

/** Constant <code>REGRESSIONCP</code> */
@Parameter(key = "regressioncp", group = "Runtime", description = "Regression testing classpath")
Expand All @@ -1540,12 +1558,17 @@ public enum Strategy {
public static int REGRESSION_ANALYSIS_OBJECTDISTANCE = 0;

/** Constant <code>REGRESSION_DIFFERENT_BRANCHES</code> */
@Deprecated
@Parameter(key = "regression_different_branches", group = "Runtime", description = "Classes under test have different branch orders")
public static boolean REGRESSION_DIFFERENT_BRANCHES = false;

/** Constant <code>REGRESSION_USE_FITNESS</code> */
@Parameter(key = "regression_use_fitness", group = "Runtime", description = "Which fitness values will be used")
public static int REGRESSION_USE_FITNESS = 4;
/** Constant <code>REGRESSION_BRANCH_DISTANCE</code> */
@Parameter(key = "regression_branch_distance", group = "Runtime", description = "Enable control-flow distance measurement for regression testing")
public static boolean REGRESSION_BRANCH_DISTANCE = false;

/** Constant <code>REGRESSION_FITNESS</code> */
@Parameter(key = "regression_fitness", group = "Runtime", description = "Set fitness function for EvosuiteR. [Defaults to Random search]")
public static RegressionMeasure REGRESSION_FITNESS = RegressionMeasure.RANDOM;

/** Constant <code>REGRESSION_ANALYZE</code> */
@Parameter(key = "regression_analyze", group = "Runtime", description = "Analyze the classes under test, to ensure the effectiveness of evosuite")
Expand All @@ -1563,6 +1586,23 @@ public enum Strategy {
@Parameter(key = "regression_diversity", group = "Runtime", description = "Include diversity fitness measurement")
public static boolean REGRESSION_DIVERSITY = false;

/** Constant <code>REGRESSION_SKIP_SIMILAR</code> */
@Parameter(key = "regression_skip_similar", group = "Runtime", description = "Skip running EvosuiteR on similar classes")
public static boolean REGRESSION_SKIP_SIMILAR = false;

/** Constant <code>REGRESSION_SKIP_DIFFERENT_CFG</code> */
@Parameter(key = "regression_skip_different_cfg", group = "Runtime", description = "Skip running EvosuiteR on classes with different control-flow-graph")
public static boolean REGRESSION_SKIP_DIFFERENT_CFG = false;

/** Constant <code>REGRESSION_STATISTICS</code> */
@Parameter(key = "regression_statistics", group = "Runtime", description = "Track extra search statistics during regression testing")
public static boolean REGRESSION_STATISTICS = false;


public enum Strategy {
ONEBRANCH, EVOSUITE, RANDOM, RANDOM_FIXED, ENTBUG, REGRESSION, MOSUITE, DSE
}

/** Constant <code>STRATEGY</code> */
@Parameter(key = "strategy", group = "Runtime", description = "Which mode to use")
public static Strategy STRATEGY = Strategy.EVOSUITE;
Expand Down Expand Up @@ -1590,9 +1630,6 @@ public enum Strategy {
public static int MIN_FREE_MEM = 50 * 1000 * 1000;


@Parameter(key = "max_perm_size", group = "Runtime", description = "MaxPermSize (in MB) for the client process")
public static int MAX_PERM_SIZE = 256;

/** Constant <code>CLIENT_ON_THREAD=false</code> */
@Parameter(key = "client_on_thread", group = "Runtime", description = "Run client process on same JVM of master in separate thread. To be used only for debugging purposes")
public static volatile boolean CLIENT_ON_THREAD = false;
Expand Down Expand Up @@ -2219,7 +2256,7 @@ protected boolean strictParseBoolean(String s) {
* a {@link java.lang.String} object.
* @param value
* an array of {@link java.lang.String} objects.
* @throws org.evosuite.Properties#NoSuchParameterException
* @throws org.evosuite.Properties.NoSuchParameterException
* if any.
* @throws java.lang.IllegalArgumentException
* if any.
Expand Down Expand Up @@ -2419,7 +2456,7 @@ private static Class<?> getTargetClass(boolean initialise) {
TestGenerationContext.getInstance().getClassLoaderForSUT());


if (STRATEGY == Strategy.REGRESSION || STRATEGY == Strategy.REGRESSIONTESTS) {
if (STRATEGY == Strategy.REGRESSION) {
TARGET_REGRESSION_CLASS_INSTANCE = Class.forName(TARGET_CLASS, initialise,
TestGenerationContext.getInstance().getRegressionClassLoaderForSUT());
}
Expand Down Expand Up @@ -2537,7 +2574,7 @@ public void resetToDefaults() {
* whether or not the regression mode is running
*/
public static boolean isRegression(){
boolean isRegression = (STRATEGY == Strategy.REGRESSION || STRATEGY == Strategy.REGRESSIONTESTS);
boolean isRegression = (STRATEGY == Strategy.REGRESSION);
return isRegression;
}

Expand Down
2 changes: 2 additions & 0 deletions client/src/main/java/org/evosuite/TestGenerationContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.evosuite.instrumentation.InstrumentingClassLoader;
import org.evosuite.instrumentation.LinePool;
import org.evosuite.runtime.Runtime;
import org.evosuite.runtime.classhandling.ModifiedTargetStaticFields;
import org.evosuite.runtime.instrumentation.MethodCallReplacementCache;
import org.evosuite.runtime.instrumentation.RemoveFinalClassAdapter;
import org.evosuite.runtime.javaee.db.DBManager;
Expand Down Expand Up @@ -235,5 +236,6 @@ public void resetContext() {
ClassReInitializer.getInstance().addInitializedClasses(initializedClasses);

InspectorManager.resetSingleton();
ModifiedTargetStaticFields.resetSingleton();
}
}
44 changes: 36 additions & 8 deletions client/src/main/java/org/evosuite/TestSuiteGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import org.evosuite.testcase.statements.MethodStatement;
import org.evosuite.testcase.statements.Statement;
import org.evosuite.testcase.statements.StringPrimitiveStatement;
import org.evosuite.testcase.statements.numeric.BooleanPrimitiveStatement;
import org.evosuite.testcase.variable.VariableReference;
import org.evosuite.testsuite.*;
import org.evosuite.utils.ArrayUtil;
Expand Down Expand Up @@ -165,14 +166,16 @@ public TestGenerationResult generateTestSuite() {
return TestGenerationResultBuilder.buildErrorResult("Could not load target class");
}

if (Properties.isRegression()) {
if (Properties.isRegression() && Properties.REGRESSION_SKIP_SIMILAR) {
// Sanity checks
if (Properties.getTargetClassRegression(true) == null) {
Properties.IGNORE_MISSING_STATISTICS = false;
logger.error("class {} was not on the regression projectCP", Properties.TARGET_CLASS);
return TestGenerationResultBuilder.buildErrorResult("Could not load target regression class");
}
if (!ResourceList.getInstance(TestGenerationContext.getInstance().getRegressionClassLoaderForSUT())
.hasClass(Properties.TARGET_CLASS)) {
Properties.IGNORE_MISSING_STATISTICS = false;
logger.error("class {} was not on the regression_cp", Properties.TARGET_CLASS);
return TestGenerationResultBuilder.buildErrorResult(
"Class " + Properties.TARGET_CLASS + " did not exist on regression classpath");
Expand All @@ -184,11 +187,23 @@ public TestGenerationResult generateTestSuite() {
// If classes are different, no point in continuing.
// TODO: report it to master to create a nice regression report
if (!areDifferent) {
Properties.IGNORE_MISSING_STATISTICS = false;
logger.error("class {} was equal on both versions", Properties.TARGET_CLASS);
return TestGenerationResultBuilder.buildErrorResult(
"Class " + Properties.TARGET_CLASS + " was not changed between the two versions");
}
}

if (Properties.isRegression() && Properties.REGRESSION_SKIP_DIFFERENT_CFG) {
// Does the class have the same CFG across the two versions of the program?
boolean sameBranches = RegressionClassDiff.sameCFG();

if (!sameBranches) {
Properties.IGNORE_MISSING_STATISTICS = false;
logger.error("Could not match the branches across the two versions.");
return TestGenerationResultBuilder.buildErrorResult("Could not match the branches across the two versions.");
}
}

TestSuiteChromosome testCases = generateTests();

Expand Down Expand Up @@ -294,11 +309,20 @@ private static DefaultTestCase buildLoadTargetClassTestCase(String className) th
currentThreadVar, Collections.emptyList());
VariableReference contextClassLoaderVar = test.addStatement(getContextClassLoaderStmt);

Method loadClassMethod = ClassLoader.class.getMethod("loadClass", String.class);
Statement loadClassStmt = new MethodStatement(test,
new GenericMethod(loadClassMethod, loadClassMethod.getDeclaringClass()), contextClassLoaderVar,
Collections.singletonList(string0));
test.addStatement(loadClassStmt);
// Method loadClassMethod = ClassLoader.class.getMethod("loadClass", String.class);
// Statement loadClassStmt = new MethodStatement(test,
// new GenericMethod(loadClassMethod, loadClassMethod.getDeclaringClass()), contextClassLoaderVar,
// Collections.singletonList(string0));
// test.addStatement(loadClassStmt);

BooleanPrimitiveStatement stmt1 = new BooleanPrimitiveStatement(test, true);
VariableReference boolean0 = test.addStatement(stmt1);

Method forNameMethod = Class.class.getMethod("forName",String.class, boolean.class, ClassLoader.class);
Statement forNameStmt = new MethodStatement(test,
new GenericMethod(forNameMethod, forNameMethod.getDeclaringClass()), null,
Arrays.<VariableReference>asList(string0, boolean0, contextClassLoaderVar));
test.addStatement(forNameStmt);

return test;
} catch (NoSuchMethodException | SecurityException e) {
Expand All @@ -319,7 +343,8 @@ protected void postProcessTests(TestSuiteChromosome testSuite) {
// down
// the rest of the process, and may lead to invalid tests
testSuite.getTestChromosomes()
.removeIf(t -> t.getLastExecutionResult() != null && t.getLastExecutionResult().hasTimeout());
.removeIf(t -> t.getLastExecutionResult() != null && (t.getLastExecutionResult().hasTimeout() ||
t.getLastExecutionResult().hasTestException()));

if (Properties.CTG_SEEDS_FILE_OUT != null) {
TestSuiteSerialization.saveTests(testSuite, new File(Properties.CTG_SEEDS_FILE_OUT));
Expand Down Expand Up @@ -691,7 +716,7 @@ public static TestGenerationResult writeJUnitTestsAndCreateResult(TestSuiteChrom
suiteWriter.writeTestSuite(name + suffix, testDir, testSuite.getLastExecutionResults());

// If in regression mode, create a separate copy of the tests
if (!RegressionSearchListener.statsID.equals("")) {
if (!RegressionSearchListener.statsID.equals("") && Properties.REGRESSION_STATISTICS) {
File evosuiterTestDir = new File("evosuiter-stats");

boolean madeDir = false;
Expand Down Expand Up @@ -926,6 +951,9 @@ private void printTestCriterion(Criterion criterion) {
case TRYCATCH:
LoggingUtils.getEvoLogger().info(" - Try-Catch Branch Coverage");
break;
case REGRESSION:
LoggingUtils.getEvoLogger().info(" - Regression");
break;
default:
throw new IllegalArgumentException("Unrecognized criterion: " + criterion);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ protected void changeClassLoader(TestSuiteChromosome suite) {

TestGenerationContext.getInstance().resetContext();
TestGenerationContext.getInstance().goingToExecuteSUTCode();
// We need to reset the target Class since it requires a different instrumentation
// for handling assertion generation.
Properties.resetTargetClass();

ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.Mutants, MutationPool.getMutantCounter());
Expand Down
Loading

0 comments on commit aff3611

Please sign in to comment.