org.evosuite.setup.TestClusterUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.evosuite.setup.TestClusterUtils.java

Source

/**
 * Copyright (C) 2010-2016 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 <http://www.gnu.org/licenses/>.
 */
package org.evosuite.setup;

import org.apache.commons.lang3.StringUtils;
import org.evosuite.PackageInfo;
import org.evosuite.TestGenerationContext;
import org.evosuite.runtime.Reflection;
import org.evosuite.runtime.mock.MockList;
import org.evosuite.runtime.util.ReflectionUtils;
import org.junit.Test;
import org.junit.runners.Suite;
import org.objectweb.asm.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * Set of pure static methods
 */
public class TestClusterUtils {

    protected static final Logger logger = LoggerFactory.getLogger(TestClusterUtils.class);

    /*
       Only final constants and caches should instantiated in this class
     */

    private static final List<String> classExceptions = Collections.unmodifiableList(
            Arrays.asList(new String[] { "com.apple.", "apple.", "sun.", "com.sun.", "com.oracle.", "sun.awt." }));
    private final static Map<Class<?>, Set<Field>> accessibleFieldCache = new LinkedHashMap<>();
    private final static Map<Class<?>, Set<Method>> methodCache = new LinkedHashMap<>();

    /**
     * Determine if this class contains JUnit tests
     * @deprecated use {@code org.evosuite.junit.CoverageAnalysis.isTest(Class<?> cls)}
     *
     * @param className
     * @return
     */
    @Deprecated
    public static boolean isTest(String className) {
        // TODO-JRO Identifying tests should be done differently:
        // If the class either contains methods
        // annotated with @Test (> JUnit 4.0)
        // or contains Test or Suite in it's inheritance structure
        try {
            Class<?> clazz = TestGenerationContext.getInstance().getClassLoaderForSUT().loadClass(className);
            Class<?> superClazz = clazz.getSuperclass();
            while (!superClazz.equals(Object.class)) {
                if (superClazz.equals(Suite.class))
                    return true;
                if (superClazz.equals(Test.class))
                    return true;

                superClazz = clazz.getSuperclass();
            }
            for (Method method : clazz.getMethods()) {
                if (method.isAnnotationPresent(Test.class)) {
                    return true;
                }
            }
        } catch (ClassNotFoundException e) {
            logger.info("Could not load class: ", className);
        }
        return false;
    }

    public static boolean isAnonymousClass(String className) {
        int pos = className.lastIndexOf('$');
        if (pos < 0)
            return false;
        char firstLetter = className.charAt(pos + 1);
        if (firstLetter >= '0' && firstLetter <= '9')
            return true;

        return false;
    }

    public static void makeAccessible(Field field) {
        if (!Modifier.isPublic(field.getModifiers())
                || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
            field.setAccessible(true);
        }
    }

    public static void makeAccessible(Method method) {
        if (!Modifier.isPublic(method.getModifiers())
                || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
            method.setAccessible(true);
        }
    }

    public static void makeAccessible(Constructor<?> constructor) {
        if (!Modifier.isPublic(constructor.getModifiers())
                || !Modifier.isPublic(constructor.getDeclaringClass().getModifiers())) {
            constructor.setAccessible(true);
        }
    }

    public static boolean isEvoSuiteClass(Class<?> c) {
        return c.getName().startsWith(PackageInfo.getEvoSuitePackage());
        //|| c.getName().equals("java.lang.String");    // This is now handled in addDependencyClass
    }

    /**
     * Calculate package distance between two classnames
     *
     * @param className1
     * @param className2
     * @return
     */
    public static int getPackageDistance(String className1, String className2) {

        String[] package1 = StringUtils.split(className1, '.');
        String[] package2 = StringUtils.split(className2, '.');

        int distance = 0;
        int same = 1;
        int num = 0;
        while (num < package1.length && num < package2.length && package1[num].equals(package2[num])) {
            same++;
            num++;
        }

        if (package1.length > same)
            distance += package1.length - same;

        if (package2.length > same)
            distance += package2.length - same;

        return distance;
    }

