Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue842 #923

Merged
merged 8 commits into from
Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions repairnator/repairnator-pipeline/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,28 @@
</repositories>

<dependencies>
<dependency>
<groupId>com.github.spoonlabs</groupId>
<artifactId>coming</artifactId>
<version>0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>fr.inria.repairnator</groupId>
<artifactId>repairnator-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,20 @@ public List<RepairPatch> getAllPatches() {
return allPatches;
}

public List<RepairPatch> getRankedPatches() {
List<RepairPatch> allPatches = getAllPatches();
allPatches.sort((patch1, patch2) -> { // ascending
double diff = patch1.getOverfittingScore() - patch2.getOverfittingScore();
if (diff < 0) {
return -1;
} else if (diff > 0) {
return 1;
}
return 0;
});
return allPatches;
}

public Map<String, List<RepairPatch>> getListOfPatches() {
return listOfPatches;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
package fr.inria.spirals.repairnator.process.inspectors;

import com.github.difflib.DiffUtils;
import com.github.difflib.UnifiedDiffUtils;
import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException;
import fr.inria.prophet4j.P4J;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

public class RepairPatch {
/**
Expand All @@ -18,10 +32,48 @@ public class RepairPatch {
*/
private String diff;

/**
* Score of the overfitting likelihood
*/
private double overfittingScore;

public RepairPatch(String toolname, String filePath, String diff) {
this.toolname = toolname;
this.filePath = filePath;
this.diff = diff;
this.overfittingScore = computeOverfittingScore();
}

private double computeOverfittingScore() {
double overfittingScore = Double.POSITIVE_INFINITY;

File buggyFile = new File(filePath);
if (buggyFile.isFile()) {
// read from buggyFile
List<String> buggyLines = new ArrayList<>();
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
stream.forEach(buggyLines::add);
} catch (IOException e) {
e.printStackTrace();
}
// prepare patches
List<String> diffLines = Arrays.asList(diff.split("\n"));
Patch<String> patches = UnifiedDiffUtils.parseUnifiedDiff(diffLines);

try {
// create patchedFile
String tmpName = buggyFile.getName();
File patchedFile = Files.createTempFile(tmpName, ".java").toFile();
// generate content of patchedFile by applying patches
List<String> patchedLines = DiffUtils.patch(buggyLines, patches);
// write to patchedFile
Files.write(Paths.get(patchedFile.getPath()), patchedLines);
overfittingScore = new P4J().computeOverfittingScore(buggyFile, patchedFile);
} catch (PatchFailedException | IOException e) {
e.printStackTrace();
}
}
return overfittingScore;
}

public String getToolname() {
Expand All @@ -36,14 +88,18 @@ public String getDiff() {
return diff;
}

public double getOverfittingScore() {
return overfittingScore;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final RepairPatch that = (RepairPatch) o;
return Objects.equals(toolname, that.toolname) &&
Objects.equals(filePath, that.filePath) &&
Objects.equals(diff, that.diff);
Objects.equals(filePath, that.filePath) &&
Objects.equals(diff, that.diff);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Prophet4J is inside the Coming lib, and is introduced to compute OverfittingScores for patches.

This folder contains necessary resources for Prophet4J. There are two same folders in total, one is at _src/main/resources_ and the other one is at _src/test/resources_. I had not found one correct way to import resources files to make Prophet4J work smoothly as one part of Maven lib. In ideal cases, we do not need these two folders at all.

If you fixed this issue, please run this test file `src/test/java/fr/inria/spirals/repairnator/process/inspectors/TestJobStatus.java` to check. Or maybe later I will do it myself.

How to fix this issue?

1. the issue is at L11 at _src/main/java/fr/inria/prophet4j/utility/Support.java_ of the [Coming Project]()
That line of code looks like `public static final String PROPHET4J_DIR = Support.class.getClassLoader().getResource("").getPath() + "prophet4j/";`
2. rewrite this line of code to make everything prefect
3. release one new version of Coming lib to Maven
4. run the test file named as `TestJobStatus.java` to check
5. remove two `prophet4j` folders locating at _src/main/resources_ and _src/test/resources_

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package fr.inria.spirals.repairnator.process.inspectors;

import ch.qos.logback.classic.Level;
import fr.inria.jtravis.entities.Build;
import fr.inria.spirals.repairnator.BuildToBeInspected;
import fr.inria.spirals.repairnator.process.step.repair.NPERepair;
import fr.inria.spirals.repairnator.process.step.repair.nopol.NopolSingleTestRepair;
import fr.inria.spirals.repairnator.utils.Utils;
import fr.inria.spirals.repairnator.config.RepairnatorConfig;
import fr.inria.spirals.repairnator.process.files.FileHelper;
import fr.inria.spirals.repairnator.process.step.StepStatus;
Expand All @@ -30,8 +28,7 @@
import java.nio.file.Files;
import java.util.*;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

Expand All @@ -43,7 +40,6 @@ public class TestJobStatus {
public void setup() {
RepairnatorConfig config = RepairnatorConfig.getInstance();
config.setZ3solverPath(Utils4Tests.getZ3SolverPath());
Utils.setLoggersLevel(Level.ERROR);
}

@After
Expand All @@ -52,12 +48,24 @@ public void tearDown() throws IOException {
FileHelper.deleteFile(tmpDir);
}

private Build checkBuildAndReturn(long buildId, boolean isPR) {
Optional<Build> optionalBuild = RepairnatorConfig.getInstance().getJTravis().build().fromId(buildId);
assertTrue(optionalBuild.isPresent());

Build build = optionalBuild.get();
assertThat(build, IsNull.notNullValue());
assertThat(buildId, Is.is(build.getId()));
assertThat(build.isPullRequest(), Is.is(isPR));

return build;
}

@Test
public void testGatheringPatches() throws IOException {
long buildId = 382484026; // surli/failingProject build
Build build = this.checkBuildAndReturn(buildId, false);

tmpDir = Files.createTempDirectory("test_nopolrepair").toFile();
tmpDir = Files.createTempDirectory("test_gathering").toFile();
BuildToBeInspected toBeInspected = new BuildToBeInspected(build, null, ScannedBuildStatus.ONLY_FAIL, "");
ProjectInspector inspector = new ProjectInspector(toBeInspected, tmpDir.getAbsolutePath(), null, null);

Expand All @@ -70,12 +78,12 @@ public void testGatheringPatches() throws IOException {
RepairnatorConfig.getInstance().setRepairTools(new HashSet<>(Arrays.asList(nopolRepair.getRepairToolName(), npeRepair.getRepairToolName())));

cloneStep.addNextStep(new CheckoutBuggyBuild(inspector, true))
.addNextStep(new TestProject(inspector))
.addNextStep(new GatherTestInformation(inspector, true, new BuildShouldFail(), false))
.addNextStep(new ComputeClasspath(inspector, true))
.addNextStep(new ComputeSourceDir(inspector, true, false))
.addNextStep(nopolRepair)
.addNextStep(npeRepair);
.addNextStep(new TestProject(inspector))
.addNextStep(new GatherTestInformation(inspector, true, new BuildShouldFail(), false))
.addNextStep(new ComputeClasspath(inspector, true))
.addNextStep(new ComputeSourceDir(inspector, true, false))
.addNextStep(nopolRepair)
.addNextStep(npeRepair);
cloneStep.execute();

assertThat(nopolRepair.isShouldStop(), is(false));
Expand All @@ -100,15 +108,86 @@ public void testGatheringPatches() throws IOException {
assertThat(inspector.getJobStatus().getToolDiagnostic().get(nopolRepair.getRepairToolName()), notNullValue());
}

private Build checkBuildAndReturn(long buildId, boolean isPR) {
Optional<Build> optionalBuild = RepairnatorConfig.getInstance().getJTravis().build().fromId(buildId);
assertTrue(optionalBuild.isPresent());
@Test
public void testRankingPatches() throws IOException {
long buildId = 382484026; // surli/failingProject build
Build build = this.checkBuildAndReturn(buildId, false);

Build build = optionalBuild.get();
assertThat(build, IsNull.notNullValue());
assertThat(buildId, Is.is(build.getId()));
assertThat(build.isPullRequest(), Is.is(isPR));
tmpDir = Files.createTempDirectory("test_ranking").toFile();
BuildToBeInspected toBeInspected = new BuildToBeInspected(build, null, ScannedBuildStatus.ONLY_FAIL, "");
ProjectInspector inspector = new ProjectInspector(toBeInspected, tmpDir.getAbsolutePath(), null, null);

return build;
CloneRepository cloneStep = new CloneRepository(inspector);
NopolSingleTestRepair nopolRepair = new NopolSingleTestRepair();
nopolRepair.setProjectInspector(inspector);
NPERepair npeRepair = new NPERepair();
npeRepair.setProjectInspector(inspector);

RepairnatorConfig.getInstance().setRepairTools(new HashSet<>(Arrays.asList(nopolRepair.getRepairToolName(), npeRepair.getRepairToolName())));

cloneStep.addNextStep(new CheckoutBuggyBuild(inspector, true))
.addNextStep(new TestProject(inspector))
.addNextStep(new GatherTestInformation(inspector, true, new BuildShouldFail(), false))
.addNextStep(new ComputeClasspath(inspector, true))
.addNextStep(new ComputeSourceDir(inspector, true, false))
.addNextStep(nopolRepair)
.addNextStep(npeRepair);
cloneStep.execute();

List<RepairPatch> rankedPatches = inspector.getJobStatus().getRankedPatches();
assertThat(rankedPatches.size(), is(16)); // 12 (nopol) + 4 (npe)

// rankedPatches.forEach(repairPatch -> {
// System.out.println(repairPatch.getToolname());
// System.out.println(repairPatch.getFilePath());
// System.out.println(repairPatch.getOverfittingScore());
// });

assertThat(rankedPatches.get(0).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(0).getFilePath(), endsWith("modelo/Solver.java"));
assertThat(rankedPatches.get(0).getOverfittingScore(), is(-3190.603359887649));
assertThat(rankedPatches.get(1).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(1).getFilePath(), endsWith("Stub/ProxyPlatoStub.java"));
assertThat(rankedPatches.get(1).getOverfittingScore(), is(-2775.6773763492697));
assertThat(rankedPatches.get(2).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(2).getFilePath(), endsWith("modelo/ApiDB.java"));
assertThat(rankedPatches.get(2).getOverfittingScore(), is(-1544.2008323597074));
assertThat(rankedPatches.get(3).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(3).getFilePath(), endsWith("modelo/InternalDB.java"));
assertThat(rankedPatches.get(3).getOverfittingScore(), is(-1011.203142967915));
assertThat(rankedPatches.get(4).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(4).getFilePath(), endsWith("modelo/ControllerInternalDB.java"));
assertThat(rankedPatches.get(4).getOverfittingScore(), is(-732.199911962387));
assertThat(rankedPatches.get(5).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(5).getFilePath(), endsWith("modelo/InternalDB.java"));
assertThat(rankedPatches.get(5).getOverfittingScore(), is(-589.2194952242268));
assertThat(rankedPatches.get(6).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(6).getFilePath(), endsWith("modelo/ControllerInternalDB.java"));
assertThat(rankedPatches.get(6).getOverfittingScore(), is(-525.0518968819456));
assertThat(rankedPatches.get(7).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(7).getFilePath(), endsWith("Validadores/ValidadorPlato.java"));
assertThat(rankedPatches.get(7).getOverfittingScore(), is(-41.19421176656324));
assertThat(rankedPatches.get(8).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(8).getFilePath(), endsWith("modelo/InternalDB.java"));
assertThat(rankedPatches.get(8).getOverfittingScore(), is(-41.19421176656324));
assertThat(rankedPatches.get(9).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(9).getFilePath(), endsWith("modelo/ControllerInternalDB.java"));
assertThat(rankedPatches.get(9).getOverfittingScore(), is(-41.19421176656324));
assertThat(rankedPatches.get(10).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(10).getFilePath(), endsWith("modelo/ControllerInternalDB.java"));
assertThat(rankedPatches.get(10).getOverfittingScore(), is(230.96289712519297));
assertThat(rankedPatches.get(11).getToolname(), is("NopolSingleTest"));
assertThat(rankedPatches.get(11).getFilePath(), endsWith("modelo/ControllerInternalDB.java"));
assertThat(rankedPatches.get(11).getOverfittingScore(), is(3465.24494158228));

// in following cases, OverfittingScore can not be computed because of invalid filePaths
assertThat(rankedPatches.get(12).getToolname(), is("NPEFix"));
assertThat(rankedPatches.get(12).getOverfittingScore(), is(Double.POSITIVE_INFINITY));
assertThat(rankedPatches.get(13).getToolname(), is("NPEFix"));
assertThat(rankedPatches.get(13).getOverfittingScore(), is(Double.POSITIVE_INFINITY));
assertThat(rankedPatches.get(14).getToolname(), is("NPEFix"));
assertThat(rankedPatches.get(14).getOverfittingScore(), is(Double.POSITIVE_INFINITY));
assertThat(rankedPatches.get(15).getToolname(), is("NPEFix"));
assertThat(rankedPatches.get(15).getOverfittingScore(), is(Double.POSITIVE_INFINITY));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Prophet4J is inside the Coming lib, and is introduced to compute OverfittingScores for patches.

This folder contains necessary resources for Prophet4J. There are two same folders in total, one is at _src/main/resources_ and the other one is at _src/test/resources_. I had not found one correct way to import resources files to make Prophet4J work smoothly as one part of Maven lib. In ideal cases, we do not need these two folders at all.

If you fixed this issue, please run this test file `src/test/java/fr/inria/spirals/repairnator/process/inspectors/TestJobStatus.java` to check. Or maybe later I will do it myself.

How to fix this issue?

1. the issue is at L11 at _src/main/java/fr/inria/prophet4j/utility/Support.java_ of the [Coming Project]()
That line of code looks like `public static final String PROPHET4J_DIR = Support.class.getClassLoader().getResource("").getPath() + "prophet4j/";`
2. rewrite this line of code to make everything prefect
3. release one new version of Coming lib to Maven
4. run the test file named as `TestJobStatus.java` to check
5. remove two `prophet4j` folders locating at _src/main/resources_ and _src/test/resources_

Large diffs are not rendered by default.

Large diffs are not rendered by default.