-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce end-to-end testing crate (#1557)
- Loading branch information
Showing
16 changed files
with
288 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
config: | ||
chronicle_funds: 10. | ||
timechain_url: 'ws://localhost:9944' | ||
prices_path: 'prices.csv' | ||
contracts: | ||
evm: | ||
additional_params: "factory/additional_config.json" | ||
proxy: "contracts/GatewayProxy.sol/GatewayProxy.json" | ||
gateway: "contracts/Gateway.sol/Gateway.json" | ||
tester: "contracts/GmpProxy.sol/GmpProxy.json" | ||
networks: | ||
2: | ||
backend: "evm" | ||
blockchain: "anvil" | ||
network: "dev" | ||
url: "ws://localhost:8545" | ||
admin_funds: 100. | ||
gateway_funds: 1. | ||
chronicle_funds: 1. | ||
batch_size: 64 | ||
batch_offset: 0 | ||
batch_gas_limit: 10000000 | ||
gmp_margin: 0.0 | ||
shard_task_limit: 50 | ||
route_gas_limit: 10000000 | ||
route_base_fee: 1400000000 | ||
shard_size: 1 | ||
shard_threshold: 1 | ||
3: | ||
backend: "evm" | ||
blockchain: "anvil" | ||
network: "dev" | ||
url: "ws://localhost:8546" | ||
admin_funds: 100. | ||
gateway_funds: 1. | ||
chronicle_funds: 1. | ||
batch_size: 64 | ||
batch_offset: 0 | ||
batch_gas_limit: 10000000 | ||
gmp_margin: 0.0 | ||
shard_task_limit: 50 | ||
route_gas_limit: 10000000 | ||
route_base_fee: 1400000000 | ||
shard_size: 1 | ||
shard_threshold: 1 | ||
chronicles: | ||
- http://localhost:8080 | ||
- http://localhost:8081 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "e2e-tests" | ||
authors.workspace = true | ||
edition.workspace = true | ||
version.workspace = true | ||
homepage.workspace = true | ||
license.workspace = true | ||
readme.workspace = true | ||
repository.workspace = true | ||
|
||
[dev-dependencies] | ||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } | ||
anyhow.workspace = true | ||
futures.workspace = true | ||
time-primitives = { workspace = true, features = ["testnet", "develop"] } | ||
tc-cli= { path = "../tc-cli", features = ["testnet", "develop"] } | ||
tracing.workspace = true | ||
tracing-subscriber.workspace = true | ||
hex.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use anyhow::{Context, Result}; | ||
use std::path::Path; | ||
use std::process; | ||
use tc_cli::{Sender, Tc}; | ||
use time_primitives::{Address, NetworkId}; | ||
|
||
pub struct TestEnv { | ||
pub tc: Tc, | ||
} | ||
|
||
const CONFIG: &str = "local-evm-e2e.yaml"; | ||
const ENV: &str = "../config/envs/local"; | ||
|
||
impl TestEnv { | ||
async fn new() -> Result<Self> { | ||
let sender = Sender::new(); | ||
let tc = Tc::new(Path::new(ENV).to_path_buf(), CONFIG, sender) | ||
.await | ||
.context("Error creating Tc client")?; | ||
Ok(TestEnv { tc }) | ||
} | ||
|
||
/// spawns new testing env | ||
pub async fn spawn(build: bool) -> Result<Self> { | ||
if build && !build_containers()? { | ||
anyhow::bail!("Failed to build containers"); | ||
} | ||
|
||
if !docker_up()? { | ||
anyhow::bail!("Failed to start containers"); | ||
} | ||
Self::new().await | ||
} | ||
|
||
/// sets up test | ||
pub async fn setup(&self, src: NetworkId, dest: NetworkId) -> Result<(Address, Address)> { | ||
self.tc.setup_test(src, dest).await | ||
} | ||
|
||
/// restart container | ||
pub async fn restart(&self, containers: Vec<&str>) -> Result<bool> { | ||
docker_restart(containers) | ||
} | ||
} | ||
|
||
impl Drop for TestEnv { | ||
/// Tear-down logic for the tests | ||
fn drop(&mut self) { | ||
if !docker_down().expect("Failed to stop containers") { | ||
println!( | ||
"Failed to stop containers, please stop by hand with:\n\ | ||
\t $> docker compose --profile=ethereum down" | ||
); | ||
}; | ||
} | ||
} | ||
|
||
fn build_containers() -> Result<bool> { | ||
let mut cmd = process::Command::new(Path::new("../scripts/build_docker.sh")); | ||
let mut child = cmd.spawn().context("Error building containers")?; | ||
|
||
child.wait().map(|c| c.success()).context("Error building containers: {e}") | ||
} | ||
|
||
fn docker_up() -> Result<bool> { | ||
let mut cmd = process::Command::new("docker"); | ||
|
||
cmd.arg("compose").arg("--profile=evm").arg("up").arg("-d").arg("--wait"); | ||
|
||
let mut child = cmd.spawn().context("Error starting containers")?; | ||
|
||
// Wait for all containers to start | ||
child.wait().map(|c| c.success()).context("Error starting containers") | ||
} | ||
|
||
fn docker_down() -> Result<bool> { | ||
let mut cmd = process::Command::new("docker"); | ||
|
||
cmd.arg("compose").arg("--profile=evm").arg("down"); | ||
|
||
let mut child = cmd.spawn().context("Error stopping containers")?; | ||
|
||
// Wait for all containers to start | ||
child.wait().map(|c| c.success()).context("Error stopping containers: {e}") | ||
} | ||
|
||
fn docker_restart(containers: Vec<&str>) -> Result<bool> { | ||
let mut cmd = process::Command::new("docker"); | ||
cmd.arg("compose").arg("stop").args(containers.as_slice()); | ||
|
||
let mut child = cmd.spawn().context("Error stopping containers")?; | ||
// wait for the containers to stop | ||
child.wait().map(|c| c.success()).context("Error stopping containers")?; | ||
let mut cmd = process::Command::new("docker"); | ||
cmd.arg("compose").arg("start").args(containers.as_slice()); | ||
let mut child = cmd.spawn().context("Error stopping containers")?; | ||
// wait for the containers to start | ||
child.wait().map(|c| c.success()).context("Error starting containers") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use futures::StreamExt; | ||
use tc_cli::Tc; | ||
use tracing_subscriber::filter::EnvFilter; | ||
|
||
mod common; | ||
|
||
use common::TestEnv; | ||
use time_primitives::{Address, NetworkId}; | ||
|
||
const SRC: NetworkId = 2; | ||
const DEST: NetworkId = 3; | ||
|
||
async fn run_smoke(tc: &Tc, src_addr: Address, dest_addr: Address) { | ||
let mut blockstream = tc.finality_notification_stream(); | ||
let (_, start) = blockstream.next().await.expect("expected block"); | ||
let gas_limit = tc | ||
.estimate_message_gas_limit(DEST, dest_addr, SRC, src_addr, vec![]) | ||
.await | ||
.unwrap(); | ||
let gas_cost = tc.estimate_message_cost(SRC, DEST, gas_limit, vec![]).await.unwrap(); | ||
|
||
let msg_id = tc | ||
.send_message(SRC, src_addr, DEST, dest_addr, gas_limit, gas_cost, vec![]) | ||
.await | ||
.unwrap(); | ||
|
||
let mut id = None; | ||
let (exec, end) = loop { | ||
let (_, end) = blockstream.next().await.expect("expected block"); | ||
let trace = tc.message_trace(SRC, msg_id).await.unwrap(); | ||
let exec = trace.exec.as_ref().map(|t| t.task); | ||
tracing::info!(target: "smoke_test", "waiting for message {}", hex::encode(msg_id)); | ||
id = Some(tc.print_table(id, "message", vec![trace]).await.unwrap()); | ||
if let Some(exec) = exec { | ||
break (exec, end); | ||
} | ||
}; | ||
let blocks = tc.read_events_blocks(exec).await.unwrap(); | ||
let msgs = tc.messages(DEST, dest_addr, blocks).await.unwrap(); | ||
let msg = msgs | ||
.into_iter() | ||
.find(|msg| msg.message_id() == msg_id) | ||
.expect("failed to find message"); | ||
tc.print_table(None, "message", vec![msg]).await.unwrap(); | ||
tc.println(None, format!("received message after {} blocks", end - start)) | ||
.await | ||
.unwrap(); | ||
} | ||
|
||
#[tokio::test] | ||
// Resembles tc-cli smoke test | ||
async fn smoke() { | ||
let filter = EnvFilter::from_default_env() | ||
.add_directive("tc_cli=info".parse().unwrap()) | ||
.add_directive("gmp_evm=info".parse().unwrap()) | ||
.add_directive("smoke_test=info".parse().unwrap()); | ||
tracing_subscriber::fmt().with_env_filter(filter).init(); | ||
|
||
let env = TestEnv::spawn(true).await.expect("Failed to spawn Test Environment"); | ||
|
||
let (src_addr, dest_addr) = env.setup(SRC, DEST).await.expect("failed to setup test"); | ||
|
||
// Run smoke test | ||
run_smoke(&env.tc, src_addr, dest_addr).await; | ||
|
||
// Restart chronicles | ||
assert!(env | ||
.restart(vec!["chronicle-2-evm", "chronicle-3-evm"]) | ||
.await | ||
.expect("Failed to restart chronicles")); | ||
|
||
// Re-run smoke test: should still work | ||
run_smoke(&env.tc, src_addr, dest_addr).await; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.