    /**
     * Check if we can use the given class directly in a JUnit test
     *
     * @param className
     *            a {@link String} object.
     * @return a boolean.
     */
    public static boolean checkIfCanUse(String className) {

        if (MockList.shouldBeMocked(className)) {
            return false;
        }

        for (String s : classExceptions) {
            if (className.startsWith(s)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Get the set of constructors defined in this class and its superclasses
     *
     * @param clazz
     * @return
     */
    public static Set<Constructor<?>> getConstructors(Class<?> clazz) {
        Map<String, Constructor<?>> helper = new TreeMap<>();

        Set<Constructor<?>> constructors = new LinkedHashSet<>();
        for (Constructor<?> c : Reflection.getDeclaredConstructors(clazz)) {
            helper.put(org.objectweb.asm.Type.getConstructorDescriptor(c), c);
        }
        for (Constructor<?> c : helper.values()) {
            constructors.add(c);
        }
        return constructors;
    }

    /**
     * Get the set of fields defined in this class and its superclasses
     *
     * @param clazz
     * @return
     */
    public static Set<Field> getFields(Class<?> clazz) {
        // TODO: Helper not necessary here!
        Map<String, Field> helper = new TreeMap<>();

        Set<Field> fields = new LinkedHashSet<>();
        if (clazz.getSuperclass() != null) {
            for (Field f : getFields(clazz.getSuperclass())) {
                helper.put(f.toGenericString(), f);
            }

        }
        for (Class<?> in : Reflection.getInterfaces(clazz)) {
            for (Field f : getFields(in)) {
                helper.put(f.toGenericString(), f);
            }
        }

        for (Field f : Reflection.getDeclaredFields(clazz)) {
            helper.put(f.toGenericString(), f);
        }
        fields.addAll(helper.values());

        return fields;
    }

    public static boolean hasStaticGenerator(Class<?> clazz) {
        for (Method m : ReflectionUtils.getMethods(clazz)) {
            if (Modifier.isStatic(m.getModifiers())) {
                if (clazz.isAssignableFrom(m.getReturnType())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Get the set of fields defined in this class and its superclasses
     *
     * @param clazz
     * @return
     */
    public static Set<Field> getAccessibleFields(Class<?> clazz) {
        if (accessibleFieldCache.containsKey(clazz)) {
            return accessibleFieldCache.get(clazz);
        }

        Set<Field> fields = new LinkedHashSet<>();
        for (Field f : Reflection.getFields(clazz)) {
            if (TestUsageChecker.canUse(f) && !Modifier.isFinal(f.getModifiers())) {
                fields.add(f);
            }
        }

        accessibleFieldCache.put(clazz, fields);
        return fields;
    }

    /**
     * Get the set of methods defined in this class and its superclasses
     *
     * @param clazz
     * @return
     */
    public static Set<Method> getMethods(Class<?> clazz) {

        // As this is expensive, doing some caching here
        // Note that with the change of a class loader the cached values could
        // be thrown away
        if (methodCache.containsKey(clazz)) {
            return methodCache.get(clazz);
        }
        Map<String, Method> helper = new TreeMap<String, Method>();

        if (clazz.getSuperclass() != null) {
            for (Method m : getMethods(clazz.getSuperclass())) {
                helper.put(m.getName() + org.objectweb.asm.Type.getMethodDescriptor(m), m);
            }
        }
        for (Class<?> in : Reflection.getInterfaces(clazz)) {
            for (Method m : getMethods(in)) {
                helper.put(m.getName() + org.objectweb.asm.Type.getMethodDescriptor(m), m);
            }
        }

        for (Method m : Reflection.getDeclaredMethods(clazz)) {
            helper.put(m.getName() + org.objectweb.asm.Type.getMethodDescriptor(m), m);
        }

        Set<Method> methods = new LinkedHashSet<>();
        methods.addAll(helper.values());
        methodCache.put(clazz, methods);
        return methods;
    }

    public static Method getMethod(Class<?> clazz, String methodName, String desc) {
        for (Method method : Reflection.getMethods(clazz)) {
            if (method.getName().equals(methodName) && Type.getMethodDescriptor(method).equals(desc))
                return method;
        }
        return null;
    }

    public static Class<?> getClass(String className) {
        try {
            Class<?> clazz = Class.forName(className, true,
                    TestGenerationContext.getInstance().getClassLoaderForSUT());
            return clazz;
        } catch (ClassNotFoundException e) {
            return null;
        } catch (NoClassDefFoundError e) {
            // an ExceptionInInitializationError might have happened during class initialization.
            return null;
        }
    }
}