org.evosuite.EvoSuite.java Source code

Java tutorial

Introduction

Here is the source code for org.evosuite.EvoSuite.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;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.evosuite.classpath.ClassPathHacker;
import org.evosuite.executionmode.Continuous;
import org.evosuite.executionmode.Help;
import org.evosuite.executionmode.ListClasses;
import org.evosuite.executionmode.WriteDependencies;
import org.evosuite.executionmode.ListParameters;
import org.evosuite.executionmode.MeasureCoverage;
import org.evosuite.executionmode.PrintStats;
import org.evosuite.executionmode.Setup;
import org.evosuite.executionmode.TestGeneration;
import org.evosuite.junit.writer.TestSuiteWriterUtils;
import org.evosuite.runtime.agent.ToolsJarLocator;
import org.evosuite.runtime.sandbox.MSecurityManager;
import org.evosuite.setup.InheritanceTree;
import org.evosuite.setup.InheritanceTreeGenerator;
import org.evosuite.utils.LoggingUtils;
import org.evosuite.utils.Randomness;
import org.evosuite.utils.SpawnProcessKeepAliveChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * EvoSuite class.
 * </p>
 *
 * @author Gordon Fraser
 */
public class EvoSuite {

    static {
        LoggingUtils.loadLogbackForEvoSuite();
    }

    private static Logger logger = LoggerFactory.getLogger(EvoSuite.class);

    private static String separator = System.getProperty("file.separator");
    private static String javaHome = System.getProperty("java.home");

    /**
     * Constant
     * <code>JAVA_CMD="javaHome + separator + bin + separatorj"{trunked}</code>
     */
    public final static String JAVA_CMD = javaHome + separator + "bin" + separator + "java";

    public static String base_dir_path = System.getProperty("user.dir");

    public static String generateInheritanceTree(String cp) throws IOException {
        LoggingUtils.getEvoLogger().info("* Analyzing classpath (generating inheritance tree)");
        List<String> cpList = Arrays.asList(cp.split(File.pathSeparator));
        // Clear current inheritance file to make sure a new one is generated
        Properties.INHERITANCE_FILE = "";
        InheritanceTree tree = InheritanceTreeGenerator.createFromClassPath(cpList);
        File outputFile = File.createTempFile("ES_inheritancetree", ".xml.gz");
        outputFile.deleteOnExit();
        InheritanceTreeGenerator.writeInheritanceTree(tree, outputFile);
        return outputFile.getAbsolutePath();
    }

    private void setupProperties() {
        if (base_dir_path.equals("")) {
            Properties.getInstanceSilent();
        } else {
            Properties.getInstanceSilent().loadProperties(base_dir_path + separator + Properties.PROPERTIES_FILE,
                    true);
        }
    }

    /**
     * <p>
     * parseCommandLine
     * </p>
     *
     * @param args an array of {@link java.lang.String} objects.
     * @return a {@link java.lang.Object} object.
     */
    public Object parseCommandLine(String[] args) {
        Options options = CommandLineParameters.getCommandLineOptions();

        List<String> javaOpts = new ArrayList<String>();

        String version = EvoSuite.class.getPackage().getImplementationVersion();
        if (version == null) {
            version = "";
        }

        // create the parser
        CommandLineParser parser = new GnuParser();
        try {
            // parse the command line arguments
            CommandLine line = parser.parse(options, args);

            if (!line.hasOption(Setup.NAME)) {
                /*
                * -setup is treated specially because it uses the extra input arguments
                * 
                * TODO: Setup should be refactored/fixed
                */
                String[] unrecognized = line.getArgs();
                if (unrecognized.length > 0) {
                    String msg = "";
                    if (unrecognized.length == 1) {
                        msg = "There is one unrecognized input:";
                    } else {
                        msg = "There are " + unrecognized.length + " unrecognized inputs:";
                    }
                    msg += " " + Arrays.toString(unrecognized);
                    msg += "\nRecall, '-Dx=v' assignments should have no space, i.e. '-Dx= v' and '-Dx = v' are wrong";
                    throw new IllegalArgumentException(msg);
                }
            }

            setupProperties();

            if (TestSuiteWriterUtils.needToUseAgent() && Properties.JUNIT_CHECK) {
                ClassPathHacker.initializeToolJar();
            }

            if (!line.hasOption("regressionSuite")) {
                if (line.hasOption("criterion")) {
                    //TODO should check if already defined
                    javaOpts.add("-Dcriterion=" + line.getOptionValue("criterion"));

                    //FIXME should really better handle the validation of javaOpts in the master, not client
                    try {
                        Properties.getInstance().setValue("criterion", line.getOptionValue("criterion"));
                    } catch (Exception e) {
                        throw new Error("Invalid value for criterion: " + e.getMessage());
                    }
                }
            } else {
                javaOpts.add("-Dcriterion=regression");
            }

            /*
             * FIXME: every time in the Master we set a parameter with -D,
             * we should check if it actually exists (ie detect typos)
             */

            CommandLineParameters.handleSeed(javaOpts, line);

            CommandLineParameters.addJavaDOptions(javaOpts, line);

            CommandLineParameters.handleClassPath(line);

            CommandLineParameters.handleJVMOptions(javaOpts, line);

            if (line.hasOption("base_dir")) {
                base_dir_path = line.getOptionValue("base_dir");
                File baseDir = new File(base_dir_path);
                if (!baseDir.exists()) {
                    LoggingUtils.getEvoLogger().error("Base directory does not exist: " + base_dir_path);
                    return null;
                }
                if (!baseDir.isDirectory()) {
                    LoggingUtils.getEvoLogger()
                            .error("Specified base directory is not a directory: " + base_dir_path);
                    return null;
                }
            }

            CommandLineParameters.validateInputOptionsAndParameters(line);

            /*
             * We shouldn't print when -listClasses, as we do not want to have
             * side effects (eg, important when using it in shell scripts)
             */
            if (!line.hasOption(ListClasses.NAME)) {

                LoggingUtils.getEvoLogger().info("* EvoSuite " + version);

                String conf = Properties.CONFIGURATION_ID;
                if (conf != null && !conf.isEmpty()) {
                    /*
                     * This is useful for debugging on cluster
                     */
                    LoggingUtils.getEvoLogger().info("* Configuration: " + conf);
                }
            }

            if (Properties.CLIENT_ON_THREAD) {
                MSecurityManager.setRunningClientOnThread(true);
            }

            if (Properties.SPAWN_PROCESS_MANAGER_PORT != null) {
                SpawnProcessKeepAliveChecker.getInstance()
                        .registerToRemoteServerAndDieIfFails(Properties.SPAWN_PROCESS_MANAGER_PORT);
            }

            /*
             * Following "options" are the actual (mutually exclusive) execution modes of EvoSuite
             */

            if (line.hasOption(Help.NAME)) {
                return Help.execute(options);
            }

            if (line.hasOption(Setup.NAME)) {
                return Setup.execute(javaOpts, line);
            }

            if (line.hasOption(MeasureCoverage.NAME)) {
                return MeasureCoverage.execute(options, javaOpts, line);
            }

            if (line.hasOption(ListClasses.NAME)) {
                return ListClasses.execute(options, line);
            }

            if (line.hasOption(WriteDependencies.NAME)) {
                return WriteDependencies.execute(options, javaOpts, line);
            }

            if (line.hasOption(PrintStats.NAME)) {
                return PrintStats.execute(options, javaOpts, line);
            }

            if (line.hasOption(ListParameters.NAME)) {
                return ListParameters.execute();
            }

            if (line.hasOption(Continuous.NAME)) {
                return Continuous.execute(options, javaOpts, line);
            }

            return TestGeneration.executeTestGeneration(options, javaOpts, line);

        } catch (ParseException exp) {
            // oops, something went wrong
            logger.error("Parsing failed.  Reason: " + exp.getMessage());
            // automatically generate the help statement
            Help.execute(options);
        }

        return null;
    }

    public static boolean hasLegacyTargets() {
        File directory = new File(Properties.OUTPUT_DIR);
        if (!directory.exists()) {
            return false;
        }
        String[] extensions = { "task" };
        return !FileUtils.listFiles(directory, extensions, false).isEmpty();
    }

    /**
     * <p>
     * main
     * </p>
     *
     * @param args an array of {@link java.lang.String} objects.
     */
    public static void main(String[] args) {

        try {
            EvoSuite evosuite = new EvoSuite();
            evosuite.parseCommandLine(args);
        } catch (Throwable t) {
            logger.error("Fatal crash on main EvoSuite process. Class " + Properties.TARGET_CLASS + " using seed "
                    + Randomness.getSeed() + ". Configuration id : " + Properties.CONFIGURATION_ID, t);
            System.exit(-1);
        }

        /*
         * Some threads could still be running, so we need to kill the process explicitly
         */
        System.exit(0);
    }

}