Skip to content

Commit 9c29bee

Browse files
committed
Improve call graph unit tests
1 parent 8ed3ccb commit 9c29bee

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

unit/analyses/call_graph.cpp

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Module: Unit test for call graph generation
1111
#include <testing-utils/catch.hpp>
1212

1313
#include <analyses/call_graph.h>
14+
#include <analyses/call_graph_helpers.h>
1415

1516
#include <util/symbol_table.h>
1617
#include <util/std_code.h>
@@ -160,12 +161,24 @@ SCENARIO("call_graph",
160161
}
161162
}
162163

164+
WHEN("A call-graph is constructed rooted at B")
165+
{
166+
call_grapht call_graph_from_b =
167+
call_grapht::create_from_root_function(goto_model, "B", false);
168+
THEN("We expect only B -> C and B -> D in the resulting graph")
169+
{
170+
const auto &check_graph=call_graph_from_b.graph;
171+
REQUIRE(check_graph.size()==2);
172+
REQUIRE(multimap_key_matches(check_graph, "B", {"C", "D"}));
173+
}
174+
}
175+
163176
WHEN("The call graph is exported as a grapht")
164177
{
165-
call_grapht::directed_call_grapht exported=
178+
call_grapht::directed_grapht exported=
166179
call_graph_from_goto_functions.get_directed_graph();
167180

168-
typedef call_grapht::directed_call_grapht::node_indext node_indext;
181+
typedef call_grapht::directed_grapht::node_indext node_indext;
169182
std::map<irep_idt, node_indext> nodes_by_name;
170183
for(node_indext i=0; i<exported.size(); ++i)
171184
nodes_by_name[exported[i].function]=i;
@@ -179,15 +192,51 @@ SCENARIO("call_graph",
179192
REQUIRE(exported.has_edge(nodes_by_name["B"], nodes_by_name["C"]));
180193
REQUIRE(exported.has_edge(nodes_by_name["B"], nodes_by_name["D"]));
181194
}
195+
196+
THEN("We expect A to have successors {A, B}")
197+
{
198+
std::set<irep_idt> successors = get_callees(exported, "A");
199+
REQUIRE(successors.size() == 2);
200+
REQUIRE(successors.count("A"));
201+
REQUIRE(successors.count("B"));
202+
}
203+
204+
THEN("We expect C to have predecessors {B}")
205+
{
206+
std::set<irep_idt> predecessors = get_callers(exported, "C");
207+
REQUIRE(predecessors.size() == 1);
208+
REQUIRE(predecessors.count("B"));
209+
}
210+
211+
THEN("We expect all of {A, B, C, D} to be reachable from A")
212+
{
213+
std::set<irep_idt> successors =
214+
get_reachable_functions(exported, "A");
215+
REQUIRE(successors.size() == 4);
216+
REQUIRE(successors.count("A"));
217+
REQUIRE(successors.count("B"));
218+
REQUIRE(successors.count("C"));
219+
REQUIRE(successors.count("D"));
220+
}
221+
222+
THEN("We expect {D, B, A} to be able to reach D")
223+
{
224+
std::set<irep_idt> predecessors =
225+
get_reaching_functions(exported, "D");
226+
REQUIRE(predecessors.size() == 3);
227+
REQUIRE(predecessors.count("A"));
228+
REQUIRE(predecessors.count("B"));
229+
REQUIRE(predecessors.count("D"));
230+
}
182231
}
183232

184233
WHEN("The call graph, with call sites, is exported as a grapht")
185234
{
186235
call_grapht call_graph_from_goto_functions(goto_model, true);
187-
call_grapht::directed_call_grapht exported=
236+
call_grapht::directed_grapht exported=
188237
call_graph_from_goto_functions.get_directed_graph();
189238

190-
typedef call_grapht::directed_call_grapht::node_indext node_indext;
239+
typedef call_grapht::directed_grapht::node_indext node_indext;
191240
std::map<irep_idt, node_indext> nodes_by_name;
192241
for(node_indext i=0; i<exported.size(); ++i)
193242
nodes_by_name[exported[i].function]=i;

0 commit comments

Comments
 (0)