11use binaryninja:: binary_view:: { AnalysisState , BinaryViewBase , BinaryViewExt } ;
2+ use binaryninja:: function:: Function ;
23use binaryninja:: headless:: Session ;
34use binaryninja:: main_thread:: execute_on_main_thread_and_wait;
4- use binaryninja:: symbol:: { SymbolBuilder , SymbolType } ;
5+ use binaryninja:: platform:: Platform ;
6+ use binaryninja:: rc:: Ref ;
7+ use binaryninja:: symbol:: { Symbol , SymbolBuilder , SymbolType } ;
58use rstest:: * ;
9+ use std:: collections:: BTreeMap ;
610use std:: path:: PathBuf ;
711
812#[ fixture]
@@ -36,11 +40,12 @@ fn test_binary_saving(_session: &Session) {
3640 // HACK: To prevent us from deadlocking in save_to_path we wait for all main thread actions to finish.
3741 execute_on_main_thread_and_wait ( || { } ) ;
3842
43+ let temp_dir = tempfile:: tempdir ( ) . expect ( "Failed to create temporary directory" ) ;
44+ let temp_path = temp_dir. path ( ) . join ( "atox.obj.new" ) ;
3945 // Save the modified file
40- assert ! ( view. save_to_path( out_dir . join ( "atox.obj.new" ) ) ) ;
46+ assert ! ( view. save_to_path( & temp_path ) ) ;
4147 // Verify that the file exists and is modified.
42- let new_view =
43- binaryninja:: load ( out_dir. join ( "atox.obj.new" ) ) . expect ( "Failed to load new view" ) ;
48+ let new_view = binaryninja:: load ( temp_path) . expect ( "Failed to load new view" ) ;
4449 assert_eq ! ( new_view. read_vec( 0x1560 , 4 ) , [ 0xff , 0xff , 0xff , 0xff ] ) ;
4550}
4651
@@ -58,12 +63,53 @@ fn test_binary_saving_database(_session: &Session) {
5863 // Verify that we modified the binary
5964 assert_eq ! ( entry_function. symbol( ) . raw_name( ) . as_str( ) , "test" ) ;
6065 // Save the modified database.
61- assert ! ( view. file( ) . create_database( out_dir. join( "atox.obj.bndb" ) ) ) ;
66+ let temp_dir = tempfile:: tempdir ( ) . expect ( "Failed to create temporary directory" ) ;
67+ let temp_path = temp_dir. path ( ) . join ( "atox.obj.bndb" ) ;
68+ assert ! ( view. file( ) . create_database( & temp_path) ) ;
6269 // Verify that the file exists and is modified.
63- let new_view =
64- binaryninja:: load ( out_dir. join ( "atox.obj.bndb" ) ) . expect ( "Failed to load new view" ) ;
70+ let new_view = binaryninja:: load ( temp_path) . expect ( "Failed to load new view" ) ;
6571 let new_entry_function = new_view
6672 . entry_point_function ( )
6773 . expect ( "Failed to get entry point function" ) ;
6874 assert_eq ! ( new_entry_function. symbol( ) . raw_name( ) . as_str( ) , "test" ) ;
6975}
76+
77+ // This is what we store to check if a function matches the expected function.
78+ // See `test_deterministic_functions` for details.
79+ #[ derive( Debug , PartialEq ) ]
80+ pub struct FunctionSnapshot {
81+ name : String ,
82+ platform : Ref < Platform > ,
83+ symbol : Ref < Symbol > ,
84+ }
85+
86+ impl From < & Function > for FunctionSnapshot {
87+ fn from ( func : & Function ) -> Self {
88+ Self {
89+ name : func. symbol ( ) . raw_name ( ) . to_string ( ) ,
90+ platform : func. platform ( ) . to_owned ( ) ,
91+ symbol : func. symbol ( ) . to_owned ( ) ,
92+ }
93+ }
94+ }
95+
96+ #[ rstest]
97+ fn test_deterministic_functions ( session : & Session ) {
98+ // Test to make sure that analysis always collects the same information on functions.
99+ let out_dir = env ! ( "OUT_DIR" ) . parse :: < PathBuf > ( ) . unwrap ( ) ;
100+ for entry in std:: fs:: read_dir ( out_dir) . expect ( "Failed to read OUT_DIR" ) {
101+ let entry = entry. expect ( "Failed to read directory entry" ) ;
102+ let path = entry. path ( ) ;
103+ if path. is_file ( ) {
104+ let view = session. load ( & path) . expect ( "Failed to load view" ) ;
105+ assert_eq ! ( view. analysis_progress( ) . state, AnalysisState :: IdleState ) ;
106+ let functions: BTreeMap < u64 , FunctionSnapshot > = view
107+ . functions ( )
108+ . iter ( )
109+ . map ( |f| ( f. start ( ) , FunctionSnapshot :: from ( f. as_ref ( ) ) ) )
110+ . collect ( ) ;
111+ let snapshot_name = path. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
112+ insta:: assert_debug_snapshot!( snapshot_name, functions) ;
113+ }
114+ }
115+ }
0 commit comments