Skip to content

Commit

Permalink
feat(e2e-tests): use near sandbox worker (#967)
Browse files Browse the repository at this point in the history
  • Loading branch information
fbozic authored Nov 19, 2024
1 parent 5654fee commit 7fc10d4
Show file tree
Hide file tree
Showing 8 changed files with 486 additions and 2,412 deletions.
2,677 changes: 332 additions & 2,345 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ libp2p-stream = "0.1.0-alpha.1"
libp2p-identity = "0.2.9"
multiaddr = "0.18.1"
near-account-id = "1.0.0"
near-crypto = "0.26.0"
near-jsonrpc-client = "0.13.0"
near-jsonrpc-primitives = "0.26.0"
near-primitives = "0.26.0"
near-crypto = "0.27.0"
near-jsonrpc-client = "0.14.0"
near-jsonrpc-primitives = "0.27.0"
near-primitives = "0.27.0"
near-sdk = "5.5.0"
near-workspaces = "0.10.0"
near-workspaces = "0.15.0"
notify = "6.1.1"
ouroboros = "0.18.3"
owo-colors = "3.5.0"
Expand Down
1 change: 1 addition & 0 deletions e2e-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ camino = { workspace = true, features = ["serde1"] }
clap = { workspace = true, features = ["env", "derive"] }
const_format.workspace = true
eyre.workspace = true
near-workspaces.workspace = true
nix = { version = "0.29.0", features = ["signal"] }
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] }
Expand Down
4 changes: 4 additions & 0 deletions e2e-tests/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@
},
"merod": {
"args": []
},
"near": {
"contextConfigContract": "./contracts/context-config/res/calimero_context_config_near.wasm",
"proxyLibContract": "./contracts/proxy-lib/res/proxy_lib.wasm"
}
}
9 changes: 9 additions & 0 deletions e2e-tests/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use camino::Utf8PathBuf;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
pub network: Network,
pub merod: MerodConfig,
pub near: Near,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand All @@ -20,3 +22,10 @@ pub struct Network {
pub struct MerodConfig {
pub args: Box<[String]>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Near {
pub context_config_contract: Utf8PathBuf,
pub proxy_lib_contract: Utf8PathBuf,
}
187 changes: 133 additions & 54 deletions e2e-tests/src/driver.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;

use eyre::{bail, Result as EyreResult};
use near_workspaces::network::Sandbox;
use near_workspaces::types::NearToken;
use near_workspaces::{Account, Contract, Worker};
use rand::seq::SliceRandom;
use serde_json::from_slice;
use tokio::fs::{read, read_dir};
Expand Down Expand Up @@ -45,7 +47,14 @@ pub struct Driver {
environment: TestEnvironment,
config: Config,
meroctl: Meroctl,
merods: RefCell<HashMap<String, Merod>>,
merods: HashMap<String, Merod>,
near: Option<NearSandboxEnvironment>,
}

pub struct NearSandboxEnvironment {
pub worker: Worker<Sandbox>,
pub root_account: Account,
pub contract: Contract,
}

impl Driver {
Expand All @@ -55,23 +64,138 @@ impl Driver {
environment,
config,
meroctl,
merods: RefCell::new(HashMap::new()),
merods: HashMap::new(),
near: None,
}
}

pub async fn run(&self) -> EyreResult<()> {
pub async fn run(&mut self) -> EyreResult<()> {
self.environment.init().await?;

let result = self.run_tests().await;
self.init_near_environment().await?;

self.stop_nodes().await;
let result = {
self.boot_merods().await?;
self.run_scenarios().await
};

self.stop_merods().await;

result
}

async fn run_tests(&self) -> EyreResult<()> {
self.boot_nodes().await?;
async fn init_near_environment(&mut self) -> EyreResult<()> {
let worker = near_workspaces::sandbox().await?;

let wasm = read(&self.config.near.context_config_contract).await?;
let context_config_contract = worker.dev_deploy(&wasm).await?;

let proxy_lib_contract = read(&self.config.near.proxy_lib_contract).await?;
drop(
context_config_contract
.call("set_proxy_code")
.args(proxy_lib_contract)
.max_gas()
.transact()
.await?
.into_result()?,
);

let root_account = worker.root_account()?;

self.near = Some(NearSandboxEnvironment {
worker,
root_account,
contract: context_config_contract,
});

Ok(())
}

async fn boot_merods(&mut self) -> EyreResult<()> {
println!("========================= Starting nodes ===========================");

for i in 0..self.config.network.node_count {
let node_name = format!("node{}", i + 1);
if !self.merods.contains_key(&node_name) {
let mut args = vec![format!(
"discovery.rendezvous.namespace=\"calimero/e2e-tests/{}\"",
self.environment.test_id
)];

if let Some(ref near) = self.near {
let near_account = near
.root_account
.create_subaccount(&node_name)
.initial_balance(NearToken::from_near(30))
.transact()
.await?
.into_result()?;
let near_secret_key = near_account.secret_key();

args.extend(vec![
format!(
"context.config.new.contract_id=\"{}\"",
near.contract.as_account().id()
),
format!("context.config.signer.use=\"{}\"", "self"),
format!(
"context.config.signer.self.near.testnet.rpc_url=\"{}\"",
near.worker.rpc_addr()
),
format!(
"context.config.signer.self.near.testnet.account_id=\"{}\"",
near_account.id()
),
format!(
"context.config.signer.self.near.testnet.public_key=\"{}\"",
near_secret_key.public_key()
),
format!(
"context.config.signer.self.near.testnet.secret_key=\"{}\"",
near_secret_key
),
]);
}

let mut config_args = vec![];
config_args.extend(args.iter().map(|arg| &**arg));

let merod = Merod::new(node_name.clone(), &self.environment);

merod
.init(
self.config.network.start_swarm_port + i,
self.config.network.start_server_port + i,
&config_args,
)
.await?;

merod.run().await?;

drop(self.merods.insert(node_name, merod));
}
}

// TODO: Implement health check?
sleep(Duration::from_secs(20)).await;

println!("====================================================================");

Ok(())
}

async fn stop_merods(&mut self) {
for (_, merod) in self.merods.iter() {
if let Err(err) = merod.stop().await {
eprintln!("Error stopping merod: {:?}", err);
}
}

self.merods.clear();
}

async fn run_scenarios(&self) -> EyreResult<()> {
let scenarios_dir = self.environment.input_dir.join("scenarios");
let mut entries = read_dir(scenarios_dir).await?;

Expand Down Expand Up @@ -124,8 +248,7 @@ impl Driver {
}

fn pick_inviter_node(&self) -> Option<(String, Vec<String>)> {
let merods = self.merods.borrow();
let mut node_names: Vec<String> = merods.keys().cloned().collect();
let mut node_names: Vec<String> = self.merods.keys().cloned().collect();
if node_names.len() < 1 {
None
} else {
Expand All @@ -135,48 +258,4 @@ impl Driver {
Some((picked_node, node_names))
}
}

async fn boot_nodes(&self) -> EyreResult<()> {
println!("========================= Starting nodes ===========================");

for i in 0..self.config.network.node_count {
let node_name = format!("node{}", i + 1);
let mut merods = self.merods.borrow_mut();
if !merods.contains_key(&node_name) {
let merod = Merod::new(node_name.clone(), &self.environment);
let args: Vec<&str> = self.config.merod.args.iter().map(|s| s.as_str()).collect();

merod
.init(
self.config.network.start_swarm_port + i,
self.config.network.start_server_port + i,
&args,
)
.await?;

merod.run().await?;

drop(merods.insert(node_name, merod));
}
}

// TODO: Implement health check?
sleep(Duration::from_secs(20)).await;

println!("====================================================================");

Ok(())
}

async fn stop_nodes(&self) {
let mut merods = self.merods.borrow_mut();

for (_, merod) in merods.iter_mut() {
if let Err(err) = merod.stop().await {
eprintln!("Error stopping merod: {:?}", err);
}
}

merods.clear();
}
}
2 changes: 1 addition & 1 deletion e2e-tests/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ async fn main() -> EyreResult<()> {
let config_content = read_to_string(config_path).await?;
let config: Config = serde_json::from_str(&config_content)?;

let driver = Driver::new(args.into(), config);
let mut driver = Driver::new(args.into(), config);

driver.run().await
}
8 changes: 1 addition & 7 deletions e2e-tests/src/merod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::TestEnvironment;

pub struct Merod {
pub name: String,
test_id: u32,
process: RefCell<Option<Child>>,
nodes_dir: Utf8PathBuf,
log_dir: Utf8PathBuf,
Expand All @@ -21,7 +20,6 @@ pub struct Merod {
impl Merod {
pub fn new(name: String, environment: &TestEnvironment) -> Self {
Self {
test_id: environment.test_id,
process: RefCell::new(None),
nodes_dir: environment.nodes_dir.clone(),
log_dir: environment.logs_dir.join(&name),
Expand Down Expand Up @@ -51,11 +49,7 @@ impl Merod {
bail!("Failed to initialize node '{}'", self.name);
}

let rendezvous_ns_arg = format!(
"discovery.rendezvous.namespace=\"calimero/e2e-tests/{}\"",
self.test_id
);
let mut config_args = vec!["config", rendezvous_ns_arg.as_str()];
let mut config_args = vec!["config"];
config_args.extend(args);

let mut child = self.run_cmd(&config_args, "config").await?;
Expand Down

0 comments on commit 7fc10d4

Please sign in to comment.