1+ mod tests {
2+ use anyhow:: Context ;
3+ use regex:: Regex ;
4+ use std:: io:: Write ;
5+ use std:: process:: Stdio ;
6+
7+ fn test_verify_program_hash_helper ( expected_hash : & str , args : & [ & str ] ) -> anyhow:: Result < ( ) > {
8+ let mut child = std:: process:: Command :: new ( "./target/debug/solana-verify" )
9+ . args ( args)
10+ . stdin ( Stdio :: piped ( ) )
11+ . stdout ( Stdio :: piped ( ) )
12+ . stderr ( Stdio :: piped ( ) )
13+ . spawn ( )
14+ . context ( "Failed to execute solana-verify command" ) ?;
15+
16+ if let Some ( mut stdin) = child. stdin . take ( ) {
17+ stdin. write_all ( b"n" ) ?;
18+ }
19+
20+ let output = child
21+ . wait_with_output ( )
22+ . context ( "Failed to wait for solana-verify command" ) ?;
23+
24+ if !output. status . success ( ) {
25+ let error = String :: from_utf8_lossy ( & output. stderr ) ;
26+ anyhow:: bail!( "Command failed: {}" , error) ;
27+ }
28+
29+ // Print the last 10 lines of the output
30+ let output_str = String :: from_utf8_lossy ( & output. stdout ) ;
31+ let lines: Vec < & str > = output_str. split ( '\n' ) . collect ( ) ;
32+ let last_10_lines: Vec < String > = lines. iter ( ) . rev ( ) . take ( 10 ) . map ( |s| s. to_string ( ) ) . collect ( ) ;
33+ println ! ( "Last 10 lines of output:\n {}" , last_10_lines. join( "\n " ) ) ;
34+
35+ let re = Regex :: new ( r"Executable Program Hash from repo: ([a-f0-9]{64})" )
36+ . context ( "Failed to compile regex" ) ?;
37+
38+ let program_hash = re
39+ . captures ( & output_str)
40+ . context ( "Could not find program hash in output" ) ?
41+ . get ( 1 )
42+ . context ( "Invalid capture group" ) ?
43+ . as_str ( ) ;
44+
45+ assert_eq ! (
46+ program_hash, expected_hash,
47+ "Program hash {} does not match expected value {}" ,
48+ program_hash, expected_hash
49+ ) ;
50+
51+ Ok ( ( ) )
52+ }
53+
54+ #[ test]
55+ fn test_phoenix_v1 ( ) -> anyhow:: Result < ( ) > {
56+ const EXPECTED_HASH : & str = "6877a5b732b3494b828a324ec846d526d962223959534dbaf4209e0da3b2d6a9" ;
57+ let args: Vec < & str > =
58+ "verify-from-repo -um --program-id PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY https://github.com/Ellipsis-Labs/phoenix-v1" . split ( " " ) . collect ( ) ;
59+ test_verify_program_hash_helper ( EXPECTED_HASH , & args) ?;
60+ Ok ( ( ) )
61+ }
62+
63+ #[ test]
64+ fn test_squads_v3 ( ) -> anyhow:: Result < ( ) > {
65+ const EXPECTED_HASH : & str = "72da599d9ee14b2a03a23ccfa6f06d53eea4a00825ad2191929cbd78fb69205c" ;
66+ let args: Vec < & str > = "verify-from-repo https://github.com/Squads-Protocol/squads-mpl --commit-hash c95b7673d616c377a349ca424261872dfcf8b19d --program-id SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu -um --library-name squads_mpl --bpf" . split ( " " ) . collect ( ) ;
67+ test_verify_program_hash_helper ( EXPECTED_HASH , & args) ?;
68+ Ok ( ( ) )
69+ }
70+
71+ #[ test]
72+ fn test_drift_v2 ( ) -> anyhow:: Result < ( ) > {
73+ const EXPECTED_HASH : & str = "e31d58edeabc3c30bf6f2aa60bfaa5e492b41ec203e9006404b463e5adee5828" ;
74+ let args: Vec < & str > = "verify-from-repo -um --program-id dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH https://github.com/drift-labs/protocol-v2 --commit-hash 110d3ff4f8ba07c178d69f9bfc7b30194fac56d6 --library-name drift" . split ( " " ) . collect ( ) ;
75+ test_verify_program_hash_helper ( EXPECTED_HASH , & args) ?;
76+ Ok ( ( ) )
77+ }
78+
79+ #[ test]
80+ fn test_marginfi_v2 ( ) -> anyhow:: Result < ( ) > {
81+ const EXPECTED_HASH : & str = "890d68f48f96991016222b1fcbc2cc81b8ef2dcbf280c44fe378c523c108fad5" ;
82+ let args: Vec < & str > = "verify-from-repo -um --program-id MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA https://github.com/mrgnlabs/marginfi-v2 --commit-hash d33e649e415c354cc2a1e3c49131725552d69ba0 --library-name marginfi" . split ( " " ) . collect ( ) ;
83+ test_verify_program_hash_helper ( EXPECTED_HASH , & args) ?;
84+ Ok ( ( ) )
85+ }
86+
87+ #[ test]
88+ fn test_local_example ( ) -> anyhow:: Result < ( ) > {
89+ const EXPECTED_HASH : & str = "08d91368d349c2b56c712422f6d274a1e8f1946ff2ecd1dc3efc3ebace52a760" ;
90+
91+ let args: Vec < & str > = "build ./examples/hello_world" . split ( " " ) . collect ( ) ;
92+ let child = std:: process:: Command :: new ( "./target/debug/solana-verify" )
93+ . args ( args)
94+ . stdin ( Stdio :: piped ( ) )
95+ . stdout ( Stdio :: piped ( ) )
96+ . stderr ( Stdio :: piped ( ) )
97+ . spawn ( )
98+ . context ( "Failed to execute solana-verify command" ) ?;
99+
100+ let output = child
101+ . wait_with_output ( )
102+ . context ( "Failed to wait for solana-verify command" ) ?;
103+
104+ if !output. status . success ( ) {
105+ let error = String :: from_utf8_lossy ( & output. stderr ) ;
106+ anyhow:: bail!( "Command failed: {}" , error) ;
107+ }
108+
109+
110+ let args: Vec < & str > = "get-executable-hash ./examples/hello_world/target/deploy/hello_world.so" . split ( " " ) . collect ( ) ;
111+ let child = std:: process:: Command :: new ( "./target/debug/solana-verify" )
112+ . args ( & args)
113+ . stdin ( Stdio :: piped ( ) )
114+ . stdout ( Stdio :: piped ( ) )
115+ . stderr ( Stdio :: piped ( ) )
116+ . spawn ( )
117+ . context ( "Failed to execute solana-verify command" ) ?;
118+
119+ let output = child
120+ . wait_with_output ( )
121+ . context ( "Failed to wait for solana-verify command" ) ?;
122+
123+ if !output. status . success ( ) {
124+ let error = String :: from_utf8_lossy ( & output. stderr ) . trim ( ) . to_string ( ) ;
125+ anyhow:: bail!( "Command failed: {}" , error) ;
126+ }
127+
128+ let hash = String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) ;
129+ assert_eq ! ( hash, EXPECTED_HASH , "Program hash {} does not match expected value {}" , hash, EXPECTED_HASH ) ;
130+ Ok ( ( ) )
131+ }
132+
133+
134+ #[ test]
135+ fn test_verify_from_image ( ) -> anyhow:: Result < ( ) > {
136+ let args: Vec < & str > = "verify-from-image -e examples/hello_world/target/deploy/hello_world.so -i ellipsislabs/hello_world_verifiable_build:latest -p 2ZrriTQSVekoj414Ynysd48jyn4AX6ZF4TTJRqHfbJfn" . split ( " " ) . collect ( ) ;
137+ let child = std:: process:: Command :: new ( "./target/debug/solana-verify" )
138+ . args ( args)
139+ . stdin ( Stdio :: piped ( ) )
140+ . stdout ( Stdio :: piped ( ) )
141+ . stderr ( Stdio :: piped ( ) )
142+ . spawn ( )
143+ . context ( "Failed to execute solana-verify command" ) ?;
144+
145+ let output = child
146+ . wait_with_output ( )
147+ . context ( "Failed to wait for solana-verify command" ) ?;
148+
149+ if !output. status . success ( ) {
150+ let error = String :: from_utf8_lossy ( & output. stderr ) ;
151+ anyhow:: bail!( "Command failed: {}" , error) ;
152+ }
153+ Ok ( ( ) )
154+ }
155+ }
0 commit comments