Skip to content

Commit e19504c

Browse files
authored
feat: testool traces (#1432)
* add trace gen * some fix * fix & cleanup * fix clippy
1 parent dd68938 commit e19504c

File tree

9 files changed

+332
-98
lines changed

9 files changed

+332
-98
lines changed

Cargo.lock

+47-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testool/Cargo.toml

+13
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,22 @@ version.workspace = true
55
edition.workspace = true
66
license.workspace = true
77

8+
[lib]
9+
name = "testool"
10+
11+
[[bin]]
12+
name = "testool"
13+
path = "src/bin/testool.rs"
14+
15+
[[bin]]
16+
name = "trace-gen"
17+
path = "src/bin/trace-gen.rs"
18+
819
[dependencies]
920
anyhow.workspace = true
1021
bus-mapping = { path = "../bus-mapping" }
1122
clap = { version = "4.5", features = ["derive"] }
23+
console = "0.15"
1224
env_logger.workspace = true
1325
eth-types = { path="../eth-types" }
1426
ethers-core.workspace = true
@@ -17,6 +29,7 @@ external-tracer = { path="../external-tracer" }
1729
glob = "0.3"
1830
handlebars = "4.3"
1931
hex.workspace = true
32+
indicatif = "0.17"
2033
sha3 = "0.10"
2134
log.workspace = true
2235
itertools.workspace = true

testool/src/main.rs testool/src/bin/testool.rs

+17-93
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,22 @@
11
#![feature(lazy_cell)]
2-
/// Execute the bytecode from an empty state and run the EVM and State circuits
3-
mod abi;
4-
mod compiler;
5-
mod config;
6-
mod statetest;
7-
mod utils;
8-
9-
use crate::{config::TestSuite, statetest::ResultLevel};
2+
//! Execute the bytecode from an empty state and run the EVM and State circuits
3+
104
use anyhow::{bail, Result};
115
use clap::Parser;
12-
use compiler::Compiler;
13-
use config::Config;
146
use log::info;
15-
use statetest::{
16-
load_statetests_suite, run_statetests_suite, run_test, CircuitsConfig, Results, StateTest,
17-
};
18-
use std::{
19-
collections::{HashMap, HashSet},
20-
env,
21-
fs::File,
22-
io::{BufRead, BufReader, Write},
23-
path::PathBuf,
24-
time::SystemTime,
25-
};
7+
use std::{collections::HashSet, path::PathBuf, time::SystemTime};
268
use strum_macros::EnumString;
27-
28-
const REPORT_FOLDER: &str = "report";
29-
const CODEHASH_FILE: &str = "./codehash.txt";
30-
const TEST_IDS_FILE: &str = "./test_ids.txt";
31-
32-
#[macro_use]
33-
extern crate prettytable;
9+
use testool::{
10+
compiler::Compiler,
11+
config::Config,
12+
config::TestSuite,
13+
load_tests,
14+
statetest::{
15+
load_statetests_suite, run_statetests_suite, run_test, CircuitsConfig, ResultLevel,
16+
Results, StateTest,
17+
},
18+
utils, write_test_ids, CODEHASH_FILE, REPORT_FOLDER,
19+
};
3420

3521
#[allow(non_camel_case_types)]
3622
#[derive(PartialEq, Parser, EnumString, Debug, Clone, Copy)]
@@ -81,55 +67,17 @@ struct Args {
8167

8268
/// Specify a file including test IDs to run these tests
8369
#[clap(long)]
84-
test_ids: Option<String>,
70+
test_ids: Option<PathBuf>,
8571

8672
/// Specify a file excluding test IDs to run these tests
8773
#[clap(long)]
88-
exclude_test_ids: Option<String>,
74+
exclude_test_ids: Option<PathBuf>,
8975

9076
/// Verbose
9177
#[clap(short, long)]
9278
v: bool,
9379
}
9480

95-
fn read_test_ids(file_path: &str) -> Result<Vec<String>> {
96-
let worker_index = env::var("WORKER_INDEX")
97-
.ok()
98-
.and_then(|val| val.parse::<usize>().ok())
99-
.expect("WORKER_INDEX not set");
100-
let total_workers = env::var("TOTAL_WORKERS")
101-
.ok()
102-
.and_then(|val| val.parse::<usize>().ok())
103-
.expect("TOTAL_WORKERS not set");
104-
info!("total workers: {total_workers}, worker index: {worker_index}");
105-
106-
info!("read_test_ids from {}", file_path);
107-
let mut total_jobs = 0;
108-
let test_ids = BufReader::new(File::open(file_path)?)
109-
.lines()
110-
.map(|r| r.map(|line| line.trim().to_string()))
111-
.inspect(|_| total_jobs += 1)
112-
.enumerate()
113-
.filter_map(|(idx, line)| {
114-
if idx % total_workers == worker_index {
115-
Some(line)
116-
} else {
117-
None
118-
}
119-
})
120-
.collect::<Result<Vec<String>, std::io::Error>>()?;
121-
122-
info!("read_test_ids {} of {total_jobs}", test_ids.len());
123-
Ok(test_ids)
124-
}
125-
126-
fn write_test_ids(test_ids: &[String]) -> Result<()> {
127-
let mut fd = File::create(TEST_IDS_FILE)?;
128-
fd.write_all(test_ids.join("\n").as_bytes())?;
129-
130-
Ok(())
131-
}
132-
13381
fn run_single_test(
13482
test: StateTest,
13583
suite: TestSuite,
@@ -212,31 +160,7 @@ fn go() -> Result<()> {
212160
// It is better to sue deterministic testing order.
213161
// If there is a list, follow list.
214162
// If not, order by test id.
215-
if let Some(test_ids_path) = args.test_ids {
216-
if args.exclude_test_ids.is_some() {
217-
log::warn!("--exclude-test-ids is ignored");
218-
}
219-
let test_ids = read_test_ids(&test_ids_path)?;
220-
let id_to_test: HashMap<_, _> = state_tests
221-
.iter()
222-
.map(|t| (t.id.clone(), t.clone()))
223-
.collect();
224-
state_tests.clear();
225-
state_tests.extend(
226-
test_ids
227-
.into_iter()
228-
.filter_map(|test_id| id_to_test.get(&test_id).cloned()),
229-
);
230-
} else {
231-
// sorting with reversed id string to prevent similar tests go together, so that
232-
// computing heavy tests will not trigger OOM.
233-
if let Some(exclude_test_ids_path) = args.exclude_test_ids {
234-
let buf = std::fs::read_to_string(exclude_test_ids_path)?;
235-
let set = buf.lines().map(|s| s.trim()).collect::<HashSet<_>>();
236-
state_tests.retain(|t| !set.contains(t.id.as_str()));
237-
}
238-
state_tests.sort_by_key(|t| t.id.chars().rev().collect::<String>());
239-
}
163+
load_tests(&mut state_tests, args.test_ids, args.exclude_test_ids)?;
240164

241165
if args.report {
242166
let git_hash = utils::current_git_commit()?;

0 commit comments

Comments
 (0)