@@ -11,10 +11,10 @@ pub mod ffi {
11
11
// API Functions
12
12
fn new_api_session ( ) -> UniquePtr < api_sessiont > ;
13
13
fn get_api_version ( & self ) -> UniquePtr < CxxString > ;
14
- fn load_model_from_files ( & self , files : & CxxVector < CxxString > ) ;
15
- fn verify_model ( & self ) ;
16
- fn validate_goto_model ( & self ) ;
17
- fn drop_unused_functions ( & self ) ;
14
+ fn load_model_from_files ( & self , files : & CxxVector < CxxString > ) -> Result < ( ) > ;
15
+ fn verify_model ( & self ) -> Result < ( ) > ;
16
+ fn validate_goto_model ( & self ) -> Result < ( ) > ;
17
+ fn drop_unused_functions ( & self ) -> Result < ( ) > ;
18
18
19
19
// Helper/Utility functions
20
20
fn translate_vector_of_string ( elements : Vec < String > ) -> & ' static CxxVector < CxxString > ;
@@ -23,25 +23,37 @@ pub mod ffi {
23
23
24
24
extern "Rust" {
25
25
fn print_response ( vec : & CxxVector < CxxString > ) ;
26
+ fn translate_response_buffer ( vec : & CxxVector < CxxString > ) -> Vec < String > ;
26
27
}
27
28
}
28
29
29
- fn print_response ( vec : & CxxVector < CxxString > ) {
30
- let vec: Vec < String > = vec
31
- . iter ( )
30
+ /// This is a utility function, whose job is to translate the responses from the C++
31
+ /// API ( which we get in the form of a C ++ std:: vector<std: string>) into a form that
32
+ /// can be easily consumed by other Rust programs.
33
+ pub fn translate_response_buffer ( vec : & CxxVector < CxxString > ) -> Vec < String > {
34
+ vec. iter ( )
32
35
. map ( |s| s. to_string_lossy ( ) . into_owned ( ) )
33
- . collect ( ) ;
36
+ . collect ( )
37
+ }
38
+
39
+ /// This is a utility function, whose aim is to simplify direct printing of the messages
40
+ /// that we get from CBMC's C++ API. Underneath, it's using translate_response_buffer
41
+ /// to translate the C++ types into Rust types and then prints out the strings contained
42
+ /// in the resultant rust vector.
43
+ pub fn print_response ( vec : & CxxVector < CxxString > ) {
44
+ let vec: Vec < String > = translate_response_buffer ( vec) ;
34
45
35
46
for s in vec {
36
47
println ! ( "{}" , s) ;
37
48
}
38
49
}
39
50
40
- // To test run "CBMC_LIB_DIR=<path_to_build/libs> cargo test -- --test-threads=1 --nocapture"
51
+ // To test run "CBMC_LIB_DIR=<path_to_build/libs> SAT_IMPL=minisat2 cargo test -- --test-threads=1 --nocapture"
41
52
#[ cfg( test) ]
42
53
mod tests {
43
54
use super :: * ;
44
55
use cxx:: let_cxx_string;
56
+ use std:: process;
45
57
46
58
#[ test]
47
59
fn it_works ( ) {
@@ -75,12 +87,28 @@ mod tests {
75
87
76
88
// Invoke load_model_from_files and see if the model
77
89
// has been loaded.
78
- client. load_model_from_files ( vect) ;
79
- // Validate integrity of passed goto-model.
80
- client. validate_goto_model ( ) ;
90
+ if let Err ( _) = client. load_model_from_files ( vect) {
91
+ eprintln ! ( "Failed to load model from files: {:?}" , vect) ;
92
+ process:: exit ( 1 ) ;
93
+ }
81
94
95
+ // Validate integrity of passed goto-model.
96
+ if let Err ( _) = client. validate_goto_model ( ) {
97
+ eprintln ! ( "Failed to validate goto model from files: {:?}" , vect) ;
98
+ process:: exit ( 1 ) ;
99
+ }
100
+
101
+ // ATTENTION: The following `.clone()` is unneeded - I keep it here in order to
102
+ // make potential printing of the message buffer easier (because of borrowing).
103
+ // This is also why a print instruction is commented out (as a guide for someone
104
+ // else in case they want to inspect the output).
105
+ let validation_msg = "Validating consistency of goto-model supplied to API session" ;
82
106
let msgs = ffi:: get_messages ( ) ;
83
- print_response ( msgs) ;
107
+ let msgs_assert = translate_response_buffer ( msgs) . clone ( ) ;
108
+
109
+ assert ! ( msgs_assert. contains( & String :: from( validation_msg) ) ) ;
110
+
111
+ // print_response(msgs);
84
112
}
85
113
86
114
#[ test]
@@ -90,15 +118,29 @@ mod tests {
90
118
let vec: Vec < String > = vec ! [ "other/example.c" . to_owned( ) ] ;
91
119
92
120
let vect = ffi:: translate_vector_of_string ( vec) ;
93
- client. load_model_from_files ( vect) ;
121
+
122
+ if let Err ( _) = client. load_model_from_files ( vect) {
123
+ eprintln ! ( "Failed to load model from files: {:?}" , vect) ;
124
+ process:: exit ( 1 ) ;
125
+ }
94
126
95
127
// Validate integrity of goto-model
96
- client. validate_goto_model ( ) ;
128
+ if let Err ( _) = client. validate_goto_model ( ) {
129
+ eprintln ! ( "Failed to validate goto model from files: {:?}" , vect) ;
130
+ process:: exit ( 1 ) ;
131
+ }
132
+
133
+ if let Err ( _) = client. verify_model ( ) {
134
+ eprintln ! ( "Failed to verify model from files: {:?}" , vect) ;
135
+ process:: exit ( 1 ) ;
136
+ }
97
137
98
- client . verify_model ( ) ;
138
+ let verification_msg = "VERIFICATION FAILED" ;
99
139
100
140
let msgs = ffi:: get_messages ( ) ;
101
- print_response ( msgs) ;
141
+ let msgs_assert = translate_response_buffer ( msgs) . clone ( ) ;
142
+
143
+ assert ! ( msgs_assert. contains( & String :: from( verification_msg) ) ) ;
102
144
}
103
145
104
146
#[ test]
@@ -114,11 +156,24 @@ mod tests {
114
156
let vect = ffi:: translate_vector_of_string ( vec) ;
115
157
assert_eq ! ( vect. len( ) , 1 ) ;
116
158
117
- client. load_model_from_files ( vect) ;
159
+ if let Err ( _) = client. load_model_from_files ( vect) {
160
+ eprintln ! ( "Failed to load model from files: {:?}" , vect) ;
161
+ process:: exit ( 1 ) ;
162
+ }
163
+
118
164
// Perform a drop of any unused functions.
119
- client. drop_unused_functions ( ) ;
165
+ if let Err ( err) = client. drop_unused_functions ( ) {
166
+ eprintln ! ( "Error during client call: {:?}" , err) ;
167
+ process:: exit ( 1 ) ;
168
+ }
169
+
170
+ let instrumentation_msg = "Performing instrumentation pass: dropping unused functions" ;
171
+ let instrumentation_msg2 = "Dropping 8 of 11 functions (3 used)" ;
120
172
121
173
let msgs = ffi:: get_messages ( ) ;
122
- print_response ( msgs) ;
174
+ let msgs_assert = translate_response_buffer ( msgs) . clone ( ) ;
175
+
176
+ assert ! ( msgs_assert. contains( & String :: from( instrumentation_msg) ) ) ;
177
+ assert ! ( msgs_assert. contains( & String :: from( instrumentation_msg2) ) ) ;
123
178
}
124
179
}
0 commit comments