Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: testool traces #1432

Merged
merged 4 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading