Skip to content

Commit

Permalink
Online flacoco
Browse files Browse the repository at this point in the history
Signed-off-by: André Silva <[email protected]>
  • Loading branch information
andre15silva committed Aug 24, 2021
1 parent 9e6a7e8 commit 0eaeb36
Showing 1 changed file with 111 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import fr.spoonlabs.flacoco.core.test.TestContext;
import fr.spoonlabs.flacoco.core.test.TestDetector;
import fr.spoonlabs.flacoco.core.test.method.TestMethod;
import spoon.Launcher;
import spoon.reflect.CtModel;
import spoon.reflect.declaration.CtTypeInformation;
import xxl.java.junit.TestCase;

import java.io.File;
Expand All @@ -21,107 +24,113 @@

public class FlacocoFaultLocalizer implements FaultLocalizer {

private Map<SourceLocation, List<TestResult>> testListPerStatement = new HashMap<>();

private List<StatementSourceLocation> statementSourceLocations = new ArrayList<>();

public FlacocoFaultLocalizer(NopolContext nopolContext, Metric metric) {
runFlacoco(nopolContext, metric);
}

public FlacocoFaultLocalizer(NopolContext nopolContext) {
this(nopolContext, new Ochiai());
}

private void runFlacoco(NopolContext nopolContext, Metric metric) {
// Because Nopol's usage of fault localization requires more information than the one returned by the API
// we need to make use of internal APIs
FlacocoConfig config = FlacocoConfig.getInstance();
config.setClasspath(Arrays.stream(nopolContext.getProjectClasspath()).map(URL::getPath)
.reduce((x, y) -> x + File.pathSeparator + y).orElse(""));

System.out.println(nopolContext);
// TODO: Fix this
config.setProjectPath(new File("../test-projects/").getAbsolutePath());
config.setComplianceLevel(nopolContext.getComplianceLevel());
config.setTestRunnerVerbose(true);

// Set tests
TestDetector testDetector = new TestDetector();
List<TestContext> tests = testDetector.getTests();

for (TestContext testContext : tests) {
if (testContext.getTestFrameworkStrategy() instanceof JUnit4Strategy) {
config.setjUnit4Tests(
testContext.getTestMethods().stream()
.filter(x -> Arrays.asList(nopolContext.getProjectTests()).contains(x.getFullyQualifiedClassName()))
.map(TestMethod::getFullyQualifiedMethodName)
.collect(Collectors.toSet())
);
}
if (testContext.getTestFrameworkStrategy() instanceof JUnit5Strategy) {
config.setjUnit5Tests(
testContext.getTestMethods().stream()
.filter(x -> Arrays.asList(nopolContext.getProjectTests()).contains(x.getFullyQualifiedClassName()))
.map(TestMethod::getFullyQualifiedMethodName)
.collect(Collectors.toSet())
);
}
}

// Get CoverageMatrix
CoverageRunner coverageRunner = new CoverageRunner();
CoverageMatrix coverageMatrix = coverageRunner.getCoverageMatrix(new TestDetector().getTests());

for (String line : coverageMatrix.getResultExecution().keySet()) {
SourceLocation sourceLocation = new SourceLocation(
line.split("@-@")[0].replace("/", "."),
Integer.parseInt(line.split("@-@")[1])
);
StatementSourceLocation statementSourceLocation = new StatementSourceLocation(metric, sourceLocation);
int ef = 0;
int ep = 0;
int nf = 0;
int np = 0;
for (TestMethod testMethod : coverageMatrix.getTests().keySet()) {
boolean iTestPassing = coverageMatrix.getTests().get(testMethod);
boolean nrExecuted = coverageMatrix.getResultExecution().get(line).contains(testMethod);
if (iTestPassing && nrExecuted) {
ep++;
} else if (!iTestPassing && nrExecuted) {
ef++;
} else if (iTestPassing && !nrExecuted) {
np++;
} else if (!iTestPassing && !nrExecuted) {
nf++;
}
}
statementSourceLocation.setEp(ep);
statementSourceLocation.setEf(ef);
statementSourceLocation.setNf(nf);
statementSourceLocation.setNp(np);

statementSourceLocations.add(statementSourceLocation);
testListPerStatement.put(
sourceLocation,
coverageMatrix.getResultExecution().get(line).stream()
.map(x -> new TestResultImpl(TestCase.from(x.getFullyQualifiedMethodName()), coverageMatrix.getTests().get(x)))
.collect(Collectors.toList())
);
}

// Sort statements line in CocoSpoonBasedSpectrumBasedFaultLocalizer
statementSourceLocations.sort((o1, o2) -> Double.compare(o2.getSuspiciousness(), o1.getSuspiciousness()));
}

@Override
public Map<SourceLocation, List<TestResult>> getTestListPerStatement() {
return testListPerStatement;
}

@Override
public List<? extends StatementSourceLocation> getStatements() {
return statementSourceLocations;
}
private Map<SourceLocation, List<TestResult>> testListPerStatement = new HashMap<>();

private List<StatementSourceLocation> statementSourceLocations = new ArrayList<>();

public FlacocoFaultLocalizer(NopolContext nopolContext, Metric metric) {
runFlacoco(nopolContext, metric);
}

public FlacocoFaultLocalizer(NopolContext nopolContext) {
this(nopolContext, new Ochiai());
}

private void runFlacoco(NopolContext nopolContext, Metric metric) {
// Because Nopol's usage of fault localization requires more information than the one returned by the API
// we need to make use of internal APIs
FlacocoConfig config = FlacocoConfig.getInstance();

Launcher spoon = new Launcher();
for (File file : nopolContext.getProjectSources()) {
spoon.addInputResource(file.getAbsolutePath());
}
CtModel model = spoon.buildModel();

config.setClasspath(Arrays.stream(nopolContext.getProjectClasspath()).map(URL::getPath)
.reduce((x, y) -> x + File.pathSeparator + y).orElse(""));
config.setJacocoIncludes(
model.getAllTypes().stream().map(CtTypeInformation::getQualifiedName).collect(Collectors.toSet()));
config.setComplianceLevel(nopolContext.getComplianceLevel());
config.setTestRunnerVerbose(true);

// Set tests
TestDetector testDetector = new TestDetector();
List<TestContext> tests = testDetector.getTests();

for (TestContext testContext : tests) {
if (testContext.getTestFrameworkStrategy() instanceof JUnit4Strategy) {
config.setjUnit4Tests(
testContext.getTestMethods().stream()
.filter(x -> Arrays.asList(nopolContext.getProjectTests())
.contains(x.getFullyQualifiedClassName()))
.map(TestMethod::getFullyQualifiedMethodName)
.collect(Collectors.toSet())
);
}
if (testContext.getTestFrameworkStrategy() instanceof JUnit5Strategy) {
config.setjUnit5Tests(
testContext.getTestMethods().stream()
.filter(x -> Arrays.asList(nopolContext.getProjectTests())
.contains(x.getFullyQualifiedClassName()))
.map(TestMethod::getFullyQualifiedMethodName)
.collect(Collectors.toSet())
);
}
}

// Get CoverageMatrix
CoverageRunner coverageRunner = new CoverageRunner();
CoverageMatrix coverageMatrix = coverageRunner.getCoverageMatrix(new TestDetector().getTests());

for (String line : coverageMatrix.getResultExecution().keySet()) {
SourceLocation sourceLocation = new SourceLocation(
line.split("@-@")[0].replace("/", "."),
Integer.parseInt(line.split("@-@")[1])
);
StatementSourceLocation statementSourceLocation = new StatementSourceLocation(metric, sourceLocation);
int ef = 0;
int ep = 0;
int nf = 0;
int np = 0;
for (TestMethod testMethod : coverageMatrix.getTests().keySet()) {
boolean iTestPassing = coverageMatrix.getTests().get(testMethod);
boolean nrExecuted = coverageMatrix.getResultExecution().get(line).contains(testMethod);
if (iTestPassing && nrExecuted) {
ep++;
} else if (!iTestPassing && nrExecuted) {
ef++;
} else if (iTestPassing && !nrExecuted) {
np++;
} else if (!iTestPassing && !nrExecuted) {
nf++;
}
}
statementSourceLocation.setEp(ep);
statementSourceLocation.setEf(ef);
statementSourceLocation.setNf(nf);
statementSourceLocation.setNp(np);

statementSourceLocations.add(statementSourceLocation);
testListPerStatement.put(
sourceLocation,
coverageMatrix.getResultExecution().get(line).stream()
.map(x -> new TestResultImpl(TestCase.from(x.getFullyQualifiedMethodName()), coverageMatrix.getTests().get(x)))
.collect(Collectors.toList())
);
}

statementSourceLocations.sort((o1, o2) -> Double.compare(o2.getSuspiciousness(), o1.getSuspiciousness()));
}

@Override
public Map<SourceLocation, List<TestResult>> getTestListPerStatement() {
return testListPerStatement;
}

@Override
public List<? extends StatementSourceLocation> getStatements() {
return statementSourceLocations;
}

}

0 comments on commit 0eaeb36

Please sign in to comment.