Bitcoind
Utility to run a regtest bitcoind process, useful in integration testing environment.
use RpcApi;
let exe_path = exe_path.expect;
let bitcoind = new.unwrap;
assert_eq!;
Automatic binaries download
When a feature like 23_0 is selected, the build script will automatically download the bitcoin core version 23.0, verify the hashes and place it in the build directory for this crate.
Use utility function downloaded_exe_path() to get the downloaded executable path.
Example
In your project Cargo.toml, activate the following features
[]
= { = "0.20.0", = [ "23_0" ] }
Then use it:
let bitcoind = new.unwrap;
When the BITCOIND_DOWNLOAD_ENDPOINT environment variable is set, bitcoind will try to download the binaries from the given endpoint. Otherwise it defaults to https://bitcoincore.org/bin/.
MSRV
The MSRV is 1.41.1 for version 0.29.* if no feature is used, otherwise is 1.57
Note: to respect 1.41.1 MSRV you need to use and older version of the which and tempfile dependencies, like it's done in the CI cargo update -p which --precise 4.3.0 and cargo update -p tempfile --precise 3.3.0. Pinning in Cargo.toml is avoided because it could cause compilation issues downstream.
Issues with traditional approach
I used integration testing based on external bash script launching needed external processes, there are many issues with this approach like:
- External script may interfere with local development environment https://github.com/rust-bitcoin/rust-bitcoincore-rpc/blob/200fc8247c1896709a673b82a89ca0da5e7aa2ce/integration_test/run.sh#L9
- Use of a single huge test to test everything https://github.com/rust-bitcoin/rust-bitcoincore-rpc/blob/200fc8247c1896709a673b82a89ca0da5e7aa2ce/integration_test/src/main.rs#L122-L203
- If test are separated, a failing test may fail to leave a clean situation, causing other test to fail (because of the initial situation, not a real failure)
- bash script are hard, especially support different OS and versions
Features
- It waits until bitcoind daemon become ready to accept RPC commands
- bitcoind use a temporary directory as datadir. You can specify the root of your temp directories so that you have node's datadir in a RAM disk (eg
/dev/shm) - Free ports are asked to the OS (a low probability race condition is still possible)
- the process is killed when the struct goes out of scope no matter how the test finishes
- allows easy spawning of dependent process like https://github.com/RCasatta/electrsd
Thanks to these features every #[test] could easily run isolated with its own environment.