-
Notifications
You must be signed in to change notification settings - Fork 15
Writing a Filter
Aaron Ong edited this page Jan 27, 2021
·
2 revisions
- Create your method filter class file under the
evosuite.shell.listmethod
package. Ensure your filter classextends MethodFlagCondFilter
and overrides thecheckMethod()
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 methodlistTestableMethods()
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 returntrue
; else returnfalse
.
- 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 thegetCorrespondingFilter()
method which should return your created method filter class.
- To run your filter, edit the
evosuite.shell.batch.ListMethodsBatch
class. Inside thejustRun()
method,runListMethod()
is called. Ensure the argument provided is theMethodFilterOption
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.