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

chore: refactor tests layout #7410

Merged
merged 11 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ jobs:
# so running `forge fmt` with `--root testdata` won't actually check anything
run: |
shopt -s extglob
cargo run --bin forge -- fmt --check testdata/**/!(Vm).sol
cargo run --bin forge -- fmt --check $(find testdata -name '*.sol' ! -name Vm.sol)

crate-checks:
runs-on: ubuntu-latest
Expand Down
8 changes: 4 additions & 4 deletions crates/forge/tests/it/cheats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use crate::{
config::*,
test_helpers::{PROJECT, RE_PATH_SEPARATOR},
test_helpers::{RE_PATH_SEPARATOR, TEST_DATA_DEFAULT},
};
use foundry_config::{fs_permissions::PathPermission, Config, FsPermissions};
use foundry_config::{fs_permissions::PathPermission, FsPermissions};
use foundry_test_utils::Filter;

/// Executes all cheat code tests but not fork cheat codes
Expand All @@ -18,9 +18,9 @@ async fn test_cheats_local() {
filter = filter.exclude_tests("(Ffi|File|Line|Root)");
}

let mut config = Config::with_root(PROJECT.root());
let mut config = TEST_DATA_DEFAULT.config.clone();
config.fs_permissions = FsPermissions::new(vec![PathPermission::read_write("./")]);
let runner = runner_with_config(config);
let runner = runner_with_config(&TEST_DATA_DEFAULT, config);

TestConfig::with_filter(runner, filter).run().await;
}
45 changes: 21 additions & 24 deletions crates/forge/tests/it/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Test config.

