188 lines
5.7 KiB
Markdown
Raw Normal View History

# Quickstart
Get a working example running quickly.
## Prerequisites
- Rust toolchain (nightly)
- Sibling `nomos-node` checkout built and available
- This repository cloned
- Unix-like system (tested on Linux and macOS)
## Your First Test
The framework ships with runnable example binaries in `examples/src/bin/`. Let's start with the local runner:
```bash
# From the nomos-testing directory
POL_PROOF_DEV_MODE=true cargo run -p runner-examples --bin local_runner
```
This runs a complete scenario with **defaults**: 1 validator + 1 executor, mixed transaction + DA workload (5 tx/block + 1 channel + 1 blob), 60s duration.
**Core API Pattern** (simplified example):
```rust
use testing_framework_core::scenario::{Deployer, ScenarioBuilder};
use testing_framework_runner_local::LocalDeployer;
use testing_framework_workflows::ScenarioBuilderExt;
use std::time::Duration;
// Define the scenario (1 validator + 1 executor, tx + DA workload)
let mut plan = ScenarioBuilder::topology()
.network_star()
.validators(1)
.executors(1)
.apply()
.wallets(64)
.transactions()
.rate(5) // 5 transactions per block
.users(8)
.apply()
.da()
.channel_rate(1) // 1 channel operation per block
.blob_rate(1) // 1 blob dispersal per block
.apply()
.expect_consensus_liveness()
.with_run_duration(Duration::from_secs(60))
.build();
// Deploy and run
let deployer = LocalDeployer::default();
let runner = deployer.deploy(&plan).await?;
let _handle = runner.run(&mut plan).await?;
```
**Note:** The examples are binaries with `#[tokio::main]`, not test functions. If you want to write integration tests, wrap this pattern in `#[tokio::test]` functions in your own test suite.
**Important:** `POL_PROOF_DEV_MODE=true` disables expensive Groth16 zero-knowledge proof generation for leader election. Without it, proof generation is CPU-intensive and tests will timeout. **This is required for all runners** (local, compose, k8s) for practical testing. Never use in production.
**What you should see:**
- Nodes spawn as local processes
- Consensus starts producing blocks
- Scenario runs for the configured duration
- Node logs written to temporary directories in working directory (auto-cleaned up after test)
- To persist logs: set `NOMOS_TESTS_TRACING=true` and `NOMOS_LOG_DIR=/path/to/logs` (files will have prefix like `nomos-node-0*`, may include timestamps)
## What Just Happened?
Let's unpack the code:
### 1. Topology Configuration
```rust
ScenarioBuilder::topology()
.network_star() // Star topology: all nodes connect to seed
.validators(1) // 1 validator node
.executors(1) // 1 executor node (validator + DA dispersal)
.apply()
```
This defines **what** your test network looks like.
### 2. Wallet Seeding
```rust
.wallets(64) // Seed 64 funded wallet accounts
```
Provides funded accounts for transaction submission.
### 3. Workloads
```rust
.transactions()
.rate(5) // 5 transactions per block
.users(8) // Use 8 of the 64 wallets
.apply()
.da()
.channel_rate(1) // 1 channel operation per block
.blob_rate(1) // 1 blob dispersal per block
.apply()
```
Generates both transaction and DA traffic to stress both subsystems.
### 4. Expectation
```rust
.expect_consensus_liveness()
```
This says **what success means**: blocks must be produced continuously.
### 5. Run Duration
```rust
.with_run_duration(Duration::from_secs(60))
```
Run for 60 seconds (~27 blocks with default 2s slots, 0.9 coefficient). Framework ensures this is at least 2× the consensus slot duration.
### 6. Deploy and Execute
```rust
let deployer = LocalDeployer::default(); // Use local process deployer
let runner = deployer.deploy(&plan).await?; // Provision infrastructure
let _handle = runner.run(&mut plan).await?; // Execute workloads & expectations
```
**Deployer** provisions the infrastructure. **Runner** orchestrates execution.
## Adjust the Topology
The binary accepts environment variables to adjust defaults:
```bash
# Scale up to 3 validators + 2 executors, run for 2 minutes
LOCAL_DEMO_VALIDATORS=3 \
LOCAL_DEMO_EXECUTORS=2 \
LOCAL_DEMO_RUN_SECS=120 \
POL_PROOF_DEV_MODE=true \
cargo run -p runner-examples --bin local_runner
```
## Try Docker Compose
Use the same API with a different deployer for reproducible containerized environment:
```bash
# Build the test image first (includes circuit assets)
chmod +x scripts/setup-nomos-circuits.sh
scripts/setup-nomos-circuits.sh v0.3.1 /tmp/nomos-circuits
cp -r /tmp/nomos-circuits/* testing-framework/assets/stack/kzgrs_test_params/
chmod +x testing-framework/assets/stack/scripts/build_test_image.sh
testing-framework/assets/stack/scripts/build_test_image.sh
# Run with Compose
NOMOS_TESTNET_IMAGE=nomos-testnet:local \
POL_PROOF_DEV_MODE=true \
cargo run -p runner-examples --bin compose_runner
```
**Benefit:** Reproducible containerized environment with Prometheus at `http://localhost:9090`.
**In code:** Just swap the deployer:
```rust
use testing_framework_runner_compose::ComposeDeployer;
// ... same scenario definition ...
let deployer = ComposeDeployer::default(); // Use Docker Compose
let runner = deployer.deploy(&plan).await?;
let _handle = runner.run(&mut plan).await?;
```
## Next Steps
Now that you have a working test:
- **Understand the philosophy**: [Testing Philosophy](testing-philosophy.md)
- **Learn the architecture**: [Architecture Overview](architecture-overview.md)
- **See more examples**: [Examples](examples.md)
- **API reference**: [Builder API Quick Reference](dsl-cheat-sheet.md)
- **Debug failures**: [Troubleshooting](troubleshooting.md)