Search in sources :

Example 1 with GenericConstructor

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

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

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

Example 4 with GenericConstructor

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

the class TestFactory method insertRandomCallOnEnvironment.

/**
 * @param test
 * @param lastValidPosition
 * @return the position where the insertion happened, or a negative value otherwise
 */
public int insertRandomCallOnEnvironment(TestCase test, int lastValidPosition) {
    int previousLength = test.size();
    currentRecursion.clear();
    List<GenericAccessibleObject<?>> shuffledOptions = TestCluster.getInstance().getRandomizedCallsToEnvironment();
    if (shuffledOptions == null || shuffledOptions.isEmpty()) {
        return -1;
    }
    // iterate (in random order) over all possible environment methods till we find one that can be inserted
    for (GenericAccessibleObject<?> o : shuffledOptions) {
        try {
            int position = ConstraintVerifier.getAValidPositionForInsertion(o, test, lastValidPosition);
            if (position < 0) {
                // the given method/constructor cannot be added
                continue;
            }
            if (o.isConstructor()) {
                GenericConstructor c = (GenericConstructor) o;
                addConstructor(test, c, position, 0);
                return position;
            } else if (o.isMethod()) {
                GenericMethod m = (GenericMethod) o;
                if (!m.isStatic()) {
                    VariableReference callee = null;
                    Type target = m.getOwnerType();
                    if (!test.hasObject(target, position)) {
                        callee = createObject(test, target, position, 0, null);
                        position += test.size() - previousLength;
                        previousLength = test.size();
                    } else {
                        callee = test.getRandomNonNullObject(target, position);
                    }
                    if (!TestUsageChecker.canUse(m.getMethod(), callee.getVariableClass())) {
                        logger.error("Cannot call method " + m + " with callee of type " + callee.getClassName());
                    }
                    addMethodFor(test, callee, m.copyWithNewOwner(callee.getGenericClass()), position);
                    return position;
                } else {
                    addMethod(test, m, position, 0);
                    return position;
                }
            } else {
                throw new RuntimeException("Unrecognized type for environment: " + o);
            }
        } catch (ConstructionFailedException e) {
            // TODO what to do here?
            AtMostOnceLogger.warn(logger, "Failed environment insertion: " + e);
        }
    }
    return -1;
}
Also used : GenericAccessibleObject(org.evosuite.utils.generic.GenericAccessibleObject) CaptureType(com.googlecode.gentyref.CaptureType) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) GenericMethod(org.evosuite.utils.generic.GenericMethod) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Example 5 with GenericConstructor

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

the class TestFactory method insertRandomCall.

/**
 * Insert a random call for the UUT at the given position
 *
 * @param test
 * @param position
 */
