Skip to content

Commit fb37364

Browse files
author
Pouria Derakhshanfar
authored
Merge pull request #101 from STAMP-project/integration_testing
Integration testing for class integration testing (CLING)
2 parents d79fcdc + 7ee8c47 commit fb37364

87 files changed

Lines changed: 6465 additions & 344 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Thumbs.db
4949
# local test directory
5050
**/test/**/botsing/local/
5151
**/test/**/botsing/model/generation/local/
52+
**/test/**/cling/local/
53+
**/test/**/coupling/analyze/local/
5254

5355

5456
# Generated website

botsing-commons/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,25 @@
2727
<artifactId>evosuite-client-botsing</artifactId>
2828
<version>${evosuite-client.version}</version>
2929
</dependency>
30+
<dependency>
31+
<groupId>eu.stamp-project</groupId>
32+
<artifactId>botsing-examples</artifactId>
33+
<version>${project.version}</version>
34+
<scope>test</scope>
35+
</dependency>
3036
</dependencies>
3137

38+
<build>
39+
<plugins>
40+
<plugin>
41+
<groupId>org.apache.maven.plugins</groupId>
42+
<artifactId>maven-surefire-plugin</artifactId>
43+
<configuration>
44+
<runOrder>alphabetical</runOrder>
45+
</configuration>
46+
</plugin>
47+
48+
</plugins>
49+
</build>
3250

