Search in sources :

Example 1 with ConstructionFailedException

use of org.evosuite.ga.ConstructionFailedException in project evosuite by EvoSuite.

the class TestCluster method removeDirectCycle.

/**
 *			if a class X has a generator non-static method for Y, but, among its own generators for X it has one
 *			that uses Y as input, then do not use any non-static method of X as generator for Y.
 *			This is to avoid nasty cycles.
 *			For example, consider the case of:
 *
 *	 		<p>
 *			X(Y y){...} <br>
 *			Y getY(){...}
 *
 *	 		<p>
 *			If we need Y, we could end up using x.getY(), which for instantiating x would need a Y, which might
 *			end up in an infinite recursion...
 */
private void removeDirectCycle() {
    // check each generator Y
    for (Map.Entry<GenericClass, Set<GenericAccessibleObject<?>>> entry : generators.entrySet()) {
        if (entry.getValue().isEmpty()) {
            continue;
        }
        // for a given type Y, check all its generators X, like "Y x.getY()"
        Iterator<GenericAccessibleObject<?>> iter = entry.getValue().iterator();
        while (iter.hasNext()) {
            GenericAccessibleObject<?> gao = iter.next();
            // or at least make sure that we don't delete constructors.
            if (gao.isConstructor() || gao.isStatic()) {
                continue;
            }
            // eg X
            GenericClass owner = gao.getOwnerClass();
            try {
                cacheGenerators(owner);
            } catch (ConstructionFailedException e) {
                continue;
            }
            for (GenericAccessibleObject<?> genOwner : generatorCache.get(owner)) {
                if (genOwner.isStatic()) {
                    // as there is no need to instantiate X, it is not an issue
                    continue;
                }
                // is any generator for X using as input an instance of Y?
                if (Arrays.asList(genOwner.getGenericParameterTypes()).stream().anyMatch(t -> t.equals(entry.getKey().getType()))) {
                    iter.remove();
                    break;
                }
            }
        }
        if (entry.getValue().isEmpty()) {
            recursiveRemoveGenerators(entry.getKey());
        }
    }
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Example 2 with ConstructionFailedException

use of org.evosuite.ga.ConstructionFailedException in project evosuite by EvoSuite.

the class TestCluster method removeUnusableGenerators.

/**
 * A generator for X might be a non-static method M of Y, but what if Y itself has no generator?
 * In that case, M should not be a generator for X, as it is impossible to instantiate Y
 */
public void removeUnusableGenerators() {
    generatorCache.clear();
    Set<GenericClass> removed = new LinkedHashSet<>();
    for (Map.Entry<GenericClass, Set<GenericAccessibleObject<?>>> entry : generators.entrySet()) {
        if (entry.getValue().isEmpty()) {
            recursiveRemoveGenerators(entry.getKey());
        }
        Set<GenericClass> toRemove = new LinkedHashSet<>();
        for (GenericAccessibleObject<?> gao : entry.getValue()) {
            GenericClass owner = gao.getOwnerClass();
            if (removed.contains(owner)) {
                continue;
            }
            try {
                cacheGenerators(owner);
            } catch (ConstructionFailedException e) {
                continue;
            }
            if (generatorCache.get(owner).isEmpty()) {
                toRemove.add(owner);
            }
        }
        for (GenericClass tr : toRemove) {
            recursiveRemoveGenerators(tr);
            removed.add(tr);
        }
    }
    removeOnlySelfGenerator();
    removeDirectCycle();
    generatorCache.clear();
}
Also used : GenericClass(org.evosuite.utils.generic.GenericClass) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Example 3 with ConstructionFailedException

use of org.evosuite.ga.ConstructionFailedException in project evosuite by EvoSuite.

the class TestCluster method getRandomGenerator.

/**
 * Randomly select one generator
 *
 * @param clazz
 * @param excluded
 * @param test
 * @return {@code null} if there is no valid generator
 * @throws ConstructionFailedException
 */
public GenericAccessibleObject<?> getRandomGenerator(GenericClass clazz, Set<GenericAccessibleObject<?>> excluded, TestCase test, int position, VariableReference generatorRefToExclude, int recursionDepth) throws ConstructionFailedException {
    logger.debug("Getting random generator for " + clazz);
    // Instantiate generics
    if (clazz.hasWildcardOrTypeVariables()) {
        logger.debug("Target class is generic: " + clazz);
        GenericClass concreteClass = clazz.getGenericInstantiation();
        if (!concreteClass.equals(clazz)) {
            logger.debug("Target class is generic: " + clazz + ", getting instantiation " + concreteClass);
            return getRandomGenerator(concreteClass, excluded, test, position, generatorRefToExclude, recursionDepth);
        }
    }
    GenericAccessibleObject<?> generator = null;
    // Collection, Map, Number
    if (isSpecialCase(clazz)) {
        generator = Randomness.choice(getGeneratorsForSpecialCase(clazz));
        if (generator == null) {
            logger.warn("No generator for special case class: " + clazz);
            throw new ConstructionFailedException("Have no generators for special case: " + clazz);
        }
    } else {
        cacheGenerators(clazz);
        Set<GenericAccessibleObject<?>> candidates = new LinkedHashSet<>(generatorCache.get(clazz));
        candidates.removeAll(excluded);
        if (Properties.JEE) {
            Iterator<GenericAccessibleObject<?>> iter = candidates.iterator();
            while (iter.hasNext()) {
                GenericAccessibleObject<?> gao = iter.next();
                if (gao instanceof GenericConstructor) {
                    Class<?> klass = gao.getDeclaringClass();
                    if (InstanceOnlyOnce.canInstantiateOnlyOnce(klass) && ConstraintHelper.countNumberOfNewInstances(test, klass) != 0) {
                        iter.remove();
                    }
                }
                if (!ConstraintVerifier.isValidPositionForInsertion(gao, test, position)) {
                    iter.remove();
                }
            }
        }
        if (generatorRefToExclude != null) {
            Iterator<GenericAccessibleObject<?>> iter = candidates.iterator();
            while (iter.hasNext()) {
                GenericAccessibleObject<?> gao = iter.next();
                // if current generator could be called from excluded ref, then we cannot use it
                if (generatorRefToExclude.isAssignableTo(gao.getOwnerType())) {
                    iter.remove();
                }
            }
        }
        logger.debug("Candidate generators for " + clazz + ": " + candidates.size());
        if (candidates.isEmpty()) {
            return null;
        }
        if (recursionDepth >= Properties.MAX_RECURSION / 2) {
            /*
					if going long into the recursion, then do prefer direct constructors or static methods,
					as non-static methods would require to get a caller which, if it is missing, would need
					to be created, and that could lead to further calls if its generators need input parameters
				 */
            Set<GenericAccessibleObject<?>> set = candidates.stream().filter(p -> p.isStatic() || p.isConstructor()).collect(Collectors.toCollection(() -> new LinkedHashSet<GenericAccessibleObject<?>>()));
            if (!set.isEmpty()) {
                candidates = set;
            }
        }
        generator = Randomness.choice(candidates);
        logger.debug("Chosen generator: " + generator);
    }
    if (generator.getOwnerClass().hasWildcardOrTypeVariables()) {
        logger.debug("Owner class has a wildcard: " + clazz.getTypeName());
        generator = generator.copyWithNewOwner(generator.getOwnerClass().getGenericInstantiation());
    }
    if (generator.hasTypeParameters()) {
        logger.debug("Generator has a type parameter: " + generator);
        generator = generator.getGenericInstantiationFromReturnValue(clazz);
        if (!generator.getGeneratedClass().isAssignableTo(clazz)) {
            throw new ConstructionFailedException("Generics error");
        }
    }
    return generator;
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass) java.util(java.util) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException) InstanceOnlyOnce(org.evosuite.testcase.jee.InstanceOnlyOnce) LoggerFactory(org.slf4j.LoggerFactory) Archive(org.evosuite.ga.archive.Archive) Constructor(java.lang.reflect.Constructor) GenericMethod(org.evosuite.utils.generic.GenericMethod) ConstraintHelper(org.evosuite.testcase.ConstraintHelper) TestCase(org.evosuite.testcase.TestCase) CoverageAnalysis(org.evosuite.junit.CoverageAnalysis) AtMostOnceLogger(org.evosuite.runtime.util.AtMostOnceLogger) Properties(org.evosuite.Properties) Logger(org.slf4j.Logger) VariableReference(org.evosuite.testcase.variable.VariableReference) Inputs(org.evosuite.runtime.util.Inputs) GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) CastClassManager(org.evosuite.seeding.CastClassManager) Collectors(java.util.stream.Collectors) Randomness(org.evosuite.utils.Randomness) TestGenerationContext(org.evosuite.TestGenerationContext) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) ListUtil(org.evosuite.utils.ListUtil) Type(java.lang.reflect.Type) Entry(java.util.Map.Entry) ConstraintVerifier(org.evosuite.testcase.ConstraintVerifier) GenericClass(org.evosuite.utils.generic.GenericClass) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Example 4 with ConstructionFailedException

