Skip to content

Commit 0654db3

Browse files
authored
Merge pull request #6 from solana-developers/local-test
Add tests for `examples/hello_world`
2 parents 64a6129 + 3a75a2a commit 0654db3

File tree

3 files changed

+162
-91
lines changed

3 files changed

+162
-91
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ solana-verify verify-from-repo -um --program-id MFv2hWf31Z9kbCa1snEPYctwafyhdvnV
149149
Final Output:
150150

151151
```
152-
Executable Program Hash from repo: 7b37482dd6b2159932b5c2595bc6ce62cf6e587ae67f237c8152b802bf7d7bb8
153-
On-chain Program Hash: 7b37482dd6b2159932b5c2595bc6ce62cf6e587ae67f237c8152b802bf7d7bb8
152+
Executable Program Hash from repo: 890d68f48f96991016222b1fcbc2cc81b8ef2dcbf280c44fe378c523c108fad5
153+
On-chain Program Hash: 890d68f48f96991016222b1fcbc2cc81b8ef2dcbf280c44fe378c523c108fad5
154154
Program hash matches ✅
155155
```
156156

src/main.rs

Lines changed: 5 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{anyhow, Context};
1+
use anyhow::anyhow;
22
use cargo_lock::Lockfile;
33
use cargo_toml::Manifest;
44
use clap::{App, Arg, SubCommand};
@@ -13,7 +13,7 @@ use solana_sdk::{
1313
pubkey::Pubkey,
1414
};
1515
use std::{
16-
io::{Read, Write},
16+
io::Read,
1717
path::PathBuf,
1818
process::{exit, Stdio},
1919
sync::{
@@ -28,6 +28,9 @@ pub mod image_config;
2828
pub mod solana_program;
2929
use image_config::IMAGE_MAP;
3030

31+
#[cfg(test)]
32+
mod test;
33+
3134
use crate::{
3235
api::send_job_to_remote,
3336
solana_program::{process_close, upload_program},
@@ -1001,90 +1004,3 @@ pub fn get_pkg_name_from_cargo_toml(cargo_toml_file: &str) -> Option<String> {
10011004
let pkg = manifest.package?;
10021005
Some(pkg.name)
10031006
}
1004-
1005-
fn test_verify_program_hash_helper(expected_hash: &str, args: &[&str]) -> anyhow::Result<()> {
1006-
let mut child = std::process::Command::new("./target/debug/solana-verify")
1007-
.args(args)
1008-
.stdin(Stdio::piped())
1009-
.stdout(Stdio::piped())
1010-
.stderr(Stdio::piped())
1011-
.spawn()
1012-
.context("Failed to execute solana-verify command")?;
1013-
1014-
if let Some(mut stdin) = child.stdin.take() {
1015-
stdin.write_all(b"n")?;
1016-
}
1017-
1018-
let output = child
1019-
.wait_with_output()
1020-
.context("Failed to wait for solana-verify command")?;
1021-
1022-
if !output.status.success() {
1023-
let error = String::from_utf8_lossy(&output.stderr);
1024-
anyhow::bail!("Command failed: {}", error);
1025-
}
1026-
1027-
// Print the last 10 lines of the output
1028-
let output_str = String::from_utf8_lossy(&output.stdout);
1029-
let lines: Vec<&str> = output_str.split('\n').collect();
1030-
let last_10_lines: Vec<String> = lines.iter().rev().take(10).map(|s| s.to_string()).collect();
1031-
println!("Last 10 lines of output:\n{}", last_10_lines.join("\n"));
1032-
1033-
let re = regex::Regex::new(r"Executable Program Hash from repo: ([a-f0-9]{64})")
1034-
.context("Failed to compile regex")?;
1035-
1036-
let program_hash = re
1037-
.captures(&output_str)
1038-
.context("Could not find program hash in output")?
1039-
.get(1)
1040-
.context("Invalid capture group")?
1041-
.as_str();
1042-
1043-
assert_eq!(
1044-
program_hash, expected_hash,
1045-
"Program hash {} does not match expected value {}",
1046-
program_hash, expected_hash
1047-
);
1048-
1049-
Ok(())
1050-
}
1051-
1052-
#[test]
1053-
fn test_phoenix_v1() -> anyhow::Result<()> {
1054-
const EXPECTED_HASH: &str = "6877a5b732b3494b828a324ec846d526d962223959534dbaf4209e0da3b2d6a9";
1055-
1056-
let args = &[
1057-
"verify-from-repo",
1058-
"-um",
1059-
"--program-id",
1060-
"PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY",
1061-
"https://github.com/Ellipsis-Labs/phoenix-v1",
1062-
];
1063-
1064-
test_verify_program_hash_helper(EXPECTED_HASH, args)?;
1065-
Ok(())
1066-
}
1067-
1068-
#[test]
1069-
fn test_squads_v3() -> anyhow::Result<()> {
1070-
const EXPECTED_HASH: &str = "72da599d9ee14b2a03a23ccfa6f06d53eea4a00825ad2191929cbd78fb69205c";
1071-
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();
1072-
test_verify_program_hash_helper(EXPECTED_HASH, &args)?;
1073-
Ok(())
1074-
}
1075-
1076-
#[test]
1077-
fn test_drift_v2() -> anyhow::Result<()> {
1078-
const EXPECTED_HASH: &str = "e31d58edeabc3c30bf6f2aa60bfaa5e492b41ec203e9006404b463e5adee5828";
1079-
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();
1080-
test_verify_program_hash_helper(EXPECTED_HASH, &args)?;
1081-
Ok(())
1082-
}
1083-
1084-
#[test]
1085-
fn test_marginfi_v2() -> anyhow::Result<()> {
1086-
const EXPECTED_HASH: &str = "7b37482dd6b2159932b5c2595bc6ce62cf6e587ae67f237c8152b802bf7d7bb8";
1087-
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();
1088-
test_verify_program_hash_helper(EXPECTED_HASH, &args)?;
1089-
Ok(())
1090-
}

src/test.rs

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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

Comments
 (0)