3351
</project>
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
package eu.stamp.botsing.commons;
2+
3+
import org.evosuite.Properties;
4+
import org.evosuite.TestSuiteGeneratorHelper;
5+
import org.evosuite.TimeController;
6+
import org.evosuite.contracts.FailingTestSet;
7+
import org.evosuite.coverage.TestFitnessFactory;
8+
import org.evosuite.junit.JUnitAnalyzer;
9+
import org.evosuite.junit.writer.TestSuiteWriter;
10+
import org.evosuite.result.TestGenerationResult;
11+
import org.evosuite.result.TestGenerationResultBuilder;
12+
import org.evosuite.rmi.ClientServices;
13+
import org.evosuite.rmi.service.ClientState;
14+
import org.evosuite.statistics.RuntimeVariable;
15+
import org.evosuite.testcase.ConstantInliner;
16+
import org.evosuite.testcase.TestCase;
17+
import org.evosuite.testcase.TestFitnessFunction;
18+
import org.evosuite.testsuite.TestSuiteChromosome;
19+
import org.evosuite.testsuite.TestSuiteMinimizer;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
23+
import java.util.ArrayList;
24+
import java.util.Collections;
25+
import java.util.Iterator;
26+
import java.util.List;
27+
28+
public class PostProcessUtility {
29+
private static final Logger LOG = LoggerFactory.getLogger(PostProcessUtility.class);
30+
31+
public static void postProcessTests(TestSuiteChromosome testSuite, List<TestFitnessFactory<? extends TestFitnessFunction>> fitnessFactories) {
32+
33+
if (Properties.INLINE) {
34+
ConstantInliner inliner = new ConstantInliner();
35+
inliner.inline(testSuite);
36+
}
37+
38+
39+
if (Properties.MINIMIZE) {
40+
double before = testSuite.getFitness();
41+
42+
TestSuiteMinimizer minimizer = new TestSuiteMinimizer(fitnessFactories);
43+
44+
LOG.info("* Minimizing test suite");
45+
minimizer.minimize(testSuite, true);
46+
47+
double after = testSuite.getFitness();
48+
if (after > before + 0.01d) { // assume minimization
49+
throw new Error("EvoSuite bug: minimization lead fitness from " + before + " to " + after);
50+
}
51+
}
52+
53+
if (Properties.ASSERTIONS) {
54+
LOG.info("Generating assertions");
55+
TestSuiteGeneratorHelper.addAssertions(testSuite);
56+
}
57+
58+
59+
compileAndCheckTests(testSuite);
60+
}
61+
62+
63+
private static void compileAndCheckTests(TestSuiteChromosome chromosome) {
64+
LOG.info("* Compiling and checking tests");
65+
66+
if (!JUnitAnalyzer.isJavaCompilerAvailable()) {
67+
String msg = "No Java compiler is available. Make sure to run EvoSuite with the JDK and not the JRE."
68+
+ "You can try to setup the JAVA_HOME system variable to point to it, as well as to make sure that the PATH "
69+
+ "variable points to the JDK before any JRE.";
70+
LOG.error(msg);
71+
throw new RuntimeException(msg);
72+
}
73+
74+
ClientServices.getInstance().getClientNode().changeState(ClientState.JUNIT_CHECK);
75+
76+
// Store this value; if this option is true then the JUnit check
77+
// would not succeed, as the JUnit classloader wouldn't find the class
78+
boolean junitSeparateClassLoader = Properties.USE_SEPARATE_CLASSLOADER;
79+
Properties.USE_SEPARATE_CLASSLOADER = false;
80+
81+
int numUnstable = 0;
82+
83+
// note: compiling and running JUnit tests can be very time consuming
84+
if (!TimeController.getInstance().isThereStillTimeInThisPhase()) {
85+
Properties.USE_SEPARATE_CLASSLOADER = junitSeparateClassLoader;
86+
return;
87+
}
88+
89+
List<TestCase> testCases = chromosome.getTests(); // make copy of
90+
// current tests
91+
92+
// first, let's just get rid of all the tests that do not compile
93+
JUnitAnalyzer.removeTestsThatDoNotCompile(testCases);
94+
95+
// compile and run each test one at a time. and keep track of total time
96+
long start = java.lang.System.currentTimeMillis();
97+
Iterator<TestCase> iter = testCases.iterator();
98+
while (iter.hasNext()) {
99+
if (!TimeController.getInstance().hasTimeToExecuteATestCase()) {
100+
break;
101+
}
102+
TestCase tc = iter.next();
103+
List<TestCase> list = new ArrayList<>();
104+
list.add(tc);
105+
numUnstable += JUnitAnalyzer.handleTestsThatAreUnstable(list);
106+
if (list.isEmpty()) {
107+
// if the test was unstable and deleted, need to remove it from
108+
// final testSuite
109+
iter.remove();
110+
}
111+
}
112+
/*
113+
* compiling and running each single test individually will take more
114+
* than compiling/running everything in on single suite. so it can be
115+
* used as an upper bound
116+
*/
117+
long delta = java.lang.System.currentTimeMillis() - start;
118+
119+
numUnstable += checkAllTestsIfTime(testCases, delta);
120+
121+
// second passage on reverse order, this is to spot dependencies among
122+
// tests
123+
if (testCases.size() > 1) {
124+
Collections.reverse(testCases);
125+
numUnstable += checkAllTestsIfTime(testCases, delta);
126+
}
127+
128+
chromosome.clearTests(); // remove all tests
129+
for (TestCase testCase : testCases) {
130+
chromosome.addTest(testCase); // add back the filtered tests
131+
}
132+
133+
boolean unstable = (numUnstable > 0);
134+
135+
if (!TimeController.getInstance().isThereStillTimeInThisPhase()) {
136+
LOG.warn("JUnit checking timed out");
137+
}
138+
139+
ClientServices.track(RuntimeVariable.HadUnstableTests, unstable);
140+
ClientServices.track(RuntimeVariable.NumUnstableTests, numUnstable);
141+
Properties.USE_SEPARATE_CLASSLOADER = junitSeparateClassLoader;
142+
143+
}
144+
145+
146+
private static int checkAllTestsIfTime(List<TestCase> testCases, long delta) {
147+
if (TimeController.getInstance().hasTimeToExecuteATestCase()
148+
&& TimeController.getInstance().isThereStillTimeInThisPhase(delta)) {
149+
return JUnitAnalyzer.handleTestsThatAreUnstable(testCases);
150+
}
151+
return 0;
152+
}
153+
154+
155+
public static TestGenerationResult writeJUnitTestsAndCreateResult(TestSuiteChromosome testSuite, String suffix) {
156+
List<TestCase> tests = testSuite.getTests();
157+
if (Properties.JUNIT_TESTS) {
158+
ClientServices.getInstance().getClientNode().changeState(ClientState.WRITING_TESTS);
159+
160+
TestSuiteWriter suiteWriter = new TestSuiteWriter();
161+
suiteWriter.insertTests(tests);
162+
163+
String name = Properties.TARGET_CLASS.substring(Properties.TARGET_CLASS.lastIndexOf(".") + 1);
164+
String testDir = Properties.TEST_DIR;
165+
166+
LOG.info("* Writing JUnit test case '" + (name + suffix) + "' to " + testDir);
167+
suiteWriter.writeTestSuite(name + suffix, testDir, testSuite.getLastExecutionResults());
168+
}
169+
return TestGenerationResultBuilder.buildSuccessResult();
170+
}
171+
172+
173+
174+
public static void writeJUnitFailingTests() {
175+
if (!Properties.CHECK_CONTRACTS) {
176+
return;
177+
}
178+
179+
FailingTestSet.sendStatistics();
180+
181+
if (Properties.JUNIT_TESTS) {
182+
183+
TestSuiteWriter suiteWriter = new TestSuiteWriter();
184+
//suiteWriter.insertTests(FailingTestSet.getFailingTests());
185+
186+
TestSuiteChromosome suite = new TestSuiteChromosome();
187+
for(TestCase test : FailingTestSet.getFailingTests()) {
188+
test.setFailing();
189+
suite.addTest(test);
190+
}
191+
192+
String name = Properties.TARGET_CLASS.substring(Properties.TARGET_CLASS.lastIndexOf(".") + 1);
193+
String testDir = Properties.TEST_DIR;
194+
LOG.info("* Writing failing test cases '" + (name + Properties.JUNIT_SUFFIX) + "' to " + testDir);
195+
suiteWriter.insertAllTests(suite.getTests());
196+
FailingTestSet.writeJUnitTestSuite(suiteWriter);
197+
198+
suiteWriter.writeTestSuite(name + Properties.JUNIT_FAILED_SUFFIX, testDir, suite.getLastExecutionResults());
199+
}
200+
}
201+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package eu.stamp.botsing.commons;
2+
3+
import org.apache.commons.cli.*;
4+
import org.evosuite.Properties;
5+
import org.evosuite.classpath.ClassPathHacker;
6+
import org.evosuite.classpath.ClassPathHandler;
7+
import org.evosuite.junit.writer.TestSuiteWriterUtils;
8+
import org.evosuite.setup.DependencyAnalysis;
9+
import org.evosuite.testcase.execution.ExecutionTrace;
10+
import org.evosuite.testcase.execution.ExecutionTracer;
11+
import org.evosuite.testcase.execution.reset.ClassReInitializer;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
15+
import java.io.File;
16+
import java.io.IOException;
17+
import java.util.Arrays;
18+
import java.util.List;
19+
20+
public class SetupUtility {
21+
22+
private static final Logger LOG = LoggerFactory.getLogger(SetupUtility.class);
23+
24+
public static void printHelpMessage(Options options, boolean integration) {
25+
HelpFormatter formatter = new HelpFormatter();
26+
if (integration){
27+
formatter.printHelp("java -jar cling.jar -target_classes class1;class2 -project_cp dep1.jar;dep2.jar )", options);
28+
return;
29+
}
30+
formatter.printHelp("java -jar botsing.jar -crash_log stacktrace.log -target_frame 2 -project_cp dep1.jar;dep2.jar )", options);
31+
}
32+
33+
34+
public static CommandLine parseCommands(String[] args, Options options, boolean integration){
35+
CommandLineParser parser = new DefaultParser();
36+
CommandLine commands;
37+
try {
38+
commands = parser.parse(options, args);
39+
} catch (ParseException e) {
40+
LOG.error("Could not parse command line!", e);
41+
printHelpMessage(options, integration);
42+
return null;
43+
}
44+
return commands;
45+
}
46+
47+
48+
49+
public static void updateEvoSuiteProperties(java.util.Properties properties){
50+
for (String property : properties.stringPropertyNames()) {
51+
try {
52+
Properties.getInstance().setValue(property, properties.getProperty(property));
53+
} catch (Properties.NoSuchParameterException e) {
54+
LOG.error("{} parameter does not exist", property);
55+
} catch (IllegalAccessException e) {
56+
e.printStackTrace();
57+
}
58+
}
59+
}
60+
61+
public static String[] getCompatibleCP(String cp){
62+
// Get EvoSuite compatible class path
63+
List<String> classPathEntries = ClassPaths.getClassPathEntries(cp);
64+
return classPathEntries.toArray(new String[classPathEntries.size()]);
65+
}
66+
67+
68+
public static void setupProjectClasspath(String[] projectCP){
69+
70+
try {
71+
ClassPathHandler.getInstance().changeTargetClassPath(projectCP);
72+
}catch (IllegalArgumentException e){
73+
LOG.error(e.getMessage());
74+
}
75+
76+
77+
78+
// locate Tool jar
79+
if (TestSuiteWriterUtils.needToUseAgent() && Properties.JUNIT_CHECK) {
80+
ClassPathHacker.initializeToolJar();
81+
}
82+
83+
// Adding the target project classpath entries.
84+
for (String entry : ClassPathHandler.getInstance().getTargetProjectClasspath().split(File.pathSeparator)) {
85+
try {
86+
ClassPathHacker.addFile(entry);
87+
} catch (IOException e) {
88+
LOG.info("* Error while adding classpath entry: " + entry);
89+
}
90+
}
91+
}
92+
93+
94+
95+
public static void configureClassReInitializer() {
96+
ExecutionTrace execTrace = ExecutionTracer.getExecutionTracer().getTrace();
97+
final List<String> initializedClasses = execTrace.getInitializedClasses();
98+
ClassReInitializer.getInstance().addInitializedClasses(initializedClasses);
99+
ClassReInitializer.getInstance().setReInitializeAllClasses(Properties.RESET_ALL_CLASSES_DURING_TEST_GENERATION);
100+
}
101+
102+
public static void analyzeClassDependencies(String className) {
103+
String cp = ClassPathHandler.getInstance().getTargetProjectClasspath();
104+
List<String> cpList = Arrays.asList(cp.split(File.pathSeparator));
105+
Properties.TARGET_CLASS=className;
106+
try {
107+
LOG.info("Starting the dependency analysis. The number of detected jar files is {}.",cpList.size());
108+
DependencyAnalysis.analyzeClass(className,Arrays.asList(cp.split(File.pathSeparator)));
109+
LOG.info("Analysing dependencies done!");
110+
} catch (ClassNotFoundException e) {
111+
e.printStackTrace();
112+
}
113+
}
114+
}

botsing-model-generation/src/main/java/eu/stamp/botsing/model/generation/analysis/classpath/CPAnalysor.java renamed to botsing-commons/src/main/java/eu/stamp/botsing/commons/analysis/classpath/CPAnalyzer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package eu.stamp.botsing.model.generation.analysis.classpath;
1+
package eu.stamp.botsing.commons.analysis.classpath;
22

33

44
import org.evosuite.setup.InheritanceTree;
@@ -9,8 +9,8 @@
99
import java.util.List;
1010

1111

12-
public class CPAnalysor {
13-
private static final Logger LOG = LoggerFactory.getLogger(CPAnalysor.class);
12+
public class CPAnalyzer {
13+
private static final Logger LOG = LoggerFactory.getLogger(CPAnalyzer.class);
1414

1515
private static InheritanceTree inheritanceTree = null;
1616

botsing-commons/src/main/java/eu/stamp/botsing/commons/fitnessfunction/CrashCoverageSuiteFitness.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,9 @@ private int calculateFitness (AbstractTestSuiteChromosome<? extends ExecutableCh
6363
totalFitnessValue = fitnessValue;
6464
return (coveredGoals/totalGoals);
6565
}
66+
67+
@Override
68+
public List<ExecutionResult> runTestSuite(AbstractTestSuiteChromosome<? extends ExecutableChromosome> suite){
69+
return super.runTestSuite(suite);
70+
}
6671
}

botsing-commons/src/main/java/eu/stamp/botsing/commons/ga/strategy/mosa/AbstractMOSA.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,10 @@ protected List<T> getArchive() {
126126
}
127127

128128
@Override
129-
protected void evolve() {
130-
131-
}
129+
protected void evolve() {}
132130

133131
@Override
134-
public void generateSolution() {
135-
136-
}
132+
public void generateSolution() {}
137133

138134

139135

0 commit comments

Comments
 (0)