/**
* Copyright (C) 2010-2017 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.utils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.URL;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.lang3.StringEscapeUtils;
import org.evosuite.Properties;
import org.evosuite.Properties.NoSuchParameterException;
import org.evosuite.contracts.AssertionErrorContract;
import org.evosuite.contracts.EqualsContract;
import org.evosuite.contracts.EqualsHashcodeContract;
import org.evosuite.contracts.EqualsNullContract;
import org.evosuite.contracts.EqualsSymmetricContract;
import org.evosuite.contracts.FailingTestSet;
import org.evosuite.contracts.HashCodeReturnsNormallyContract;
import org.evosuite.contracts.JCrasherExceptionContract;
import org.evosuite.contracts.NullPointerExceptionContract;
import org.evosuite.contracts.ToStringReturnsNormallyContract;
import org.evosuite.contracts.UndeclaredExceptionContract;
import org.evosuite.ga.Chromosome;
import org.evosuite.ga.metaheuristics.GeneticAlgorithm;
import org.evosuite.ga.metaheuristics.SearchListener;
import org.evosuite.runtime.sandbox.PermissionStatistics;
import org.evosuite.testcase.ExecutionResult;
import org.evosuite.testcase.ExecutionTrace;
import org.evosuite.testcase.ExecutionTracer;
import org.evosuite.testcase.JUnitTestCarvedChromosomeFactory;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.TestCaseExecutor;
import org.evosuite.testcase.TestChromosome;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.panayotis.gnuplot.JavaPlot;
import com.panayotis.gnuplot.plot.AbstractPlot;
import com.panayotis.gnuplot.style.PlotStyle;
import com.panayotis.gnuplot.style.Style;
import com.panayotis.gnuplot.terminal.FileTerminal;
import com.panayotis.gnuplot.terminal.GNUPlotTerminal;
/**
* <p>
* Abstract ReportGenerator class.
* </p>
*
* @author Gordon Fraser
*/
@Deprecated
public abstract class ReportGenerator implements SearchListener, Serializable {
private static final long serialVersionUID = -920540796220051609L;
/** Constant <code>logger</code> */
protected static final Logger logger = LoggerFactory.getLogger(ReportGenerator.class);
/**
* Return the folder of where reports should be generated.
* If the folder does not exist, try to create it
*
* @return
* @throws RuntimeException if folder does not exist, and we cannot create it
*/
public static File getReportDir() throws RuntimeException{
File dir = new File(Properties.REPORT_DIR);
if(!dir.exists()){
boolean created = dir.mkdirs();
if(!created){
String msg = "Cannot create report dir: "+Properties.REPORT_DIR;
logger.error(msg);
throw new RuntimeException(msg);
}
}
return dir;
}
/**
* <p>
* This enumeration defines all the runtime variables we want to store in
* the CSV files. Note, it is perfectly fine to add new ones, in any
* position. Just be sure to define a proper mapper in {@code getCSVvalue}.
* </p>
*
* <p>
* WARNING: do not change the name of any variable! If you do, current R
* scripts will break. If you really need to change a name, please first
* contact Andrea Arcuri.
* </p>
*
* @author arcuri
*
*/
@Deprecated
public enum RuntimeVariable {
/** The class under test */
Class,
/** Number of predicates */
Predicates,
Total_Branches,
Covered_Branches,
Total_Methods,
Branchless_Methods,
Covered_Methods,
Covered_Branchless_Methods,
Total_Goals,
Covered_Goals,
Statements_Executed,
/** Obtained coverage of the chosen testing criterion */
Coverage,
/**
* Obtained coverage at different points in time
*/
CoverageTimeline,
/**
* Not only the covered branches ratio, but also including the
* branchless methods
*/
BranchCoverage,
NumberOfGeneratedTestCases,
/**
* The number of serialized objects that EvoSuite is
* going to use for seeding strategies
*/
NumberOfInputPoolObjects,
DefUseCoverage,
WeakMutationScore,
Creation_Time,
Minimization_Time,
Total_Time,
Test_Execution_Time,
Goal_Computation_Time,
Result_Size,
Result_Length,
Minimized_Size,
Minimized_Length,
Chromosome_Length,
Population_Size,
Random_Seed,
Budget,
AllPermission,
SecurityPermission,
UnresolvedPermission,
AWTPermission,
FilePermission,
SerializablePermission,
ReflectPermission,
RuntimePermission,
NetPermission,
SocketPermission,
SQLPermission,
PropertyPermission,
LoggingPermission,
SSLPermission,
AuthPermission,
AudioPermission,
OtherPermission,
Threads,
CoveredBranchesBitString,
MutationScore,
Explicit_MethodExceptions,
Explicit_TypeExceptions,
Implicit_MethodExceptions,
Implicit_TypeExceptions,
Error_Predicates,
Error_Branches_Covered,
Error_Branchless_Methods,
Error_Branchless_Methods_Covered,
AssertionContract,
EqualsContract,
EqualsHashcodeContract,
EqualsNullContract,
EqualsSymmetricContract,
HashCodeReturnsNormallyContract,
JCrasherExceptionContract,
NullPointerExceptionContract,
ToStringReturnsNormallyContract,
UndeclaredExceptionContract,
Contract_Violations,
Unique_Violations,
Data_File,
/**
* Dataflow stuff
*/
Definitions,
Uses,
DefUsePairs,
IntraMethodPairs,
InterMethodPairs,
IntraClassPairs,
ParameterPairs,
AliasingIntraMethodPairs,
AliasingInterMethodPairs,
AliasingIntraClassPairs,
AliasingParameterPairs,
CoveredIntraMethodPairs,
CoveredInterMethodPairs,
CoveredIntraClassPairs,
CoveredParameterPairs,
CoveredAliasIntraMethodPairs,
CoveredAliasInterMethodPairs,
CoveredAliasIntraClassPairs,
CoveredAliasParameterPairs,
CarvedTests,
CarvedCoverage,
HadUnstableTests
};
/** Constant <code>DATE_FORMAT_NOW="yyyy-MM-dd HH:mm:ss"</code> */
protected static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
/**
* Statistics about one test generation run
*
* @author Gordon Fraser
*
*/
public class StatisticEntry implements Serializable {
private static final long serialVersionUID = 8690481387977534927L;
/** Run id */
public int id = 0;
public String className;
public int population_size;
public int chromosome_length;
/** Total number of branches */
public int total_branches;
public int error_branches = 0;
public int error_branches_covered = 0;
public int error_branchless_methods = 0;
public int error_branchless_methods_covered = 0;
/** Total number of branches */
public int covered_branches;
public int total_methods;
public int branchless_methods;
public int covered_branchless_methods;
public int covered_methods;
public int total_goals;
public int covered_goals;
public Set<Integer> coverage = new HashSet<Integer>();
public double mutationScore = 0.0;
public Map<String, Double> coverageMap = new HashMap<String, Double>();
/** Resulting test cases */
public List<TestCase> tests = null;
/** History of best fitness values */
public List<Double> fitness_history = new ArrayList<Double>();
/** History of best test suite size */
public List<Integer> size_history = new ArrayList<Integer>();
/** History of best test length */
public List<Integer> length_history = new ArrayList<Integer>();
/** History of average test length */
public List<Double> average_length_history = new ArrayList<Double>();
/** History of best test coverage */
public List<Double> coverage_history = new ArrayList<Double>();
/** History of best test length */
public List<Long> tests_executed = new ArrayList<Long>();
/** History of best test length */
public List<Long> statements_executed = new ArrayList<Long>();
/** History of the time stamps for generations */
public List<Long> timeStamps = new ArrayList<Long>();
/** History of best test length */
public List<Long> fitness_evaluations = new ArrayList<Long>();
/** Time at which this entry was created */
public final long creationTime = System.currentTimeMillis();
/** Number of tests after GA */
public int size_final = 0;
/** Total length of tests after GA */
public int length_final = 0;
/** Number of tests after minimization */
public int size_minimized = 0;
/** Total length of tests after minimization */
public int length_minimized = 0;
public Map<TestCase, Map<Integer, Throwable>> results = new HashMap<TestCase, Map<Integer, Throwable>>();
public long start_time;
public long end_time;
public long minimized_time;
public long testExecutionTime;
public long goalComputationTime;
public int result_fitness_evaluations = 0;
public long result_tests_executed = 0;
public long result_statements_executed = 0;
public int age = 0;
public double fitness = 0.0;
public long seed = 0;
public long stoppingCondition;
public long globalTimeStoppingCondition;
public boolean timedOut;
public int numDefinitions;
public int numUses;
public int numDefUsePairs;
public int numIntraMethodPairs;
public int numInterMethodPairs;
public int numIntraClassPairs;
public int numParameterPairs;
public int coveredIntraMethodPairs;
public int coveredInterMethodPairs;
public int coveredIntraClassPairs;
public int coveredParameterPairs;
public int aliasingIntraMethodPairs;
public int aliasingInterMethodPairs;
public int aliasingIntraClassPairs;
public int aliasingParameterPairs;
public int coveredAliasIntraMethodPairs;
public int coveredAliasInterMethodPairs;
public int coveredAliasIntraClassPairs;
public int coveredAliasParameterPairs;
public String goalCoverage;
public int explicitMethodExceptions;
public int explicitTypeExceptions;
public int implicitMethodExceptions;
public int implicitTypeExceptions;
public Map<String, Set<Class<?>>> implicitExceptions;
public Map<String, Set<Class<?>>> explicitExceptions;
public boolean hadUnstableTests;
//--------------------------------------------------
private String[] getTimelineHeaderSuffixes() {
int numberOfIntervals = calculateNumberOfIntervals();
String[] suffixes = new String[numberOfIntervals];
for (int i = 0; i < suffixes.length; i++) {
/*
* NOTE: we start from T1 and not T0 because, by definition, coverage
* at T0 is equal to 0, and no point in showing it in a graph
*/
suffixes[i] = "_T" + (i + 1);
}
return suffixes;
}
private int calculateNumberOfIntervals() {
long interval = Properties.TIMELINE_INTERVAL;
/*
* TODO: this might need refactoring once we choose
* a different way to handle search timeouts.
*
* The point here is that we need to support both if we use time
* as search budget, and fitness/statement evaluations.
* We cannot just look at the obtained history, because the search might
* have finished earlier, eg if 100% coverage
*/
long totalTime = Properties.GLOBAL_TIMEOUT * 1000l;
int numberOfIntervals = (int) (totalTime / interval);
return numberOfIntervals;
}
/**
* Return array of variables to dump in CSV files, based on what defined
* in {@code Properties.OUTPUT_VARIABLES}
*
* @return
*/
public String[] getUsedVariables() throws IllegalStateException {
String property = Properties.OUTPUT_VARIABLES;
List<String> runtimeList = new ArrayList<String>();
for (RuntimeVariable var : RuntimeVariable.values()) {
runtimeList.add(var.toString());
}
//no choice define, just dump all runtime variables
if (property == null) {
handleTimelineVariableHeaders(runtimeList);
return runtimeList.toArray(new String[runtimeList.size()]);
}
//extract parameters
String[] splitArray = property.split(",");
List<String> usedList = new ArrayList<String>();
for (int i = 0; i < splitArray.length; i++) {
splitArray[i] = splitArray[i].trim();
if (!splitArray[i].isEmpty()) {
usedList.add(splitArray[i]);
}
}
//check if parameters exist
for (String param : usedList) {
if (runtimeList.contains(param)) {
continue;
}
if (Properties.hasParameter(param)) {
continue;
}
throw new IllegalStateException("Parameter \"" + param
+ "\" defined inside \"output_variables\" does not exist");
}
handleTimelineVariableHeaders(usedList);
String[] usedArray = usedList.toArray(new String[usedList.size()]);
return usedArray;
}
private void handleTimelineVariableHeaders(List<String> usedList) {
/*
* now, handle timeline variables. For now, it is just coverage
*/
String covTimeline = RuntimeVariable.CoverageTimeline.toString();
if (usedList.contains(covTimeline)) {
usedList.remove(covTimeline);
for (String suf : getTimelineHeaderSuffixes()) {
usedList.add(covTimeline + suf);
}
}
}
/**
* Return value of a parameter, based on whether it is a EvoSuite
* property (e.g., population size), or something calculated at runtime
* (e.g. coverage)
*
* @return
*/
private String getValueOfOutputVariable(String name) {
//first check if it is an EvoSuite parameter (e.g. population size)
if (Properties.hasParameter(name)) {
try {
return Properties.getStringValue(name);
} catch (Exception e) {
/*
* when we call this method, the parameters should had been already validated, and program aborted if necessary.
* An exception here is likely a bug
*/
logger.error("Error in getting value of parameter " + name, e);
throw new Error(
"If this method inside EvoSuite is called, then it should never happen that the following exception is raised: "
+ e.getMessage());
}
}
if (isTimelineVariable(name)) {
return timeLineValue(name);
}
//check if it is a runtime property of the search, e.g. coverage
RuntimeVariable var = null;
try {
var = RuntimeVariable.valueOf(name);
} catch (Exception e) {
//note: we throw an Error as this protected method should never be called with wrong input / or on wrong internal state
throw new Error("Parameter " + name + " does not exist");
}
//if it is not an EvoSuite property, it has to be a runtime one
return getCSVvalue(var);
}
private String timeLineValue(String name) {
long interval = Properties.TIMELINE_INTERVAL;
int index = Integer.parseInt((name.split("_T"))[1]);
long preferredTime = interval * index;
assert this.timeStamps.size() == this.coverage_history.size();
/*
* No data. Is it even possible? Maybe if population is too large,
* and budget was not enough to get even first generation
*/
if (timeStamps.size() == 0) {
return "" + 0;
}
for (int i = 0; i < timeStamps.size(); i++) {
/*
* find the first stamp that is after the time we would like to
* get coverage from
*/
long stamp = timeStamps.get(i);
if (stamp < preferredTime) {
continue;
}
if (i == 0) {
/*
* it is the first element, so not much to do, we just use it as value
*/
return "" + coverage_history.get(i);
}
/*
* Now we interpolate the coverage, as usually we don't have the value for exact time we want
*/
long timeDelta = timeStamps.get(i) - timeStamps.get(i - 1);
if (timeDelta > 0) {
double covDelta = coverage_history.get(i)
- coverage_history.get(i - 1);
double ratio = covDelta / timeDelta;
long diff = preferredTime - timeStamps.get(i - 1);
double cov = coverage_history.get(i - 1) + (diff * ratio);
return "" + cov;
}
}
/*
* No time stamp was higher. This might happen if coverage is 100% and we stop search.
* So just return last value seen
*/
return "" + coverage_history.get(coverage_history.size() - 1);
}
private boolean isTimelineVariable(String name) {
if (name == null || name.isEmpty()) {
return false;
}
if (name.startsWith(RuntimeVariable.CoverageTimeline.toString())) {
return true;
} else {
return false;
}
}
public String getCSVHeader() {
StringBuilder r = new StringBuilder();
String[] variables = getUsedVariables();
if (variables.length > 0) {
r.append(variables[0]);
}
for (int i = 1; i < variables.length; i++) {
r.append(",");
r.append(variables[i]);
}
return r.toString();
}
public String getCSVData() {
StringBuilder r = new StringBuilder();
String[] variables = getUsedVariables();
if (variables.length > 0) {
r.append(getValueOfOutputVariable(variables[0]));
}
for (int i = 1; i < variables.length; i++) {
r.append(",");
r.append(getValueOfOutputVariable(variables[i]));
}
return r.toString();
}
private String getCSVvalue(RuntimeVariable var) {
PermissionStatistics pstats = PermissionStatistics.getInstance();
switch (var) {
case Class:
return className;
case Predicates:
return "" + total_branches;
case Total_Branches:
return "" + (total_branches * 2);
case Covered_Branches:
return "" + covered_branches;
case Total_Methods:
return "" + total_methods;
case Branchless_Methods:
return "" + branchless_methods;
case Covered_Methods:
return "" + covered_methods;
case Covered_Branchless_Methods:
return "" + covered_branchless_methods;
case Total_Goals:
return "" + total_goals;
case Covered_Goals:
return "" + covered_goals;
case Coverage:
return "" + getCoverageDouble();
case NumberOfGeneratedTestCases:
return ""+ (tests!=null? tests.size() : 0);
case NumberOfInputPoolObjects:
String s = Properties.OBJECT_POOLS;
if(s==null || s.isEmpty()){
return ""+0;
} else {
return ""+s.split(File.pathSeparator).length;
}
case BranchCoverage:
double cov = 0.0;
if (total_branches + branchless_methods > 0)
cov = (double) (covered_branches + covered_branchless_methods)
/ (double) ((total_branches * 2) + branchless_methods);
else
cov = 1.0;
if (!(cov >= 0 && cov <= 1)) {
String message = "Invalid coverage: " + cov;
message += " . covered_branches=" + covered_branches;
message += " , covered_branchless_methods="
+ covered_branchless_methods;
message += " , total_branches*2=" + (total_branches * 2);
message += " , branchless_methods=" + branchless_methods;
logger.error(message);
throw new AssertionError("Wrong coverage value: " + cov);
}
return "" + cov;
case DefUseCoverage:
if (coverageMap.containsKey("DEFUSE"))
return "" + coverageMap.get("DEFUSE");
else
return "";
case WeakMutationScore:
if (coverageMap.containsKey("WEAKMUTATION"))
return "" + coverageMap.get("WEAKMUTATION");
else
return "";
case Creation_Time:
return "" + (minimized_time - start_time);
case Minimization_Time:
return "" + (minimized_time - end_time);
case Total_Time:
return "" + (end_time - start_time);
case Test_Execution_Time:
return "" + testExecutionTime;
case Goal_Computation_Time:
return "" + goalComputationTime;
case Result_Size:
return "" + size_final;
case Result_Length:
return "" + length_final;
case Minimized_Size:
return "" + size_minimized;
case Minimized_Length:
return "" + length_minimized;
case Chromosome_Length:
return "" + chromosome_length;
case Population_Size:
return "" + population_size;
case Random_Seed:
return "" + seed;
case Budget:
return "" + Properties.SEARCH_BUDGET;
case AllPermission:
return "" + pstats.getNumAllPermission();
case SecurityPermission:
return "" + pstats.getNumSecurityPermission();
case UnresolvedPermission:
return "" + pstats.getNumUnresolvedPermission();
case AWTPermission:
return "" + pstats.getNumAWTPermission();
case FilePermission:
return "" + pstats.getNumFilePermission();
case SerializablePermission:
return "" + pstats.getNumSerializablePermission();
case ReflectPermission:
return "" + pstats.getNumReflectPermission();
case RuntimePermission:
return "" + pstats.getNumRuntimePermission();
case NetPermission:
return "" + pstats.getNumNetPermission();
case SocketPermission:
return "" + pstats.getNumSocketPermission();
case SQLPermission:
return "" + pstats.getNumSQLPermission();
case PropertyPermission:
return "" + pstats.getNumPropertyPermission();
case LoggingPermission:
return "" + pstats.getNumLoggingPermission();
case SSLPermission:
return "" + pstats.getNumSSLPermission();
case AuthPermission:
return "" + pstats.getNumAuthPermission();
case AudioPermission:
return "" + pstats.getNumAudioPermission();
case OtherPermission:
return "" + pstats.getNumOtherPermission();
case Threads:
return "" + pstats.getMaxThreads();
case CoveredBranchesBitString:
return "" + goalCoverage;
case MutationScore:
return "" + mutationScore;
case Explicit_MethodExceptions:
return "" + explicitMethodExceptions;
case Explicit_TypeExceptions:
return "" + explicitTypeExceptions;
case Implicit_MethodExceptions:
return "" + implicitMethodExceptions;
case Implicit_TypeExceptions:
return "" + implicitTypeExceptions;
case Error_Predicates:
return "" + error_branches;
case Error_Branches_Covered:
return "" + error_branches_covered;
case Error_Branchless_Methods:
return "" + error_branchless_methods;
case Error_Branchless_Methods_Covered:
return "" + error_branchless_methods_covered;
case AssertionContract:
return ""
+ FailingTestSet.getNumberOfViolations(AssertionErrorContract.class);
case EqualsContract:
return "" + FailingTestSet.getNumberOfViolations(EqualsContract.class);
case EqualsHashcodeContract:
return ""
+ FailingTestSet.getNumberOfViolations(EqualsHashcodeContract.class);
case EqualsNullContract:
return ""
+ FailingTestSet.getNumberOfViolations(EqualsNullContract.class);
case EqualsSymmetricContract:
return ""
+ FailingTestSet.getNumberOfViolations(EqualsSymmetricContract.class);
case HashCodeReturnsNormallyContract:
return ""
+ FailingTestSet.getNumberOfViolations(HashCodeReturnsNormallyContract.class);
case JCrasherExceptionContract:
return ""
+ FailingTestSet.getNumberOfViolations(JCrasherExceptionContract.class);
case NullPointerExceptionContract:
return ""
+ FailingTestSet.getNumberOfViolations(NullPointerExceptionContract.class);
case ToStringReturnsNormallyContract:
return ""
+ FailingTestSet.getNumberOfViolations(ToStringReturnsNormallyContract.class);
case UndeclaredExceptionContract:
return ""
+ FailingTestSet.getNumberOfViolations(UndeclaredExceptionContract.class);
case Contract_Violations:
return "" + FailingTestSet.getNumberOfViolations();
case Unique_Violations:
return "" + FailingTestSet.getNumberOfUniqueViolations();
case Data_File:
return getCSVFilepath();
case Statements_Executed:
return "" + result_statements_executed;
case Definitions:
//if (Properties.CRITERION == Properties.Criterion.DEFUSE
// || Properties.ANALYSIS_CRITERIA.toUpperCase().contains("DEFUSE"))
// return "" + DefUsePool.getDefCounter();
//else
return ""+numDefinitions;
case Uses:
//if (Properties.CRITERION == Properties.Criterion.DEFUSE
// || Properties.ANALYSIS_CRITERIA.toUpperCase().contains("DEFUSE"))
// return "" + DefUsePool.getUseCounter();
//else
return "" + numUses;
case DefUsePairs:
//if (Properties.CRITERION == Properties.Criterion.DEFUSE
// || Properties.ANALYSIS_CRITERIA.toUpperCase().contains("DEFUSE"))
// return "" + DefUseCoverageFactory.getDUGoals().size();
//else
return ""+numDefUsePairs;
case IntraMethodPairs:
//if (Properties.CRITERION == Properties.Criterion.DEFUSE
// || Properties.ANALYSIS_CRITERIA.toUpperCase().contains("DEFUSE"))
// return "" + DefUseCoverageFactory.getIntraMethodGoalsCount();
//else
return ""+numIntraMethodPairs;
case InterMethodPairs:
//if (Properties.CRITERION == Properties.Criterion.DEFUSE
// || Properties.ANALYSIS_CRITERIA.toUpperCase().contains("DEFUSE"))
// return "" + DefUseCoverageFactory.getInterMethodGoalsCount();
//else
return "" + numInterMethodPairs;
case IntraClassPairs:
//if (Properties.CRITERION == Properties.Criterion.DEFUSE
// || Properties.ANALYSIS_CRITERIA.toUpperCase().contains("DEFUSE"))
// return "" + DefUseCoverageFactory.getIntraClassGoalsCount();
//else
return ""+numIntraClassPairs;
case ParameterPairs:
//if (Properties.CRITERION == Properties.Criterion.DEFUSE
// || Properties.ANALYSIS_CRITERIA.toUpperCase().contains("DEFUSE"))
// return "" + DefUseCoverageFactory.getParamGoalsCount();
//else
return ""+numParameterPairs;
case CoveredIntraMethodPairs:
return "" + coveredIntraMethodPairs;
case CoveredInterMethodPairs:
return "" + coveredInterMethodPairs;
case CoveredIntraClassPairs:
return "" + coveredIntraClassPairs;
case CoveredParameterPairs:
return "" + coveredParameterPairs;
case CoveredAliasIntraMethodPairs:
return "" + coveredAliasIntraMethodPairs;
case CoveredAliasInterMethodPairs:
return "" + coveredAliasInterMethodPairs;
case CoveredAliasIntraClassPairs:
return "" + coveredAliasIntraClassPairs;
case CoveredAliasParameterPairs:
return "" + coveredAliasParameterPairs;
case AliasingIntraMethodPairs:
return "" + aliasingIntraMethodPairs;
case AliasingInterMethodPairs:
return "" + aliasingInterMethodPairs;
case AliasingIntraClassPairs:
return "" + aliasingIntraClassPairs;
case AliasingParameterPairs:
return "" + aliasingParameterPairs;
case CarvedTests:
return ""+JUnitTestCarvedChromosomeFactory.getTotalNumberOfTestsCarved();
case CarvedCoverage:
return ""+JUnitTestCarvedChromosomeFactory.getCoverageOfCarvedTests();
case HadUnstableTests:
return ""+hadUnstableTests;
default:
break;
}
/*
* note, this should never happen. If it does, then it is a bug in EvoSuite. But instead of throwing an exception,
* we just log it. In this way, we still get the CSV file for debugging
*/
logger.error("No mapping defined for variable " + var.toString());
return "-1";
}
public String getCSVFilepath() {
return getReportDir().getAbsolutePath() + File.separator + getCSVFileName();
}
public String getCSVFileName() {
return "data" + File.separator + "statistics_" + className + "-" + id
+ ".csv.gz";
}
public String getExceptionFilepath() {
return getReportDir().getAbsolutePath() + "/data/exceptions_" + className
+ "-" + id + ".csv";
}
public String getCoverage() {
if (total_goals == 0)
return "100.00%";
else
return String.format("%.2f",
(100.0 * covered_goals / (1.0 * total_goals))).replaceAll(",",
".")
+ "%";
}
public double getCoverageDouble() {
if (total_goals == 0)
return 1.0;
else
return covered_goals / (1.0 * total_goals);
}
};
protected List<StatisticEntry> statistics = new ArrayList<StatisticEntry>();
/** Constant <code>html_analyzer</code> */
protected static final HtmlAnalyzer html_analyzer = new HtmlAnalyzer();
/**
* <p>
* writeIntegerChart
* </p>
*
* @param values
* a {@link java.util.List} object.
* @param className
* a {@link java.lang.String} object.
* @param title
* a {@link java.lang.String} object.
* @return a {@link java.lang.String} object.
*/
protected String writeIntegerChart(List<Integer> values, String className,
String title) {
File file = new File(getReportDir().getAbsolutePath() + "/img/statistics_"
+ title + "_" + className + ".png");
JavaPlot plot = new JavaPlot();
GNUPlotTerminal terminal = new FileTerminal("png", getReportDir()
+ "/img/statistics_" + title + "_" + className + ".png");
plot.setTerminal(terminal);
// plot.set("size", "1, 0.5");
plot.set("xlabel", "\"Generation\"");
plot.set("ylabel", "\"" + title + "\"");
// plot.set("xrange", "[0:]");
// plot.set("yrange", "[0:]");
plot.set("autoscale", "ymax");
int[][] data = new int[values.size()][2];
for (int i = 0; i < values.size(); i++) {
data[i][0] = i;
data[i][1] = values.get(i);
}
plot.addPlot(data);
PlotStyle stl = ((AbstractPlot) plot.getPlots().get(0)).getPlotStyle();
stl.setStyle(Style.LINESPOINTS);
plot.setKey(JavaPlot.Key.OFF);
plot.plot();
return file.getName();
}
/**
* <p>
* writeDoubleChart
* </p>
*
* @param values
* a {@link java.util.List} object.
* @param className
* a {@link java.lang.String} object.
* @param title
* a {@link java.lang.String} object.
* @return a {@link java.lang.String} object.
*/
protected String writeDoubleChart(List<Double> values, String className, String title) {
File file = new File(getReportDir().getAbsolutePath() + "/img/statistics_"
+ title + "_" + className + ".png");
JavaPlot plot = new JavaPlot();
GNUPlotTerminal terminal = new FileTerminal("png", getReportDir()
+ "/img/statistics_" + title + "_" + className + ".png");
plot.setTerminal(terminal);
//plot.set("size", "1, 0.8");
plot.set("xlabel", "\"Generation\"");
plot.set("ylabel", "\"" + title + "\"");
// plot.set("xrange", "[0:]");
// plot.set("yrange", "[0:]");
plot.set("autoscale", "ymax");
double[][] data = new double[values.size()][2];
for (int i = 0; i < values.size(); i++) {
data[i][0] = i;
data[i][1] = values.get(i);
}
plot.addPlot(data);
PlotStyle stl = ((AbstractPlot) plot.getPlots().get(0)).getPlotStyle();
stl.setStyle(Style.LINESPOINTS);
plot.setKey(JavaPlot.Key.OFF);
plot.plot();
return file.getName();
}
/**
* HTML header
*
* @param buffer
* a {@link java.lang.StringBuffer} object.
* @param title
* a {@link java.lang.String} object.
*/
public static void writeHTMLHeader(StringBuffer buffer, String title) {
buffer.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">\n");
buffer.append("<html>\n");
buffer.append("<head>\n");
buffer.append("<title>\n");
buffer.append(title);
buffer.append("\n</title>\n");
buffer.append("<link href=\"files/prettify.css\" type=\"text/css\" rel=\"stylesheet\" />\n");
buffer.append("<link href=\"files/style.css\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\"/>\n");
buffer.append("<script type=\"text/javascript\" src=\"files/prettify.js\"></script>\n");
buffer.append("<script type=\"text/javascript\" src=\"files/jquery.js\"></script>\n");
buffer.append("<script type=\"text/javascript\" src=\"files/foldButton.js\"></script>\n");
buffer.append("<script type=\"text/javascript\">\n");
buffer.append(" $(document).ready(function() {\n");
//buffer.append(" $('div.tests').foldButton({'closedText':'open TITLE' });\n");
//buffer.append(" $('div.source').foldButton({'closedText':'open TITLE' });\n");
//buffer.append(" $('div.statistics').foldButton({'closedText':'open TITLE' });\n");
buffer.append(" $('H2#tests').foldButton();\n");
buffer.append(" $('H2#source').foldButton();\n");
buffer.append(" $('H2#parameters').foldButton();\n");
buffer.append(" });");
buffer.append("</script>\n");
buffer.append("<link href=\"files/foldButton.css\" rel=\"stylesheet\" type=\"text/css\">\n");
buffer.append("</head>\n");
buffer.append("<body onload=\"prettyPrint()\">\n");
buffer.append("<div id=\"wrapper\">\n");
buffer.append("<img src=\"files/evosuite.png\" height=\"40\"/>\n");
}
/**
* HTML footer
*
* @param buffer
* a {@link java.lang.StringBuffer} object.
*/
public static void writeHTMLFooter(StringBuffer buffer) {
buffer.append("</div>\n");
buffer.append("</body>\n");
buffer.append("</html>\n");
}
/**
* <p>
* writeCSVData
* </p>
*
* @param filename
* a {@link java.lang.String} object.
* @param data
* a {@link java.util.List} object.
*/
protected void writeCSVData(String filename, List<?>... data) {
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(filename,
false));
out.putNextEntry(new ZipEntry(filename.replace(".gz", "")));
//BufferedWriter out = new BufferedWriter(new FileWriter(filename, true));
int length = Integer.MAX_VALUE;
out.write("Generation,Fitness,Coverage,Size,Length,AverageLength,Evaluations,Tests,Statements,Time\n".getBytes());
for (List<?> d : data) {
length = Math.min(length, d.size());
}
for (int i = 0; i < length; i++) {
out.write(("" + i).getBytes());
for (List<?> d : data) {
out.write(("," + d.get(i)).getBytes());
}
out.write("\n".getBytes());
}
out.close();
} catch (IOException e) {
logger.info("Exception while writing CSV data: " + e);
}
}
/**
* <p>
* writeExceptionData
* </p>
*
* @param filename
* a {@link java.lang.String} object.
* @param exceptions
* a {@link java.util.Map} object.
*/
protected void writeExceptionData(String filename,
Map<String, Set<Class<?>>> implicitExceptions,
Map<String, Set<Class<?>>> explicitExceptions) {
try {
BufferedWriter out = new BufferedWriter(new FileWriter(filename, true));
out.write("Method,Exception,Explicit\n");
for (String key : explicitExceptions.keySet()) {
for (Class<?> exception : explicitExceptions.get(key)) {
out.write(key + "," + exception.getCanonicalName() + ",1\n");
}
}
for (String key : implicitExceptions.keySet()) {
for (Class<?> exception : implicitExceptions.get(key)) {
out.write(key + "," + exception.getCanonicalName() + ",0\n");
}
}
out.close();
} catch (IOException e) {
logger.info("Exception while writing exception data: " + e);
}
}
/**
* <p>
* getNumber
* </p>
*
* @param className
* a {@link java.lang.String} object.
* @return a int.
*/
protected int getNumber(final String className) {
int num = 0;
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith("statistics_" + className)
&& (name.endsWith(".csv.gz") || name.endsWith(".csv")); // && !dir.isDirectory();
}
};
List<String> filenames = new ArrayList<String>();
File[] files = (new File(getReportDir().getAbsolutePath() + "/data")).listFiles(filter);
if (files != null) {
for (File f : files)
filenames.add(f.getName());
while (filenames.contains("statistics_" + className + "-" + num + ".csv")
|| filenames.contains("statistics_" + className + "-" + num
+ ".csv.gz"))
num++;
}
return num;
}
/**
* Write a file for a particular run
*
* @param run
* a {@link org.evosuite.utils.ReportGenerator.StatisticEntry}
* object.
* @return a {@link java.lang.String} object.
*/
protected String writeRunPage(StatisticEntry run) {
StringBuffer sb = new StringBuffer();
writeHTMLHeader(sb, run.className);
sb.append("<div id=\"header\"><div id=\"logo\">");
sb.append("<h2>");
sb.append(run.className);
sb.append(": ");
sb.append(String.format("%.2f", 100.0 * run.covered_goals / run.total_goals));
sb.append("%");
sb.append("</h2></div></div>\n");
sb.append("<p><a href=\"../report-generation.html\">Overview</a></p>\n");
writeResultTable(sb, run);
// writeMutationTable(sb);
sb.append("<div id=\"page\"><div id=\"page-bgtop\"><div id=\"page-bgbtm\"><div id=\"content\">");
sb.append("<div id=\"post\">");
// Resulting test case
sb.append("<h2 class=title>Test suite</h2>\n");
if (run.tests != null) {
int num = 0;
for (TestCase test : run.tests) {
sb.append("<h3>Test case ");
sb.append(++num);
sb.append("</h3>\n");
/*
* if(test.exceptionThrown != null) { sb.append("<p>Raises:");
* sb.append(test.exceptionThrown); sb.append("</p>"); }
*/
sb.append("<pre class=\"prettyprint\" style=\"border: 1px solid #888;padding: 2px\">\n");
int linecount = 1;
String code = null;
if (run.results.containsKey(test))
code = test.toCode(run.results.get(test));
else
code = test.toCode();
for (String line : code.split("\n")) {
sb.append(String.format("<span class=\"nocode\"><a name=\"%d\">%3d: </a></span>",
linecount, linecount));
/*
* if(test.exceptionsThrown != null &&
* test.exception_statement == test_line)
* sb.append("<span style=\"background: #FF0000\">");
*/
sb.append(StringEscapeUtils.escapeHtml4(line));
/*
* if(test.exceptionThrown != null &&
* test.exception_statement == test_line)
* sb.append("</span>");
*/
linecount++;
sb.append("\n");
}
sb.append("</pre>\n");
}
} else {
sb.append("No test cases generated");
}
sb.append("</div>");
sb.append("<div id=\"post\">");
// Source code
/*
* Iterable<String> source =
* html_analyzer.getClassContent(run.className);
* sb.append("<h2>Coverage</h2>\n"); sb.append("<p>"); sb.append(
* "<pre class=\"prettyprint\" style=\"border: 1px solid #888;padding: 2px\">"
* ); int line_num = run.mutation.getLineNumber() - 3; if(line_num < 0)
* line_num = 0; int linecount = 1; for (String line : source) {
* if(linecount >= line_num && linecount < (line_num + 6)) {
* sb.append(String.format( "<span class=\"nocode\">%3d: </span>",
* linecount)); sb.append(StringEscapeUtils.escapeHtml(line));
* sb.append("\n"); } linecount++; } sb.append("</pre>\n");
*/
// Chart of fitness
if (Properties.PLOT) {
if (run.fitness_history.isEmpty()) {
sb.append("<h2>No fitness history</h2>\n");
} else {
String filename = writeDoubleChart(run.fitness_history, run.className
+ "-" + run.id, "Fitness");
sb.append("<h2>Fitness</h2>\n");
sb.append("<p>");
sb.append("<img src=\"../img/");
sb.append(filename);
sb.append("\">");
sb.append("</p>\n");
}
// Chart of size
if (run.size_history.isEmpty()) {
sb.append("<h2>No size history</h2>\n");
} else {
String filename = writeIntegerChart(run.size_history, run.className + "-"
+ run.id, "Size");
sb.append("<h2>Size</h2>\n");
sb.append("<p>");
sb.append("<img src=\"../img/");
sb.append(filename);
sb.append("\">");
sb.append("</p>\n");
}
// Chart of length
if (run.length_history.isEmpty()) {
sb.append("<h2>No length history</h2>\n");
} else {
String filename = writeIntegerChart(run.length_history, run.className
+ "-" + run.id, "Length");
sb.append("<h2>Length</h2>\n");
sb.append("<p>");
sb.append("<img src=\"../img/");
sb.append(filename);
sb.append("\">");
sb.append("</p>\n");
}
// Chart of average length
if (run.average_length_history.isEmpty()) {
sb.append("<h2>No average length history</h2>\n");
} else {
String filename = writeDoubleChart(run.average_length_history,
run.className + "-" + run.id, "Length");
sb.append("<h2>Average Length</h2>\n");
sb.append("<p>");
sb.append("<img src=\"../img/");
sb.append(filename);
sb.append("\">");
sb.append("</p>\n");
}
}
sb.append("</div>");
sb.append("<div id=\"post\">");
// Source code
try {
Iterable<String> source = html_analyzer.getClassContent(run.className);
sb.append("<h2 class=title>Source Code</h2>\n");
sb.append("<p>");
sb.append("<pre class=\"prettyprint\" style=\"border: 1px solid #888;padding: 2px\">");
int linecount = 1;
for (String line : source) {
sb.append(String.format("<span class=\"nocode\"><a name=\"%d\">%3d: </a></span>",
linecount, linecount));
if (run.coverage.contains(linecount)) {
sb.append("<span style=\"background-color: #ffffcc\">");
sb.append(StringEscapeUtils.escapeHtml4(line));
sb.append("</span>");
}
else
sb.append(StringEscapeUtils.escapeHtml4(line));
sb.append("\n");
linecount++;
}
sb.append("</pre>\n");
sb.append("</p>\n");
} catch (Exception e) {
// Don't display source if there is an error
}
sb.append("</div>");
sb.append("<div id=\"post\">");
writeParameterTable(sb, run);
sb.append("</div>");
writeHTMLFooter(sb);
String filename = "report-" + run.className + "-" + run.id + ".html";
File file = new File(getReportDir().getAbsolutePath() + "/html/" + filename);
Utils.writeFile(sb.toString(), file);
// return file.getAbsolutePath();
return filename;
}
/**
* Write some overall stats
*
* @param buffer
* a {@link java.lang.StringBuffer} object.
* @param entry
* a {@link org.evosuite.utils.ReportGenerator.StatisticEntry}
* object.
*/
protected void writeParameterTable(StringBuffer buffer, StatisticEntry entry) {
buffer.append("<h2 id=parameters>EvoSuite Parameters</h2>\n");
buffer.append("<div class=statistics><ul>\n");
for (String key : Properties.getParameters()) {
try {
buffer.append("<li>" + key + ": " + Properties.getStringValue(key) + "\n"); // TODO
} catch (NoSuchParameterException e) {
logger.error(e.getMessage(),e);
} catch (IllegalArgumentException e) {
logger.error(e.getMessage(),e);
} catch (IllegalAccessException e) {
logger.error(e.getMessage(),e);
}
}
buffer.append("</ul></div>\n");
}
/**
* Write some overall stats
*
* @param buffer
* a {@link java.lang.StringBuffer} object.
* @param entry
* a {@link org.evosuite.utils.ReportGenerator.StatisticEntry}
* object.
*/
protected void writeResultTable(StringBuffer buffer, StatisticEntry entry) {
//buffer.append("<h2>Statistics</h2>\n");
buffer.append("<ul>\n");
buffer.append("<li>");
buffer.append(entry.result_fitness_evaluations);
buffer.append(" fitness evaluations, ");
buffer.append(entry.age);
buffer.append(" generations, ");
buffer.append(entry.result_statements_executed);
buffer.append(" statements, ");
buffer.append(entry.result_tests_executed);
buffer.append(" tests.\n");
long duration_GA = (entry.end_time - entry.start_time) / 1000;
long duration_MI = (entry.minimized_time - entry.end_time) / 1000;
long duration_TO = (entry.minimized_time - entry.start_time) / 1000;
buffer.append("<li>Time: "
+ String.format("%d:%02d:%02d", duration_TO / 3600,
(duration_TO % 3600) / 60, (duration_TO % 60)));
buffer.append("(Search: "
+ String.format("%d:%02d:%02d", duration_GA / 3600,
(duration_GA % 3600) / 60, (duration_GA % 60)) + ", ");
buffer.append("minimization: "
+ String.format("%d:%02d:%02d", duration_MI / 3600,
(duration_MI % 3600) / 60, (duration_MI % 60)) + ")\n");
buffer.append("<li>Coverage: " + entry.covered_branches + "/"
+ (2 * entry.total_branches) + " branches, ");
buffer.append(entry.covered_methods + "/" + entry.total_methods + " methods, ");
buffer.append(entry.covered_goals + "/" + entry.total_goals + " total goals\n");
buffer.append("<li>Mutation score: "
+ NumberFormat.getPercentInstance().format(entry.mutationScore) + "\n");
buffer.append("</ul>\n");
}
/**
* The big table of results
*
* @param buffer
* a {@link java.lang.StringBuffer} object.
*/
protected void writeRunTable(StringBuffer buffer) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
for (StatisticEntry entry : statistics) {
buffer.append("<tr>");
// buffer.append("<td>" + entry.id + "</td>");
buffer.append("<td>");
buffer.append(sdf.format(new Date(entry.start_time)));
buffer.append("</td>");
long duration_TO = (entry.minimized_time - entry.start_time) / 1000;
buffer.append("<td>");
buffer.append(String.format("%d:%02d:%02d", duration_TO / 3600,
(duration_TO % 3600) / 60, (duration_TO % 60)));
buffer.append("</td>");
buffer.append("<td>");
buffer.append(entry.getCoverage());
buffer.append("</td>");
buffer.append("<td><a href=\"html/");
String filename = writeRunPage(entry);
buffer.append(filename);
buffer.append("\">");
buffer.append(entry.className);
// buffer.append("</a></td>");
// buffer.append("<td><a href=\"");
// buffer.append(entry.getCSVFileName());
// buffer.append("\">CSV</a></td>");
buffer.append("</tr>\n");
}
//
buffer.append("<!-- EVOSUITE INSERTION POINT -->\n");
buffer.append("<tr class=\"top\"><td colspan=\"3\"> <td></tr>\n");
buffer.append("</table>");
}
/**
* <p>
* writeCSV
* </p>
*/
public void writeCSV() {
if (statistics.isEmpty())
return;
StatisticEntry entry = statistics.get(statistics.size() - 1);
try {
File f = new File(getReportDir().getAbsolutePath() + "/statistics.csv");
logger.info("Writing CSV to "+f.getAbsolutePath());
BufferedWriter out = new BufferedWriter(new FileWriter(f, true));
if (f.length() == 0L) {
out.write(entry.getCSVHeader() + "\n");
}
out.write(entry.getCSVData() + "\n");
out.close();
} catch (IOException e) {
logger.warn("Error while writing statistics: " + e.getMessage());
}
if (Properties.SAVE_ALL_DATA) {
if (ArrayUtil.contains(Properties.CRITERION, Properties.Criterion.EXCEPTION)) {
writeExceptionData(entry.getExceptionFilepath(),
entry.implicitExceptions, entry.explicitExceptions);
}
writeCSVData(entry.getCSVFilepath(), entry.fitness_history,
entry.coverage_history, entry.size_history,
entry.length_history, entry.average_length_history,
entry.fitness_evaluations, entry.tests_executed,
entry.statements_executed, entry.timeStamps);
}
}
/**
* <p>
* copyFile
* </p>
*
* @param src
* a {@link java.net.URL} object.
* @param dest
* a {@link java.io.File} object.
*/
public static void copyFile(URL src, File dest) {
try {
InputStream in;
in = src.openStream();
OutputStream out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
logger.error(e.getMessage(),e);
}
}
/**
* <p>
* copyFile
* </p>
*
* @param name
* a {@link java.lang.String} object.
*/
public static void copyFile(String name) {
URL systemResource = ClassLoader.getSystemResource("report/" + name);
logger.debug("Copying from resource: " + systemResource);
copyFile(systemResource, new File(getReportDir(), "files/" + name));
copyFile(systemResource, new File(getReportDir().getAbsolutePath()
+ "/html/files/" + name));
}
/**
* Write an HTML report
*/
public void writeReport() {
if (!Properties.HTML)
return;
if (statistics.isEmpty())
return;
new File(getReportDir().getAbsolutePath() + "/img").mkdirs();
new File(getReportDir().getAbsolutePath() + "/html/files/").mkdirs();
new File(getReportDir().getAbsolutePath() + "/data/").mkdirs();
new File(getReportDir().getAbsolutePath() + "/files/").mkdirs();
copyFile("prettify.js");
copyFile("prettify.css");
copyFile("style.css");
copyFile("foldButton.js");
copyFile("foldButton.css");
copyFile("jquery.js");
copyFile("detected.png");
copyFile("not_detected.png");
copyFile("img01.jpg");
copyFile("img02.jpg");
copyFile("img03.jpg");
copyFile("img04.png");
copyFile("evosuite.png");
File file = new File(getReportDir(), "report-generation.html");
StringBuffer report = new StringBuffer();
if (file.exists()) {
List<String> lines = Utils.readFile(file);
for (String line : lines) {
if (line.contains("<!-- EVOSUITE INSERTION POINT -->")) {
break;
}
report.append(line);
}
} else {
writeHTMLHeader(report, Properties.PROJECT_PREFIX);
report.append("<div id=\"header\"><div id=\"logo\">");
/*
if (!Properties.PROJECT_PREFIX.isEmpty()) {
report.append("<h1 class=title>EvoSuite: " + Properties.PROJECT_PREFIX
+ "</h1>\n");
}
*/
report.append("</div><br></div>");
try {
report.append("Run on "
+ java.net.InetAddress.getLocalHost().getHostName() + "\n");
} catch (Exception e) {
}
report.append("<div id=\"page\"><div id=\"page-bgtop\"><div id=\"page-bgbtm\"><div id=\"content\">");
report.append("<div id=\"post\">");
report.append("<h2 class=\"title\">Test generation runs:</h2>\n");
report.append("<div style=\"clear: both;\"> </div><div class=\"entry\">");
report.append("<table cellspacing=0>"); // border=0 cellspacing=0 cellpadding=3>");
report.append("<tr class=\"top bottom\">");
// report.append("<td>Run</td>");
report.append("<td>Date</td>");
report.append("<td>Time</td>");
report.append("<td>Coverage</td>");
report.append("<td>Class</td>");
// report.append("<td></td>");
report.append("</tr>\n");
}
writeRunTable(report);
report.append("</div></div></div></div></div></div>");
writeHTMLFooter(report);
Utils.writeFile(report.toString(), file);
}
/**
* <p>
* getCoveredLines
* </p>
*
* @param trace
* a {@link org.evosuite.testcase.ExecutionTrace} object.
* @param className
* a {@link java.lang.String} object.
* @return a {@link java.util.Set} object.
*/
public Set<Integer> getCoveredLines(ExecutionTrace trace, String className) {
return trace.getCoveredLines(className);
}
/**
* <p>
* executeTest
* </p>
*
* @param testChromosome
* a {@link org.evosuite.testcase.TestChromosome} object.
* @param className
* a {@link java.lang.String} object.
* @return a {@link org.evosuite.testcase.ExecutionResult} object.
*/
public ExecutionResult executeTest(TestChromosome testChromosome, String className) {
ExecutionResult result = testChromosome.getLastExecutionResult();
if (result == null || testChromosome.isChanged()) {
try {
if (logger.isTraceEnabled()) {
logger.trace(testChromosome.getTestCase().toCode());
}
TestCaseExecutor executor = TestCaseExecutor.getInstance();
result = executor.execute(testChromosome.getTestCase());
} catch (Exception e) {
logger.error("TG: Exception caught: " + e.getMessage(), e);
try {
Thread.sleep(1000);
result.setTrace(ExecutionTracer.getExecutionTracer().getTrace());
} catch (Exception e1) {
logger.error("Cannot set trace in test case with exception. Going to kill client",
e1);
throw new Error(e1);
}
}
}
StatisticEntry entry = statistics.get(statistics.size() - 1);
entry.results.put(testChromosome.getTestCase(),
result.getCopyOfExceptionMapping());
return result;
}
/**
* <p>
* minimized
* </p>
*
* @param result
* a {@link org.evosuite.ga.Chromosome} object.
*/
public abstract void minimized(Chromosome result);
/**
* <p>
* makeDirs
* </p>
*/
protected void makeDirs() {
getReportDir().mkdirs();
if (Properties.SAVE_ALL_DATA)
(new File(getReportDir().getAbsolutePath() + "/data")).mkdir();
if (Properties.PLOT)
(new File(getReportDir().getAbsolutePath() + "/img")).mkdir();
if (Properties.HTML)
(new File(getReportDir().getAbsolutePath() + "/html")).mkdir();
}
/** {@inheritDoc} */
@Override
public void searchStarted(GeneticAlgorithm<?> algorithm) {
StatisticEntry entry = new StatisticEntry();
entry.className = Properties.TARGET_CLASS;
entry.id = getNumber(entry.className);
entry.start_time = System.currentTimeMillis();
entry.population_size = Properties.POPULATION;
entry.chromosome_length = Properties.CHROMOSOME_LENGTH;
entry.seed = Randomness.getSeed();
statistics.add(entry);
}
/** {@inheritDoc} */
@Override
public void iteration(GeneticAlgorithm<?> algorithm) {
StatisticEntry entry = statistics.get(statistics.size() - 1);
Chromosome best = algorithm.getBestIndividual();
entry.fitness_history.add(best.getFitness());
entry.size_history.add(best.size());
double average = 0.0;
for (Chromosome individual : algorithm.getPopulation()) {
average += individual.size();
}
entry.average_length_history.add(average / algorithm.getPopulation().size());
// TODO: Need to get data of average size in here - how? Pass population
// as parameter?
entry.age++;
}
/** {@inheritDoc} */
@Override
public void fitnessEvaluation(Chromosome result) {
StatisticEntry entry = statistics.get(statistics.size() - 1);
entry.result_fitness_evaluations++;
}
/*
* (non-Javadoc)
*
* @see
* org.evosuite.ga.SearchListener#mutation(org.evosuite
* .ga.Chromosome)
*/
/** {@inheritDoc} */
@Override
public void modification(Chromosome individual) {
// TODO Auto-generated method stub
}
}