Writing a Filter - llmhyy/evosuite-plus-plus GitHub Wiki
- Create your method filter class file under the
evosuite.shell.listmethod
package. Ensure your filter class extends MethodFlagCondFilter
and overrides the checkMethod()
method. Below is an example method filter:
package evosuite.shell.listmethod;
public class ExampleMethodFilter extends MethodFlagCondFilter {
private static Logger log = LoggerUtils.getLogger(ExampleMethodFilter.class);
@Override
protected boolean checkMethod(ClassLoader classLoader, String className, String methodName, MethodNode node,
ClassNode cn) throws AnalyzerException, IOException, ClassNotFoundException {
log.debug(String.format("#Method %s#%s", className, methodName));
// Get actual CFG for target method
ActualControlFlowGraph cfg = GraphPool.getInstance(classLoader).getActualCFG(className,
methodName);
if (cfg == null) {
BytecodeAnalyzer bytecodeAnalyzer = new BytecodeAnalyzer();
bytecodeAnalyzer.analyze(classLoader, className, methodName, node);
bytecodeAnalyzer.retrieveCFGGenerator().registerCFGs();
cfg = GraphPool.getInstance(classLoader).getActualCFG(className, methodName);
}
// Get instructions for target method
BytecodeInstructionPool insPool = BytecodeInstructionPool.getInstance(classLoader);
List<BytecodeInstruction> instructions = insPool.getAllInstructionsAtMethod(className, methodName);
// Write your filter logic here
// Return true if the method passes your filter
return false;
}
}
MethodFlagCondFilter
overrides a method listTestableMethods()
that filters out the following unwanted methods by default:
- Abstract methods
- Class constructors
- Methods that do not contain any branches
- If you would like to analyze these methods, override the
listTestableMethods()
method in your own method filter.
- Your method filter should override the
checkMethod()
method, as seen in the example above. checkMethod()
is called for each target method. If the target method passes your filter, checkMethod()
should return true
; else return false
.
- Edit the enum class
evosuite.shell.listmethod.MethodFilterOption
, to create the option for using your filter. The class should look something like this:
public enum MethodFilterOption {
FLAG_PROCEDURE_METHOD ("flagProc"),
FLAG_PROCEDURE_METHOD_WITH_SIMPLE_RETURN ("flagProcSimplRet"),
HAS_BRANCH ("hasBranch"),
...
EXAMPLE_METHOD("exampleMethod"); // (1) Add your new filter here
...
public IMethodFilter getCorrespondingFilter() {
switch(this) {
case FLAG_PROCEDURE_METHOD:
return new MethodFlagCondFilter();
case FLAG_PROCEDURE_METHOD_WITH_SIMPLE_RETURN:
return new MethodFlagCondWithSimpleReturnFilter();
case HAS_BRANCH:
return new MethodHasBranchFilter();
...
// (2) Add your new filter here
case EXAMPLE_METHOD:
return new ExampleMethodFilter();
}
return null;
}
...
}
- (1) Firstly, add a new enum for your filter. You can name it anything, preferably something related to your filter.
- (2) Secondly, add a new
case
for your filter in the getCorrespondingFilter()
method which should return your created method filter class.
- To run your filter, edit the
evosuite.shell.batch.ListMethodsBatch
class. Inside the justRun()
method, runListMethod()
is called. Ensure the argument provided is the MethodFilterOption
enum for your desired filter. An example is shown below:
public class ListMethodsBatch {
@Test
public void justRun() throws IOException {
org.evosuite.Properties.ALWAYS_REGISTER_BRANCH = true;
runListMethod(MethodFilterOption.EXAMPLE_METHOD); // Ensure argument is the enum for your filter
}
...
}
- To run the filter, run the
justRun()
method as a JUnit Test.