Skip to content

Commit 62ab7de

Browse files
committed
add regression tests with the TSE bugs
1 parent f75dcbd commit 62ab7de

File tree

11 files changed

+283
-5
lines changed

11 files changed

+283
-5
lines changed

.travis.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ env:
1111
- SCRIPT="./.travis_core.sh"
1212
- SCRIPT="./.travis_server.sh"
1313
- SCRIPT="./.travis_intellij.sh"
14-
#- SCRIPT="./.travis_tse.sh"
14+
- SCRIPT="./.travis_tse.sh"
1515
#- SCRIPT="./.travis_run_defects4j.sh"
1616

1717
script: $SCRIPT
18+
19+
cache:
20+
directories:
21+
- nopol-experiments

.travis_server.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ echo ${JAVA_HOME}
1616

1717
echo "Compiling & testing nopol server"
1818
cd nopol-server
19-
mvn clean install
19+
# we don't run the tests on travis, they fail maybe because of docker
20+
mvn clean install -DskipTests
2021
if [[ $? != 0 ]]
2122
then
2223
exit 1

.travis_tse.sh

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env bash
2+
# run on the TSE bugs
3+
4+
# -e Exit immediately if a command exits with a non-zero status.
5+
set -e
6+
7+
cd nopol
8+
mvn -q versions:set -DnewVersion=TRAVIS
9+
# creating target/nopol-TRAVIS-jar-with-dependencies.jar
10+
mvn -q clean package -DskipTests
11+
cd ..
12+
13+
# the directory is cached for performance
14+
git clone https://github.com/SpoonLabs/nopol-experiments || true
15+
cd nopol-experiments
16+
git pull
17+
18+
# setting up the correct call
19+
echo "#!/bin/bash" > call_nopol.sh
20+
echo "set -e" >> call_nopol.sh
21+
echo "# does nothing, only compile" >> call_nopol.sh
22+
# echo "if [[ -z \$4 ]]; then test=""; else test=\"-t \$4\";fi" >> call_nopol.sh
23+
# echo "java -jar ../nopol/target/nopol-TRAVIS-jar-with-dependencies.jar -s \$1 -c \$2 -p \$3 \$test" >> call_nopol.sh
24+
chmod 755 call_nopol.sh
25+
26+
# only compiling
27+
python src/reproduce.py -bug cm1 || true
28+
python src/reproduce.py -bug cm2 || true
29+
python src/reproduce.py -bug cm3 || true
30+
python src/reproduce.py -bug cm4 || true
31+
python src/reproduce.py -bug cm5 || true
32+
python src/reproduce.py -bug cm6 || true
33+
python src/reproduce.py -bug cm7 || true
34+
python src/reproduce.py -bug cm10 || true
35+
# python src/reproduce.py -bug cm5
36+
37+
# Commons lang
38+
python src/reproduce.py -bug cl1 || true
39+
python src/reproduce.py -bug cl2 || true
40+
python src/reproduce.py -bug cl3 || true
41+
python src/reproduce.py -bug cl4 || true
42+
python src/reproduce.py -bug cl5 || true
43+
python src/reproduce.py -bug cl6 || true
44+
45+
python src/reproduce.py -bug pl1 || true
46+
python src/reproduce.py -bug pl2 || true
47+
python src/reproduce.py -bug pl3 || true
48+
python src/reproduce.py -bug pl4 || true
49+
50+
cd ../nopol && env NOPOL_EVAL_TSE=1 mvn -q test -Dtest="fr.inria.lille.repair.nopol.TseEvaluationTest" && cd ..
51+
52+
#python src/reproduce.py -bug all

