Skip to content

Commit 5996247

Browse files
committed
Add unit test to check symbol table JSON input and output format consistency
The unit test first outputs a symbol table to JSON via show_symbol_table() and then reads it back in again via symbol_table_from_json(). Then, it checks that the initial symbol table and the symbol table read back in again are equal.
1 parent f6e948c commit 5996247

File tree

3 files changed

+153
-2
lines changed

3 files changed

+153
-2
lines changed

src/util/ui_message.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ class ui_message_handlert : public message_handlert
2727

2828
virtual ~ui_message_handlert();
2929

30-
uit get_ui() const
30+
virtual uit get_ui() const
3131
{
3232
return _ui;
3333
}
3434

3535
virtual void flush(unsigned level) override;
3636

37-
json_stream_arrayt &get_json_stream()
37+
virtual json_stream_arrayt &get_json_stream()
3838
{
3939
PRECONDITION(json_stream!=nullptr);
4040
return *json_stream;

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SRC += analyses/ai/ai.cpp \
2828
goto-symex/ssa_equation.cpp \
2929
interpreter/interpreter.cpp \
3030
json/json_parser.cpp \
31+
json_symbol_table.cpp \
3132
path_strategies.cpp \
3233
pointer-analysis/value_set.cpp \
3334
solvers/floatbv/float_utils.cpp \

unit/json_symbol_table.cpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/// Author: Daniel Poetzl
2+
3+
/// \file json symbol table read/write consistency
4+
5+
#include <ansi-c/ansi_c_language.h>
6+
7+
#include <cbmc/cbmc_parse_options.h>
8+
9+
#include <goto-programs/goto_convert_functions.h>
10+
#include <goto-programs/goto_model.h>
11+
#include <goto-programs/initialize_goto_model.h>
12+
#include <goto-programs/show_symbol_table.h>
13+
14+
#include <json-symtab-language/json_symbol_table.h>
15+
#include <json/json_parser.h>
16+
17+
#include <langapi/language_file.h>
18+
#include <langapi/mode.h>
19+
20+
#include <util/cmdline.h>
21+
#include <util/config.h>
22+
#include <util/message.h>
23+
#include <util/options.h>
24+
#include <util/symbol_table.h>
25+
26+
#include <testing-utils/catch.hpp>
27+
#include <testing-utils/message.h>
28+
29+
#include <iosfwd>
30+
31+
class test_ui_message_handlert : public ui_message_handlert
32+
{
33+
public:
34+
explicit test_ui_message_handlert(std::ostream &out)
35+
: ui_message_handlert(cmdlinet(), ""), json_stream_array(out, 0)
36+
{
37+
}
38+
39+
uit get_ui() const
40+
{
41+
return uit::JSON_UI;
42+
}
43+
44+
json_stream_arrayt &get_json_stream()
45+
{
46+
return json_stream_array;
47+
}
48+
49+
json_stream_arrayt json_stream_array;
50+
};
51+
52+
void get_goto_model(std::istream &in, goto_modelt &goto_model)
53+
{
54+
optionst options;
55+
cbmc_parse_optionst::set_default_options(options);
56+
57+
null_message_handlert null_message_handler;
58+
messaget null_message(null_message_handler);
59+
60+
language_filest language_files;
61+
language_files.set_message_handler(null_message_handler);
62+
63+
std::string filename("");
64+
65+
language_filet &language_file = language_files.add_file(filename);
66+
67+
language_file.language = get_default_language();
68+
69+
languaget &language = *language_file.language;
70+
language.set_message_handler(null_message_handler);
71+
language.set_language_options(options);
72+
73+
{
74+
bool r = language.parse(in, filename);
75+
REQUIRE(!r);
76+
}
77+
78+
language_file.get_modules();
79+
80+
{
81+
bool r = language_files.typecheck(goto_model.symbol_table);
82+
REQUIRE(!r);
83+
}
84+
85+
REQUIRE(!goto_model.symbol_table.has_symbol(goto_functionst::entry_point()));
86+
87+
{
88+
bool r = language_files.generate_support_functions(goto_model.symbol_table);
89+
REQUIRE(!r);
90+
}
91+
92+
goto_convert(
93+
goto_model.symbol_table, goto_model.goto_functions, null_message_handler);
94+
}
95+
96+
TEST_CASE("json symbol table read/write consistency")
97+
{
98+
register_language(new_ansi_c_language);
99+
100+
cmdlinet cmdline;
101+
config.main = "main";
102+
config.set(cmdline);
103+
104+
goto_modelt goto_model;
105+
106+
// Get symbol table associated with goto program
107+
108+
{
109+
std::string program = "int main() { return 0; }\n";
110+
111+
std::istringstream in(program);
112+
get_goto_model(in, goto_model);
113+
}
114+
115+
const symbol_tablet &symbol_table1 = goto_model.symbol_table;
116+
117+
// Convert symbol table to json string
118+
119+
std::ostringstream out;
120+
121+
{
122+
test_ui_message_handlert ui_message_handler(out);
123+
REQUIRE(ui_message_handler.get_ui() == ui_message_handlert::uit::JSON_UI);
124+
125+
show_symbol_table(symbol_table1, ui_message_handler);
126+
}
127+
128+
// Convert json string to symbol table
129+
130+
symbol_tablet symbol_table2;
131+
132+
{
133+
std::istringstream in(out.str());
134+
jsont json;
135+
136+
bool r = parse_json(in, "", null_message_handler, json);
137+
REQUIRE(!r);
138+
139+
REQUIRE(json.is_array());
140+
141+
const json_arrayt &json_array = to_json_array(json);
142+
const jsont &json_symbol_table = *json_array.begin();
143+
144+
symbol_table_from_json(json_symbol_table, symbol_table2);
145+
}
146+
147+
// Finally check if symbol tables are consistent
148+
149+
REQUIRE(symbol_table1 == symbol_table2);
150+
}

0 commit comments

Comments
 (0)