feat: use testcontainers for integration tests#1572
feat: use testcontainers for integration tests#1572cylewitruk wants to merge 16 commits intomainfrom
testcontainers for integration tests#1572Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces the use of the testcontainers crate for integration tests by creating a dedicated crate (sbtc-docker-testing) and refactors existing regtest and integration test modules to support asynchronous testing with Tokio. It also updates the CI configuration and Nextest settings.
- Introduced sbtc-docker-testing for container image management and integration testing.
- Refactored the sbtc regtest module and integration tests to remove static references and leverage async tests.
- Updated Cargo.toml and CI workflows to include the new testing crate and nextest configuration.
Reviewed Changes
Copilot reviewed 36 out of 38 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| signer/src/testing/docker.rs | Added Docker test utilities for BitcoinCore. |
| signer/src/bitcoin/rpc.rs | Added AsRef and Deref implementations for BitcoinCoreClient. |
| signer/Cargo.toml | Updated testing features to include sbtc-docker-testing. |
| sbtc/tests/integration/validation.rs | Refactored integration tests to use async Tokio tests with testcontainers. |
| sbtc/src/testing/regtest.rs | Refactored regtest module and faucet initialization. |
| sbtc/Cargo.toml | Added sbtc-docker-testing dependency to the testing feature. |
| nextest.toml | Added configuration for test groups and overrides. |
| docker/docker-compose.test.yml | Commented out the bitcoind service configuration. |
| docker-testing/* | Added new testcontainers integration modules (images, logging, error). |
| Cargo.toml | Added docker-testing as a workspace member and dependency. |
| .github/workflows/on-push.yaml | Updated CI configuration with the new nextest version. |
Files not reviewed (2)
- .github/actions/docker.override.conf: Language not supported
- Makefile: Language not supported
Comments suppressed due to low confidence (1)
sbtc/src/testing/regtest.rs:211
- The signature for Faucet::new has been changed from taking a static reference to owning a Client, which might affect usage elsewhere. Confirm that this change is intentional and update documentation or related code if needed.
fn new(secret_key: &str, kind: AddressType, rpc: Client) -> Self {
| fn container_name(name: &str) -> String { | ||
| let suffix: String = rand::thread_rng() | ||
| .sample_iter(&Alphanumeric) | ||
| .take(12) |
There was a problem hiding this comment.
The documentation for container_name states an 8-character random suffix, but the code generates a 12-character suffix. Please update the comment or modify the code to ensure consistency.
| } | ||
| }) | ||
| .await | ||
| .expect("ZMQ endpooint not accessible within allotted timeout"); |
There was a problem hiding this comment.
| .expect("ZMQ endpooint not accessible within allotted timeout"); | |
| .expect("ZMQ endpoint not accessible within allotted timeout"); |
| /// # Returns | ||
| /// * `Ok(())` if connection was established successfully | ||
| /// * `Err(Error)` if timeout occurred before successful connection | ||
| pub async fn wait_for_tcp_connectivity(host: &str, port: u16, timeout: Duration) { |
There was a problem hiding this comment.
Why not use a circuit breaker here (like failsafe-rs or resilient) with exponential back-offs instead of manually handling timeouts?
There was a problem hiding this comment.
We want the tests to be able to continue ASAP, so exponential back-off isn't really applicable, at least in the current use case. This is almost instantaneous in the current usages as well, so bringing in another dependency for something tokio already gives us isn't very appealing.
| .map(char::from) | ||
| .collect(); | ||
|
|
||
| format!("sbtc-test-{name}-{suffix}") |
There was a problem hiding this comment.
Could we include the test name in the container name for easier debugging?
- Current:
sbtc-test-bitcoind-abc123 - Maybe:
sbtc-test-bitcoind-test_get_block_works-abc123?
In this example, test_get_block_works is the test name (can probably be derived).
There was a problem hiding this comment.
Using a derive macro, sure, but otherwise we're stuck either providing the name as a string, or using a (questionably reliable) hack like any::type_name<fn()>() and stripping module prefix/suffixes...
| more-asserts.workspace = true | ||
| sbtc = { path = ".", features = ["testing"] } | ||
| sbtc-docker-testing.workspace = true | ||
| tokio.workspace = true No newline at end of file |
| assert_matches.workspace = true | ||
| more-asserts.workspace = true No newline at end of file | ||
| more-asserts.workspace = true | ||
| sbtc = { path = ".", features = ["testing"] } |
| } | ||
|
|
||
| // Return an immediately-resolved future | ||
| async move {}.boxed() |
There was a problem hiding this comment.
I think you can return std::future::ready(()) here.
Description
Supersedes: #1223
Probably 80% of the changes here are updating tests to use testcontainers vs.
regtest::initialize_blockchain().Changes
testcontainerscrate and implements images for bitcoin core and emily & co. I stuffed these into a separate cratesbtc-docker-testingat the moment, I'm on the fence if we should bake it into thesbtccrate or not...sbtc::testing::regtestmodule a bit to get rid ofstaticreferences (it made sense when there was only a singlebitcoind...).nextest.tomland updates theMakefilecommands to use it. This lets us specify specific test filters that nextest will use to group tests, run certain tests serially, using more/less threads, etc.Note that the current structure is:
sbtc-docker-testingcrate: contains the basetestcontainersintegrationsbtccrate: builds onsbtc-docker-testingadding "common" regtest functionality (faucet, etc). Needed here to support the integration tests in this crate.signercrate: builds on bothsbtcandsbtc-docker-testing, adding additional support for e.g.BitcoinCoreClient,BitcoinCoreMessageStreametc. which are local to this crate.Testing Information
nextest(cargo install nextest --locked) as some of the config file options are only available in newer versions.maketesting commands as usual.P.S. still working on getting CI to work properly
Checklist: