Skip to content

Port the integration tests to Rust code - #969

Draft
bal-e wants to merge 14 commits into
mainfrom
rusty-integration-tests
Draft

Port the integration tests to Rust code#969
bal-e wants to merge 14 commits into
mainfrom
rusty-integration-tests

Conversation

@bal-e

@bal-e bal-e commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

This introduces a new pure-Rust integration test infrastructure. Like the existing infrastructure, it relies on Docker; but it uses bollard to control Docker from Rust. Tests are written as Rust code that starts and manipulates Docker containers. Tests run in parallel (using a shared multi-threaded Tokio runtime) and are very efficient. I have also optimized the Docker image, minimizing the Docker context and parallelizing some steps.

Advantages:

  • Tests can run in CI.
  • Tests can programmatically manipulate data:
    • Using serde types instead of sed to change config files.
    • Generating test zones (including signed ones) programmatically.
    • Automatically updating
  • Tests are significantly faster and more efficient.
    • Also improves our ability to catch race conditions.
  • All our tests are unified under cargo test.

It retains the advantages of the existing infrastructure (running tests in a clean and reproducible environment, exercising all the dnst keyset code, isolating dependency versions).

Disadvantages:

  • The new infrastructure does not test the cascade CLI.
  • The large amount of new code. The new infrastructure is ~2000 lines of (fairly involved) Rust code, while the existing infrastructure was ~1500 lines of shell scripts and GitHub actions.
  • bollard adds to our dependency tree, but only for development.
A simple benchmark

Both are run with a hot cache.

Existing infrastructure:

> time ./act-wrapper --rm --job add-zone-query --job remove-zone
________________________________________________________
Executed in    4.89 secs    fish           external
   usr time    2.86 secs    1.37 millis    2.86 secs
   sys time    1.31 secs    0.11 millis    1.31 secs

This PR:

> time cargo test --test integration -- add-zone-query remove-zone
________________________________________________________
Executed in    1.24 secs      fish           external
   usr time  142.19 millis    0.00 millis  142.19 millis
   sys time   29.39 millis    1.42 millis   27.98 millis

While the overall latency is not very different, there is an order-of-magnitude difference in the (userspace and kernelspace) CPU time. This suggests the new infrastructure will scale much better to a large number of tests.

Most of the new code is in tests/integration/infra. A quick overview:

  • image.rs -- building the Docker image
  • container.rs -- managing and interacting with Docker containers (startup, shutdown, sending DNS queries, executing commands, changing files, dumping tarballs)
  • cascade.rs -- programmatic control of Cascade (startup, shutdown, communication over HTTP API)
  • services.rs -- managing Unbound, BIND, NSD, etc. (similar to manage-test-environment.sh)
  • test.rs -- defining tests, filtering names, multiplexing (filling in for act)
  • runtime.rs -- helpers for async code (catching signals, async drop)

tests/integration/main.rs contains the tests as well as the top-level runner code (including argument parsing, because it can't use the normal Rust test harness).

@bal-e bal-e self-assigned this Aug 18, 2026
@bal-e
bal-e force-pushed the rusty-integration-tests branch 3 times, most recently from aa89e81 to 77d12c1 Compare August 18, 2026 19:55
@bal-e
bal-e force-pushed the rusty-integration-tests branch from 77d12c1 to 63daba9 Compare August 18, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant