mina_node_testing/
lib.rs

1//! # Mina Node Testing Framework
2//!
3//! A comprehensive testing framework for the Mina Rust node implementation.
4//! Provides scenario-based testing capabilities with deterministic execution,
5//! cluster management, and cross-implementation compatibility testing.
6//!
7//! ## Key Features
8//!
9//! - **Scenario-based testing**: Deterministic, repeatable test sequences
10//! - **Cluster orchestration**: Multi-node test coordination
11//! - **Cross-implementation**: Tests both Rust and OCaml node compatibility
12//! - **Recording/replay**: Capture and reproduce test scenarios
13//! - **Network simulation**: Controlled network environments
14//!
15//! ## Documentation
16//!
17//! For detailed usage and examples, see:
18//! - [Scenario Tests](https://o1-labs.github.io/mina-rust/developers/testing/scenario-tests)
19//! - [Testing Framework](https://o1-labs.github.io/mina-rust/developers/testing/testing-framework)
20//! - [Network Connectivity](https://o1-labs.github.io/mina-rust/developers/testing/network-connectivity)
21//!
22//! ## Usage
23//!
24//! The main entry point is the `mina-node-testing` binary:
25//!
26//! ```bash
27//! # List available scenarios
28//! cargo run --release --bin mina-node-testing -- scenarios-list
29//!
30//! # Run a specific scenario
31//! cargo run --release --bin mina-node-testing -- scenarios-run --name scenario-name
32//! ```
33
34mod exit_with_error;
35
36use std::sync::Arc;
37
38pub use exit_with_error::exit_with_error;
39
40pub mod cluster;
41pub mod node;
42pub mod scenario;
43#[cfg(feature = "scenario-generators")]
44pub mod scenarios;
45pub mod service;
46pub mod simulator;
47
48pub mod hosts;
49pub mod network_debugger;
50
51mod server;
52pub use server::server;
53use tokio::sync::{Mutex, MutexGuard};
54
55pub fn setup() -> tokio::runtime::Runtime {
56    mina_node_native::tracing::initialize(mina_node_native::tracing::Level::INFO);
57    rayon::ThreadPoolBuilder::new()
58        .num_threads(num_cpus::get().max(2) - 1)
59        .thread_name(|i| format!("mina_rayon_{i}"))
60        .build_global()
61        .unwrap();
62
63    tokio::runtime::Builder::new_current_thread()
64        .enable_all()
65        .build()
66        .unwrap()
67}
68
69pub fn setup_without_rt() {
70    lazy_static::lazy_static! {
71        static ref INIT: () = {
72            let level = std::env::var("MINA_TRACING_LEVEL").ok().and_then(|level| {
73                match level.parse() {
74                    Ok(v) => Some(v),
75                    Err(e) => {
76                        eprintln!("cannot parse {level} as tracing level: {e}");
77                        None
78                    }
79                }
80            }).unwrap_or(mina_node_native::tracing::Level::INFO);
81            mina_node_native::tracing::initialize(level);
82
83            if let Err(err) = tracing_log::LogTracer::init() {
84                eprintln!("cannot initialize log tracing bridge: {err}");
85            }
86
87            rayon::ThreadPoolBuilder::new()
88                .num_threads(num_cpus::get().max(2) - 1)
89                .thread_name(|i| format!("mina_rayon_{i}"))
90                .build_global()
91                .unwrap();
92        };
93    };
94    *INIT;
95}
96
97lazy_static::lazy_static! {
98    static ref GATE: Arc<Mutex<()>> = Arc::new(Mutex::new(()));
99}
100
101pub struct TestGate(#[allow(dead_code)] MutexGuard<'static, ()>);
102
103impl TestGate {
104    async fn there_can_be_only_one() -> Self {
105        Self(GATE.lock().await)
106    }
107    pub fn release(self) {}
108}
109
110pub async fn wait_for_other_tests() -> TestGate {
111    TestGate::there_can_be_only_one().await
112}