![JAR search and dependency download from the Maven repository](/logo.png)
org.evosuite.testcarver.extraction.CarvingManager Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see .
*/
package org.evosuite.testcarver.extraction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.evosuite.Properties;
import org.evosuite.classpath.ResourceList;
import org.evosuite.rmi.ClientServices;
import org.evosuite.rmi.service.ClientState;
import org.evosuite.testcarver.capture.FieldRegistry;
import org.evosuite.testcarver.testcase.CarvedTestCase;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.execution.ExecutionResult;
import org.evosuite.testcase.execution.TestCaseExecutor;
import org.evosuite.utils.LoggingUtils;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CarvingManager {
private static Logger logger = LoggerFactory.getLogger(CarvingManager.class);
private static CarvingManager instance = null;
private CarvingManager() {
}
public static CarvingManager getInstance() {
if(instance == null)
instance = new CarvingManager();
return instance;
}
private Map, List> carvedTests = new LinkedHashMap<>();
private boolean carvingDone = false;
private Collection getListOfJUnitClassNames() throws IllegalStateException {
String prop = Properties.SELECTED_JUNIT;
if (prop == null || prop.trim().isEmpty()) {
throw new IllegalStateException(
"Trying to use a test carver factory, but empty Properties.SELECTED_JUNIT");
}
String[] paths = prop.split(":");
Collection junitTestNames = new HashSet();
for (String s : paths) {
junitTestNames.add(s.trim());
}
/*
Pattern pattern = Pattern.compile(Properties.JUNIT_PREFIX+".*.class");
Collection junitTestNames = ResourceList.getResources(pattern);
logger.info("Found "+junitTestNames.size()+" candidate junit classes for pattern "+pattern);
*/
return junitTestNames;
}
private void chopException(TestCase test, ExecutionResult result) {
if (!result.noThrownExceptions()) {
// No code including or after an exception should be in the pool
Integer pos = result.getFirstPositionOfThrownException();
if (pos != null) {
test.chop(pos);
} else {
test.chop(test.size() - 1);
}
}
}
private void readTestCases() throws IllegalStateException {
ClientServices.getInstance().getClientNode().changeState(ClientState.CARVING);
Collection junitTestNames = getListOfJUnitClassNames();
LoggingUtils.getEvoLogger().info("* Executing tests from {} test {} for carving",
junitTestNames.size(), junitTestNames.size() == 1 ? "class" : "classes");
final JUnitCore runner = new JUnitCore();
final CarvingRunListener listener = new CarvingRunListener();
runner.addListener(listener);
final List> junitTestClasses = new ArrayList>();
final org.evosuite.testcarver.extraction.CarvingClassLoader classLoader = new org.evosuite.testcarver.extraction.CarvingClassLoader();
// TODO: This really needs to be done in a nicer way!
FieldRegistry.carvingClassLoader = classLoader;
try {
// instrument target class
classLoader.loadClass(Properties.TARGET_CLASS);
} catch (final ClassNotFoundException e) {
throw new RuntimeException(e);
}
for (String className : junitTestNames) {
String classNameWithDots = ResourceList.getClassNameFromResourcePath(className);
try {
final Class> junitClass = classLoader.loadClass(classNameWithDots);
junitTestClasses.add(junitClass);
} catch (ClassNotFoundException e) {
logger.error("Failed to load JUnit test class {}: {}", classNameWithDots, e);
}
}
final Class>[] classes = new Class>[junitTestClasses.size()];
junitTestClasses.toArray(classes);
Result result = runner.run(classes);
logger.info("Result: {}/{}", result.getFailureCount(), result.getRunCount());
for(Failure failure : result.getFailures()) {
logger.info("Failure: {}", failure.getMessage());
logger.info("Exception: {}", failure.getException());
}
Map, List> testMap = listener.getTestCases();
for(Class> targetClass : testMap.keySet()) {
List processedTests = new ArrayList<>();
for (TestCase test : testMap.get(targetClass)) {
String testName = ((CarvedTestCase)test).getName();
if (test.isEmpty())
continue;
ExecutionResult executionResult = null;
try {
executionResult = TestCaseExecutor.runTest(test);
} catch(Throwable t) {
logger.info("Error while executing carved test {}: {}", testName, t);
continue;
}
if (executionResult.noThrownExceptions()) {
logger.info("Adding carved test without exception");
logger.info(test.toCode());
processedTests.add(test);
} else {
logger.info("Exception thrown in carved test {}: {}", testName,
executionResult.getExceptionThrownAtPosition(executionResult.getFirstPositionOfThrownException()));
for (StackTraceElement elem : executionResult.getExceptionThrownAtPosition(executionResult.getFirstPositionOfThrownException()).getStackTrace()) {
logger.info(elem.toString());
}
logger.info(test.toCode(executionResult.exposeExceptionMapping()));
if (Properties.CHOP_CARVED_EXCEPTIONS) {
logger.info("Chopping exception of carved test");
chopException(test, executionResult);
if (test.hasObject(Properties.getTargetClassAndDontInitialise(), test.size())) {
processedTests.add(test);
} else {
logger.info("Chopped test is empty");
}
} else {
logger.info("Not adding carved test with exception: ");
}
}
}
// junitTests.addAll(listener.getTestCases());
if (processedTests.size() > 0) {
LoggingUtils.getEvoLogger().info(" -> Carved {} tests for class {} from existing JUnit tests",
processedTests.size(), targetClass);
if (logger.isDebugEnabled()) {
for (TestCase test : processedTests) {
logger.debug("Carved Test {}: {}", ((CarvedTestCase) test).getName(), test.toCode());
}
}
} else {
//String outcome = "";
//for (Failure failure : result.getFailures()) {
// outcome += "(" + failure.getDescription() + ", " + failure.getTrace()
// + ") ";
//}
logger.info("It was not possible to carve any test case for class {} from {}", targetClass.getName(),
Arrays.toString(junitTestNames.toArray()));
// + ". Test execution results: " + outcome);
}
carvedTests.put(targetClass, processedTests);
}
carvingDone = true;
// TODO: Argh.
FieldRegistry.carvingClassLoader = null;
// TODO:
// ClientNodeLocal client = ClientServices.getInstance().getClientNode();
// client.trackOutputVariable(RuntimeVariable.CarvedTests, totalNumberOfTestsCarved);
// client.trackOutputVariable(RuntimeVariable.CarvedCoverage,carvedCoverage);
}
public void clear() {
carvingDone = false;
carvedTests.clear();
}
public List getTestsForClass(Class> clazz) {
if(!carvingDone)
readTestCases();
if(!carvedTests.containsKey(clazz))
return new ArrayList();
return carvedTests.get(clazz);
}
public Set> getClassesWithTests() {
if(!carvingDone)
readTestCases();
return carvedTests.keySet();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy