/**
* 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.coverage.path;
import org.evosuite.testcase.ExecutionResult;
import org.evosuite.testcase.MethodCall;
import org.evosuite.testcase.TestChromosome;
import org.evosuite.testcase.TestFitnessFunction;
/**
* <p>
* PrimePathTestFitness class.
* </p>
*
* @author Gordon Fraser
*/
public class PrimePathTestFitness extends TestFitnessFunction {
private static final long serialVersionUID = 704930253578667965L;
private final PrimePath path;
private final String className;
private final String methodName;
private final int length;
/**
* <p>
* Constructor for PrimePathTestFitness.
* </p>
*
* @param path
* a {@link org.evosuite.coverage.path.PrimePath} object.
* @param className
* a {@link java.lang.String} object.
* @param methodName
* a {@link java.lang.String} object.
*/
public PrimePathTestFitness(PrimePath path, String className, String methodName) {
this.path = path;
this.className = className;
this.methodName = methodName;
length = path.branches.size();
}
@SuppressWarnings("unused")
private static int getNextBranch(PrimePath path, int position) {
for (int i = position + 1; i < path.getSize(); i++) {
if (path.get(i).isBranch())
return i;
}
return path.getSize();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestFitnessFunction#getFitness(org.evosuite.testcase.TestChromosome, org.evosuite.testcase.ExecutionResult)
*/
/** {@inheritDoc} */
@Override
public double getFitness(TestChromosome individual, ExecutionResult result) {
double minMatch = length;
for (MethodCall call : result.getTrace().getMethodCalls()) {
if (call.className.equals(className) && call.methodName.equals(methodName)) {
double matches = 0.0;
for (Integer i : call.branchTrace) {
logger.debug(" |-> " + i);
}
logger.debug("-------");
logger.debug(path.toString());
for (int i = 0; i < path.branches.size(); i++) {
logger.debug(" -> " + path.branches.get(i).branch + " "
+ path.branches.get(i).value);
}
logger.debug("Length: " + length);
int pos_path = 0;
int pos_trace = 0;
while (pos_path < path.branches.size()) {
logger.debug("Current matches: " + matches);
if (pos_trace >= call.branchTrace.size()) {
logger.debug("End of trace?"
+ ": "
+ (normalize(call.trueDistanceTrace.get(pos_trace - 1)) + normalize(call.falseDistanceTrace.get(pos_trace - 1))));
matches += 1 - (normalize(call.trueDistanceTrace.get(pos_trace - 1)) + normalize(call.falseDistanceTrace.get(pos_trace - 1)));
break;
} else if (path.branches.get(pos_path).branch.getActualBranchId() == call.branchTrace.get(pos_trace)) {
logger.debug("Found branch match: "
+ path.branches.get(pos_path).branch);
matches++;
if (path.branches.get(pos_path).value == true) {
if (call.trueDistanceTrace.get(pos_trace) == 0.0) {
logger.debug("[True] Truth value match");
pos_path++;
pos_trace++;
} else {
logger.debug("[True] Truth value mismatch: "
+ (normalize(call.trueDistanceTrace.get(pos_trace)))
+ " / "
+ (normalize(call.falseDistanceTrace.get(pos_trace))));
matches -= (normalize(call.trueDistanceTrace.get(pos_trace)));
break;
}
} else {
if (call.falseDistanceTrace.get(pos_trace) == 0.0) {
logger.debug("[False] Truth value match");
pos_path++;
pos_trace++;
} else {
logger.debug("[False] Truth value mismatch: "
+ (normalize(call.falseDistanceTrace.get(pos_trace)))
+ " / "
+ (normalize(call.trueDistanceTrace.get(pos_trace))));
matches -= (normalize(call.falseDistanceTrace.get(pos_trace)));
break;
}
}
} else {
logger.warn("Size of trace: " + call.trueDistanceTrace.size());
logger.warn("Position: " + pos_trace);
logger.debug("Found mismatch at "
+ pos_path
+ " / "
+ path.getSize()
+ ": "
+ (normalize(call.trueDistanceTrace.get(pos_trace - 1)) + normalize(call.falseDistanceTrace.get(pos_trace - 1))));
matches += 1 - (normalize(call.trueDistanceTrace.get(pos_trace - 1)) + normalize(call.falseDistanceTrace.get(pos_trace - 1)));
// -1?
break;
}
}
matches = length - matches;
logger.debug("Current fitness: " + matches);
minMatch = Math.min(minMatch, matches);
logger.debug("Current best fitness: " + minMatch);
assert (minMatch >= 0) : "Fitness is " + minMatch;
}
}
logger.debug("Final Fitness: " + minMatch);
return minMatch;
}
/** {@inheritDoc} */
@Override
public String toString() {
return path.toString();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestFitnessFunction#compareTo(org.evosuite.testcase.TestFitnessFunction)
*/
@Override
public int compareTo(TestFitnessFunction other) {
if (other instanceof PrimePathTestFitness) {
// TODO
return length - ((PrimePathTestFitness) other).length;
}
return 0;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestFitnessFunction#getTargetClass()
*/
@Override
public String getTargetClass() {
return path.className;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestFitnessFunction#getTargetMethod()
*/
@Override
public String getTargetMethod() {
return path.methodName;
}
}