Skip to content

Commit

Permalink
Test logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
Grant Wuerker committed Sep 26, 2023
1 parent 0b0172a commit 661644d
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 45 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions crates/abi/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ impl Serialize for AbiType {

#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct AbiTupleField {
name: String,
pub name: String,
#[serde(flatten)]
ty: AbiType,
pub ty: AbiType,
}

impl AbiTupleField {
Expand Down
8 changes: 7 additions & 1 deletion crates/codegen/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
use std::rc::Rc;

use fe_abi::{contract::AbiContract, event::AbiEvent, function::AbiFunction, types::AbiType};
use fe_analyzer::{db::AnalyzerDbStorage, namespace::items::ContractId, AnalyzerDb};
use fe_analyzer::{
db::AnalyzerDbStorage,
namespace::items::{ContractId, ModuleId},
AnalyzerDb,
};
use fe_common::db::{SourceDb, SourceDbStorage, Upcast, UpcastMut};
use fe_mir::{
db::{MirDb, MirDbStorage},
Expand Down Expand Up @@ -31,6 +35,8 @@ pub trait CodegenDb: MirDb + Upcast<dyn MirDb> + UpcastMut<dyn MirDb> {
fn codegen_abi_event(&self, ty: TypeId) -> AbiEvent;
#[salsa::invoke(queries::abi::abi_contract)]
fn codegen_abi_contract(&self, contract: ContractId) -> AbiContract;
#[salsa::invoke(queries::abi::abi_module_events)]
fn codegen_abi_module_events(&self, module: ModuleId) -> Vec<AbiEvent>;
#[salsa::invoke(queries::abi::abi_type_maximum_size)]
fn codegen_abi_type_maximum_size(&self, ty: TypeId) -> usize;
#[salsa::invoke(queries::abi::abi_type_minimum_size)]
Expand Down
12 changes: 9 additions & 3 deletions crates/codegen/src/db/queries/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use fe_abi::{
use fe_analyzer::{
constants::INDEXED,
namespace::{
items::ContractId,
items::{ContractId, ModuleId},
types::{CtxDecl, SelfDecl},
},
};
Expand All @@ -32,8 +32,14 @@ pub fn abi_contract(db: &dyn CodegenDb, contract: ContractId) -> AbiContract {
}
}

let events = abi_module_events(db, contract.module(db.upcast()));

AbiContract::new(funcs, events)
}

pub fn abi_module_events(db: &dyn CodegenDb, module: ModuleId) -> Vec<AbiEvent> {
let mut events = vec![];
for &s in db.module_structs(contract.module(db.upcast())).as_ref() {
for &s in db.module_structs(module).as_ref() {
let struct_ty = s.as_type(db.upcast());
// TODO: This is a hack to avoid generating an ABI for non-`emittable` structs.
if struct_ty.is_emittable(db.upcast()) {
Expand All @@ -43,7 +49,7 @@ pub fn abi_contract(db: &dyn CodegenDb, contract: ContractId) -> AbiContract {
}
}

AbiContract::new(funcs, events)
events
}

pub fn abi_function(db: &dyn CodegenDb, function: FunctionId) -> AbiFunction {
Expand Down
62 changes: 58 additions & 4 deletions crates/driver/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#![allow(unused_imports, dead_code)]

use fe_abi::event::AbiEvent;
use fe_abi::types::{AbiTupleField, AbiType};
pub use fe_codegen::db::{CodegenDb, Db};

use fe_analyzer::namespace::items::{ContractId, FunctionId, IngotId, IngotMode, ModuleId};
use fe_common::diagnostics::Diagnostic;
use fe_common::files::FileKind;
use fe_common::{db::Upcast, utils::files::BuildFiles};
use fe_parser::ast::SmolStr;
use fe_test_runner::ethabi::{Event, EventParam, ParamType};
use fe_test_runner::TestSink;
use indexmap::{indexmap, IndexMap};
use serde_json::Value;
Expand All @@ -30,20 +33,70 @@ pub struct CompiledContract {
#[cfg(feature = "solc-backend")]
pub struct CompiledTest {
pub name: SmolStr,
events: Vec<AbiEvent>,
bytecode: String,
}

#[cfg(feature = "solc-backend")]
impl CompiledTest {
pub fn new(name: SmolStr, bytecode: String) -> Self {
Self { name, bytecode }
pub fn new(name: SmolStr, events: Vec<AbiEvent>, bytecode: String) -> Self {
Self {
name,
events,
bytecode,
}
}

pub fn execute(&self, sink: &mut TestSink) -> bool {
fe_test_runner::execute(&self.name, &self.bytecode, sink)
let events = map_abi_events(&self.events);
fe_test_runner::execute(&self.name, &events, &self.bytecode, sink)
}
}

fn map_abi_events(events: &[AbiEvent]) -> Vec<Event> {
events.iter().map(map_abi_event).collect()
}

fn map_abi_event(event: &AbiEvent) -> Event {
let inputs = event
.inputs
.iter()
.map(|input| {
let kind = map_abi_type(&input.ty);
EventParam {
name: input.name.to_owned(),
kind,
indexed: input.indexed,
}
})
.collect();
Event {
name: event.name.to_owned(),
inputs,
anonymous: event.anonymous,
}
}

fn map_abi_type(typ: &AbiType) -> ParamType {
match typ {
AbiType::UInt(value) => ParamType::Uint(*value),
AbiType::Int(value) => ParamType::Int(*value),
AbiType::Address => ParamType::Address,
AbiType::Bool => ParamType::Bool,
AbiType::Function => panic!("function cannot be mapped to an actual ABI value type"),
AbiType::Array { elem_ty, len } => {
ParamType::FixedArray(Box::new(map_abi_type(elem_ty)), *len)
}
AbiType::Tuple(params) => ParamType::Tuple(map_abi_types(params)),
AbiType::Bytes => ParamType::Bytes,
AbiType::String => ParamType::String,
}
}

fn map_abi_types(fields: &[AbiTupleField]) -> Vec<ParamType> {
fields.iter().map(|field| map_abi_type(&field.ty)).collect()
}

#[derive(Debug)]
pub struct CompileError(pub Vec<Diagnostic>);

Expand Down Expand Up @@ -167,7 +220,8 @@ fn compile_test(db: &mut Db, test: FunctionId, optimize: bool) -> CompiledTest {
.to_string()
.replace('"', "\\\"");
let bytecode = compile_to_evm("test", &yul_test, optimize);
CompiledTest::new(test.name(db), bytecode)
let events = db.codegen_abi_module_events(test.module(db));
CompiledTest::new(test.name(db), events, bytecode)
}

#[cfg(feature = "solc-backend")]
Expand Down
52 changes: 29 additions & 23 deletions crates/fe/src/task/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub struct TestArgs {
input_path: String,
#[clap(long, takes_value(true))]
optimize: Option<bool>,
#[clap(long)]
logs: bool,
}

pub fn test(args: TestArgs) {
Expand All @@ -27,13 +29,36 @@ pub fn test(args: TestArgs) {
};

println!("{test_sink}");

if test_sink.failure_count() != 0 {
std::process::exit(1)
}
}

pub fn execute_tests(module_name: &str, tests: &[CompiledTest], sink: &mut TestSink) {
if tests.len() == 1 {
println!("executing 1 test in {module_name}:");
} else {
println!("executing {} tests in {}:", tests.len(), module_name);
}

for test in tests {
print!(" {} ...", test.name);
let test_passed = test.execute(sink);

if test_passed {
println!(" {}", "passed".green())
} else {
println!(" {}", "failed".red())
}
}
println!();
}

fn test_single_file(args: &TestArgs) -> TestSink {
let input_path = &args.input_path;
let optimize = args.optimize.unwrap_or(true);
let logs = args.logs;

let mut db = fe_driver::Db::default();
let content = match std::fs::read_to_string(input_path) {
Expand All @@ -44,9 +69,9 @@ fn test_single_file(args: &TestArgs) -> TestSink {
Ok(content) => content,
};

match fe_driver::compile_single_file_tests(&mut db, input_path, &content, true) {
match fe_driver::compile_single_file_tests(&mut db, input_path, &content, optimize) {
Ok((name, tests)) => {
let mut sink = TestSink::default();
let mut sink = TestSink::new(logs);
execute_tests(&name, &tests, &mut sink);
sink
}
Expand All @@ -58,29 +83,10 @@ fn test_single_file(args: &TestArgs) -> TestSink {
}
}

pub fn execute_tests(module_name: &str, tests: &[CompiledTest], sink: &mut TestSink) {
if tests.len() == 1 {
println!("executing 1 test in {module_name}:");
} else {
println!("executing {} tests in {}:", tests.len(), module_name);
}

for test in tests {
print!(" {} ...", test.name);
let test_passed = test.execute(sink);

if test_passed {
println!(" {}", "passed".green())
} else {
println!(" {}", "failed".red())
}
}
println!();
}

fn test_ingot(args: &TestArgs) -> TestSink {
let input_path = &args.input_path;
let optimize = args.optimize.unwrap_or(true);
let logs = args.logs;

if !Path::new(input_path).exists() {
eprintln!("Input directory does not exist: `{input_path}`.");
Expand All @@ -99,7 +105,7 @@ fn test_ingot(args: &TestArgs) -> TestSink {

match fe_driver::compile_ingot_tests(&mut db, &build_files, optimize) {
Ok(test_batches) => {
let mut sink = TestSink::default();
let mut sink = TestSink::new(logs);
for (module_name, tests) in test_batches {
execute_tests(&module_name, &tests, &mut sink);
}
Expand Down
2 changes: 2 additions & 0 deletions crates/test-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ repository = "https://github.com/ethereum/fe"
hex="0.4"
bytes = "1.3"
colored = "2.0"
ethabi = { default-features = false, features = ["full-serde"], version = "18.0" }
indexmap = "1.6.2"

# used by revm; we need to force the js feature for wasm support
getrandom = { version = "0.2.8", features = ["js"] }
Expand Down
Loading

0 comments on commit 661644d

Please sign in to comment.