public boolean insertRandomCall(TestCase test, int position) {
    int previousLength = test.size();
    String name = "";
    currentRecursion.clear();
    logger.debug("Inserting random call at position {}", position);
    try {
        if (reflectionFactory == null) {
            final Class<?> targetClass = Properties.getTargetClassAndDontInitialise();
            reflectionFactory = new ReflectionFactory(targetClass);
        }
        if (reflectionFactory.hasPrivateFieldsOrMethods() && TimeController.getInstance().getPhasePercentage() >= Properties.REFLECTION_START_PERCENT && (Randomness.nextDouble() < Properties.P_REFLECTION_ON_PRIVATE || TestCluster.getInstance().getNumTestCalls() == 0)) {
            logger.debug("Going to insert random reflection call");
            return insertRandomReflectionCall(test, position, 0);
        }
        GenericAccessibleObject<?> o = TestCluster.getInstance().getRandomTestCall(test);
        if (o == null) {
            logger.warn("Have no target methods to test");
            return false;
        } else if (o.isConstructor()) {
            if (InstanceOnlyOnce.canInstantiateOnlyOnce(o.getDeclaringClass()) && ConstraintHelper.countNumberOfNewInstances(test, o.getDeclaringClass()) != 0) {
                return false;
            }
            GenericConstructor c = (GenericConstructor) o;
            logger.debug("Adding constructor call {}", c.getName());
            name = c.getName();
            addConstructor(test, c, position, 0);
        } else if (o.isMethod()) {
            GenericMethod m = (GenericMethod) o;
            logger.debug("Adding method call {}", m.getName());
            name = m.getName();
            if (!m.isStatic()) {
                logger.debug("Getting callee of type {}", m.getOwnerClass().getTypeName());
                VariableReference callee = null;
                Type target = m.getOwnerType();
                if (!test.hasObject(target, position)) {
                    // no FM for SUT
                    callee = createObject(test, target, position, 0, null, false, false, true);
                    position += test.size() - previousLength;
                    previousLength = test.size();
                } else {
                    callee = test.getRandomNonNullObject(target, position);
                // This may also be an inner class, in this case we can't use a SUT instance
                // if (!callee.isAssignableTo(m.getDeclaringClass())) {
                // callee = test.getRandomNonNullObject(m.getDeclaringClass(), position);
                // }
                }
                logger.debug("Got callee of type {}", callee.getGenericClass().getTypeName());
                if (!TestUsageChecker.canUse(m.getMethod(), callee.getVariableClass())) {
                    logger.debug("Cannot call method {} with callee of type {}", m, callee.getClassName());
                    throw new ConstructionFailedException("Cannot apply method to this callee");
                }
                addMethodFor(test, callee, m.copyWithNewOwner(callee.getGenericClass()), position);
            } else {
                // We only use this for static methods to avoid using wrong constructors (?)
                addMethod(test, m, position, 0);
            }
        } else if (o.isField()) {
            GenericField f = (GenericField) o;
            name = f.getName();
            logger.debug("Adding field {}", f.getName());
            if (Randomness.nextBoolean()) {
                addFieldAssignment(test, f, position, 0);
            } else {
                addField(test, f, position, 0);
            }
        } else {
            logger.error("Got type other than method or constructor!");
            return false;
        }
        return true;
    } catch (ConstructionFailedException e) {
        // TODO: Check this! - TestCluster replaced
        // TestCluster.getInstance().checkDependencies(o);
        logger.debug("Inserting statement {} has failed. Removing statements: {}", name, e);
        // TODO: Doesn't work if position != test.size()
        int lengthDifference = test.size() - previousLength;
        for (int i = lengthDifference - 1; i >= 0; i--) {
            // we need to remove them in order, so that the testcase is at all time consistent
            if (logger.isDebugEnabled()) {
                logger.debug("  Removing statement: " + test.getStatement(position + i).getCode());
            }
            test.remove(position + i);
        }
        return false;
    }
}
Also used : CaptureType(com.googlecode.gentyref.CaptureType) ReflectionFactory(org.evosuite.testcase.statements.reflection.ReflectionFactory) GenericConstructor(org.evosuite.utils.generic.GenericConstructor) GenericMethod(org.evosuite.utils.generic.GenericMethod) GenericField(org.evosuite.utils.generic.GenericField) ConstructionFailedException(org.evosuite.ga.ConstructionFailedException)

Aggregations

GenericConstructor (org.evosuite.utils.generic.GenericConstructor)76 GenericMethod (org.evosuite.utils.generic.GenericMethod)61 VariableReference (org.evosuite.testcase.variable.VariableReference)56 Test (org.junit.Test)47 Method (java.lang.reflect.Method)30 GenericClass (org.evosuite.utils.generic.GenericClass)25 MethodStatement (org.evosuite.testcase.statements.MethodStatement)22 ConstructorStatement (org.evosuite.testcase.statements.ConstructorStatement)19 ArrayList (java.util.ArrayList)17 IntPrimitiveStatement (org.evosuite.testcase.statements.numeric.IntPrimitiveStatement)17 DefaultTestCase (org.evosuite.testcase.DefaultTestCase)11 Injector (org.evosuite.runtime.javaee.injection.Injector)9 GenericAccessibleObject (org.evosuite.utils.generic.GenericAccessibleObject)8 GenericField (org.evosuite.utils.generic.GenericField)8 AbstractEnumInInnerClass (com.examples.with.different.packagename.AbstractEnumInInnerClass)7 BranchCoverageSuiteFitness (org.evosuite.coverage.branch.BranchCoverageSuiteFitness)7 ConstructionFailedException (org.evosuite.ga.ConstructionFailedException)7 EnumInInnerClass (com.examples.with.different.packagename.EnumInInnerClass)6 FactoryExample (com.examples.with.different.packagename.FactoryExample)6 Type (java.lang.reflect.Type)6