Search in sources :

Example 1 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject 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 GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject 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 3 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject 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 4 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject in project evosuite by EvoSuite.

the class TestCluster method sortCalls.

/**
 * Sort by remaining uncovered goals to bias search towards most rewarding methods
 *
 * @param testMethods
 * @return
 */
private List<GenericAccessibleObject<?>> sortCalls(List<GenericAccessibleObject<?>> testMethods) {
    // TODO: This can be done more efficiently, but we're just trying to see if this makes a difference at all
    Map<GenericAccessibleObject<?>, String> mapCallToName = new LinkedHashMap<>();
    for (GenericAccessibleObject<?> call : testMethods) {
        String name = call.getDeclaringClass().getCanonicalName();
        if (call.isMethod()) {
            GenericMethod method = (GenericMethod) call;
            name += method.getNameWithDescriptor();
        } else if (call.isConstructor()) {
            GenericConstructor constructor = (GenericConstructor) call;
            name += constructor.getNameWithDescriptor();
        } else {
            throw new RuntimeException("Coverage goals must be methods or constructors");
        }
        mapCallToName.put(call, name);
    }
    Map<String, Integer> mapMethodToGoals = new LinkedHashMap<>();
    for (String methodName : mapCallToName.values()) {
        // MethodKey is class+method+desc
        mapMethodToGoals.put(methodName, Archive.getArchiveInstance().getNumOfRemainingTargets(methodName));
    }
    return testMethods.stream().sorted(Comparator.comparingInt(item -> mapMethodToGoals.get(mapCallToName.get(item))).reversed()).collect(Collectors.toList());
}
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) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) GenericMethod(org.evosuite.utils.generic.GenericMethod)

Example 5 with GenericAccessibleObject

use of org.evosuite.utils.generic.GenericAccessibleObject in project evosuite by EvoSuite.

the class EnvironmentTestClusterAugmenter method addEnvironmentClassToCluster.

/**
 * Add the given klass to the test cluster. Also recursively add (as
 * modifiers) all the other EvoSuite classes for which the given class is a
 * generator
 *
 * @param klass
 */
private boolean addEnvironmentClassToCluster(Class<?> klass) {
    if (handledClasses.contains(klass.getCanonicalName()) || !TestClusterUtils.isEvoSuiteClass(klass)) {
        // already handled, or not valid
        return false;
    }
    handledClasses.add(klass.getCanonicalName());
    boolean excludeClass = klass.getAnnotation(EvoSuiteClassExclude.class) != null;
    for (Constructor c : klass.getConstructors()) {
        // first check if it should be skipped
        if (shouldSkip(excludeClass, c)) {
            continue;
        }
        GenericAccessibleObject gc = new GenericConstructor(c, klass);
        TestCluster.getInstance().addEnvironmentTestCall(gc);
        GenericClass genclass = new GenericClass(klass);
        TestCluster.getInstance().invalidateGeneratorCache(genclass);
        TestCluster.getInstance().addGenerator(genclass, gc);
        testClusterGenerator.addNewDependencies(Arrays.asList(c.getParameterTypes()));
    }
    for (Method m : klass.getMethods()) {
        if (shouldSkip(excludeClass, m)) {
            continue;
        }
        GenericAccessibleObject gm = new GenericMethod(m, klass);
        TestCluster.getInstance().addEnvironmentTestCall(gm);
        testClusterGenerator.addNewDependencies(Arrays.asList(m.getParameterTypes()));
        Class<?> returnType = m.getReturnType();
        if (!returnType.equals(Void.TYPE)) {
            GenericClass genclass = new GenericClass(returnType);
            TestCluster.getInstance().invalidateGeneratorCache(genclass);
            TestCluster.getInstance().addGenerator(genclass, gm);
            addEnvironmentDependency(returnType);
        }
    }
    return true;
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) GenericClass(org.evosuite.utils.generic.GenericClass) Constructor(java.lang.reflect.Constructor) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) GenericMethod(org.evosuite.utils.generic.GenericMethod) Method(java.lang.reflect.Method) GenericMethod(org.evosuite.utils.generic.GenericMethod)

Aggregations

GenericAccessibleObject (org.evosuite.utils.generic.GenericAccessibleObject)20 GenericClass (org.evosuite.utils.generic.GenericClass)14 ConstructionFailedException (org.evosuite.ga.ConstructionFailedException)11 GenericMethod (org.evosuite.utils.generic.GenericMethod)8 GenericConstructor (org.evosuite.utils.generic.GenericConstructor)7 CaptureType (com.googlecode.gentyref.CaptureType)3 Constructor (java.lang.reflect.Constructor)3 ArrayList (java.util.ArrayList)3 Entry (java.util.Map.Entry)3 Collectors (java.util.stream.Collectors)3 Properties (org.evosuite.Properties)3 TestGenerationContext (org.evosuite.TestGenerationContext)3 AtMostOnceLogger (org.evosuite.runtime.util.AtMostOnceLogger)3 Inputs (org.evosuite.runtime.util.Inputs)3 CastClassManager (org.evosuite.seeding.CastClassManager)3 TestCluster (org.evosuite.setup.TestCluster)3 InstanceOnlyOnce (org.evosuite.testcase.jee.InstanceOnlyOnce)3 Method (java.lang.reflect.Method)2 Type (java.lang.reflect.Type)2 java.util (java.util)2