This commit is contained in:
Luke Parker 2023-10-23 07:25:00 -04:00
parent c4bdbdde11
commit 08180cc563
No known key found for this signature in database
5 changed files with 119 additions and 60 deletions

View file

@ -31,8 +31,8 @@ jobs:
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
- name: Test Dependencies
uses: ./.github/actions/test-dependencies
- name: Build Dependencies
uses: ./.github/actions/build-dependencies
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
@ -51,8 +51,8 @@ jobs:
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
- name: Test Dependencies
uses: ./.github/actions/test-dependencies
- name: Build Dependencies
uses: ./.github/actions/build-dependencies
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

2
Cargo.lock generated
View file

@ -8432,6 +8432,7 @@ dependencies = [
"bitcoin-serai",
"ciphersuite",
"dalek-ff-group",
"dockertest",
"env_logger",
"flexible-transcript",
"frost-schnorrkel",
@ -8448,6 +8449,7 @@ dependencies = [
"secp256k1",
"serai-client",
"serai-db",
"serai-docker-tests",
"serai-env",
"serai-message-queue",
"serai-processor-messages",

View file

@ -70,6 +70,9 @@ frost = { package = "modular-frost", path = "../crypto/frost", features = ["test
env_logger = "0.10"
dockertest = "0.4"
serai-docker-tests = { path = "../tests/docker" }
[features]
secp256k1 = ["k256", "frost/secp256k1"]
bitcoin = ["dep:secp256k1", "secp256k1", "bitcoin-serai", "serai-client/bitcoin"]

View file

@ -1,5 +1,11 @@
use dockertest::{
PullPolicy, StartPolicy, LogOptions, LogAction, LogPolicy, LogSource, Image,
TestBodySpecification, DockerOperations, DockerTest,
};
#[cfg(feature = "bitcoin")]
mod bitcoin {
use super::*;
use crate::networks::{Network, Bitcoin};
#[test]
@ -13,14 +19,47 @@ mod bitcoin {
check::<IsTrue<{ Bitcoin::DUST >= bitcoin_serai::wallet::DUST }>>();
}
async fn bitcoin() -> Bitcoin {
let bitcoin = Bitcoin::new("http://serai:seraidex@127.0.0.1:18443".to_string()).await;
fn spawn_bitcoin() -> DockerTest {
serai_docker_tests::build("bitcoin".to_string());
let composition = TestBodySpecification::with_image(
Image::with_repository("serai-dev-bitcoin").pull_policy(PullPolicy::Never),
)
.replace_cmd(vec![
"bitcoind".to_string(),
"-txindex".to_string(),
"-regtest".to_string(),
format!("-rpcuser=serai"),
format!("-rpcpassword=seraidex"),
"-rpcbind=0.0.0.0".to_string(),
"-rpcallowip=0.0.0.0/0".to_string(),
"-rpcport=8332".to_string(),
])
.set_start_policy(StartPolicy::Strict)
.set_log_options(Some(LogOptions {
action: LogAction::Forward,
policy: LogPolicy::OnError,
source: LogSource::Both,
}))
.set_publish_all_ports(true);
let mut test = DockerTest::new().with_network(dockertest::Network::Isolated);
test.provide_container(composition);
test
}
async fn bitcoin(ops: &DockerOperations) -> Bitcoin {
let handle = ops.handle("serai-dev-bitcoin").host_port(8332).unwrap();
// TODO: Replace with a check if the node has booted
tokio::time::sleep(core::time::Duration::from_secs(20)).await;
let bitcoin = Bitcoin::new(format!("http://serai:seraidex@{}:{}", handle.0, handle.1)).await;
bitcoin.fresh_chain().await;
bitcoin
}
test_network!(
Bitcoin,
spawn_bitcoin,
bitcoin,
bitcoin_key_gen,
bitcoin_scanner,
@ -33,10 +72,44 @@ mod bitcoin {
#[cfg(feature = "monero")]
mod monero {
use super::*;
use crate::networks::{Network, Monero};
async fn monero() -> Monero {
let monero = Monero::new("http://127.0.0.1:18081".to_string());
fn spawn_monero() -> DockerTest {
serai_docker_tests::build("monero".to_string());
let composition = TestBodySpecification::with_image(
Image::with_repository("serai-dev-monero").pull_policy(PullPolicy::Never),
)
.replace_cmd(vec![
"monerod".to_string(),
"--regtest".to_string(),
"--offline".to_string(),
"--fixed-difficulty=1".to_string(),
"--rpc-bind-ip=0.0.0.0".to_string(),
format!("--rpc-login=serai:seraidex"),
"--rpc-access-control-origins=*".to_string(),
"--confirm-external-bind".to_string(),
"--non-interactive".to_string(),
])
.set_start_policy(StartPolicy::Strict)
.set_log_options(Some(LogOptions {
action: LogAction::Forward,
policy: LogPolicy::OnError,
source: LogSource::Both,
}))
.set_publish_all_ports(true);
let mut test = DockerTest::new().with_network(dockertest::Network::Isolated);
test.provide_container(composition);
test
}
async fn monero(ops: &DockerOperations) -> Monero {
let handle = ops.handle("serai-dev-monero").host_port(18081).unwrap();
// TODO: Replace with a check if the node has booted
tokio::time::sleep(core::time::Duration::from_secs(20)).await;
let monero = Monero::new(format!("http://serai:seraidex@{}:{}", handle.0, handle.1));
while monero.get_latest_block_number().await.unwrap() < 150 {
monero.mine_block().await;
}
@ -45,6 +118,7 @@ mod monero {
test_network!(
Monero,
spawn_monero,
monero,
monero_key_gen,
monero_scanner,

View file

@ -20,39 +20,11 @@ lazy_static::lazy_static! {
static ref INIT_LOGGER: () = env_logger::init();
}
#[macro_export]
macro_rules! sequential {
() => {
lazy_static::lazy_static! {
static ref SEQUENTIAL: tokio::sync::Mutex<()> = tokio::sync::Mutex::new(());
}
};
}
#[macro_export]
macro_rules! async_sequential {
($(async fn $name: ident() $body: block)*) => {
$(
#[tokio::test]
async fn $name() {
*$crate::tests::INIT_LOGGER;
let guard = SEQUENTIAL.lock().await;
let local = tokio::task::LocalSet::new();
local.run_until(async move {
if let Err(err) = tokio::task::spawn_local(async move { $body }).await {
drop(guard);
Err(err).unwrap()
}
}).await;
}
)*
}
}
#[macro_export]
macro_rules! test_network {
(
$N: ident,
$docker: ident,
$network: ident,
$key_gen: ident,
$scanner: ident,
@ -66,42 +38,50 @@ macro_rules! test_network {
test_addresses,
};
// This doesn't interact with a node and accordingly doesn't need to be run sequentially
// This doesn't interact with a node and accordingly doesn't need to be run
#[tokio::test]
async fn $key_gen() {
test_key_gen::<$N>().await;
}
sequential!();
async_sequential! {
async fn $scanner() {
test_scanner($network().await).await;
}
#[test]
fn $scanner() {
let docker = $docker();
docker.run(|ops| async move {
test_scanner($network(&ops).await).await;
});
}
async_sequential! {
async fn $signer() {
test_signer($network().await).await;
}
#[test]
fn $signer() {
let docker = $docker();
docker.run(|ops| async move {
test_signer($network(&ops).await).await;
});
}
async_sequential! {
async fn $wallet() {
test_wallet($network().await).await;
}
#[test]
fn $wallet() {
let docker = $docker();
docker.run(|ops| async move {
test_wallet($network(&ops).await).await;
});
}
async_sequential! {
async fn $addresses() {
test_addresses($network().await).await;
}
#[test]
fn $addresses() {
let docker = $docker();
docker.run(|ops| async move {
test_addresses($network(&ops).await).await;
});
}
async_sequential! {
async fn $no_deadlock_in_multisig_completed() {
test_no_deadlock_in_multisig_completed($network().await).await;
}
#[test]
fn $no_deadlock_in_multisig_completed() {
let docker = $docker();
docker.run(|ops| async move {
test_no_deadlock_in_multisig_completed($network(&ops).await).await;
});
}
};
}