use of org.evosuite.coverage.mutation.Mutation in project evosuite by EvoSuite.
the class MutationInstrumentation method addInstrumentation.
/**
* <p>
* addInstrumentation
* </p>
*
* @param mn
* a {@link org.objectweb.asm.tree.MethodNode} object.
* @param original
* a {@link org.objectweb.asm.tree.AbstractInsnNode} object.
* @param mutations
* a {@link java.util.List} object.
*/
protected void addInstrumentation(MethodNode mn, AbstractInsnNode original, List<Mutation> mutations) {
InsnList instructions = new InsnList();
// TODO: All mutations in the id are touched, not just one!
for (Mutation mutation : mutations) {
instructions.add(mutation.getInfectionDistance());
instructions.add(new LdcInsnNode(mutation.getId()));
MethodInsnNode touched = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(ExecutionTracer.class), "passedMutation", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.DOUBLE_TYPE, Type.INT_TYPE }), false);
instructions.add(touched);
}
LabelNode endLabel = new LabelNode();
for (Mutation mutation : mutations) {
LabelNode nextLabel = new LabelNode();
LdcInsnNode mutationId = new LdcInsnNode(mutation.getId());
instructions.add(mutationId);
FieldInsnNode activeId = new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(MutationObserver.class), "activeMutation", "I");
instructions.add(activeId);
instructions.add(new JumpInsnNode(Opcodes.IF_ICMPNE, nextLabel));
instructions.add(mutation.getMutation());
instructions.add(new JumpInsnNode(Opcodes.GOTO, endLabel));
instructions.add(nextLabel);
}
mn.instructions.insertBefore(original, instructions);
mn.instructions.insert(original, endLabel);
}
use of org.evosuite.coverage.mutation.Mutation in project evosuite by EvoSuite.
the class MutationInstrumentation method analyze.
/* (non-Javadoc)
* @see org.evosuite.cfg.instrumentation.MethodInstrumentation#analyze(org.objectweb.asm.tree.MethodNode, java.lang.String, java.lang.String, int)
*/
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) {
if (methodName.startsWith("<clinit>"))
return;
if (methodName.startsWith(ClassResetter.STATIC_RESET))
return;
RawControlFlowGraph graph = GraphPool.getInstance(classLoader).getRawCFG(className, methodName);
Iterator<AbstractInsnNode> j = mn.instructions.iterator();
getFrames(mn, className);
boolean constructorInvoked = false;
if (!methodName.startsWith("<init>"))
constructorInvoked = true;
logger.info("Applying mutation operators ");
int frameIndex = 0;
int numMutants = 0;
if (frames.length != mn.instructions.size()) {
logger.error("Number of frames does not match number number of bytecode instructions: " + frames.length + "/" + mn.instructions.size());
logger.error("Skipping mutation of method " + className + "." + methodName);
return;
}
// + " vs " + mn.instructions.size();
while (j.hasNext()) {
Frame currentFrame = frames[frameIndex++];
AbstractInsnNode in = j.next();
if (!constructorInvoked) {
if (in.getOpcode() == Opcodes.INVOKESPECIAL) {
if (className.matches(".*\\$\\d+$")) {
// so best not mutate the constructor
continue;
}
MethodInsnNode cn = (MethodInsnNode) in;
Set<String> superClasses = new HashSet<String>();
if (DependencyAnalysis.getInheritanceTree() != null && DependencyAnalysis.getInheritanceTree().hasClass(className))
superClasses.addAll(DependencyAnalysis.getInheritanceTree().getSuperclasses(className));
superClasses.add(className);
String classNameWithDots = ResourceList.getClassNameFromResourcePath(cn.owner);
if (superClasses.contains(classNameWithDots)) {
constructorInvoked = true;
}
} else {
continue;
}
}
boolean inInstrumentation = false;
for (BytecodeInstruction v : graph.vertexSet()) {
// If the bytecode is instrumented by EvoSuite, then don't mutate
if (v.isLabel()) {
LabelNode labelNode = (LabelNode) v.getASMNode();
if (labelNode.getLabel() instanceof AnnotatedLabel) {
AnnotatedLabel aLabel = (AnnotatedLabel) labelNode.getLabel();
if (aLabel.isStartTag()) {
inInstrumentation = true;
} else {
inInstrumentation = false;
}
}
}
if (inInstrumentation) {
continue;
}
// If this is in the CFG
if (in.equals(v.getASMNode())) {
logger.info(v.toString());
List<Mutation> mutations = new LinkedList<Mutation>();
// TODO: More than one mutation operator might apply to the same instruction
for (MutationOperator mutationOperator : mutationOperators) {
if (numMutants++ > Properties.MAX_MUTANTS_PER_METHOD) {
logger.info("Reached maximum number of mutants per method");
break;
}
// logger.info("Checking mutation operator on instruction " + v);
if (mutationOperator.isApplicable(v)) {
logger.info("Applying mutation operator " + mutationOperator.getClass().getSimpleName());
mutations.addAll(mutationOperator.apply(mn, className, methodName, v, currentFrame));
}
}
if (!mutations.isEmpty()) {
logger.info("Adding instrumentation for mutation");
// InsnList instrumentation = getInstrumentation(in, mutations);
addInstrumentation(mn, in, mutations);
}
}
if (numMutants > Properties.MAX_MUTANTS_PER_METHOD) {
break;
}
}
}
j = mn.instructions.iterator();
logger.info("Result of mutation: ");
while (j.hasNext()) {
AbstractInsnNode in = j.next();
logger.info(new BytecodeInstruction(classLoader, className, methodName, 0, 0, in).toString());
}
logger.info("Done.");
// mn.maxStack += 3;
}
use of org.evosuite.coverage.mutation.Mutation in project evosuite by EvoSuite.
the class ReplaceBitwiseOperator method apply.
/* (non-Javadoc)
* @see org.evosuite.cfg.instrumentation.MutationOperator#apply(org.objectweb.asm.tree.MethodNode, java.lang.String, java.lang.String, org.evosuite.cfg.BytecodeInstruction)
*/
/**
* {@inheritDoc}
*/
@Override
public List<Mutation> apply(MethodNode mn, String className, String methodName, BytecodeInstruction instruction, Frame frame) {
numVariable = ReplaceArithmeticOperator.getNextIndex(mn);
// TODO: Check if this operator is applicable at all first
// Should we do this via a method defined in the interface?
InsnNode node = (InsnNode) instruction.getASMNode();
List<Mutation> mutations = new LinkedList<Mutation>();
Set<Integer> replacement = new HashSet<Integer>();
if (opcodesInt.contains(node.getOpcode()))
replacement.addAll(opcodesInt);
else if (opcodesIntShift.contains(node.getOpcode()))
replacement.addAll(opcodesIntShift);
else if (opcodesLong.contains(node.getOpcode()))
replacement.addAll(opcodesLong);
else if (opcodesLongShift.contains(node.getOpcode()))
replacement.addAll(opcodesLongShift);
replacement.remove(node.getOpcode());
for (int opcode : replacement) {
InsnNode mutation = new InsnNode(opcode);
// insert mutation into pool
Mutation mutationObject = MutationPool.addMutation(className, methodName, NAME + " " + getOp(node.getOpcode()) + " -> " + getOp(opcode), instruction, mutation, getInfectionDistance(node.getOpcode(), opcode));
mutations.add(mutationObject);
}
return mutations;
}
use of org.evosuite.coverage.mutation.Mutation in project evosuite by EvoSuite.
the class ReplaceConstant method apply.
/* (non-Javadoc)
* @see org.evosuite.cfg.instrumentation.MutationOperator#apply(org.objectweb.asm.tree.MethodNode, java.lang.String, java.lang.String, org.evosuite.cfg.BytecodeInstruction)
*/
/**
* {@inheritDoc}
*/
@Override
public List<Mutation> apply(MethodNode mn, String className, String methodName, BytecodeInstruction instruction, Frame frame) {
List<Mutation> mutations = new LinkedList<Mutation>();
Object value = getValue(instruction.getASMNode());
for (Object replacement : getReplacement(value)) {
// insert mutation into bytecode with conditional
LdcInsnNode mutation = new LdcInsnNode(replacement);
// insert mutation into pool
String summary = NAME + " - " + value + " -> " + replacement;
if (replacement instanceof String) {
summary = summary.replace("*/", "*_/");
}
Mutation mutationObject = MutationPool.addMutation(className, methodName, summary, instruction, mutation, Mutation.getDefaultInfectionDistance());
mutations.add(mutationObject);
}
return mutations;
}
use of org.evosuite.coverage.mutation.Mutation in project evosuite by EvoSuite.
the class InsertUnaryOperator method apply.
/* (non-Javadoc)
* @see org.evosuite.cfg.instrumentation.mutation.MutationOperator#apply(org.objectweb.asm.tree.MethodNode, java.lang.String, java.lang.String, org.evosuite.cfg.BytecodeInstruction)
*/
/**
* {@inheritDoc}
*/
@Override
public List<Mutation> apply(MethodNode mn, String className, String methodName, BytecodeInstruction instruction, Frame frame) {
// TODO - need to keep InsnList in Mutation, not only Instruction?
// Mutation: Insert an INEG _after_ an iload
List<Mutation> mutations = new LinkedList<Mutation>();
List<InsnList> mutationCode = new LinkedList<InsnList>();
List<String> descriptions = new LinkedList<String>();
if (instruction.getASMNode() instanceof VarInsnNode) {
try {
InsnList mutation = new InsnList();
VarInsnNode node = (VarInsnNode) instruction.getASMNode();
// insert mutation into bytecode with conditional
mutation.add(new VarInsnNode(node.getOpcode(), node.var));
mutation.add(new InsnNode(getNegation(node.getOpcode())));
mutationCode.add(mutation);
if (!mn.localVariables.isEmpty())
descriptions.add("Negation of " + getName(mn, node));
else
descriptions.add("Negation");
if (node.getOpcode() == Opcodes.ILOAD) {
if (frame.getStack(frame.getStackSize() - 1) != BooleanValueInterpreter.BOOLEAN_VALUE) {
mutation = new InsnList();
mutation.add(new IincInsnNode(node.var, 1));
mutation.add(new VarInsnNode(node.getOpcode(), node.var));
if (!mn.localVariables.isEmpty())
descriptions.add("IINC 1 " + getName(mn, node));
else
descriptions.add("IINC 1");
mutationCode.add(mutation);
mutation = new InsnList();
mutation.add(new IincInsnNode(node.var, -1));
mutation.add(new VarInsnNode(node.getOpcode(), node.var));
if (!mn.localVariables.isEmpty())
descriptions.add("IINC -1 " + getName(mn, node));
else
descriptions.add("IINC -1");
mutationCode.add(mutation);
}
}
} catch (VariableNotFoundException e) {
logger.info("Could not find variable: " + e);
return new ArrayList<Mutation>();
}
} else {
InsnList mutation = new InsnList();
FieldInsnNode node = (FieldInsnNode) instruction.getASMNode();
Type type = Type.getType(node.desc);
mutation.add(new FieldInsnNode(node.getOpcode(), node.owner, node.name, node.desc));
mutation.add(new InsnNode(getNegation(type)));
descriptions.add("Negation");
mutationCode.add(mutation);
if (type == Type.INT_TYPE) {
mutation = new InsnList();
mutation.add(new FieldInsnNode(node.getOpcode(), node.owner, node.name, node.desc));
mutation.add(new InsnNode(Opcodes.ICONST_1));
mutation.add(new InsnNode(Opcodes.IADD));
descriptions.add("+1");
mutationCode.add(mutation);
mutation = new InsnList();
mutation.add(new FieldInsnNode(node.getOpcode(), node.owner, node.name, node.desc));
mutation.add(new InsnNode(Opcodes.ICONST_M1));
mutation.add(new InsnNode(Opcodes.IADD));
descriptions.add("-1");
mutationCode.add(mutation);
}
}
int i = 0;
for (InsnList mutation : mutationCode) {
// insert mutation into pool
Mutation mutationObject = MutationPool.addMutation(className, methodName, NAME + " " + descriptions.get(i++), instruction, mutation, Mutation.getDefaultInfectionDistance());
mutations.add(mutationObject);
}
return mutations;
}
Aggregations