Skip to content

Commit

Permalink
refactor: update dspot-prettifier with new version of DSpot (#917)
Browse files Browse the repository at this point in the history
  • Loading branch information
danglotb authored Nov 4, 2019
1 parent a993411 commit 0c8f83c
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 522 deletions.
2 changes: 1 addition & 1 deletion dspot-prettifier/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
<dependency>
<groupId>eu.stamp-project</groupId>
<artifactId>dspot</artifactId>
<version>2.2.1</version>
<version>${project.version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
Expand Down
110 changes: 92 additions & 18 deletions dspot-prettifier/src/main/java/eu/stamp_project/prettifier/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.stamp_project.automaticbuilder.AutomaticBuilder;
import eu.stamp_project.prettifier.code2vec.Code2VecExecutor;
import eu.stamp_project.prettifier.code2vec.Code2VecParser;
import eu.stamp_project.prettifier.code2vec.Code2VecWriter;
Expand All @@ -10,12 +11,15 @@
import eu.stamp_project.prettifier.minimization.Minimizer;
import eu.stamp_project.prettifier.minimization.PitMutantMinimizer;
import eu.stamp_project.prettifier.options.InputConfiguration;
import eu.stamp_project.prettifier.options.JSAPOptions;
import eu.stamp_project.prettifier.output.PrettifiedTestMethods;
import eu.stamp_project.prettifier.output.report.ReportJSON;
import eu.stamp_project.test_framework.TestFramework;
import eu.stamp_project.utils.compilation.DSpotCompiler;
import eu.stamp_project.utils.options.check.Checker;
import eu.stamp_project.utils.options.check.InputErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;
import spoon.Launcher;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtClass;
Expand All @@ -29,6 +33,8 @@
import java.util.*;
import java.util.stream.Collectors;

import static eu.stamp_project.Main.completeDependencies;

/**
* created by Benjamin DANGLOT
* benjamin.danglot@inria.fr
Expand All @@ -41,36 +47,86 @@ public class Main {
public static ReportJSON report = new ReportJSON();

public static void main(String[] args) {
JSAPOptions.parse(args);
final CtType<?> amplifiedTestClass = loadAmplifiedTestClass();
final List<CtMethod<?>> prettifiedAmplifiedTestMethods = run(amplifiedTestClass);
InputConfiguration inputConfiguration = new InputConfiguration();
final CommandLine commandLine = new CommandLine(inputConfiguration);
commandLine.setUsageHelpWidth(120);
try {
commandLine.parseArgs(args);
} catch (Exception e) {
e.printStackTrace();
commandLine.usage(System.err);
return;
}
if (commandLine.isUsageHelpRequested()) {
commandLine.usage(System.out);
return;
}
if (commandLine.isVersionHelpRequested()) {
commandLine.printVersionHelp(System.out);
return;
}
if (inputConfiguration.shouldRunExample()) {
inputConfiguration.configureExample();
}
try {
Checker.preChecking(inputConfiguration);
} catch (InputErrorException e) {
e.printStackTrace();
commandLine.usage(System.err);
return;
}
eu.stamp_project.Main.verbose = inputConfiguration.isVerbose();
run(inputConfiguration);
}

public static void run(InputConfiguration configuration) {
final CtType<?> amplifiedTestClass = loadAmplifiedTestClass(configuration);
final List<CtMethod<?>> prettifiedAmplifiedTestMethods =
run(
amplifiedTestClass,
configuration
);
// output now
output(amplifiedTestClass, prettifiedAmplifiedTestMethods);
output(amplifiedTestClass, prettifiedAmplifiedTestMethods, configuration);
}

public static CtType<?> loadAmplifiedTestClass() {
public static CtType<?> loadAmplifiedTestClass(InputConfiguration configuration) {
Launcher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.addInputResource(InputConfiguration.get().getPathToAmplifiedTestClass());
launcher.addInputResource(configuration.getPathToAmplifiedTestClass());
launcher.buildModel();
return launcher.getFactory().Class().getAll().get(0);
}

public static List<CtMethod<?>> run(CtType<?> amplifiedTestClass) {
public static List<CtMethod<?>> run(CtType<?> amplifiedTestClass,
InputConfiguration configuration) {

final AutomaticBuilder automaticBuilder = configuration.getBuilderEnum().getAutomaticBuilder(configuration);
final String dependencies = completeDependencies(configuration, automaticBuilder);
final DSpotCompiler compiler = DSpotCompiler.createDSpotCompiler(
configuration,
dependencies
);
configuration.setFactory(compiler.getLauncher().getFactory());
eu.stamp_project.Main.initHelpers(configuration);

final List<CtMethod<?>> testMethods = TestFramework.getAllTest(amplifiedTestClass);
Main.report.nbTestMethods = testMethods.size();
// 1 minimize amplified test methods
final List<CtMethod<?>> minimizedAmplifiedTestMethods = applyMinimization(
testMethods,
amplifiedTestClass
amplifiedTestClass,
configuration
);
// 2 rename test methods
applyCode2Vec(minimizedAmplifiedTestMethods);
applyCode2Vec(minimizedAmplifiedTestMethods, configuration);
// 3 Rename local variables TODO train one better model
return applyContext2Name(minimizedAmplifiedTestMethods);
}

public static List<CtMethod<?>> applyMinimization(List<CtMethod<?>> amplifiedTestMethodsToBeMinimized, CtType<?> amplifiedTestClass) {
public static List<CtMethod<?>> applyMinimization(List<CtMethod<?>> amplifiedTestMethodsToBeMinimized,
CtType<?> amplifiedTestClass,
InputConfiguration configuration) {

Main.report.medianNbStatementBefore = Main.getMedian(amplifiedTestMethodsToBeMinimized.stream()
.map(ctMethod -> ctMethod.getElements(new TypeFilter<>(CtStatement.class)))
Expand All @@ -86,8 +142,18 @@ public static List<CtMethod<?>> applyMinimization(List<CtMethod<?>> amplifiedTes
.forEach(amplifiedTestClass::removeMethod);
amplifiedTestMethodsToBeMinimized.forEach(amplifiedTestClass::addMethod);

final AutomaticBuilder automaticBuilder = configuration.getBuilderEnum().getAutomaticBuilder(configuration);
// 2nd apply a specific minimization
amplifiedTestMethodsToBeMinimized = Main.applyGivenMinimizer(new PitMutantMinimizer(amplifiedTestClass), amplifiedTestMethodsToBeMinimized);
amplifiedTestMethodsToBeMinimized = Main.applyGivenMinimizer(
new PitMutantMinimizer(
amplifiedTestClass,
automaticBuilder,
configuration.getAbsolutePathToProjectRoot(),
configuration.getClasspathClassesProject(),
configuration.getAbsolutePathToTestClasses()
),
amplifiedTestMethodsToBeMinimized
);

Main.report.medianNbStatementAfter = Main.getMedian(amplifiedTestMethodsToBeMinimized.stream()
.map(ctMethod -> ctMethod.getElements(new TypeFilter<>(CtStatement.class)))
Expand All @@ -105,12 +171,17 @@ private static List<CtMethod<?>> applyGivenMinimizer(Minimizer minimizer, List<C
return minimizedAmplifiedTestMethods;
}

public static void applyCode2Vec(List<CtMethod<?>> amplifiedTestMethodsToBeRenamed) {
Code2VecWriter writer = new Code2VecWriter();
public static void applyCode2Vec(List<CtMethod<?>> amplifiedTestMethodsToBeRenamed,
InputConfiguration configuration) {
Code2VecWriter writer = new Code2VecWriter(configuration.getPathToRootOfCode2Vec());
Code2VecParser parser = new Code2VecParser();
Code2VecExecutor code2VecExecutor = null;
try {
code2VecExecutor = new Code2VecExecutor();
code2VecExecutor = new Code2VecExecutor(
configuration.getPathToRootOfCode2Vec(),
configuration.getRelativePathToModelForCode2Vec(),
configuration.getTimeToWaitForCode2vecInMillis()
);
for (CtMethod<?> amplifiedTestMethodToBeRenamed : amplifiedTestMethodsToBeRenamed) {
writer.writeCtMethodToInputFile(amplifiedTestMethodToBeRenamed);
code2VecExecutor.run();
Expand Down Expand Up @@ -154,10 +225,13 @@ public static <T extends Number & Comparable<T>> Double getMedian(List<T> list)
new Double(list.stream().skip(list.size() / 2).findFirst().get().toString());
}

public static void output(CtType<?> amplifiedTestClass, List<CtMethod<?>> prettifiedAmplifiedTestMethods) {
PrettifiedTestMethods.output(amplifiedTestClass, prettifiedAmplifiedTestMethods);
public static void output(CtType<?> amplifiedTestClass,
List<CtMethod<?>> prettifiedAmplifiedTestMethods,
InputConfiguration configuration) {
new PrettifiedTestMethods(configuration.getOutputDirectory())
.output(amplifiedTestClass, prettifiedAmplifiedTestMethods);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
final String pathname = eu.stamp_project.utils.program.InputConfiguration.get().getOutputDirectory() +
final String pathname = configuration.getOutputDirectory() +
"/" + amplifiedTestClass.getSimpleName() + "report.json";
LOGGER.info("Output a report in {}", pathname);
final File file = new File(pathname);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,24 @@ public class Code2VecExecutor {

private ByteArrayOutputStream outStream;

private String pathToRootOfCode2Vec;

private String relativePathToModelForCode2Vec;

/**
* Construct the Code2VecExecutor.
* This class will initialize the model of Code2Vec, then provide an API to predict a name for a test method.
*/
public Code2VecExecutor() {
final String root = InputConfiguration.get().getPathToRootOfCode2Vec();
final String pathToModel = InputConfiguration.get().getRelativePathToModelForCode2Vec();

public Code2VecExecutor(String pathToRootOfCode2Vec,
String relativePathToModelForCode2Vec,
long timeoutForCode2VecInMillis) {
this.pathToRootOfCode2Vec = pathToRootOfCode2Vec;
this.relativePathToModelForCode2Vec = relativePathToModelForCode2Vec;
this.service = Executors.newSingleThreadExecutor();
try {
final String command = COMMAND_LINE + pathToModel + PREDICT_ARGUMENT;
this.code2vecProcess = Runtime.getRuntime().exec(command, (String[]) null, new File(root));
LOGGER.info("Executing: {} in {}", command, root);
final String command = COMMAND_LINE + this.relativePathToModelForCode2Vec + PREDICT_ARGUMENT;
this.code2vecProcess = Runtime.getRuntime().exec(command, (String[]) null, new File(this.pathToRootOfCode2Vec));
LOGGER.info("Executing: {} in {}", command, this.pathToRootOfCode2Vec);
} catch (IOException var12) {
throw new RuntimeException(var12);
}
Expand All @@ -58,8 +63,8 @@ public Code2VecExecutor() {
this.future = this.service.submit(this.task);
this.writer = new BufferedWriter(new OutputStreamWriter(this.code2vecProcess.getOutputStream()));
try {
LOGGER.info("Waiting {} seconds that code2vec is well initialized...", InputConfiguration.get().getTimeToWaitForCode2vecInMillis() / 1000);
Thread.sleep(InputConfiguration.get().getTimeToWaitForCode2vecInMillis());
LOGGER.info("Waiting {} seconds that code2vec is well initialized...", timeoutForCode2VecInMillis / 1000);
Thread.sleep(timeoutForCode2VecInMillis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ public class Code2VecWriter {

private static final Logger LOGGER = LoggerFactory.getLogger(Code2VecWriter.class);

private String pathToRootOfCode2Vec;

public Code2VecWriter(String pathToRootOfCove2Vec) {
this.pathToRootOfCode2Vec = DSpotUtils.shouldAddSeparator.apply(pathToRootOfCove2Vec);
}

/**
* write the given test method in the Input.java file.
* @param testMethod method to output in the file
*/
public void writeCtMethodToInputFile(CtMethod<?> testMethod) {
try {
final String fileName = InputConfiguration.get().getPathToRootOfCode2Vec() + FILENAME;
final String fileName = this.pathToRootOfCode2Vec + FILENAME;
LOGGER.info("Writing content of {} into {}.", testMethod.getSimpleName(), fileName);
FileWriter writer = new FileWriter(fileName, false);
writer.write(testMethod.toString());
Expand Down
Loading

0 comments on commit 0c8f83c

Please sign in to comment.