use crate::test_helpers::{COMPILED, EVM_OPTS, PROJECT, TEST_OPTS};
use crate::test_helpers::ForgeTestData;
use forge::{
result::{SuiteResult, TestStatus},
MultiContractRunner, MultiContractRunnerBuilder,
Expand Down Expand Up @@ -31,10 +31,6 @@ impl TestConfig {
Self::with_filter(runner, Filter::matches_all())
}

pub fn filter(filter: Filter) -> Self {
Self::with_filter(runner(), filter)
}

pub fn with_filter(runner: MultiContractRunner, filter: Filter) -> Self {
init_tracing();
Self { runner, should_fail: false, filter }
Expand Down Expand Up @@ -119,58 +115,59 @@ pub fn manifest_root() -> &'static Path {
}

/// Builds a base runner
pub fn base_runner() -> MultiContractRunnerBuilder {
pub fn base_runner(test_data: &ForgeTestData) -> MultiContractRunnerBuilder {
init_tracing();
MultiContractRunnerBuilder::default()
.sender(EVM_OPTS.sender)
.with_test_options(TEST_OPTS.clone())
.sender(test_data.evm_opts.sender)
.with_test_options(test_data.test_opts.clone())
}

/// Builds a non-tracing runner
pub fn runner() -> MultiContractRunner {
let mut config = Config::with_root(PROJECT.root());
pub fn runner(test_data: &ForgeTestData) -> MultiContractRunner {
let mut config = test_data.config.clone();
config.fs_permissions = FsPermissions::new(vec![PathPermission::read_write(manifest_root())]);
runner_with_config(config)
runner_with_config(test_data, config)
}

/// Builds a non-tracing runner
pub fn runner_with_config(mut config: Config) -> MultiContractRunner {
pub fn runner_with_config(test_data: &ForgeTestData, mut config: Config) -> MultiContractRunner {
config.rpc_endpoints = rpc_endpoints();
config.allow_paths.push(manifest_root().to_path_buf());

let root = &PROJECT.paths.root;
let opts = &*EVM_OPTS;
let root = test_data.project.root();
let opts = test_data.evm_opts.clone();
let env = opts.local_evm_env();
let output = COMPILED.clone();
base_runner()
let output = test_data.output.clone();
base_runner(test_data)
.with_cheats_config(CheatsConfig::new(&config, opts.clone(), None))
.sender(config.sender)
.with_test_options(test_data.test_opts.clone())
.build(root, output, env, opts.clone())
.unwrap()
}

/// Builds a tracing runner
pub fn tracing_runner() -> MultiContractRunner {
let mut opts = EVM_OPTS.clone();
pub fn tracing_runner(test_data: &ForgeTestData) -> MultiContractRunner {
let mut opts = test_data.evm_opts.clone();
opts.verbosity = 5;
base_runner()
.build(&PROJECT.paths.root, (*COMPILED).clone(), EVM_OPTS.local_evm_env(), opts)
base_runner(test_data)
.build(test_data.project.root(), test_data.output.clone(), opts.local_evm_env(), opts)
.unwrap()
}

// Builds a runner that runs against forked state
pub async fn forked_runner(rpc: &str) -> MultiContractRunner {
let mut opts = EVM_OPTS.clone();
pub async fn forked_runner(test_data: &ForgeTestData, rpc: &str) -> MultiContractRunner {
DaniPopes marked this conversation as resolved.
Show resolved Hide resolved
let mut opts = test_data.evm_opts.clone();

opts.env.chain_id = None; // clear chain id so the correct one gets fetched from the RPC
opts.fork_url = Some(rpc.to_string());

let env = opts.evm_env().await.expect("Could not instantiate fork environment");
let fork = opts.get_fork(&Default::default(), env.clone());

base_runner()
base_runner(test_data)
.with_fork(fork)
.build(&PROJECT.paths.root, (*COMPILED).clone(), env, opts)
.build(test_data.project.root(), test_data.output.clone(), env, opts)
.unwrap()
}

Expand Down
49 changes: 26 additions & 23 deletions crates/forge/tests/it/core.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Forge tests for core functionality.

use crate::config::*;
use crate::{config::*, test_helpers::TEST_DATA_DEFAULT};
use forge::result::SuiteResult;
use foundry_evm::traces::TraceKind;
use foundry_test_utils::Filter;
Expand All @@ -9,14 +9,14 @@ use std::{collections::BTreeMap, env};
#[tokio::test(flavor = "multi_thread")]
async fn test_core() {
let filter = Filter::new(".*", ".*", ".*core");
let mut runner = runner();
let mut runner = runner(&TEST_DATA_DEFAULT);
let results = runner.test_collect(&filter);

assert_multiple(
&results,
BTreeMap::from([
(
"core/FailingSetup.t.sol:FailingSetupTest",
"default/core/FailingSetup.t.sol:FailingSetupTest",
vec![(
"setUp()",
false,
Expand All @@ -26,7 +26,7 @@ async fn test_core() {
)],
),
(
"core/MultipleSetup.t.sol:MultipleSetup",
"default/core/MultipleSetup.t.sol:MultipleSetup",
vec![(
"setUp()",
false,
Expand All @@ -36,34 +36,37 @@ async fn test_core() {
)],
),
(
"core/Reverting.t.sol:RevertingTest",
"default/core/Reverting.t.sol:RevertingTest",
vec![("testFailRevert()", true, None, None, None)],
),
(
"core/SetupConsistency.t.sol:SetupConsistencyCheck",
"default/core/SetupConsistency.t.sol:SetupConsistencyCheck",
vec![
("testAdd()", true, None, None, None),
("testMultiply()", true, None, None, None),
],
),
(
"core/DSStyle.t.sol:DSStyleTest",
"default/core/DSStyle.t.sol:DSStyleTest",
vec![("testFailingAssertions()", true, None, None, None)],
),
(
"core/ContractEnvironment.t.sol:ContractEnvironmentTest",
"default/core/ContractEnvironment.t.sol:ContractEnvironmentTest",
vec![
("testAddresses()", true, None, None, None),
("testEnvironment()", true, None, None, None),
],
),
(
"core/PaymentFailure.t.sol:PaymentFailureTest",
"default/core/PaymentFailure.t.sol:PaymentFailureTest",
vec![("testCantPay()", false, Some("EvmError: Revert".to_string()), None, None)],
),
("core/Abstract.t.sol:AbstractTest", vec![("testSomething()", true, None, None, None)]),
(
"core/FailingTestAfterFailedSetup.t.sol:FailingTestAfterFailedSetupTest",
"default/core/Abstract.t.sol:AbstractTest",
vec![("testSomething()", true, None, None, None)],
),
(
"default/core/FailingTestAfterFailedSetup.t.sol:FailingTestAfterFailedSetupTest",
vec![(
"setUp()",
false,
Expand All @@ -79,25 +82,25 @@ async fn test_core() {
#[tokio::test(flavor = "multi_thread")]
async fn test_linking() {
let filter = Filter::new(".*", ".*", ".*linking");
let mut runner = runner();
let mut runner = runner(&TEST_DATA_DEFAULT);
let results = runner.test_collect(&filter);

assert_multiple(
&results,
BTreeMap::from([
(
"linking/simple/Simple.t.sol:SimpleLibraryLinkingTest",
"default/linking/simple/Simple.t.sol:SimpleLibraryLinkingTest",
vec![("testCall()", true, None, None, None)],
),
(
"linking/nested/Nested.t.sol:NestedLibraryLinkingTest",
"default/linking/nested/Nested.t.sol:NestedLibraryLinkingTest",
vec![
("testDirect()", true, None, None, None),
("testNested()", true, None, None, None),
],
),
(
"linking/duplicate/Duplicate.t.sol:DuplicateLibraryLinkingTest",
"default/linking/duplicate/Duplicate.t.sol:DuplicateLibraryLinkingTest",
vec![
("testA()", true, None, None, None),
("testB()", true, None, None, None),
Expand All @@ -113,14 +116,14 @@ async fn test_linking() {
#[tokio::test(flavor = "multi_thread")]
async fn test_logs() {
let filter = Filter::new(".*", ".*", ".*logs");
let mut runner = runner();
let mut runner = runner(&TEST_DATA_DEFAULT);
let results = runner.test_collect(&filter);

assert_multiple(
&results,
BTreeMap::from([
(
"logs/DebugLogs.t.sol:DebugLogsTest",
"default/logs/DebugLogs.t.sol:DebugLogsTest",
vec![
(
"test1()",
Expand Down Expand Up @@ -289,7 +292,7 @@ async fn test_logs() {
],
),
(
"logs/HardhatLogs.t.sol:HardhatLogsTest",
"default/logs/HardhatLogs.t.sol:HardhatLogsTest",
vec![
(
"testInts()",
Expand Down Expand Up @@ -678,7 +681,7 @@ async fn test_env_vars() {
env::remove_var(env_var_key);

let filter = Filter::new("testSetEnv", ".*", ".*");
let mut runner = runner();
let mut runner = runner(&TEST_DATA_DEFAULT);
let _ = runner.test_collect(&filter);

assert_eq!(env::var(env_var_key).unwrap(), env_var_val);
Expand All @@ -687,16 +690,16 @@ async fn test_env_vars() {
#[tokio::test(flavor = "multi_thread")]
async fn test_doesnt_run_abstract_contract() {
let filter = Filter::new(".*", ".*", ".*Abstract.t.sol".to_string().as_str());
let mut runner = runner();
let mut runner = runner(&TEST_DATA_DEFAULT);
let results = runner.test_collect(&filter);
assert!(!results.contains_key("core/Abstract.t.sol:AbstractTestBase"));
assert!(results.contains_key("core/Abstract.t.sol:AbstractTest"));
assert!(!results.contains_key("default/core/Abstract.t.sol:AbstractTestBase"));
assert!(results.contains_key("default/core/Abstract.t.sol:AbstractTest"));
}

#[tokio::test(flavor = "multi_thread")]
async fn test_trace() {
let filter = Filter::new(".*", ".*", ".*trace");
let mut runner = tracing_runner();
let mut runner = tracing_runner(&TEST_DATA_DEFAULT);
let suite_result = runner.test_collect(&filter);

// TODO: This trace test is very basic - it is probably a good candidate for snapshot
Expand Down
28 changes: 15 additions & 13 deletions crates/forge/tests/it/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

use crate::{
config::*,
test_helpers::{PROJECT, RE_PATH_SEPARATOR},
test_helpers::{RE_PATH_SEPARATOR, TEST_DATA_DEFAULT},
};
use forge::result::SuiteResult;
use foundry_config::{fs_permissions::PathPermission, Config, FsPermissions};
use foundry_config::{fs_permissions::PathPermission, FsPermissions};
use foundry_test_utils::Filter;

/// Executes reverting fork test
Expand All @@ -16,7 +16,7 @@ async fn test_cheats_fork_revert() {
".*",
&format!(".*cheats{RE_PATH_SEPARATOR}Fork"),
);
let mut runner = runner();
let mut runner = runner(&TEST_DATA_DEFAULT);
let suite_result = runner.test_collect(&filter);
assert_eq!(suite_result.len(), 1);

Expand All @@ -33,9 +33,9 @@ async fn test_cheats_fork_revert() {
/// Executes all non-reverting fork cheatcodes
#[tokio::test(flavor = "multi_thread")]
async fn test_cheats_fork() {
let mut config = Config::with_root(PROJECT.root());
let mut config = TEST_DATA_DEFAULT.config.clone();
config.fs_permissions = FsPermissions::new(vec![PathPermission::read("./fixtures")]);
let runner = runner_with_config(config);
let runner = runner_with_config(&TEST_DATA_DEFAULT, config);
let filter = Filter::new(".*", ".*", &format!(".*cheats{RE_PATH_SEPARATOR}Fork"))
.exclude_tests(".*Revert");
TestConfig::with_filter(runner, filter).run().await;
Expand All @@ -44,9 +44,9 @@ async fn test_cheats_fork() {
/// Executes eth_getLogs cheatcode
#[tokio::test(flavor = "multi_thread")]
async fn test_get_logs_fork() {
let mut config = Config::with_root(PROJECT.root());
let mut config = TEST_DATA_DEFAULT.config.clone();
config.fs_permissions = FsPermissions::new(vec![PathPermission::read("./fixtures")]);
let runner = runner_with_config(config);
let runner = runner_with_config(&TEST_DATA_DEFAULT, config);
let filter = Filter::new("testEthGetLogs", ".*", &format!(".*cheats{RE_PATH_SEPARATOR}Fork"))
.exclude_tests(".*Revert");
TestConfig::with_filter(runner, filter).run().await;
Expand All @@ -55,9 +55,9 @@ async fn test_get_logs_fork() {
/// Executes rpc cheatcode
#[tokio::test(flavor = "multi_thread")]
async fn test_rpc_fork() {
let mut config = Config::with_root(PROJECT.root());
let mut config = TEST_DATA_DEFAULT.config.clone();
config.fs_permissions = FsPermissions::new(vec![PathPermission::read("./fixtures")]);
let runner = runner_with_config(config);
let runner = runner_with_config(&TEST_DATA_DEFAULT, config);
let filter = Filter::new("testRpc", ".*", &format!(".*cheats{RE_PATH_SEPARATOR}Fork"))
.exclude_tests(".*Revert");
TestConfig::with_filter(runner, filter).run().await;
Expand All @@ -67,7 +67,7 @@ async fn test_rpc_fork() {
#[tokio::test(flavor = "multi_thread")]
async fn test_launch_fork() {
let rpc_url = foundry_common::rpc::next_http_archive_rpc_endpoint();
let runner = forked_runner(&rpc_url).await;
let runner = forked_runner(&TEST_DATA_DEFAULT, &rpc_url).await;
let filter = Filter::new(".*", ".*", &format!(".*fork{RE_PATH_SEPARATOR}Launch"));
TestConfig::with_filter(runner, filter).run().await;
}
Expand All @@ -76,21 +76,23 @@ async fn test_launch_fork() {
#[tokio::test(flavor = "multi_thread")]
async fn test_launch_fork_ws() {
let rpc_url = foundry_common::rpc::next_ws_archive_rpc_endpoint();
let runner = forked_runner(&rpc_url).await;
let runner = forked_runner(&TEST_DATA_DEFAULT, &rpc_url).await;
let filter = Filter::new(".*", ".*", &format!(".*fork{RE_PATH_SEPARATOR}Launch"));
TestConfig::with_filter(runner, filter).run().await;
}

/// Tests that we can transact transactions in forking mode
#[tokio::test(flavor = "multi_thread")]
async fn test_transact_fork() {
let runner = runner(&TEST_DATA_DEFAULT);
let filter = Filter::new(".*", ".*", &format!(".*fork{RE_PATH_SEPARATOR}Transact"));
TestConfig::filter(filter).run().await;
TestConfig::with_filter(runner, filter).run().await;
}

/// Tests that we can create the same fork (provider,block) concurretnly in different tests
#[tokio::test(flavor = "multi_thread")]
async fn test_create_same_fork() {
let runner = runner(&TEST_DATA_DEFAULT);
let filter = Filter::new(".*", ".*", &format!(".*fork{RE_PATH_SEPARATOR}ForkSame"));
TestConfig::filter(filter).run().await;
TestConfig::with_filter(runner, filter).run().await;
}
Loading
Loading