edu.odu.cs.cs350.yellow1.ui.cli.Main.java Source code

Java tutorial

Introduction

Here is the source code for edu.odu.cs.cs350.yellow1.ui.cli.Main.java

Source

/**
*   Copyright (C) 2014  John Berlin, James Ord
*
*   This program is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.
*
*   This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
*   along with this program.  If not, see http://www.gnu.org/licenses/
*/
package edu.odu.cs.cs350.yellow1.ui.cli;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tools.ant.BuildException;

import edu.odu.cs.cs350.yellow1.ant.AntRunner;
import edu.odu.cs.cs350.yellow1.ant.BuildFileNotFoundException;
import edu.odu.cs.cs350.yellow1.ant.TargetNotFoundException;
import edu.odu.cs.cs350.yellow1.file.FileMover;
import edu.odu.cs.cs350.yellow1.file.FileMovingException;
import edu.odu.cs.cs350.yellow1.jar.ExecutionResults;
import edu.odu.cs.cs350.yellow1.jar.ExecutionState;
import edu.odu.cs.cs350.yellow1.jar.JarExecutor;
import edu.odu.cs.cs350.yellow1.jar.JarExecutorBuilder;
import edu.odu.cs.cs350.yellow1.jar.JarUtil;
import edu.odu.cs.cs350.yellow1.mutationgeneration.JavaFile;
import edu.odu.cs.cs350.yellow1.mutationgeneration.JavaFile.EOL;

/**
 * Main running class for package jar
 * 
 * @author jberlin
 * @author jord
 */
public class Main {

    private static JavaFile a;
    private static FileMover fMover;
    private static JarUtil jar;
    private static AntRunner ant;
    private static JarExecutor jarExecutor;
    private static byte[] goldOrgContent;
    private static Path goldPath;
    private static Logger logger;
    private static File mutLog;
    private static File aliveLog;
    private static File logFolder;

    /**
     * Parses CLI to recievedArgs and feeds user input params to mutate function
     * @param args From user input
     */
    public static void main(String[] args) {
        ClI commandLine = new ClI(args);
        try {
            commandLine.parse();
        } catch (RequireArgumentsNotRecieved e) {
            System.err.println(e.getMessage());
            System.exit(0);
        }
        Map<String, String> recievedArgs = commandLine.getRecievedArguments();

        String srcFolder = recievedArgs.get("src");
        String fileToBeMutated = recievedArgs.get("mutF");
        String testSuitePath = recievedArgs.get("testSte");
        String goldOutput = recievedArgs.get("goldOut");

        try {
            mutate(srcFolder, fileToBeMutated, testSuitePath, goldOutput);
        } catch (BuildFileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.exit(0);

    }

    /**
     * Main program function. Creates and runs mutants as well as logging and output files
     * 
     * @param srcFolder Source folder for project to be mutated
     * @param fileToBeMutated Source file for project to be mutated
     * @param testSuitePath Path for test suite
     * @param goldOutput Original version output file
     * @throws BuildFileNotFoundException
     * @throws IOException
     */
    @SuppressWarnings("static-access")
    public static void mutate(String srcFolder, String fileToBeMutated, String testSuitePath, String goldOutput)
            throws BuildFileNotFoundException, IOException {

        //Step 1: Set up file directory paths for antRunner, jarExecutor, and fileMover

        logger = LogManager.getLogger(Main.class);
        mutLog = new File(srcFolder.toString() + File.separator + "mutantDir" + File.separator + "logs"
                + File.separator + "mutationsApplied.txt");
        aliveLog = new File(srcFolder.toString() + File.separator + "mutantDir" + File.separator + "logs"
                + File.separator + "mutationsAlive.txt");
        logFolder = new File(srcFolder.toString() + File.separator + "mutantDir" + File.separator + "logs");
        // ok because of the output on jenkins sanitize the logs directory
        if (logFolder.exists())
            if (logFolder.isDirectory())
                for (File f : logFolder.listFiles())
                    f.delete();
        //give ant runer the project location
        ant = new AntRunner(srcFolder);
        ant.requiresInit(true);
        //call setup
        ant.setUp();
        a = new JavaFile();

        //give the jarUtil the  directory where to expect the jar   the directory where to put the jar
        jar = new JarUtil((srcFolder + File.separator + "bin"), (srcFolder + File.separator + "mutantDir"));

        //get a file object to the original file
        File goldFile = new File(fileToBeMutated);
        goldPath = goldFile.toPath();
        //get the bytes from it for checking if applying mutation and restore works
        goldOrgContent = Files.readAllBytes(goldPath);

        File script = new File(srcFolder + File.separator + "compare.sh");
        //build the JarExecutor using the JarExecutor
        jarExecutor = JarExecutorBuilder.pathToJarDirectory(srcFolder + File.separator + "mutantDir")
                .pathToCompareScript(script.getAbsolutePath())
                .pathToLogDir(srcFolder + File.separator + "mutantDir" + File.separator + "logs")
                .pathToGold(goldOutput.toString()).withExecutionState(ExecutionState.multiFile)
                .withTestSuitePath(testSuitePath).create();
        File tDir = new File(srcFolder + File.separator + "mutantDir");
        if (!tDir.exists())
            tDir.mkdir();
        //Create a fileMover object give it the directory where mutations will be placed   the directory of the original file location
        fMover = new FileMover(srcFolder + File.separator + "mutantDir", fileToBeMutated);
        fMover.setNoDelete(true);
        try {

            fMover.setUp();
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();

        }

        //Step2: Create and run mutants

        try {
            a.readFile(fileToBeMutated);
        } catch (IOException e) {
            e.printStackTrace();
        }

        a.executeAll();
        int mutantsCreated = a.getMutantCaseVector().getSize();
        logger.info("Created " + mutantsCreated + " Mutants");
        for (int i = 0; i < a.getMutantCaseVector().getSize(); i++) {
            a.getMutantCaseOperations(i).writeMutation(srcFolder + File.separator + "mutantDir" + File.separator
                    + "Mutation" + Integer.toString(i + 1) + ".java");
        }

        //get the files into the file mover object
        fMover.pullFiles();

        //check to see if the filemover got all the files
        //assertEquals(fMover.getFileToBeMovedCount(),mutantsCreated);

        int moved = 0;
        int failed = 0;
        //move through each file moving them one by one
        while (fMover.hasMoreFiles()) {
            try {
                //move next file
                fMover.moveNextFile();

                //build the new executable
                ant.build();
                //move the created jar with correct number corresponding to the mutation created 
                jar.moveJarToDestNumbered();
                //clean the project
                ant.clean();
                //check to see if the mutation was applied
                //assertThat(additionOrgContent, IsNot.not(IsEqual.equalTo(Files.readAllBytes(additionPath))));

            } catch (FileMovingException | BuildException | TargetNotFoundException | IOException e) {

                //build failed
                if (e instanceof BuildException) {
                    logger.error("Build exception " + e.getMessage());

                    //restore the file back since compilation was not successful 
                    fMover.restorTarget();
                    //try {
                    //   //check to see if the file was restored
                    //   assertArrayEquals(goldOrgContent, Files.readAllBytes(goldPath));
                    //} catch (IOException e1) {
                    //   
                    //}
                    //clean the project
                    try {
                        ant.clean();
                    } catch (BuildException e1) {

                    } catch (TargetNotFoundException e1) {

                    }
                    //indicate compile failure
                    ++failed;
                }
                //fail();
            }

            //restore the file back to its original state
            fMover.restorTarget();
            //check to see if the file was restored
            //try {
            //   assertArrayEquals(goldOrgContent, Files.readAllBytes(goldPath));
            //} catch (IOException e) {
            //   
            //}

            //increment move count
            ++moved;
            //see if the file mover has the correct amount of mutatants still to be moved
            //assertEquals(fMover.getFileToBeMovedCount(), mutantsCreated - moved);
        }

        //set up for execution
        jarExecutor.setUp();
        //start execution of jars
        jarExecutor.start();

        //get the number of successful and failed runs
        int succesful = jarExecutor.getNumberOfMutantsKilled();
        int failurs = jarExecutor.getNumberOfMutantsNotKilled();
        int numTests = jarExecutor.getNumberOfTests();
        int total = succesful + failurs;
        String aliveFile = null;
        String newLine = System.lineSeparator();

        //Find any test jars that remain alive and write them to the log file
        List<ExecutionResults> testResults = jarExecutor.getMutationTestingResults();
        for (ExecutionResults result : testResults) {
            if (!result.isKilled()) {
                aliveFile = result.getJarName();
                FileUtils.writeStringToFile(aliveLog, aliveFile + newLine, true);
            }
        }

        //moved - failed = number of jars actually created
        moved = moved - failed;
        //see if the total number of executions equals the total amount of jars created
        //assertEquals(succesful+failurs,moved);
        logger.debug("Compilation failurs= " + failed + " total files moved= " + moved);
        logger.debug("Execution succesful=" + succesful + " Execution failurs= " + failurs);

        EOL eol = System.getProperty("os.name").toLowerCase().contains("windows") ? EOL.DOS : EOL.NIX;
        try {
            a.writeMutationsLog(srcFolder.toString() + File.separator + "mutantDir" + File.separator + "logs"
                    + File.separator + "mutationsApplied.txt", eol);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        String finalOutput = "Number of tests: " + numTests + " " + "Number of mutants: " + total + " "
                + "Mutants killed: " + succesful;
        FileUtils.writeStringToFile(mutLog, newLine + finalOutput, true);

        System.out.println(finalOutput + "\n");
    }
}