Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package tfm;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.stmt.ThrowStmt;
import com.github.javaparser.ast.stmt.TryStmt;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import tfm.exec.GraphLog;
import tfm.exec.PDGLog;
import tfm.graphs.CFG.ACFG;
import tfm.graphs.PDG;
import tfm.graphs.PDG.APDG;
import tfm.graphs.PDG.PPDG;
import tfm.nodes.GraphNode;
import tfm.slicing.GraphNodeCriterion;
import tfm.slicing.SlicingCriterion;
import tfm.utils.Logger;
import tfm.visitors.cfg.CFGBuilder;
import tfm.visitors.pdg.ControlDependencyBuilder;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;
import java.util.stream.Collectors;
public class PDGTests {
static {
JavaParser.getStaticConfiguration().setAttributeComments(false);
}
private boolean error = false;
@ParameterizedTest(name = "[{index}] {0} ({1})")
@MethodSource("tfm.FileFinder#findAllMethodDeclarations")
public void ppdgTest(File file, String methodName, MethodDeclaration root) throws IOException {
runPdg(file, root, PDGLog.PPDG);
}
@ParameterizedTest(name = "[{index}] {0} ({1})")
@MethodSource("tfm.FileFinder#findAllMethodDeclarations")
public void apdgTest(File file, String methodName, MethodDeclaration root) throws IOException {
runPdg(file, root, PDGLog.APDG);
}
@ParameterizedTest(name = "[{index}] {0} ({1})")
@MethodSource("tfm.FileFinder#findAllMethodDeclarations")
public void pdgTest(File file, String methodName, MethodDeclaration root) throws IOException {
runPdg(file, root, PDGLog.PDG);
}
private void runPdg(File file, Node root, int type) throws IOException {
GraphLog<?> graphLog = new PDGLog(type);
graphLog.visit(root);
graphLog.log();
try {
graphLog.generateImages(file.getPath());
} catch (Exception e) {
System.err.println("Could not generate PNG");
System.err.println(e.getMessage());
}
}
@ParameterizedTest(name = "[{index}] {0} ({1})")
@MethodSource("tfm.FileFinder#findAllMethodDeclarations")
public void pdgCompare(File file, String methodName, MethodDeclaration root) throws IOException {
ControlDependencyBuilder ctrlDepBuilder;
if (containsUnsupportedStatements(root)) {
System.err.println("Contains unsupported instructions");
}
// Create APDG
ACFG acfg = new ACFG();
root.accept(new CFGBuilder(acfg), null);
APDG apdg = new APDG(acfg);
ctrlDepBuilder = new ControlDependencyBuilder(apdg, acfg);
ctrlDepBuilder.analyze();
// Create PPDG
PPDG ppdg = new PPDG(acfg);
ctrlDepBuilder = new ControlDependencyBuilder(ppdg, acfg);
ctrlDepBuilder.analyze();
// Compare
Logger.log("COMPARE APDG and PPDG");
compareGraphs(apdg, ppdg);
assert !error;
}
public static boolean containsUnsupportedStatements(Node node) {
return node.findFirst(TryStmt.class).isPresent()
|| node.findFirst(ThrowStmt.class).isPresent();
}
/** Slices both graphs on every possible node and compares the result */
public void compareGraphs(PDG pdg1, PDG pdg2) {
for (GraphNode<?> node : pdg1.getNodes().stream()
.sorted(Comparator.comparingInt(GraphNode::getId))
.collect(Collectors.toList())) {
if (node.getAstNode() instanceof MethodDeclaration)
continue;
SlicingCriterion sc = new GraphNodeCriterion(node, "x");
Set<Integer> slice1 = pdg1.slice(sc);
Set<Integer> slice2 = pdg2.slice(sc);
Logger.log("Slicing on " + node.getId());
boolean ok = slice1.equals(slice2);
if (!ok) {
Logger.log("FAILED!");
error = true;
}
printSlices(pdg1, slice1, slice2);
}
}
@SafeVarargs
public final void printSlices(PDG pdg, Set<Integer>... slices) {
pdg.getNodes().stream()
.sorted(Comparator.comparingInt(GraphNode::getId))
.forEach(n -> Logger.format("%3d: %s %s",
n.getId(),
Arrays.stream(slices)
.map(s -> s.contains(n.getId()) ? "x" : " ")
.reduce((a, b) -> a + " " + b),
n.getData()));
}
}