Skip to content

Commit

Permalink
Fix: generation of diff (#795)
Browse files Browse the repository at this point in the history
* fix: produce now correctly the patch using the diff unix command line

* feat: support both format git diff and diff Unix

* fix: read the content of the patch file correctly

* ci: add a test to run diff-test-selection with and without the patch
  • Loading branch information
danglotb authored May 15, 2019
1 parent bb15b84 commit 8bc3bae
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 43 deletions.
16 changes: 16 additions & 0 deletions .travis/travis-diff-test-selection.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,19 @@ DPSOT_VERSION=${1}
cd dspot-diff-test-selection/src/test/resources/tavern

mvn clean eu.stamp-project:dspot-diff-test-selection:${DSPOT_VERSION}:list -Dpath-dir-second-version="../tavern-refactor" eu.stamp-project:dspot-maven:${DSPOT_VERSION}:amplify-unit-tests -Dpath-to-test-list-csv=testsThatExecuteTheChange.csv -Dverbose -Dtest-criterion=ChangeDetectorSelector -Dpath-to-properties=src/main/resources/tavern.properties -Damplifiers=NumberLiteralAmplifier -Diteration=2

if [ -f output/fr/inria/stamp/MainTest.java ]; then
echo "SUCCESS"
else
exit 1
fi

rm -rf output

mvn clean eu.stamp-project:dspot-diff-test-selection:${DSPOT_VERSION}:list -Dpath-dir-second-version="../tavern-refactor" -Dpath-to-diff=patch.diff eu.stamp-project:dspot-maven:${DSPOT_VERSION}:amplify-unit-tests -Dpath-to-test-list-csv=testsThatExecuteTheChange.csv -Dverbose -Dtest-criterion=ChangeDetectorSelector -Dpath-to-properties=src/main/resources/tavern.properties -Damplifiers=NumberLiteralAmplifier -Diteration=2

if [ -f output/fr/inria/stamp/MainTest.java ]; then
exit 0
else
exit 1
fi
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import eu.stamp_project.diff_test_selection.configuration.Configuration;
import eu.stamp_project.diff_test_selection.coverage.Coverage;
import eu.stamp_project.diff_test_selection.report.CSVReport;
import gumtree.spoon.AstComparator;
import gumtree.spoon.diff.Diff;
import gumtree.spoon.diff.operations.Operation;
Expand Down Expand Up @@ -46,32 +47,44 @@ public Coverage getCoverage() {

Map<String, Set<String>> getTestThatExecuteChanges() {
final Map<String, Set<String>> testMethodPerTestClasses = new LinkedHashMap<>();
try (BufferedReader reader = new BufferedReader(new FileReader(new File(configuration.pathToDiff)))) {
String currentLine = null;
while ((currentLine = reader.readLine()) != null) {
if ((currentLine.startsWith("+++") || currentLine.startsWith("---")) && currentLine.endsWith(".java")) {
Map<String, List<Integer>> modifiedLinesPerQualifiedName =
getModifiedLinesPerQualifiedName(currentLine, reader.readLine());
if (modifiedLinesPerQualifiedName == null) {
continue;
}
//this.coverage.addModifiedLines(modifiedLinesPerQualifiedName);
Map<String, Set<String>> matchedChangedWithCoverage = matchChangedWithCoverage(this.mapCoverage, modifiedLinesPerQualifiedName);
matchedChangedWithCoverage.keySet().forEach(key -> {
if (!testMethodPerTestClasses.containsKey(key)) {
testMethodPerTestClasses.put(key, matchedChangedWithCoverage.get(key));
} else {
testMethodPerTestClasses.get(key).addAll(matchedChangedWithCoverage.get(key));
}
});
String[] lines = configuration.diff.split(System.getProperty("line.separator"));
for (int i = 0; i < lines.length; i++) {
String currentLine = lines[i];
if ((currentLine.startsWith("+++") || currentLine.startsWith("---")) &&
!getJavaFile(currentLine).isEmpty()) {
Map<String, List<Integer>> modifiedLinesPerQualifiedName =
getModifiedLinesPerQualifiedName(currentLine, lines[++i]);
if (modifiedLinesPerQualifiedName == null) {
continue;
}
//this.coverage.addModifiedLines(modifiedLinesPerQualifiedName);
Map<String, Set<String>> matchedChangedWithCoverage = matchChangedWithCoverage(this.mapCoverage, modifiedLinesPerQualifiedName);
matchedChangedWithCoverage.keySet().forEach(key -> {
if (!testMethodPerTestClasses.containsKey(key)) {
testMethodPerTestClasses.put(key, matchedChangedWithCoverage.get(key));
} else {
testMethodPerTestClasses.get(key).addAll(matchedChangedWithCoverage.get(key));
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
return testMethodPerTestClasses;
}

private String getJavaFile(String currentLine) {
for (String item : currentLine.split(" ")) {
if (item.endsWith(".java")) {
return item;
}
for (String value : item.split("\t")) {
if (value.endsWith(".java")) {
return value;
}
}
}
return "";
}

private Map<String, Set<String>> matchChangedWithCoverage(Map<String, Map<String, Map<String, List<Integer>>>> coverage,
Map<String, List<Integer>> modifiedLinesPerQualifiedName) {
Map<String, Set<String>> testClassNamePerTestMethodNamesThatCoverChanges = new LinkedHashMap<>();
Expand All @@ -96,13 +109,12 @@ private Map<String, Set<String>> matchChangedWithCoverage(Map<String, Map<String
return testClassNamePerTestMethodNamesThatCoverChanges;
}

@Nullable
private Map<String, List<Integer>> getModifiedLinesPerQualifiedName(String currentLine,
String secondLine) throws Exception {
String secondLine) {
final File baseDir = new File(this.configuration.pathToFirstVersion);
final String file1 = getCorrectPathFile(currentLine);
final String file2 = getCorrectPathFile(secondLine);
if (!file2.endsWith(file1)) {
if (shouldSkip(file1, file2)) {
LOGGER.warn("Could not match " + file1 + " and " + file2);
return null;
}
Expand All @@ -119,14 +131,26 @@ private Map<String, List<Integer>> getModifiedLinesPerQualifiedName(String curre
}
}

private boolean shouldSkip(String file1, String file2) {
if (file2.endsWith(file1)) {
return false;
}
if (new File(file1).isAbsolute() && new File(file2).isAbsolute() &&
file2.endsWith(file1.substring(this.configuration.pathToFirstVersion.length()))) {
return false;
}
LOGGER.warn("Could not match " + file1 + " and " + file2);
return true;
}

@NotNull
private Map<String, List<Integer>> buildMap(Diff compare) {
Map<String, List<Integer>> modifiedLinesPerQualifiedName = new LinkedHashMap<>();// keeps the order
final List<Operation> allOperations = compare.getAllOperations();
final List<CtStatement> statements = new ArrayList<>();
for (Operation operation : allOperations) {
final CtElement node = filterOperation(operation);
if ( node != null && !statements.contains(node.getParent(CtStatement.class))) {
if (node != null && !statements.contains(node.getParent(CtStatement.class))) {
final int line = node.getPosition().getLine();
final String qualifiedName = node
.getPosition()
Expand All @@ -137,7 +161,7 @@ private Map<String, List<Integer>> buildMap(Diff compare) {
modifiedLinesPerQualifiedName.put(qualifiedName, new ArrayList<>());
}
modifiedLinesPerQualifiedName.get(qualifiedName).add(line);
if (!(node.getParent(CtStatement.class)instanceof CtBlock<?>)) {
if (!(node.getParent(CtStatement.class) instanceof CtBlock<?>)) {
this.coverage.addModifiedLine(qualifiedName, line);
}
statements.add(node.getParent(CtStatement.class));
Expand Down Expand Up @@ -168,19 +192,19 @@ private boolean filterOperationFromNode(CtElement element) {
}

private File getCorrectFile(String baseDir, String fileName) {
File file = new File(fileName);
if (file.isAbsolute() && file.exists()) {
return file;
}
if (fileName.substring(1).startsWith(this.configuration.module)) {
fileName = fileName.substring(this.configuration.module.length() + 1);
}
final File file = new File(baseDir + "/" + fileName);
file = new File(baseDir + "/" + fileName);
return file.exists() ? file : new File(baseDir + "/../" + fileName);
}

private String getCorrectPathFile(String path) {
final String s = path.split(" ")[1];
if (s.contains("\t")) {
return removeDiffPrefix(s.split("\t")[0]);
}
return removeDiffPrefix(s);
return removeDiffPrefix(getJavaFile(path));
}

private String removeDiffPrefix(String s) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.transform.sax.SAXSource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

/**
* created by Benjamin DANGLOT
Expand All @@ -29,23 +32,23 @@ public class Configuration {

public final String module;

public final String pathToDiff;
public final String diff;

public Configuration(String pathToFirstVersion, String pathToSecondVersion, String outputPath, String reportFormat, String module, String pathToDiff) {
this.pathToFirstVersion = pathToFirstVersion;
this.pathToSecondVersion = pathToSecondVersion;
this.reportFormat = ReportEnum.valueOf(reportFormat);
this.module = module == null ? "" : module;
if (pathToDiff == null || pathToDiff.isEmpty() || !new File(pathToDiff).exists()) {
if (pathToDiff == null || pathToDiff.isEmpty()) {
LOGGER.warn("No path to diff file has been specified.");
LOGGER.warn("I'll compute a diff file using the UNIX diff command");
LOGGER.warn("You may encounter troubles.");
LOGGER.warn("If so, please specify a path to a correct diff file");
LOGGER.warn("or implement a new way to compute a diff file.");
new DiffComputer().computeDiffWithDiffCommand(new File(pathToFirstVersion), new File(pathToSecondVersion));
this.pathToDiff = pathToFirstVersion + "/" + DiffComputer.DIFF_FILE_NAME;
this.diff = new DiffComputer()
.computeDiffWithDiffCommand(new File(pathToFirstVersion), new File(pathToSecondVersion));
} else {
this.pathToDiff = pathToDiff;
this.diff = this.readFile(pathToDiff);
}
if (outputPath == null || outputPath.isEmpty()) {
this.outputPath = this.pathToFirstVersion +
Expand All @@ -56,6 +59,19 @@ public Configuration(String pathToFirstVersion, String pathToSecondVersion, Stri
}
}

private String readFile(String pathToFileToRead) {
final String nl = System.getProperty("line.separator");
StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(new File(pathToFileToRead)))) {
reader.lines().forEach(
line -> builder.append(line).append(nl)
);
} catch (Exception e) {
throw new RuntimeException(e);
}
return builder.toString();
}

public enum ReportEnum {
CSV(new CSVReport());
public final Report instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.*;

/**
Expand All @@ -24,7 +26,7 @@ public class DiffComputer {
* @param command the command to launch
* @param pathToWorkingDirectory the directory from where the command must be launch
*/
private void executeCommand(String command, File pathToWorkingDirectory) {
private String executeCommand(String command, File pathToWorkingDirectory) {
LOGGER.info(String.format("Executing: %s from %s", command,
pathToWorkingDirectory != null ?
pathToWorkingDirectory.getAbsolutePath() :
Expand All @@ -44,10 +46,32 @@ private void executeCommand(String command, File pathToWorkingDirectory) {
} catch (Exception e) {
throw new RuntimeException(e);
}
;
});
try {
submit.get(5, TimeUnit.SECONDS);
if (process != null) {
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
int current;
StringBuilder output = new StringBuilder();
while (true) {
try {
if ((current = inputStreamReader.read()) == -1) {
break;
}
output.append((char) current);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
try (FileWriter writer = new FileWriter(pathToWorkingDirectory + DIFF_FILE_NAME, false)) {
writer.write(output.toString());
} catch (Exception e) {
throw new RuntimeException(e);
}
return output.toString();
} else {
return "";
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
Expand All @@ -59,7 +83,8 @@ private void executeCommand(String command, File pathToWorkingDirectory) {
}
}

public void computeDiffWithDiffCommand(File directoryVersionOne, File directoryVersionTwo) {
public String computeDiffWithDiffCommand(File directoryVersionOne,
File directoryVersionTwo) {
LOGGER.info("Computing the diff with diff commnd line");
LOGGER.info("The diff will be computed between:");
LOGGER.info(directoryVersionOne.getAbsolutePath() + " and ");
Expand All @@ -68,11 +93,9 @@ public void computeDiffWithDiffCommand(File directoryVersionOne, File directoryV
"diff",
"-ru",
directoryVersionOne.getAbsolutePath(),
directoryVersionTwo.getAbsolutePath(),
">",
DIFF_FILE_NAME
directoryVersionTwo.getAbsolutePath()
});
this.executeCommand(command, directoryVersionOne);
return this.executeCommand(command, directoryVersionOne);
}

}

0 comments on commit 8bc3bae

Please sign in to comment.