Skip to content

Commit

Permalink
feat: testool traces (#1432)
Browse files Browse the repository at this point in the history
* add trace gen

* some fix

* fix & cleanup

* fix clippy
  • Loading branch information
lightsing authored Oct 15, 2024
1 parent dd68938 commit e19504c
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 98 deletions.
48 changes: 47 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions testool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ version.workspace = true
edition.workspace = true
license.workspace = true

[lib]
name = "testool"

[[bin]]
name = "testool"
path = "src/bin/testool.rs"

[[bin]]
name = "trace-gen"
path = "src/bin/trace-gen.rs"

[dependencies]
anyhow.workspace = true
bus-mapping = { path = "../bus-mapping" }
clap = { version = "4.5", features = ["derive"] }
console = "0.15"
env_logger.workspace = true
eth-types = { path="../eth-types" }
ethers-core.workspace = true
Expand All @@ -17,6 +29,7 @@ external-tracer = { path="../external-tracer" }
glob = "0.3"
handlebars = "4.3"
hex.workspace = true
indicatif = "0.17"
sha3 = "0.10"
log.workspace = true
itertools.workspace = true
Expand Down
110 changes: 17 additions & 93 deletions testool/src/main.rs → testool/src/bin/testool.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
#![feature(lazy_cell)]
/// Execute the bytecode from an empty state and run the EVM and State circuits
mod abi;
mod compiler;
mod config;
mod statetest;
mod utils;

use crate::{config::TestSuite, statetest::ResultLevel};
//! Execute the bytecode from an empty state and run the EVM and State circuits

use anyhow::{bail, Result};
use clap::Parser;
use compiler::Compiler;
use config::Config;
use log::info;
use statetest::{
load_statetests_suite, run_statetests_suite, run_test, CircuitsConfig, Results, StateTest,
};
use std::{
collections::{HashMap, HashSet},
env,
fs::File,
io::{BufRead, BufReader, Write},
path::PathBuf,
time::SystemTime,
};
use std::{collections::HashSet, path::PathBuf, time::SystemTime};
use strum_macros::EnumString;

const REPORT_FOLDER: &str = "report";
const CODEHASH_FILE: &str = "./codehash.txt";
const TEST_IDS_FILE: &str = "./test_ids.txt";

#[macro_use]
extern crate prettytable;
use testool::{
compiler::Compiler,
config::Config,
config::TestSuite,
load_tests,
statetest::{
load_statetests_suite, run_statetests_suite, run_test, CircuitsConfig, ResultLevel,
Results, StateTest,
},
utils, write_test_ids, CODEHASH_FILE, REPORT_FOLDER,
};

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

/// Specify a file including test IDs to run these tests
#[clap(long)]
test_ids: Option<String>,
test_ids: Option<PathBuf>,

/// Specify a file excluding test IDs to run these tests
#[clap(long)]
exclude_test_ids: Option<String>,
exclude_test_ids: Option<PathBuf>,

/// Verbose
#[clap(short, long)]
v: bool,
}

fn read_test_ids(file_path: &str) -> Result<Vec<String>> {
let worker_index = env::var("WORKER_INDEX")
.ok()
.and_then(|val| val.parse::<usize>().ok())
.expect("WORKER_INDEX not set");
let total_workers = env::var("TOTAL_WORKERS")
.ok()
.and_then(|val| val.parse::<usize>().ok())
.expect("TOTAL_WORKERS not set");
info!("total workers: {total_workers}, worker index: {worker_index}");

info!("read_test_ids from {}", file_path);
let mut total_jobs = 0;
let test_ids = BufReader::new(File::open(file_path)?)
.lines()
.map(|r| r.map(|line| line.trim().to_string()))
.inspect(|_| total_jobs += 1)
.enumerate()
.filter_map(|(idx, line)| {
if idx % total_workers == worker_index {
Some(line)
} else {
None
}
})
.collect::<Result<Vec<String>, std::io::Error>>()?;

info!("read_test_ids {} of {total_jobs}", test_ids.len());
Ok(test_ids)
}

fn write_test_ids(test_ids: &[String]) -> Result<()> {
let mut fd = File::create(TEST_IDS_FILE)?;
fd.write_all(test_ids.join("\n").as_bytes())?;

Ok(())
}

fn run_single_test(
test: StateTest,
suite: TestSuite,
Expand Down Expand Up @@ -212,31 +160,7 @@ fn go() -> Result<()> {
// It is better to sue deterministic testing order.
// If there is a list, follow list.
// If not, order by test id.
if let Some(test_ids_path) = args.test_ids {
if args.exclude_test_ids.is_some() {
log::warn!("--exclude-test-ids is ignored");
}
let test_ids = read_test_ids(&test_ids_path)?;
let id_to_test: HashMap<_, _> = state_tests
.iter()
.map(|t| (t.id.clone(), t.clone()))
.collect();
state_tests.clear();
state_tests.extend(
test_ids
.into_iter()
.filter_map(|test_id| id_to_test.get(&test_id).cloned()),
);
} else {
// sorting with reversed id string to prevent similar tests go together, so that
// computing heavy tests will not trigger OOM.
if let Some(exclude_test_ids_path) = args.exclude_test_ids {
let buf = std::fs::read_to_string(exclude_test_ids_path)?;
let set = buf.lines().map(|s| s.trim()).collect::<HashSet<_>>();
state_tests.retain(|t| !set.contains(t.id.as_str()));
}
state_tests.sort_by_key(|t| t.id.chars().rev().collect::<String>());
}
load_tests(&mut state_tests, args.test_ids, args.exclude_test_ids)?;

if args.report {
let git_hash = utils::current_git_commit()?;
Expand Down
Loading

0 comments on commit e19504c

Please sign in to comment.