package kr.ac.snu.selab.soot;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import kr.ac.snu.selab.soot.analyzer.AbstractAnalyzer;
import kr.ac.snu.selab.soot.core.AbstractProject;
import kr.ac.snu.selab.soot.core.ProjectManager;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import soot.Hierarchy;
import soot.PackManager;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.Transform;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Edge;
public class CallgraphTest {
private static Logger logger = Logger.getLogger(CallgraphTest.class);
private static final String PROJECTS_NAME = "SparkTest";
private static final String PROJECTS_FILE_NAME = "projects.xml";
int targetClassCount = 0;
@Before
public void prepare() throws Throwable {
targetClassCount = 0;
ProjectManager projects = ProjectManager.getInstance();
FileInputStream fis = null;
try {
fis = new FileInputStream(findProjectsFile());
projects.loadProjects(fis);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
}
}
}
AbstractProject project = projects.getProject(PROJECTS_NAME);
assertNotNull("Cannot find project!!!", project);
AbstractAnalyzer analyzer = new TestRunner(project);
PackManager.v().getPack("jtp")
.add(new Transform("jtp.Experiment", analyzer));
final String[] arguments = { "-cp", project.getClassPath(), "-f", "J", "-w", "-p", "cg.spark", "verbose:true,on-fly-cg:true",
"-d", project.getJimpleDirectory(), "--process-dir", project.getSourceDirectory()};
soot.Main.main(arguments);
}
@Test
public void classNumber() {
//assertEquals(8, targetClassCount);
logger.debug("hello");
}
private class TestRunner extends AbstractAnalyzer {
public TestRunner(AbstractProject project) {
super(project);
}
@Override
protected void analyze(List<SootClass> classList, Hierarchy hierarchy) {
CallGraph cg = Scene.v().getCallGraph();
assertNotNull("Target classes not found", classList);
// assertEquals(7, classList.size());
targetClassCount = classList.size();
logger.debug("###############################");
logger.debug("Call Graph after applying Spark");
logger.debug("###############################");
logger.debug("cg size: " + cg.size());
logger.debug("class number: " + classList.size());
for (SootClass aClass : classList) {
logger.debug("get in the loop");
for (SootMethod aMethod : aClass.getMethods()) {
logger.debug("**************************");
logger.debug("Callgraph of Method: " + aMethod.getSignature());
Iterator<Edge> edgesInto = cg.edgesInto(aMethod);
while (edgesInto.hasNext()) {
SootMethod srcMethod = edgesInto.next().src();
logger.debug(srcMethod.getSignature() + "=====>");
}
Iterator<Edge> edgesOutOf = cg.edgesOutOf(aMethod);
while (edgesOutOf.hasNext()) {
SootMethod tgtMethod = edgesOutOf.next().tgt();
logger.debug("=====>" + tgtMethod.getSignature());
}
logger.debug("**************************");
}
}
}
}
private static File findProjectsFile() {
URL url = ClassLoader.getSystemResource(PROJECTS_FILE_NAME);
if (url == null) {
return null;
}
File file = new File(url.getFile());
if (file == null || !file.exists() || !file.isFile()) {
return null;
}
return file;
}
}