@@ -11,10 +11,10 @@ pub mod ffi {
1111 // API Functions
1212 fn new_api_session ( ) -> UniquePtr < api_sessiont > ;
1313 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 < ( ) > ;
1818
1919 // Helper/Utility functions
2020 fn translate_vector_of_string ( elements : Vec < String > ) -> & ' static CxxVector < CxxString > ;
@@ -23,25 +23,37 @@ pub mod ffi {
2323
2424 extern "Rust" {
2525 fn print_response ( vec : & CxxVector < CxxString > ) ;
26+ fn translate_response_buffer ( vec : & CxxVector < CxxString > ) -> Vec < String > ;
2627 }
2728}
2829
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 ( )
3235 . 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) ;
3445
3546 for s in vec {
3647 println ! ( "{}" , s) ;
3748 }
3849}
3950
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"
4152#[ cfg( test) ]
4253mod tests {
4354 use super :: * ;
4455 use cxx:: let_cxx_string;
56+ use std:: process;
4557
4658 #[ test]
4759 fn it_works ( ) {
@@ -75,12 +87,28 @@ mod tests {
7587
7688 // Invoke load_model_from_files and see if the model
7789 // 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+ }
8194
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" ;
82106 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);
84112 }
85113
86114 #[ test]
@@ -90,15 +118,29 @@ mod tests {
90118 let vec: Vec < String > = vec ! [ "other/example.c" . to_owned( ) ] ;
91119
92120 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+ }
94126
95127 // 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+ }
97137
98- client . verify_model ( ) ;
138+ let verification_msg = "VERIFICATION FAILED" ;
99139
100140 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) ) ) ;
102144 }
103145
104146 #[ test]
@@ -114,11 +156,24 @@ mod tests {
114156 let vect = ffi:: translate_vector_of_string ( vec) ;
115157 assert_eq ! ( vect. len( ) , 1 ) ;
116158
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+
118164 // 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)" ;
120172
121173 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) ) ) ;
123178 }
124179}
0 commit comments