use of org.evosuite.ga.ConstructionFailedException in project evosuite by EvoSuite.

the class TestCluster method getObjectGenerators.

/**
 * Determine the set of generators for an Object.class instance
 *
 * @return a collection of all cast classes stored in {@link CastClassManager}; cannot be <code>null</code>>.
 */
public Set<GenericAccessibleObject<?>> getObjectGenerators() {
    // TODO: Use probabilities based on distance to SUT
    Set<GenericAccessibleObject<?>> result = new LinkedHashSet<>();
    List<GenericClass> classes = new ArrayList<>(CastClassManager.getInstance().getCastClasses());
    for (GenericClass clazz : classes) {
        try {
            result.addAll(getGenerators(clazz, true));
        } catch (ConstructionFailedException e) {
        // ignore
        }
    }
    try {
        result.addAll(getGenerators(new GenericClass(Object.class), true));
    } catch (ConstructionFailedException e) {
    // ignore
    }
    return result;
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Example 5 with ConstructionFailedException

use of org.evosuite.ga.ConstructionFailedException in project evosuite by EvoSuite.

the class TestFactory method addFieldFor.

/**
 * Add reference to a field of variable "callee"
 *
 * @param test
 * @param callee
 * @param field
 * @param position
 * @return
 * @throws ConstructionFailedException
 */
public VariableReference addFieldFor(TestCase test, VariableReference callee, GenericField field, int position) throws ConstructionFailedException {
    logger.debug("Adding field " + field + " for variable " + callee);
    if (position <= callee.getStPosition())
        throw new ConstructionFailedException("Cannot insert call on object before the object is defined");
    currentRecursion.clear();
    FieldReference fieldVar = new FieldReference(test, field, callee);
    int length = test.size();
    VariableReference value = createOrReuseVariable(test, fieldVar.getType(), position, 0, callee, true, false, true);
    int newLength = test.size();
    position += (newLength - length);
    Statement st = new AssignmentStatement(test, fieldVar, value);
    VariableReference ret = test.addStatement(st, position);
    ret.setDistance(callee.getDistance() + 1);
    assert (test.isValid());
    return ret;
}
Also used : PrivateMethodStatement(org.evosuite.testcase.statements.reflection.PrivateMethodStatement) PrivateFieldStatement(org.evosuite.testcase.statements.reflection.PrivateFieldStatement) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Aggregations

ConstructionFailedException (org.evosuite.ga.ConstructionFailedException)43 GenericClass (org.evosuite.utils.generic.GenericClass)16 PrivateFieldStatement (org.evosuite.testcase.statements.reflection.PrivateFieldStatement)14 PrivateMethodStatement (org.evosuite.testcase.statements.reflection.PrivateMethodStatement)14 CaptureType (com.googlecode.gentyref.CaptureType)11 GenericAccessibleObject (org.evosuite.utils.generic.GenericAccessibleObject)11 GenericMethod (org.evosuite.utils.generic.GenericMethod)10 ArrayList (java.util.ArrayList)8 GenericField (org.evosuite.utils.generic.GenericField)7 TestFactory (org.evosuite.testcase.TestFactory)6 GenericConstructor (org.evosuite.utils.generic.GenericConstructor)6 TestCase (org.evosuite.testcase.TestCase)4 VariableReference (org.evosuite.testcase.variable.VariableReference)4 Type (java.lang.reflect.Type)3 GenericArrayType (java.lang.reflect.GenericArrayType)2 ParameterizedType (java.lang.reflect.ParameterizedType)2 TypeVariable (java.lang.reflect.TypeVariable)2 WildcardType (java.lang.reflect.WildcardType)2 List (java.util.List)2 Collectors (java.util.stream.Collectors)2