# Development ## The loop ```sh cargo check --features mycelium,libp2p,tor,dashboard # does it compile: seconds cargo quick # every test but the simulations: seconds cargo sim # the simulations (src/simtest/): under a minute cargo test --features mycelium,libp2p,tor,dashboard # both cargo benchmarks # the benchmarks, in release builds ``` `cargo quick`, `cargo sim` and `cargo benchmarks` are aliases ([`.cargo/config.toml`](../.cargo/config.toml)), with every transport and the dashboard (`dashboard`, `GET /admin/dashboard`; [`docs/dashboard.md`](dashboard.md)). Each transport is a feature, none of them default, and a build needs at least one: a transport left out takes its tests and dependencies with it (`--features libp2p` builds neither `reqwest` and the daemon supervision of Mycelium, nor arti; among Mycelium's tests is a swarm simulated on its envelope). The benchmarks are ignored tests named `bench_*`: the document's (writes and sync messages, `document/bench.rs`), the remakes' replay (`remake/bench.rs`), and what passing changes on costs over the simulated network (`simtest/bench.rs`: messages and bytes per write by kind, propagation delays, for a full mesh, a writer behind NAT, two transports, partial meshes of 50 and 100 nodes, lossy links (with delays at random, and with Mycelium's round trips, each link its own; and Tor's, with some slow circuits), a member away for a while, and members joining during the writes; several minutes, or one scenario alone with `BENCH_SCENARIO`, part of its name: `BENCH_SCENARIO=NAT`; all at once with `BENCH_PARALLEL=1`, faster on many cores, though sharing them makes delays come out somewhat higher; and in `bench_bridge`, large values from a writer on a fast transport through a bridge to a node on a slow one: what that node gets as sync messages and as blobs against what was written, 200 values unless `BENCH_BRIDGE_WRITES` says otherwise, over a fast link of 1 GiB/s and 5 ms round trips and a slow one of 50 MiB/s and 500 ms unless `BENCH_BRIDGE_FAST_RATE`, `BENCH_BRIDGE_SLOW_RATE` (MiB/s), `BENCH_BRIDGE_FAST_RTT` and `BENCH_BRIDGE_SLOW_RTT` (ms) say otherwise), and the same estimated on the member list's graph alone for up to 2000 members, with some links down, as now and along the writer's tree (`swarm/topology/tests.rs`, `bench_writer_trees`). One of them alone: `cargo test --release --features mycelium,libp2p,tor,dashboard bench_propagation -- --ignored --nocapture`. The simulations send the wire encoding alone, as libp2p and Tor do; a simulated net can put messages into a transport's envelope instead (`SimNet::with_codec`), and every message kind is round-tripped through each codec (`wire::samples`). The dev profile ([`Cargo.toml`](../Cargo.toml)) keeps the loop short: the crate gets line tables only (backtraces still name files and lines), and the dependencies are built optimised and without debug info. Automerge's work dominates the tests, so they run several times faster; the binaries are a quarter of the size, so they link faster. The dependencies build once (a few minutes, longer on few cores); after that, a change rebuilds in seconds. To step through a dependency in a debugger, override it locally (`debug = true` for that package). Measured on 2 cores, `--features libp2p,tor` (before Mycelium became a feature), after touching one file, with Cargo's default dev profile and with this one: | | Default profile | This profile | |---|---|---| | `cargo check` | — | 3 s | | test build | 8 s | 6 s | | binary build | 13 s | 6 s | | tests but the simulations | 6 s | 1.4 s | | all tests | 40 s | 31–35 s | | test binary | 550–670 MB | 100–155 MB | ## The simulations The simulations ([`src/simtest/`](../src/simtest/)) run whole nodes on a simulated network ([`transport/sim.rs`](../src/transport/sim.rs)), in real time: tokio's clock isn't paused, because a node's document work runs on the blocking pool, which a paused clock doesn't wait for. So they take as long as the protocol's timeouts make them, however fast the machine, and on a busy machine some fail now and then (a node's timer fires before the work it waits for is done). One failing alone (`cargo sim `) and passing then is that, not a regression; one failing again and again is a regression. A node on several transports is a node on several simulated nets, one per scheme (`Sim::start_on`, under the identity layer): nodes on different nets can't reach each other, as one on Tor alone and one on libp2p alone can't, so a swarm whose transports don't all meet is simulated with the simulated transport alone.