![JAR search and dependency download from the Maven repository](/logo.png)
org.evosuite.seeding.ObjectPool 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.seeding;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.file.Paths;
import java.util.*;
import be.vibes.dsl.io.Xml;
import be.vibes.dsl.selection.Dissimilar;
import be.vibes.ts.Action;
import be.vibes.ts.TestSet;
import be.vibes.ts.Transition;
import be.vibes.ts.UsageModel;
import org.apache.commons.lang3.StringUtils;
import org.evosuite.Properties;
import org.evosuite.TestGenerationContext;
import org.evosuite.setup.TestClusterUtils;
import org.evosuite.testcarver.extraction.CarvingRunListener;
import org.evosuite.testcase.DefaultTestCase;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.TestChromosome;
import org.evosuite.testcase.TestFactory;
import org.evosuite.testsuite.TestSuiteChromosome;
import org.evosuite.utils.DebuggingObjectOutputStream;
import org.evosuite.utils.LoggingUtils;
import org.evosuite.utils.generic.GenericClass;
import org.evosuite.utils.Randomness;
import org.evosuite.utils.generic.GenericConstructor;
import org.evosuite.utils.generic.GenericMethod;
import org.junit.runner.JUnitCore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Pool of interesting method sequences for different objects
*
* @author Gordon Fraser
*/
public class ObjectPool implements Serializable {
private static final long serialVersionUID = 2016387518459994272L;
/** The actual object pool */
protected final Map> pool = new HashMap>();
protected final Map> usedPool = new HashMap>();
public final Map abstractTests = new HashMap();
protected static final Logger logger = LoggerFactory.getLogger(ObjectPool.class);
/**
* Insert a new sequence for given Type
*
* @param clazz
* a {@link java.lang.reflect.Type} object.
* @param sequence
* a {@link org.evosuite.testcase.TestCase} object.
*/
public void addSequence(GenericClass clazz, TestCase sequence) {
ObjectSequence seq = new ObjectSequence(clazz, sequence);
addSequence(seq);
}
public void addAbstractTest(String className, TestSet abstractTests){
this.abstractTests.put(className,abstractTests);
}
protected void concretizeTest(be.vibes.ts.TestCase abstractTestCase, HashSet alreadyConcretized){
if (alreadyConcretized == null){
alreadyConcretized = new HashSet<>();
}
TestCase newTestCase = new DefaultTestCase();
GenericClass genericClass = null;
for (Transition transition : abstractTestCase) {
Action sequence = transition.getAction();
if (sequence.getName().indexOf(".") != -1) {
// Class name:
String className = sequence.getName().substring(0, sequence.getName().indexOf("("));
className = className.substring(0, className.lastIndexOf('.'));
// Method name:`
String methodName = StringUtils.substringAfterLast(sequence.getName().substring(0, sequence.getName().indexOf("(")), ".");
String paramString = sequence.getName().substring(sequence.getName().indexOf("(") + 1);
// Params:
paramString = paramString.substring(0, paramString.indexOf(")"));
String[] paramArr = paramString.split(",");
// try {
//Getting the Class
Class> sequenceClass = null;
try {
sequenceClass = Class.forName(className, true, TestGenerationContext.getInstance().getClassLoaderForSUT());
} catch (ClassNotFoundException | ExceptionInInitializerError | NoClassDefFoundError e) {
logger.debug("could not load " + className);
}
if (sequenceClass != null) {
genericClass = new GenericClass(sequenceClass);
//Getting methods
Set methods = TestClusterUtils.getMethods(sequenceClass);
//Getting Constructors
Set> constructors = TestClusterUtils.getConstructors(sequenceClass);
// find the method that we want
Method target = null;
for (Method m : methods) {
if (m.getName().equals(methodName)) {
target = m;
break;
} else {
target = null;
}
}
// Find the constructor that we want
Constructor targetC = null;
for (Constructor c : constructors) {
boolean same = true;
int counter = 0;
for (Class> cl : c.getParameterTypes()) {
if (paramArr.length > counter && !cl.getName().equals(paramArr[counter])) {
same = false;
}
counter++;
}
if (same) {
targetC = c;
break;
}
}
if (target != null) {
GenericMethod genericMethod = new GenericMethod(target, sequenceClass);
try {
TestFactory.getInstance().addMethod(newTestCase, genericMethod, newTestCase.size(), 0);
logger.debug("method call {} is added", genericMethod.getName());
} catch (Exception e) {
logger.debug("Error in addidng " + genericMethod.getName() + " " + e.getMessage());
}
} else if (targetC != null) {
GenericConstructor genericConstructor = new GenericConstructor(targetC, sequenceClass);
try {
TestFactory.getInstance().addConstructor(newTestCase, genericConstructor, newTestCase.size(), 0);
logger.debug("constructor {} is added", genericConstructor.getName());
} catch (Exception e) {
logger.debug("Error in addidng " + genericConstructor.getName() + " " + e.getMessage());
}
} else {
logger.debug("Fail to add the call to add!");
}
}
}
}
// Add test case to pool
if (genericClass != null){
logger.debug("New test case added for class {}",genericClass.getClassName());
try{
String testCode = newTestCase.toCode();
logger.debug("Add the following tests case to the object pool of class {}: {}",genericClass.getClassName(),testCode);
if(!alreadyConcretized.contains(testCode)) {
this.addSequence(genericClass, newTestCase);
alreadyConcretized.add(testCode);
}
}catch (Exception e){
logger.debug("The generated test case is not valid.");
}
}
}
private void reConcretizeTests(String clazz){
HashSet alreadyConcretized = new HashSet<>();
TestSet ts = this.abstractTests.get(clazz);
for (int i=0; i());
pool.get(sequence.getGeneratedClass()).add(sequence.getSequence());
logger.info("Added new sequence for " + sequence.getGeneratedClass());
logger.info(sequence.getSequence().toCode());
}
public void resetUsedSequences(GenericClass clazz){
for (TestCase seq: usedPool.get(clazz)){
getSequences(clazz).add(seq);
}
usedPool.get(clazz).clear();
// LoggingUtils.getEvoLogger().info(clazz.getClassName()+" pool resetting.");
}
/**
* Randomly choose a sequence for a given Type
*
* @param clazz
* a {@link java.lang.reflect.Type} object.
* @return a {@link org.evosuite.testcase.TestCase} object.
*/
public TestCase getRandomSequence(GenericClass clazz) {
if(Properties.MODEL_PATH != null){
if (getSequences(clazz).size() == 0) {
resetUsedSequences(clazz);
// refillSequences(clazz);
// reConcretizeTests(clazz.getClassName());
}
TestCase result = Randomness.choice(getSequences(clazz));
getSequences(clazz).remove(result);
if (!usedPool.containsKey(clazz))
usedPool.put(clazz, new HashSet());
usedPool.get(clazz).add(result);
// LoggingUtils.getEvoLogger().info("using sequence {} of object {}.",result.toCode(),clazz.getClassName());
return result;
}else{
return Randomness.choice(getSequences(clazz));
}
}
private void refillSequences(GenericClass clazz) {
File folder = new File(Properties.MODEL_PATH);
String modelPath=Paths.get(folder.getAbsolutePath(), clazz.getClassName()+".xml").toString();
fillObjectPool(clazz,modelPath);
}
/**
* Retrieve all possible sequences for a given Type
*
* @param clazz
* a {@link java.lang.reflect.Type} object.
* @return a {@link java.util.Set} object.
*/
public Set getSequences(GenericClass clazz) {
if (pool.containsKey(clazz))
return pool.get(clazz);
Set> candidates = new LinkedHashSet>();
for (GenericClass poolClazz : pool.keySet()) {
if (poolClazz.isAssignableTo(clazz))
candidates.add(pool.get(poolClazz));
}
return Randomness.choice(candidates);
}
public Set getClasses() {
return pool.keySet();
}
/**
* Check if there are sequences for given Type
*
* @param clazz
* a {@link java.lang.reflect.Type} object.
* @return a boolean.
*/
public boolean hasSequence(GenericClass clazz) {
if (pool.containsKey(clazz))
return true;
for (GenericClass poolClazz : pool.keySet()) {
if (poolClazz.isAssignableTo(clazz))
return true;
}
return false;
}
public int getNumberOfClasses() {
return pool.size();
}
public int getNumberOfSequences(GenericClass clazz) {
int nonUsed = 0;
int used = 0;
if(pool.containsKey(clazz)){
nonUsed = pool.get(clazz).size();
}
if(usedPool.containsKey(clazz)){
used = usedPool.size();
}
return used+nonUsed;
}
public int getNumberOfSequences() {
int num = 0;
for (Set p : pool.values()) {
num += p.size();
}
return num;
}
public boolean isEmpty() {
return pool.isEmpty();
}
/**
* Read a serialized pool
*
* @param fileName
*/
public static ObjectPool getPoolFromFile(String fileName) {
try {
InputStream in = new FileInputStream(fileName);
ObjectInputStream objectIn = new ObjectInputStream(in);
ObjectPool pool = (ObjectPool) objectIn.readObject();
in.close();
// TODO: Do we also need to call that in the other factory methods?
pool.filterUnaccessibleTests();
return pool;
} catch (Exception e) {
logger.error("Exception while trying to get object pool from " + fileName
+ " , " + e.getMessage(), e);
}
return null;
}
protected void filterUnaccessibleTests() {
for(Set testSet : pool.values()) {
Iterator testIterator = testSet.iterator();
while(testIterator.hasNext()) {
TestCase currentTest = testIterator.next();
if(!currentTest.isAccessible()) {
logger.info("Removing test containing inaccessible elements");
testIterator.remove();
}
}
}
}
/**
* Convert a test suite to a pool
*
* @param testSuite
*/
public static ObjectPool getPoolFromTestSuite(TestSuiteChromosome testSuite) {
ObjectPool pool = new ObjectPool();
for (TestChromosome testChromosome : testSuite.getTestChromosomes()) {
TestCase test = testChromosome.getTestCase().clone();
test.removeAssertions();
/*
if (testChromosome.hasException()) {
// No code including or after an exception should be in the pool
Integer pos = testChromosome.getLastExecutionResult().getFirstPositionOfThrownException();
if (pos != null) {
test.chop(pos);
} else {
test.chop(test.size() - 1);
}
}
*/
Class> targetClass = Properties.getTargetClassAndDontInitialise();
if (!testChromosome.hasException()
&& test.hasObject(targetClass, test.size())) {
pool.addSequence(new GenericClass(targetClass), test);
}
}
return pool;
}
/**
* Execute all tests in a JUnit test suite and add resulting sequences from
* carver
*
* @param targetClass
* @param testSuite
*/
public static ObjectPool getPoolFromJUnit(GenericClass targetClass, Class> testSuite) {
final JUnitCore runner = new JUnitCore();
final CarvingRunListener listener = new CarvingRunListener();
runner.addListener(listener);
final org.evosuite.testcarver.extraction.CarvingClassLoader classLoader = new org.evosuite.testcarver.extraction.CarvingClassLoader();
try {
// instrument target class
classLoader.loadClass(Properties.TARGET_CLASS);
} catch (final ClassNotFoundException e) {
throw new RuntimeException(e);
}
ObjectPool pool = new ObjectPool();
//final Result result =
runner.run(testSuite);
for (TestCase test : listener.getTestCases().get(Properties.getTargetClassAndDontInitialise())) {
// TODO: Maybe we would get the targetClass from the last object generated in the sequence?
pool.addSequence(targetClass, test);
}
// TODO: Some messages based on result
return pool;
}
public void writePool(String fileName) {
try {
ObjectOutputStream out = new DebuggingObjectOutputStream(
new FileOutputStream(fileName));
out.writeObject(this);
out.close();
} catch (IOException e) {
logger.warn("Error while writing pool to file "+fileName+": "+e);
}
}
protected void fillObjectPool(GenericClass clazz, String modelPath) {
Properties.ALLOW_OBJECT_POOL_USAGE=false;
try {
UsageModel um = Xml.loadUsageModel(modelPath);
TestSet ts = Dissimilar.from(um).withGlobalMaxDistance(Dissimilar.jaccard()).during(500).generate(Properties.POPULATION);
HashSet alreadyConcretized = new HashSet<>();
for (be.vibes.ts.TestCase abstractTestCase : ts) {
concretizeTest(abstractTestCase,alreadyConcretized);
}
}catch (Exception e) {
logger.debug("Could not load model " + clazz.getClassName());
}finally {
Properties.ALLOW_OBJECT_POOL_USAGE=true;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy