use of fr.inria.stamp.test.listener.TestListener in project dspot by STAMP-project.
the class ChangeDetectorSelector method selectToKeep.
@Override
public List<CtMethod<?>> selectToKeep(List<CtMethod<?>> amplifiedTestToBeKept) {
if (amplifiedTestToBeKept.isEmpty()) {
return amplifiedTestToBeKept;
}
CtType clone = this.currentClassTestToBeAmplified.clone();
clone.setParent(this.currentClassTestToBeAmplified.getParent());
this.currentClassTestToBeAmplified.getMethods().stream().filter(AmplificationChecker::isTest).forEach(clone::removeMethod);
amplifiedTestToBeKept.forEach(clone::addMethod);
DSpotUtils.printCtTypeToGivenDirectory(clone, new File(DSpotCompiler.pathToTmpTestSources));
final String classpath = AutomaticBuilderFactory.getAutomaticBuilder(this.configuration).buildClasspath(this.program.getProgramDir()) + AmplificationHelper.PATH_SEPARATOR + "target/dspot/dependencies/";
DSpotCompiler.compile(DSpotCompiler.pathToTmpTestSources, classpath + AmplificationHelper.PATH_SEPARATOR + this.program.getProgramDir() + "/" + this.program.getClassesDir() + AmplificationHelper.PATH_SEPARATOR + this.program.getProgramDir() + "/" + this.program.getTestClassesDir(), new File(this.pathToChangedVersionOfProgram + "/" + this.program.getTestClassesDir()));
final TestListener results = TestLauncher.run(this.configuration, classpath + AmplificationHelper.PATH_SEPARATOR + this.pathToChangedVersionOfProgram + "/" + this.program.getClassesDir() + AmplificationHelper.PATH_SEPARATOR + this.pathToChangedVersionOfProgram + "/" + this.program.getTestClassesDir(), clone, amplifiedTestToBeKept.stream().map(CtNamedElement::getSimpleName).collect(Collectors.toList()));
if (!results.getFailingTests().isEmpty()) {
results.getFailingTests().forEach(failure -> this.failurePerAmplifiedTest.put(amplifiedTestToBeKept.stream().filter(ctMethod -> ctMethod.getSimpleName().equals(failure.getDescription().getMethodName())).findFirst().get(), failure));
}
return amplifiedTestToBeKept;
}
use of fr.inria.stamp.test.listener.TestListener in project dspot by STAMP-project.
the class JacocoExecutor method executeJacoco.
public CoverageResults executeJacoco(CtType<?> testClass) {
final String testClassesDirectory = this.program.getProgramDir() + "/" + this.program.getTestClassesDir();
final RuntimeData data = new RuntimeData();
final ExecutionDataStore executionData = new ExecutionDataStore();
final SessionInfoStore sessionInfos = new SessionInfoStore();
URLClassLoader classLoader;
try {
classLoader = new URLClassLoader(new URL[] { new File(testClassesDirectory).toURI().toURL() }, this.internalClassLoader);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
final String resource = testClass.getQualifiedName().replace('.', '/') + ".class";
try {
this.internalClassLoader.addDefinition(testClass.getQualifiedName(), IOUtils.toByteArray(classLoader.getResourceAsStream(resource)));
runtime.startup(data);
final TestListener listener = TestLauncher.run(this.configuration, this.internalClassLoader, testClass);
if (!listener.getFailingTests().isEmpty()) {
LOGGER.warn("Some test(s) failed during computation of coverage:" + AmplificationHelper.LINE_SEPARATOR + listener.getFailingTests().stream().map(Failure::toString).collect(Collectors.joining(AmplificationHelper.LINE_SEPARATOR)));
}
data.collect(executionData, sessionInfos, false);
runtime.shutdown();
clearCache(this.internalClassLoader);
return coverageResults(executionData);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of fr.inria.stamp.test.listener.TestListener in project dspot by STAMP-project.
the class JacocoExecutor method executeJacoco.
public Map<String, CoverageResults> executeJacoco(CtType<?> testClass, Collection<String> methodNames) {
final String testClassesDirectory = this.program.getProgramDir() + "/" + this.program.getTestClassesDir();
final String classesDirectory = this.program.getProgramDir() + "/" + this.program.getClassesDir();
URLClassLoader classLoader;
try {
classLoader = new URLClassLoader(new URL[] { new File(testClassesDirectory).toURI().toURL() }, this.internalClassLoader);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
final String resource = testClass.getQualifiedName().replace('.', '/') + ".class";
try {
this.internalClassLoader.addDefinition(testClass.getQualifiedName(), IOUtils.toByteArray(classLoader.getResourceAsStream(resource)));
final RuntimeData data = new RuntimeData();
this.runtime.startup(data);
final JacocoListener jacocoListener = new JacocoListener(data, classesDirectory);
final TestListener listener = TestLauncher.run(this.configuration, this.internalClassLoader, testClass, methodNames, jacocoListener);
if (!listener.getFailingTests().isEmpty()) {
LOGGER.warn("Some test(s) failed during computation of coverage:" + AmplificationHelper.LINE_SEPARATOR + listener.getFailingTests().stream().map(Failure::toString).collect(Collectors.joining(AmplificationHelper.LINE_SEPARATOR)));
}
this.runtime.shutdown();
clearCache(this.internalClassLoader);
return jacocoListener.getCoverageResultsMap();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of fr.inria.stamp.test.listener.TestListener in project dspot by STAMP-project.
the class Amplification method preAmplification.
/**
* Adds new assertions in multiple tests.
*
* <p>Makes sure the test suite is valid before the assertion amplification {@link AssertGenerator#generateAsserts(CtType, List)}.
*
* @param classTest Test class
* @param tests New test methods
* @retur Valid amplified tests
* @throws IOException
* @throws ClassNotFoundException
*/
private List<CtMethod<?>> preAmplification(CtType classTest, List<CtMethod<?>> tests) throws IOException, ClassNotFoundException {
TestListener result = compileAndRunTestsNoFail(classTest, tests);
if (result == null) {
LOGGER.warn("Need a green test suite to run dspot");
return Collections.emptyList();
}
if (!result.getFailingTests().isEmpty()) {
LOGGER.warn("{} tests failed before the amplifications", result.getFailingTests().size());
LOGGER.warn("{}", result.getFailingTests().stream().map(Object::toString).collect(Collectors.joining(System.getProperty("line.separator"))));
LOGGER.warn("Discarding following test cases for the amplification");
result.getFailingTests().stream().map(Failure::getDescription).map(Description::getMethodName).forEach(failure -> {
try {
CtMethod testToRemove = tests.stream().filter(m -> failure.equals(m.getSimpleName())).findFirst().get();
tests.remove(tests.indexOf(testToRemove));
LOGGER.warn("{}", testToRemove.getSimpleName());
} catch (Exception ignored) {
// ignored
}
});
return preAmplification(classTest, tests);
} else {
LOGGER.info("Try to add assertions before amplification");
final List<CtMethod<?>> amplifiedTestToBeKept = assertGenerator.generateAsserts(classTest, testSelector.selectToAmplify(tests));
if (!amplifiedTestToBeKept.isEmpty()) {
result = compileAndRunTestsNoFail(classTest, amplifiedTestToBeKept);
if (result == null) {
LOGGER.warn("Need a green test suite to run dspot");
return Collections.emptyList();
}
}
testSelector.selectToKeep(amplifiedTestToBeKept);
return testSelector.getAmplifiedTestCases();
}
}
use of fr.inria.stamp.test.listener.TestListener in project dspot by STAMP-project.
the class DefaultTestRunner method run.
@Override
public TestListener run(Class<?> testClass, Collection<String> testMethodNames, RunListener... additionalListeners) {
ExecutorService executor = Executors.newSingleThreadExecutor();
TestListener listener = new TestListener();
final Future<?> submit = executor.submit(() -> {
Request request = Request.aClass(testClass);
if (!testMethodNames.isEmpty()) {
request = request.filterWith(new MethodFilter(testMethodNames));
}
Runner runner = request.getRunner();
RunNotifier runNotifier = new RunNotifier();
Arrays.stream(additionalListeners).forEach(runNotifier::addListener);
runNotifier.addFirstListener(listener);
// Since we want to use our custom ClassLoader to run the tests of the project being executed by DSpot,
// and since we create a new thread for starting the JUnit Runner, we need to set the context ClassLoader
// to be our custom ClassLoader. This is so that any code in the tests or triggered by the test that uses
// the context ClassLoader will work.
// As an example if the tests call some code that uses Java's ServiceLoader then it would fail to find and
// load any provider located in our custom ClassLoader.
Thread.currentThread().setContextClassLoader(this.classLoader);
runner.run(runNotifier);
});
try {
long timeBeforeTimeOut = testMethodNames.isEmpty() ? AmplificationHelper.getTimeOutInMs() * (testClass.getMethods().length + 1) : AmplificationHelper.getTimeOutInMs() * (testMethodNames.size() + 1);
submit.get(timeBeforeTimeOut, TimeUnit.MILLISECONDS);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
submit.cancel(true);
executor.shutdownNow();
}
return listener;
}
Aggregations