1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), warn(unused_extern_crates))]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![allow(
5 clippy::incompatible_msrv,
6 clippy::needless_update,
7 clippy::collapsible_if,
8 unreachable_pub,
9 dead_code,
10 missing_docs,
11 missing_debug_implementations
12)]
13
14pub mod btest;
15pub mod compiled;
16pub mod diagnostic;
17pub mod merkle_trie;
18pub mod runner;
19pub mod utils;
20
21use std::path::{Path, PathBuf};
22use walkdir::{DirEntry, WalkDir};
23
24pub fn find_all_json_tests(path: &Path) -> Vec<PathBuf> {
28 if path.is_file() {
29 vec![path.to_path_buf()]
30 } else {
31 WalkDir::new(path)
32 .into_iter()
33 .filter_map(Result::ok)
34 .filter(|e| e.path().extension() == Some("json".as_ref()))
35 .map(DirEntry::into_path)
36 .collect()
37 }
38}
39
40const DEFAULT_ETHTESTS_PATH: &str = "tests/ethereum-tests";
42
43const DEFAULT_FIXTURES_PATH: &str = "test-fixtures";
45
46const STATE_TESTS_TARBALL: &str = "fixtures_general_state_tests.tgz";
47
48fn workspace_root() -> PathBuf {
50 let manifest_dir = env!("CARGO_MANIFEST_DIR");
51 Path::new(manifest_dir)
52 .ancestors()
53 .find(|p| p.join("Cargo.lock").exists())
54 .map(Path::to_path_buf)
55 .unwrap_or_else(|| PathBuf::from("."))
56}
57
58pub fn get_ethtests_path() -> PathBuf {
60 if let Ok(path) = std::env::var("ETHTESTS") {
61 return PathBuf::from(path);
62 }
63 let root = workspace_root();
64 let path = root.join(DEFAULT_ETHTESTS_PATH);
65 if path.exists() { path } else { PathBuf::from(DEFAULT_ETHTESTS_PATH) }
66}
67
68pub fn get_fixtures_path() -> PathBuf {
70 if let Ok(path) = std::env::var("REVMC_TEST_FIXTURES") {
71 return PathBuf::from(path);
72 }
73 workspace_root().join(DEFAULT_FIXTURES_PATH)
74}
75
76pub fn get_general_state_tests_path() -> Option<PathBuf> {
83 let root = get_ethtests_path();
84
85 if let Some(parent) = root.parent() {
87 let dir = parent.join("GeneralStateTests");
88 if dir.is_dir() {
89 return Some(dir);
90 }
91 }
92
93 let dir = root.join("GeneralStateTests");
95 if dir.is_dir() {
96 return Some(dir);
97 }
98
99 let tarball = root.join(STATE_TESTS_TARBALL);
100 if !tarball.is_file() {
101 return None;
102 }
103
104 let extract_dir = root.parent()?;
106 let status = std::process::Command::new("tar")
107 .arg("xzf")
108 .arg(&tarball)
109 .arg("-C")
110 .arg(extract_dir)
111 .status()
112 .ok()?;
113 if !status.success() {
114 return None;
115 }
116
117 let dir = extract_dir.join("GeneralStateTests");
118 dir.is_dir().then_some(dir)
119}
120
121pub fn get_exec_spec_stable_state_tests_path() -> Option<PathBuf> {
123 let dir = get_fixtures_path().join("main/stable/state_tests");
124 dir.is_dir().then_some(dir)
125}
126
127pub fn get_exec_spec_develop_state_tests_path() -> Option<PathBuf> {
129 let dir = get_fixtures_path().join("main/develop/state_tests");
130 dir.is_dir().then_some(dir)
131}
132
133pub fn get_legacy_cancun_state_tests_path() -> Option<PathBuf> {
135 let dir = get_fixtures_path().join("legacytests/Cancun/GeneralStateTests");
136 dir.is_dir().then_some(dir)
137}
138
139pub fn get_legacy_constantinople_state_tests_path() -> Option<PathBuf> {
141 let dir = get_fixtures_path().join("legacytests/Constantinople/GeneralStateTests");
142 dir.is_dir().then_some(dir)
143}
144
145pub fn get_exec_spec_stable_blockchain_tests_path() -> Option<PathBuf> {
147 let dir = get_fixtures_path().join("main/stable/blockchain_tests");
148 dir.is_dir().then_some(dir)
149}
150
151pub fn get_exec_spec_develop_blockchain_tests_path() -> Option<PathBuf> {
153 let dir = get_fixtures_path().join("main/develop/blockchain_tests");
154 dir.is_dir().then_some(dir)
155}