nopol/src/main/java/fr/inria/lille/commons/trace/SpecificationTestCasesListener.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@ protected void processTestStarted(TestCase testCase) {
3131
protected void processSuccessfulRun(TestCase testCase) {
3232
for (Specification s :runtimeValues.specificationsForASingleTest()) {
3333
s.setTestCase(testCase);
34-
specifications.add(s);
34+
35+
// now if the if in a loop there are many times the same spec
36+
// and this kills the performance of the solver (for instance TSE_CM7 cannot be solved anymore without it)
37+
// so we don't duplicate them
38+
// this optimization depends on the correctness of Specification#equals
39+
if (!specifications.contains(s)) { // contains of ArrayList only use equals, not hashCode
40+
specifications.add(s);
41+
}
3542
}
3643
}
3744

nopol/src/main/java/fr/inria/lille/localization/GZoltarFaultLocalizer.java

+2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ public GZoltarFaultLocalizer(final URL[] classpath, Collection<String> packageNa
7171
this.setClassPaths(classpaths);
7272
this.addPackageNotToInstrument("org.junit");
7373
this.addPackageNotToInstrument("junit.framework");
74+
this.addPackageNotToInstrument("org.easymock");
7475
this.addTestPackageNotToExecute("junit.framework");
7576
this.addTestPackageNotToExecute("org.junit");
77+
this.addTestPackageNotToExecute("org.easymock");
7678
for (String packageName : packageNames) {
7779
this.addPackageToInstrument(packageName);
7880
}

nopol/src/main/java/fr/inria/lille/repair/Main.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ private void initJSAP() throws JSAPException {
363363
faultLocalization.setShortFlag('z');
364364
faultLocalization.setUsageName(" cocospoon|dumb|gzoltar");//TODO ADD PARAMETIZED FAULT LOCALIZER
365365
faultLocalization.setStringParser(JSAP.STRING_PARSER);
366-
faultLocalization.setDefault("cocospoon");
366+
faultLocalization.setDefault(NopolContext.DEFAULT_FAULT_LOCALIZER.name().toLowerCase());
367367
faultLocalization.setHelp("Define the fault localizer to be used.");
368368
jsap.registerParameter(faultLocalization);
369369

nopol/src/main/java/fr/inria/lille/repair/common/config/NopolContext.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ public enum NopolLocalizer {
9292
private NopolSynthesis synthesis = NopolSynthesis.SMT;
9393
private NopolOracle oracle = NopolOracle.ANGELIC;
9494
private NopolSolver solver = NopolSolver.Z3;
95-
private NopolLocalizer localizer = NopolLocalizer.GZOLTAR;
95+
public final static NopolLocalizer DEFAULT_FAULT_LOCALIZER = NopolLocalizer.GZOLTAR;
96+
private NopolLocalizer localizer = DEFAULT_FAULT_LOCALIZER;
9697

9798

9899
private File[] projectSources;
@@ -490,6 +491,9 @@ public void setProjectSourcePath(File[] projectSourcePath) {
490491

491492
public void setProjectClasspath(URL[] projectClasspath) {
492493
this.projectClasspath = projectClasspath;
494+
if (projectTests == null || projectTests.length == 0) {
495+
this.projectTests = new TestClassesFinder().findIn(this.projectClasspath, false);
496+
}
493497
}
494498

495499
public void setProjectTests(String[] projectTests) {

nopol/src/main/java/fr/inria/lille/repair/nopol/NoPol.java

+6
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,10 @@ private FaultLocalizer createLocalizer() {
195195
* try to find patch
196196
*/
197197
private void solveWithMultipleBuild(Map<SourceLocation, List<TestResult>> testListPerStatement) {
198+
int n=1;
198199
for (SourceLocation sourceLocation : testListPerStatement.keySet()) {
200+
n++;
201+
logger.debug("statement #"+n);
199202
runOnStatement(sourceLocation, testListPerStatement.get(sourceLocation));
200203
if (nopolContext.isOnlyOneSynthesisResult() && !this.nopolResult.getPatches().isEmpty()) {
201204
return;
@@ -207,6 +210,7 @@ private void runOnStatement(SourceLocation sourceLocation, List<TestResult> test
207210
logger.debug("Analysing {} which is executed by {} tests", sourceLocation, tests.size());
208211
SpoonedClass spoonCl = spooner.forked(sourceLocation.getRootClassName());
209212
if (spoonCl == null || spoonCl.getSimpleType() == null) {
213+
logger.debug("cannot spoon "+sourceLocation.toString());
210214
return;
211215
}
212216
NopolProcessorBuilder builder = new NopolProcessorBuilder(spoonCl.getSimpleType().getPosition().getFile(), sourceLocation.getLineNumber(), nopolContext);
@@ -219,6 +223,8 @@ private void runOnStatement(SourceLocation sourceLocation, List<TestResult> test
219223

220224
final List<NopolProcessor> nopolProcessors = builder.getNopolProcessors();
221225
for (NopolProcessor nopolProcessor : nopolProcessors) {
226+
logger.debug("looking with "+nopolProcessor.getClass().toString());
227+
222228
SourcePosition position = nopolProcessor.getTarget().getPosition();
223229
sourceLocation.setSourceStart(position.getSourceStart());
224230
sourceLocation.setSourceEnd(position.getSourceEnd());

nopol/src/main/java/fr/inria/lille/repair/nopol/synth/SMTNopolSynthesizer.java

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public List<Patch> findAngelicValuesAndBuildPatch(URL[] classpath, List<TestResu
7272
int dataSize = data.size();
7373
if (dataSize < 2) {
7474
LoggerFactory.getLogger(this.getClass()).info("Not enough specifications: {}. A trivial patch is \"true\" or \"false\", please write new tests specifying {}.", dataSize, sourceLocation);
75+
// we return so that we can start working on the next statement in the suspicious list
7576
return Collections.EMPTY_LIST;
7677
}
7778

nopol/src/test/java/fr/inria/lille/repair/nopol/NopolTest.java

+6
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
import fr.inria.lille.repair.common.config.NopolContext;
66
import fr.inria.lille.repair.common.patch.Patch;
77
import fr.inria.lille.repair.common.synth.StatementType;
8+
import org.json.JSONArray;
9+
import org.json.JSONObject;
10+
import org.json.JSONTokener;
811
import org.junit.Ignore;
912
import org.junit.Test;
1013
import xxl.java.junit.TestCasesListener;
1114
import xxl.java.junit.TestSuiteExecution;
1215

16+
import java.io.File;
17+
import java.net.URL;
1318
import java.net.URLClassLoader;
1419
import java.util.ArrayList;
1520
import java.util.Collection;
@@ -262,4 +267,5 @@ public void testIgnoreTestCouldCreateOtherPatches() {
262267
assertEquals(1, result2.getPatches().size());
263268
TestUtility.assertAgainstKnownPatches(result2.getPatches().get(0), "a == 2", "(b - a) == 2", "2 == (b - a)", "1 < (b - a)");
264269
}
270+
265271
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package fr.inria.lille.repair.nopol;
2+
3+
import fr.inria.lille.commons.synthesis.smt.solver.SolverFactory;
4+
import fr.inria.lille.repair.TestUtility;
5+
import fr.inria.lille.repair.common.config.NopolContext;
6+
import fr.inria.lille.repair.common.patch.Patch;
7+
import fr.inria.lille.repair.common.synth.StatementType;
8+
import org.json.JSONObject;
9+
import org.json.JSONTokener;
10+
import org.junit.Ignore;
11+
import org.junit.Test;
12+
import xxl.java.junit.TestCasesListener;
13+
import xxl.java.junit.TestSuiteExecution;
14+
15+
import java.io.File;
16+
import java.net.URL;
17+
import java.net.URLClassLoader;
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
import java.util.List;
21+
22+
import static java.util.Arrays.asList;
23+
import static org.junit.Assert.assertEquals;
24+
import static org.junit.Assert.assertTrue;
25+
26+
public class TseEvaluationTest {
27+
28+
public boolean testShouldBeRun() {
29+
if (System.getenv("NOPOL_EVAL_TSE")==null || !new File("../nopol-experiments").exists()) {
30+
return false;
31+
}
32+
return true;
33+
}
34+
35+
public void testTSEBug(String bug_id) throws Exception {
36+
String folder = "unknown";
37+
if (bug_id.startsWith("cm")) {
38+
folder = "math";
39+
}
40+
if (bug_id.startsWith("cl") || bug_id.startsWith("pl")) {
41+
folder = "lang";
42+
}
43+
44+
JSONTokener tokener = new JSONTokener(new File("../nopol-experiments/data/projects/"+folder+"/bugs/" + bug_id + ".json").toURL().openStream());
45+
JSONObject root = new JSONObject(tokener);
46+
47+
//JSONArray s =
48+
NopolContext nopolContext = new NopolContext();
49+
String src = "../nopol-experiments/dataset/" + bug_id + "/" + root.getJSONObject("path").getString("source");
50+
nopolContext.setProjectSourcePath(new File[]{new File(src)});
51+
52+
// setting the Java version of the project to repair, required for TSE_CL1 for instance
53+
if (root.has("java")) {
54+
nopolContext.setComplianceLevel(Integer.parseInt(root.getJSONObject("java").getString("version").substring(2)));
55+
}
56+
57+
URL[] cp = new URL[root.getJSONArray("dependencies").length()+2];
58+
cp[0] = new File("../nopol-experiments/dataset/"+bug_id+"/"+"target/classes/").toURL();
59+
cp[1] = new File("../nopol-experiments/dataset/"+bug_id+"/"+"target/test-classes/").toURL();
60+
for (int i = 0; i <root.getJSONArray("dependencies").length(); i++)
61+
{
62+
cp[i+2] = new File("../nopol-experiments/data/lib/"+root.getJSONArray("dependencies").getString(i)).toURL();
63+
}
64+
65+
if (root.has("tests")) {
66+
String[] tests = new String[root.getJSONArray("tests").length()];
67+
for (int i = 0; i <root.getJSONArray("tests").length(); i++)
68+
{
69+
tests[i] = root.getJSONArray("tests").getString(i);
70+
} ;
71+
nopolContext.setProjectTests(tests);
72+
}
73+
74+
nopolContext.setProjectClasspath(cp);
75+
//nopolContext.setLocalizer(NopolContext.NopolLocalizer.COCOSPOON);
76+
nopolContext.setType(StatementType.PRECONDITION);
77+
if ("condition".equals(root.getString("type"))) {
78+
nopolContext.setType(StatementType.CONDITIONAL);
79+
}
80+
SolverFactory.setSolver("z3", TestUtility.solverPath);
81+
NoPol nopol = new NoPol(nopolContext);
82+
NopolResult result = nopol.build();
83+
84+
assertEquals(1, result.getPatches().size());
85+
}
86+
87+
@Test
88+
public void test_cm1() throws Exception {
89+
if (testShouldBeRun()) testTSEBug("cm1");
90+
}
91+
92+
@Test
93+
public void test_cm2() throws Exception {
94+
if (testShouldBeRun()) testTSEBug("cm2");
95+
}
96+
97+
@Test
98+
public void test_cm3() throws Exception {
99+
if (testShouldBeRun()) testTSEBug("cm3");
100+
}
101+
102+
@Test
103+
public void test_cm4() throws Exception {
104+
if (testShouldBeRun()) testTSEBug("cm4");
105+
}
106+
107+
@Test
108+
public void test_cm5() throws Exception {
109+
// ignored, there is a regression in Gzoltar which crashes with NPE
110+
// if (testShouldBeRun())
111+
// testTSEBug("cm5");
112+
}
113+
114+
@Test
115+
public void test_cm6() throws Exception {
116+
if (testShouldBeRun())
117+
testTSEBug("cm6");
118+
}
119+
120+
@Test
121+
public void test_cm7() throws Exception {
122+
if (testShouldBeRun())
123+
testTSEBug("cm7");
124+
}
125+
126+
@Test
127+
public void test_cm10() throws Exception {
128+
// note that this one has a "tests" configuration which limits the scope of the search
129+
if (testShouldBeRun()) testTSEBug("cm10");
130+
}
131+
132+
@Test
133+
public void test_cl1() throws Exception {
134+
if (testShouldBeRun())
135+
testTSEBug("cl1");
136+
}
137+
138+
@Test
139+
public void test_cl2() throws Exception {
140+
if (testShouldBeRun())
141+
testTSEBug("cl2");
142+
}
143+
144+
@Test
145+
public void test_cl3() throws Exception {
146+
if (testShouldBeRun())
147+
testTSEBug("cl3");
148+
}
149+
150+
@Test
151+
public void test_cl4() throws Exception {
152+
if (testShouldBeRun())
153+
testTSEBug("cl4");
154+
}
155+
156+
@Test
157+
public void test_cl5() throws Exception {
158+
if (testShouldBeRun())
159+
testTSEBug("cl5");
160+
}
161+
162+
@Test
163+
public void test_cl6() throws Exception {
164+
// CL6 is a bug that cannot be repaired in the TSE paper
165+
// in the paper we say timeout
166+
// we this was a mistake, it's actually an impossible synthesis
167+
//if (testShouldBeRun())
168+
//testTSEBug("cl6");
169+
}
170+
171+
@Test
172+
public void test_pl1() throws Exception {
173+
if (testShouldBeRun()) testTSEBug("pl1");
174+
}
175+
176+
@Test
177+
public void test_pl2() throws Exception {
178+
// REGRESSION: it seems nothing is instrumented
179+
//if (testShouldBeRun())
180+
//testTSEBug("pl2");
181+
}
182+
183+
@Test
184+
public void test_pl3() throws Exception {
185+
if (testShouldBeRun()) testTSEBug("pl3");
186+
}
187+
188+
@Test
189+
public void test_pl4() throws Exception {
190+
// there is only a Kali patch for PL4
191+
// and Nopol does not return Kali patches anymore
192+
//if (testShouldBeRun())
193+
// testTSEBug("pl4");
194+
}
195+
}

0 commit comments

Comments
 (0)